FreeCalypso > hg > gsm-codec-lib
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 |
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 } |