comparison miscutil/pcm16-to-ulaw.c @ 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 67cbfa0aeb1c
children
comparison
equal deleted inserted replaced
233:bbdefd2ef950 234:c7f02428bda6
1 /* 1 /*
2 * This program reads a 16-bit PCM recording in raw format (robe by default, 2 * This program reads a 16-bit PCM recording in raw format (robe by default,
3 * or LE with -l option) and converts it to 8-bit PCM in North American 3 * or LE with -l option) and converts it to 8-bit PCM in North American
4 * mu-law encoding. It is based on the ulaw_compress() function from ITU-T 4 * mu-law encoding. It is based on the ulaw_compress() function from ITU-T
5 * G.191 STL, using the most significant 14 bits of each input linear PCM 5 * G.191 STL, using the most significant 14 bits of each input linear PCM
6 * sample, rather than just 13. 6 * sample, rather than just 13. A command line option is also provided
7 * to truncate each input value to 13 bits prior to mu-law encoding, to
8 * replicate the effect of using a table lookup conversion method that
9 * only considers the upper 13 bits - specify -t option to select this mode.
7 */ 10 */
8 11
9 #include <stdio.h> 12 #include <stdio.h>
10 #include <stdint.h> 13 #include <stdint.h>
11 #include <stdlib.h> 14 #include <stdlib.h>
12 #include <string.h> 15 #include <string.h>
13 #include <strings.h> 16 #include <strings.h>
17 #include <unistd.h>
14 18
15 static unsigned 19 static unsigned
16 ulaw_compress(input) 20 ulaw_compress(input)
17 unsigned input; 21 unsigned input;
18 { 22 {
62 } 66 }
63 67
64 main(argc, argv) 68 main(argc, argv)
65 char **argv; 69 char **argv;
66 { 70 {
67 int little_endian; 71 int opt, little_endian = 0, truncate = 0;
68 char *infname, *outfname; 72 char *infname, *outfname;
69 FILE *inf, *outf; 73 FILE *inf, *outf;
70 uint8_t inb[2]; 74 uint8_t inb[2];
71 uint16_t ins; 75 uint16_t ins;
72 int cc; 76 int cc;
77 extern int optind;
73 78
74 if (argc == 3 && argv[1][0] != '-') { 79 while ((opt = getopt(argc, argv, "lt")) != EOF) {
75 little_endian = 0; 80 switch (opt) {
76 infname = argv[1]; 81 case 'l':
77 outfname = argv[2]; 82 little_endian = 1;
78 } else if (argc == 4 && !strcmp(argv[1], "-l")) { 83 continue;
79 little_endian = 1; 84 case 't':
80 infname = argv[2]; 85 truncate = 1;
81 outfname = argv[3]; 86 continue;
82 } else { 87 default:
83 fprintf(stderr, "usage: %s [-l] input.pcm16 output.ulaw\n", 88 usage:
84 argv[0]); 89 fprintf(stderr,
85 exit(1); 90 "usage: %s [-l] [-t] input.pcm16 output.ulaw\n",
91 argv[0]);
92 exit(1);
93 }
86 } 94 }
95 if (argc != optind + 2)
96 goto usage;
97 infname = argv[optind];
98 outfname = argv[optind+1];
99
87 inf = fopen(infname, "r"); 100 inf = fopen(infname, "r");
88 if (!inf) { 101 if (!inf) {
89 perror(infname); 102 perror(infname);
90 exit(1); 103 exit(1);
91 } 104 }
105 } 118 }
106 if (little_endian) 119 if (little_endian)
107 ins = ((uint16_t) inb[1] << 8) | ((uint16_t) inb[0]); 120 ins = ((uint16_t) inb[1] << 8) | ((uint16_t) inb[0]);
108 else 121 else
109 ins = ((uint16_t) inb[0] << 8) | ((uint16_t) inb[1]); 122 ins = ((uint16_t) inb[0] << 8) | ((uint16_t) inb[1]);
110 putc(ulaw_compress(ins >> 2), outf); 123 ins >>= 2;
124 if (truncate)
125 ins &= ~1;
126 putc(ulaw_compress(ins), outf);
111 } 127 }
112 fclose(outf); 128 fclose(outf);
113 exit(0); 129 exit(0);
114 } 130 }