changeset 234:c7f02428bda6

pcm16-to-ulaw: add -t option for 13-bit mode
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 07 May 2023 21:56:09 +0000
parents bbdefd2ef950
children 0ee1a66c1846
files miscutil/pcm16-to-ulaw.c
diffstat 1 files changed, 31 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/miscutil/pcm16-to-ulaw.c	Sun May 07 21:19:30 2023 +0000
+++ b/miscutil/pcm16-to-ulaw.c	Sun May 07 21:56:09 2023 +0000
@@ -3,7 +3,10 @@
  * or LE with -l option) and converts it to 8-bit PCM in North American
  * mu-law encoding.  It is based on the ulaw_compress() function from ITU-T
  * G.191 STL, using the most significant 14 bits of each input linear PCM
- * sample, rather than just 13.
+ * sample, rather than just 13.  A command line option is also provided
+ * to truncate each input value to 13 bits prior to mu-law encoding, to
+ * replicate the effect of using a table lookup conversion method that
+ * only considers the upper 13 bits - specify -t option to select this mode.
  */
 
 #include <stdio.h>
@@ -11,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <unistd.h>
 
 static unsigned
 ulaw_compress(input)
@@ -64,26 +68,35 @@
 main(argc, argv)
 	char **argv;
 {
-	int little_endian;
+	int opt, little_endian = 0, truncate = 0;
 	char *infname, *outfname;
 	FILE *inf, *outf;
 	uint8_t inb[2];
 	uint16_t ins;
 	int cc;
+	extern int optind;
 
-	if (argc == 3 && argv[1][0] != '-') {
-		little_endian = 0;
-		infname = argv[1];
-		outfname = argv[2];
-	} else if (argc == 4 && !strcmp(argv[1], "-l")) {
-		little_endian = 1;
-		infname = argv[2];
-		outfname = argv[3];
-	} else {
-		fprintf(stderr, "usage: %s [-l] input.pcm16 output.ulaw\n",
-			argv[0]);
-		exit(1);
+	while ((opt = getopt(argc, argv, "lt")) != EOF) {
+		switch (opt) {
+		case 'l':
+			little_endian = 1;
+			continue;
+		case 't':
+			truncate = 1;
+			continue;
+		default:
+		usage:
+			fprintf(stderr,
+				"usage: %s [-l] [-t] input.pcm16 output.ulaw\n",
+				argv[0]);
+			exit(1);
+		}
 	}
+	if (argc != optind + 2)
+		goto usage;
+	infname = argv[optind];
+	outfname = argv[optind+1];
+
 	inf = fopen(infname, "r");
 	if (!inf) {
 		perror(infname);
@@ -107,7 +120,10 @@
 			ins = ((uint16_t) inb[1] << 8) | ((uint16_t) inb[0]);
 		else
 			ins = ((uint16_t) inb[0] << 8) | ((uint16_t) inb[1]);
-		putc(ulaw_compress(ins >> 2), outf);
+		ins >>= 2;
+		if (truncate)
+			ins &= ~1;
+		putc(ulaw_compress(ins), outf);
 	}
 	fclose(outf);
 	exit(0);