annotate miscutil/pcm16-to-ulaw.c @ 229:f00bf3687286

pcm16-to-ulaw: replace toast table with STL function
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 23 Apr 2023 17:19:03 +0000
parents c4c45148cde1
children 67cbfa0aeb1c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
219
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This program reads a 16-bit PCM recording in raw format (robe by default,
220
c4c45148cde1 miscutil: new program pcm16-to-ulaw
Mychaela Falconia <falcon@freecalypso.org>
parents: 219
diff changeset
3 * or LE with -l option) and converts it to 8-bit PCM in North American
229
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
4 * mu-law encoding. It is based on the ulaw_compress() function from ITU-T
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
5 * G.191 STL, using the most significant 14 bits of each input linear PCM
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
6 * sample, rather than just 13.
219
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 */
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdio.h>
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdint.h>
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdlib.h>
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <string.h>
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <strings.h>
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14
229
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
15 static unsigned
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
16 ulaw_compress(input)
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
17 unsigned input;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
18 {
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
19 short i; /* aux.var. */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
20 short absno; /* absolute value of linear (input) sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
21 short segno; /* segment (Table 2/G711, column 1) */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
22 short low_nibble; /* low nibble of log companded sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
23 short high_nibble; /* high nibble of log companded sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
24 unsigned output;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
25
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
26 /* -------------------------------------------------------------------- */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
27 /* Input is 14-bit right-justified in this version */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
28 /* Compute absolute value; adjust for easy processing */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
29 /* -------------------------------------------------------------------- */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
30 absno = input >= 0x2000 /* compute 1's complement in case of */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
31 ? (~input & 0x1FFF) + 33 /* negative samples */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
32 : input + 33; /* NB: 33 is the difference value */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
33 /* between the thresholds for */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
34 /* A-law and u-law. */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
35 if (absno > (0x1FFF)) /* limitation to "absno" < 8192 */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
36 absno = (0x1FFF);
219
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37
229
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
38 /* Determination of sample's segment */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
39 i = absno >> 6;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
40 segno = 1;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
41 while (i != 0) {
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
42 segno++;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
43 i >>= 1;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
44 }
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
45
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
46 /* Mounting the high-nibble of the log-PCM sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
47 high_nibble = (0x0008) - segno;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
48
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
49 /* Mounting the low-nibble of the log PCM sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
50 low_nibble = (absno >> segno) /* right shift of mantissa and */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
51 &(0x000F); /* masking away leading '1' */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
52 low_nibble = (0x000F) - low_nibble;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
53
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
54 /* Joining the high-nibble and the low-nibble of the log PCM sample */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
55 output = (high_nibble << 4) | low_nibble;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
56
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
57 /* Add sign bit */
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
58 if (input < 0x2000)
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
59 output = output | (0x0080);
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
60
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
61 return output;
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
62 }
219
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 main(argc, argv)
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 char **argv;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 int little_endian;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 char *infname, *outfname;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 FILE *inf, *outf;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 uint8_t inb[2];
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 uint16_t ins;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 int cc;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 if (argc == 3 && argv[1][0] != '-') {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 little_endian = 0;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 infname = argv[1];
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 outfname = argv[2];
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 } else if (argc == 4 && !strcmp(argv[1], "-l")) {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 little_endian = 1;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 infname = argv[2];
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 outfname = argv[3];
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 } else {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 fprintf(stderr, "usage: %s [-l] input.pcm16 output.alaw\n",
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 argv[0]);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 exit(1);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 }
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 inf = fopen(infname, "r");
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 if (!inf) {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 perror(infname);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 exit(1);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 }
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 outf = fopen(outfname, "w");
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 if (!outf) {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 perror(outfname);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 exit(1);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 }
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 for (;;) {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 cc = fread(inb, 1, 2, inf);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 if (cc <= 0)
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 break;
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 if (cc & 1) {
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 fprintf(stderr, "error: %s has odd number of bytes\n",
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 infname);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 exit(1);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 }
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 if (little_endian)
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 ins = ((uint16_t) inb[1] << 8) | ((uint16_t) inb[0]);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 else
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 ins = ((uint16_t) inb[0] << 8) | ((uint16_t) inb[1]);
229
f00bf3687286 pcm16-to-ulaw: replace toast table with STL function
Mychaela Falconia <falcon@freecalypso.org>
parents: 220
diff changeset
110 putc(ulaw_compress(ins >> 2), outf);
219
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 }
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 fclose(outf);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 exit(0);
dc52c3857bf7 miscutil: new program pcm16-to-alaw
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 }