diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2010-01-27 17:25:10 +0000 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2010-01-27 17:25:10 +0000 |
commit | c9183bf15e56bbc795f9fb08027ee6285b2ebed4 (patch) | |
tree | e355d4ebbdb9b06e7da5260ec58679aa96da15f1 /apps/codecs/libpcm/itut_g711.c | |
parent | 7a50f6f2740b84d10cbb021fd59a870c09688b88 (diff) | |
download | rockbox-c9183bf15e56bbc795f9fb08027ee6285b2ebed4.tar.gz rockbox-c9183bf15e56bbc795f9fb08027ee6285b2ebed4.zip |
Commit FS#10422 by Yoshihisa Uchida. Seperates WAV and AIFF parsing from PCM decoding by introducing libpcm, a library for decoding linear and non-uniform PCM independently of the container format.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24346 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libpcm/itut_g711.c')
-rw-r--r-- | apps/codecs/libpcm/itut_g711.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c new file mode 100644 index 0000000000..1f235943ad --- /dev/null +++ b/apps/codecs/libpcm/itut_g711.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Dave Chapman | ||
11 | * Copyright (C) 2009 Yoshihisa Uchida | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include "codeclib.h" | ||
23 | #include "pcm_common.h" | ||
24 | |||
25 | /* | ||
26 | * ITU-T G.711 A-law mu-law | ||
27 | */ | ||
28 | |||
29 | static const int16_t alaw2linear16[256] ICONST_ATTR = { | ||
30 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, | ||
31 | -4736, -7552, -7296, -8064, -7808, -6528, -6272, | ||
32 | -7040, -6784, -2752, -2624, -3008, -2880, -2240, | ||
33 | -2112, -2496, -2368, -3776, -3648, -4032, -3904, | ||
34 | -3264, -3136, -3520, -3392, -22016, -20992, -24064, | ||
35 | -23040, -17920, -16896, -19968, -18944, -30208, -29184, | ||
36 | -32256, -31232, -26112, -25088, -28160, -27136, -11008, | ||
37 | -10496, -12032, -11520, -8960, -8448, -9984, -9472, | ||
38 | -15104, -14592, -16128, -15616, -13056, -12544, -14080, | ||
39 | -13568, -344, -328, -376, -360, -280, -264, | ||
40 | -312, -296, -472, -456, -504, -488, -408, | ||
41 | -392, -440, -424, -88, -72, -120, -104, | ||
42 | -24, -8, -56, -40, -216, -200, -248, | ||
43 | -232, -152, -136, -184, -168, -1376, -1312, | ||
44 | -1504, -1440, -1120, -1056, -1248, -1184, -1888, | ||
45 | -1824, -2016, -1952, -1632, -1568, -1760, -1696, | ||
46 | -688, -656, -752, -720, -560, -528, -624, | ||
47 | -592, -944, -912, -1008, -976, -816, -784, | ||
48 | -880, -848, 5504, 5248, 6016, 5760, 4480, | ||
49 | 4224, 4992, 4736, 7552, 7296, 8064, 7808, | ||
50 | 6528, 6272, 7040, 6784, 2752, 2624, 3008, | ||
51 | 2880, 2240, 2112, 2496, 2368, 3776, 3648, | ||
52 | 4032, 3904, 3264, 3136, 3520, 3392, 22016, | ||
53 | 20992, 24064, 23040, 17920, 16896, 19968, 18944, | ||
54 | 30208, 29184, 32256, 31232, 26112, 25088, 28160, | ||
55 | 27136, 11008, 10496, 12032, 11520, 8960, 8448, | ||
56 | 9984, 9472, 15104, 14592, 16128, 15616, 13056, | ||
57 | 12544, 14080, 13568, 344, 328, 376, 360, | ||
58 | 280, 264, 312, 296, 472, 456, 504, | ||
59 | 488, 408, 392, 440, 424, 88, 72, | ||
60 | 120, 104, 24, 8, 56, 40, 216, | ||
61 | 200, 248, 232, 152, 136, 184, 168, | ||
62 | 1376, 1312, 1504, 1440, 1120, 1056, 1248, | ||
63 | 1184, 1888, 1824, 2016, 1952, 1632, 1568, | ||
64 | 1760, 1696, 688, 656, 752, 720, 560, | ||
65 | 528, 624, 592, 944, 912, 1008, 976, | ||
66 | 816, 784, 880, 848 | ||
67 | }; | ||
68 | |||
69 | static const int16_t ulaw2linear16[256] ICONST_ATTR = { | ||
70 | -32124, -31100, -30076, -29052, -28028, -27004, -25980, | ||
71 | -24956, -23932, -22908, -21884, -20860, -19836, -18812, | ||
72 | -17788, -16764, -15996, -15484, -14972, -14460, -13948, | ||
73 | -13436, -12924, -12412, -11900, -11388, -10876, -10364, | ||
74 | -9852, -9340, -8828, -8316, -7932, -7676, -7420, | ||
75 | -7164, -6908, -6652, -6396, -6140, -5884, -5628, | ||
76 | -5372, -5116, -4860, -4604, -4348, -4092, -3900, | ||
77 | -3772, -3644, -3516, -3388, -3260, -3132, -3004, | ||
78 | -2876, -2748, -2620, -2492, -2364, -2236, -2108, | ||
79 | -1980, -1884, -1820, -1756, -1692, -1628, -1564, | ||
80 | -1500, -1436, -1372, -1308, -1244, -1180, -1116, | ||
81 | -1052, -988, -924, -876, -844, -812, -780, | ||
82 | -748, -716, -684, -652, -620, -588, -556, | ||
83 | -524, -492, -460, -428, -396, -372, -356, | ||
84 | -340, -324, -308, -292, -276, -260, -244, | ||
85 | -228, -212, -196, -180, -164, -148, -132, | ||
86 | -120, -112, -104, -96, -88, -80, -72, | ||
87 | -64, -56, -48, -40, -32, -24, -16, | ||
88 | -8, 0, 32124, 31100, 30076, 29052, 28028, | ||
89 | 27004, 25980, 24956, 23932, 22908, 21884, 20860, | ||
90 | 19836, 18812, 17788, 16764, 15996, 15484, 14972, | ||
91 | 14460, 13948, 13436, 12924, 12412, 11900, 11388, | ||
92 | 10876, 10364, 9852, 9340, 8828, 8316, 7932, | ||
93 | 7676, 7420, 7164, 6908, 6652, 6396, 6140, | ||
94 | 5884, 5628, 5372, 5116, 4860, 4604, 4348, | ||
95 | 4092, 3900, 3772, 3644, 3516, 3388, 3260, | ||
96 | 3132, 3004, 2876, 2748, 2620, 2492, 2364, | ||
97 | 2236, 2108, 1980, 1884, 1820, 1756, 1692, | ||
98 | 1628, 1564, 1500, 1436, 1372, 1308, 1244, | ||
99 | 1180, 1116, 1052, 988, 924, 876, 844, | ||
100 | 812, 780, 748, 716, 684, 652, 620, | ||
101 | 588, 556, 524, 492, 460, 428, 396, | ||
102 | 372, 356, 340, 324, 308, 292, 276, | ||
103 | 260, 244, 228, 212, 196, 180, 164, | ||
104 | 148, 132, 120, 112, 104, 96, 88, | ||
105 | 80, 72, 64, 56, 48, 40, 32, | ||
106 | 24, 16, 8, 0 | ||
107 | }; | ||
108 | |||
109 | static struct pcm_format *fmt; | ||
110 | |||
111 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | ||
112 | { | ||
113 | fmt = format; | ||
114 | |||
115 | (void)fmtpos; | ||
116 | |||
117 | if (fmt->bitspersample != 8) | ||
118 | { | ||
119 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | if (fmt->totalsamples == 0) | ||
124 | { | ||
125 | fmt->bytespersample = fmt->channels; | ||
126 | fmt->totalsamples = fmt->numbytes/fmt->bytespersample; | ||
127 | } | ||
128 | |||
129 | /* chunksize is computed so that one chunk is about 1/50s. | ||
130 | * this make 4096 for 44.1kHz 16bits stereo. | ||
131 | * It also has to be a multiple of blockalign */ | ||
132 | fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign; | ||
133 | |||
134 | /* check that the output buffer is big enough (convert to samplespersec, | ||
135 | then round to the blockalign multiple below) */ | ||
136 | if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3) | ||
137 | /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE) | ||
138 | fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec | ||
139 | /((uint64_t)ci->id3->frequency * fmt->channels * 2 | ||
140 | * fmt->blockalign)) * fmt->blockalign; | ||
141 | |||
142 | return true; | ||
143 | } | ||
144 | |||
145 | static uint32_t get_seek_pos(long seek_time) | ||
146 | { | ||
147 | uint32_t newpos; | ||
148 | |||
149 | /* use avgbytespersec to round to the closest blockalign multiple, | ||
150 | add firstblockposn. 64-bit casts to avoid overflows. */ | ||
151 | newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) | ||
152 | / (1000LL*fmt->blockalign))*fmt->blockalign; | ||
153 | return newpos; | ||
154 | } | ||
155 | |||
156 | static int decode_alaw(const uint8_t *inbuf, size_t inbufsize, | ||
157 | int32_t *outbuf, int *outbufsize) | ||
158 | { | ||
159 | uint32_t i; | ||
160 | |||
161 | for (i = 0; i < inbufsize; i++) | ||
162 | outbuf[i] = alaw2linear16[inbuf[i]] << 13; | ||
163 | |||
164 | *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize; | ||
165 | |||
166 | return CODEC_OK; | ||
167 | } | ||
168 | |||
169 | static int decode_mulaw(const uint8_t *inbuf, size_t inbufsize, | ||
170 | int32_t *outbuf, int *outbufsize) | ||
171 | { | ||
172 | uint32_t i; | ||
173 | |||
174 | for (i = 0; i < inbufsize; i++) | ||
175 | outbuf[i] = ulaw2linear16[inbuf[i]] << 13; | ||
176 | |||
177 | *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize; | ||
178 | |||
179 | return CODEC_OK; | ||
180 | } | ||
181 | |||
182 | static const struct pcm_codec alaw_codec = { | ||
183 | set_format, | ||
184 | get_seek_pos, | ||
185 | decode_alaw, | ||
186 | }; | ||
187 | |||
188 | static const struct pcm_codec mulaw_codec = { | ||
189 | set_format, | ||
190 | get_seek_pos, | ||
191 | decode_mulaw, | ||
192 | }; | ||
193 | |||
194 | const struct pcm_codec *get_itut_g711_alaw_codec(void) | ||
195 | { | ||
196 | return &alaw_codec; | ||
197 | } | ||
198 | |||
199 | const struct pcm_codec *get_itut_g711_mulaw_codec(void) | ||
200 | { | ||
201 | return &mulaw_codec; | ||
202 | } | ||
203 | |||