diff options
Diffstat (limited to 'apps/codecs/wav.c')
-rw-r--r-- | apps/codecs/wav.c | 648 |
1 files changed, 130 insertions, 518 deletions
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index b3efbc10ce..1f210a99bf 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2005 Dave Chapman | 10 | * Copyright (C) 2005 Dave Chapman |
11 | * Copyright (C) 2009 Yoshihisa Uchida | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
@@ -21,16 +22,11 @@ | |||
21 | 22 | ||
22 | #include "codeclib.h" | 23 | #include "codeclib.h" |
23 | #include "inttypes.h" | 24 | #include "inttypes.h" |
25 | #include "codecs/libpcm/support_formats.h" | ||
24 | 26 | ||
25 | CODEC_HEADER | 27 | CODEC_HEADER |
26 | 28 | ||
27 | /* Macro that sign extends an unsigned byte */ | 29 | /* WAVE (RIFF) codec: |
28 | #define SE(x) ((int32_t)((int8_t)(x))) | ||
29 | |||
30 | /* This codec support WAVE files with the following formats: | ||
31 | * - PCM, up to 32 bits, supporting 32 bits playback when useful. | ||
32 | * - ALAW and MULAW (16 bits compressed on 8 bits). | ||
33 | * - DVI_ADPCM (16 bits compressed on 3 or 4 bits). | ||
34 | * | 30 | * |
35 | * For a good documentation on WAVE files, see: | 31 | * For a good documentation on WAVE files, see: |
36 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html | 32 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html |
@@ -40,198 +36,74 @@ CODEC_HEADER | |||
40 | * For sample WAV files, see: | 36 | * For sample WAV files, see: |
41 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html | 37 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html |
42 | * | 38 | * |
43 | * The most common formats seem to be PCM, ADPCM, DVI_ADPCM, IEEE_FLOAT, | ||
44 | * ALAW and MULAW | ||
45 | */ | 39 | */ |
46 | 40 | ||
47 | /* These constants are from RFC 2361. */ | 41 | static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR; |
42 | |||
43 | /* This codec support WAVE files with the following formats: */ | ||
48 | enum | 44 | enum |
49 | { | 45 | { |
50 | WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ | 46 | WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ |
51 | WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ | 47 | WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ |
52 | WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */ | ||
53 | WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */ | ||
54 | WAVE_FORMAT_VSELP = 0x0004, /* Compaq Computer's VSELP */ | ||
55 | WAVE_FORMAT_IBM_CVSD = 0x0005, /* IBM CVSD */ | ||
56 | WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ | 48 | WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ |
57 | WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ | 49 | WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ |
58 | WAVE_FORMAT_OKI_ADPCM = 0x0010, /* OKI ADPCM */ | ||
59 | WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ | 50 | WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ |
60 | WAVE_FORMAT_MEDIASPACE_ADPCM = 0x0012, /* Videologic's MediaSpace ADPCM */ | ||
61 | WAVE_FORMAT_SIERRA_ADPCM = 0x0013, /* Sierra ADPCM */ | ||
62 | WAVE_FORMAT_G723_ADPCM = 0x0014, /* G.723 ADPCM */ | ||
63 | WAVE_FORMAT_DIGISTD = 0x0015, /* DSP Solutions' DIGISTD */ | ||
64 | WAVE_FORMAT_DIGIFIX = 0x0016, /* DSP Solutions' DIGIFIX */ | ||
65 | WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */ | ||
66 | WAVE_FORMAT_MEDIAVISION_ADPCM = 0x0018, /* MediaVision ADPCM */ | ||
67 | WAVE_FORMAT_CU_CODEC = 0x0019, /* HP CU */ | ||
68 | WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */ | ||
69 | WAVE_FORMAT_SONARC = 0x0021, /* Speech Compression's Sonarc */ | ||
70 | WAVE_FORMAT_DSP_TRUESPEECH = 0x0022, /* DSP Group's True Speech */ | ||
71 | WAVE_FORMAT_ECHOSC1 = 0x0023, /* Echo Speech's EchoSC1 */ | ||
72 | WAVE_FORMAT_AUDIOFILE_AF36 = 0x0024, /* Audiofile AF36 */ | ||
73 | WAVE_FORMAT_APTX = 0x0025, /* APTX */ | ||
74 | WAVE_FORMAT_DOLBY_AC2 = 0x0030, /* Dolby AC2 */ | ||
75 | WAVE_FORMAT_GSM610 = 0x0031, /* GSM610 */ | ||
76 | WAVE_FORMAT_MSNAUDIO = 0x0032, /* MSNAudio */ | ||
77 | WAVE_FORMAT_ANTEX_ADPCME = 0x0033, /* Antex ADPCME */ | ||
78 | |||
79 | WAVE_FORMAT_MPEG = 0x0050, /* MPEG */ | ||
80 | WAVE_FORMAT_MPEGLAYER3 = 0x0055, /* MPEG layer 3 */ | ||
81 | WAVE_FORMAT_LUCENT_G723 = 0x0059, /* Lucent G.723 */ | ||
82 | WAVE_FORMAT_G726_ADPCM = 0x0064, /* G.726 ADPCM */ | ||
83 | WAVE_FORMAT_G722_ADPCM = 0x0065, /* G.722 ADPCM */ | ||
84 | |||
85 | IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */ | 51 | IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */ |
86 | IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */ | 52 | IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */ |
87 | IBM_FORMAT_ADPCM = 0x0103, | ||
88 | |||
89 | WAVE_FORMAT_CREATIVE_ADPCM = 0x0200, | ||
90 | |||
91 | WAVE_FORMAT_EXTENSIBLE = 0xFFFE | 53 | WAVE_FORMAT_EXTENSIBLE = 0xFFFE |
92 | }; | 54 | }; |
93 | 55 | ||
94 | /* Maximum number of bytes to process in one iteration */ | 56 | const struct pcm_entry wave_codecs[] = { |
95 | /* for 44.1kHz stereo 16bits, this represents 0.023s ~= 1/50s */ | 57 | { WAVE_FORMAT_UNKNOWN, 0 }, |
96 | #define WAV_CHUNK_SIZE (1024*2) | 58 | { WAVE_FORMAT_PCM, get_linear_pcm_codec }, |
97 | 59 | { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec }, | |
98 | static const int16_t alaw2linear16[256] ICONST_ATTR = { | 60 | { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec }, |
99 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, | 61 | { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec }, |
100 | -4736, -7552, -7296, -8064, -7808, -6528, -6272, | 62 | { IBM_FORMAT_MULAW, get_itut_g711_mulaw_codec }, |
101 | -7040, -6784, -2752, -2624, -3008, -2880, -2240, | 63 | { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec }, |
102 | -2112, -2496, -2368, -3776, -3648, -4032, -3904, | ||
103 | -3264, -3136, -3520, -3392, -22016, -20992, -24064, | ||
104 | -23040, -17920, -16896, -19968, -18944, -30208, -29184, | ||
105 | -32256, -31232, -26112, -25088, -28160, -27136, -11008, | ||
106 | -10496, -12032, -11520, -8960, -8448, -9984, -9472, | ||
107 | -15104, -14592, -16128, -15616, -13056, -12544, -14080, | ||
108 | -13568, -344, -328, -376, -360, -280, -264, | ||
109 | -312, -296, -472, -456, -504, -488, -408, | ||
110 | -392, -440, -424, -88, -72, -120, -104, | ||
111 | -24, -8, -56, -40, -216, -200, -248, | ||
112 | -232, -152, -136, -184, -168, -1376, -1312, | ||
113 | -1504, -1440, -1120, -1056, -1248, -1184, -1888, | ||
114 | -1824, -2016, -1952, -1632, -1568, -1760, -1696, | ||
115 | -688, -656, -752, -720, -560, -528, -624, | ||
116 | -592, -944, -912, -1008, -976, -816, -784, | ||
117 | -880, -848, 5504, 5248, 6016, 5760, 4480, | ||
118 | 4224, 4992, 4736, 7552, 7296, 8064, 7808, | ||
119 | 6528, 6272, 7040, 6784, 2752, 2624, 3008, | ||
120 | 2880, 2240, 2112, 2496, 2368, 3776, 3648, | ||
121 | 4032, 3904, 3264, 3136, 3520, 3392, 22016, | ||
122 | 20992, 24064, 23040, 17920, 16896, 19968, 18944, | ||
123 | 30208, 29184, 32256, 31232, 26112, 25088, 28160, | ||
124 | 27136, 11008, 10496, 12032, 11520, 8960, 8448, | ||
125 | 9984, 9472, 15104, 14592, 16128, 15616, 13056, | ||
126 | 12544, 14080, 13568, 344, 328, 376, 360, | ||
127 | 280, 264, 312, 296, 472, 456, 504, | ||
128 | 488, 408, 392, 440, 424, 88, 72, | ||
129 | 120, 104, 24, 8, 56, 40, 216, | ||
130 | 200, 248, 232, 152, 136, 184, 168, | ||
131 | 1376, 1312, 1504, 1440, 1120, 1056, 1248, | ||
132 | 1184, 1888, 1824, 2016, 1952, 1632, 1568, | ||
133 | 1760, 1696, 688, 656, 752, 720, 560, | ||
134 | 528, 624, 592, 944, 912, 1008, 976, | ||
135 | 816, 784, 880, 848 | ||
136 | }; | 64 | }; |
137 | 65 | ||
138 | static const int16_t ulaw2linear16[256] ICONST_ATTR = { | 66 | #define NUM_FORMATS 7 |
139 | -32124, -31100, -30076, -29052, -28028, -27004, -25980, | 67 | |
140 | -24956, -23932, -22908, -21884, -20860, -19836, -18812, | 68 | static const struct pcm_codec *get_wave_codec(uint32_t formattag) |
141 | -17788, -16764, -15996, -15484, -14972, -14460, -13948, | 69 | { |
142 | -13436, -12924, -12412, -11900, -11388, -10876, -10364, | 70 | int i; |
143 | -9852, -9340, -8828, -8316, -7932, -7676, -7420, | 71 | |
144 | -7164, -6908, -6652, -6396, -6140, -5884, -5628, | 72 | for (i = 0; i < NUM_FORMATS; i++) |
145 | -5372, -5116, -4860, -4604, -4348, -4092, -3900, | 73 | { |
146 | -3772, -3644, -3516, -3388, -3260, -3132, -3004, | 74 | if (wave_codecs[i].format_tag == formattag) |
147 | -2876, -2748, -2620, -2492, -2364, -2236, -2108, | 75 | { |
148 | -1980, -1884, -1820, -1756, -1692, -1628, -1564, | 76 | if (wave_codecs[i].get_codec) |
149 | -1500, -1436, -1372, -1308, -1244, -1180, -1116, | 77 | return wave_codecs[i].get_codec(); |
150 | -1052, -988, -924, -876, -844, -812, -780, | 78 | return 0; |
151 | -748, -716, -684, -652, -620, -588, -556, | 79 | } |
152 | -524, -492, -460, -428, -396, -372, -356, | 80 | } |
153 | -340, -324, -308, -292, -276, -260, -244, | 81 | return 0; |
154 | -228, -212, -196, -180, -164, -148, -132, | 82 | } |
155 | -120, -112, -104, -96, -88, -80, -72, | ||
156 | -64, -56, -48, -40, -32, -24, -16, | ||
157 | -8, 0, 32124, 31100, 30076, 29052, 28028, | ||
158 | 27004, 25980, 24956, 23932, 22908, 21884, 20860, | ||
159 | 19836, 18812, 17788, 16764, 15996, 15484, 14972, | ||
160 | 14460, 13948, 13436, 12924, 12412, 11900, 11388, | ||
161 | 10876, 10364, 9852, 9340, 8828, 8316, 7932, | ||
162 | 7676, 7420, 7164, 6908, 6652, 6396, 6140, | ||
163 | 5884, 5628, 5372, 5116, 4860, 4604, 4348, | ||
164 | 4092, 3900, 3772, 3644, 3516, 3388, 3260, | ||
165 | 3132, 3004, 2876, 2748, 2620, 2492, 2364, | ||
166 | 2236, 2108, 1980, 1884, 1820, 1756, 1692, | ||
167 | 1628, 1564, 1500, 1436, 1372, 1308, 1244, | ||
168 | 1180, 1116, 1052, 988, 924, 876, 844, | ||
169 | 812, 780, 748, 716, 684, 652, 620, | ||
170 | 588, 556, 524, 492, 460, 428, 396, | ||
171 | 372, 356, 340, 324, 308, 292, 276, | ||
172 | 260, 244, 228, 212, 196, 180, 164, | ||
173 | 148, 132, 120, 112, 104, 96, 88, | ||
174 | 80, 72, 64, 56, 48, 40, 32, | ||
175 | 24, 16, 8, 0 | ||
176 | }; | ||
177 | 83 | ||
178 | static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = { | ||
179 | 7, 8, 9, 10, 11, 12, 13, 14, | ||
180 | 16, 17, 19, 21, 23, 25, 28, 31, | ||
181 | 34, 37, 41, 45, 50, 55, 60, 66, | ||
182 | 73, 80, 88, 97, 107, 118, 130, 143, | ||
183 | 157, 173, 190, 209, 230, 253, 279, 307, | ||
184 | 337, 371, 408, 449, 494, 544, 598, 658, | ||
185 | 724, 796, 876, 963, 1060, 1166, 1282, 1411, | ||
186 | 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, | ||
187 | 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, | ||
188 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | ||
189 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, | ||
190 | 32767 }; | ||
191 | |||
192 | static const int dvi_adpcm_indextab4[8] ICONST_ATTR = { | ||
193 | -1, -1, -1, -1, 2, 4, 6, 8 }; | ||
194 | |||
195 | static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 }; | ||
196 | |||
197 | static int32_t samples[WAV_CHUNK_SIZE] IBSS_ATTR; | ||
198 | |||
199 | static enum codec_status | ||
200 | decode_dvi_adpcm(struct codec_api *ci, | ||
201 | const uint8_t *buf, | ||
202 | int n, | ||
203 | uint16_t channels, uint16_t bitspersample, | ||
204 | int32_t *pcmout, | ||
205 | size_t *pcmoutsize); | ||
206 | 84 | ||
207 | /* this is the codec entry point */ | 85 | /* this is the codec entry point */ |
208 | enum codec_status codec_main(void) | 86 | enum codec_status codec_main(void) |
209 | { | 87 | { |
210 | uint32_t numbytes, bytesdone; | 88 | int status = CODEC_OK; |
211 | uint32_t totalsamples = 0; | 89 | struct pcm_format format; |
212 | uint16_t channels = 0; | 90 | uint32_t bytesdone, decodedbytes; |
213 | uint16_t samplesperblock = 0; | ||
214 | int bytespersample = 0; | ||
215 | uint16_t bitspersample; | ||
216 | uint32_t i; | 91 | uint32_t i; |
217 | size_t n; | 92 | size_t n; |
218 | int bufcount; | 93 | int bufcount; |
219 | int endofstream; | 94 | int endofstream; |
220 | unsigned char *buf; | 95 | unsigned char *buf; |
221 | uint8_t *wavbuf; | 96 | uint8_t *wavbuf; |
222 | long chunksize; | ||
223 | uint16_t formattag = 0; | ||
224 | uint16_t blockalign = 0; | ||
225 | uint32_t avgbytespersec = 0; | ||
226 | off_t firstblockposn; /* position of the first block in file */ | 97 | off_t firstblockposn; /* position of the first block in file */ |
227 | 98 | const struct pcm_codec *codec; | |
228 | 99 | ||
229 | /* Generic codec initialisation */ | 100 | /* Generic codec initialisation */ |
230 | ci->configure(DSP_SET_SAMPLE_DEPTH, 28); | 101 | ci->configure(DSP_SET_SAMPLE_DEPTH, 28); |
231 | 102 | ||
232 | next_track: | 103 | next_track: |
233 | if (codec_init()) { | 104 | if (codec_init()) { |
234 | i = CODEC_ERROR; | 105 | DEBUGF("codec_init() error\n"); |
106 | status = CODEC_ERROR; | ||
235 | goto exit; | 107 | goto exit; |
236 | } | 108 | } |
237 | 109 | ||
@@ -246,11 +118,12 @@ next_track: | |||
246 | /* get RIFF chunk header */ | 118 | /* get RIFF chunk header */ |
247 | buf = ci->request_buffer(&n, 12); | 119 | buf = ci->request_buffer(&n, 12); |
248 | if (n < 12) { | 120 | if (n < 12) { |
249 | i = CODEC_ERROR; | 121 | DEBUGF("request_buffer error\n"); |
122 | status = CODEC_ERROR; | ||
250 | goto done; | 123 | goto done; |
251 | } | 124 | } |
252 | if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) { | 125 | if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) { |
253 | i = CODEC_ERROR; | 126 | status = CODEC_ERROR; |
254 | goto done; | 127 | goto done; |
255 | } | 128 | } |
256 | 129 | ||
@@ -258,17 +131,21 @@ next_track: | |||
258 | ci->advance_buffer(12); | 131 | ci->advance_buffer(12); |
259 | 132 | ||
260 | firstblockposn = 12; | 133 | firstblockposn = 12; |
261 | bitspersample = 0; | 134 | ci->memset(&format, 0, sizeof(struct pcm_format)); |
262 | numbytes = 0; | 135 | format.is_signed = true; |
263 | totalsamples = 0; | 136 | format.is_little_endian = true; |
137 | |||
138 | decodedbytes = 0; | ||
139 | codec = 0; | ||
264 | 140 | ||
265 | /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */ | 141 | /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */ |
266 | while (true) { | 142 | while (true) { |
267 | /* get WAVE chunk header */ | 143 | /* get WAVE chunk header */ |
268 | buf = ci->request_buffer(&n, 1024); | 144 | buf = ci->request_buffer(&n, 1024); |
269 | if (n < 8) { | 145 | if (n < 8) { |
146 | DEBUGF("data chunk request_buffer error\n"); | ||
270 | /* no more chunks, 'data' chunk must not have been found */ | 147 | /* no more chunks, 'data' chunk must not have been found */ |
271 | i = CODEC_ERROR; | 148 | status = CODEC_ERROR; |
272 | goto done; | 149 | goto done; |
273 | } | 150 | } |
274 | 151 | ||
@@ -278,54 +155,70 @@ next_track: | |||
278 | if (i < 16) { | 155 | if (i < 16) { |
279 | DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n", | 156 | DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n", |
280 | (unsigned long)i); | 157 | (unsigned long)i); |
281 | i = CODEC_ERROR; | 158 | status = CODEC_ERROR; |
282 | goto done; | 159 | goto done; |
283 | } | 160 | } |
284 | /* wFormatTag */ | 161 | /* wFormatTag */ |
285 | formattag=buf[8]|(buf[9]<<8); | 162 | format.formattag=buf[8]|(buf[9]<<8); |
286 | /* wChannels */ | 163 | /* wChannels */ |
287 | channels=buf[10]|(buf[11]<<8); | 164 | format.channels=buf[10]|(buf[11]<<8); |
288 | /* skipping dwSamplesPerSec */ | 165 | /* skipping dwSamplesPerSec */ |
289 | /* dwAvgBytesPerSec */ | 166 | /* dwAvgBytesPerSec */ |
290 | avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24); | 167 | format.avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24); |
291 | /* wBlockAlign */ | 168 | /* wBlockAlign */ |
292 | blockalign=buf[20]|(buf[21]<<8); | 169 | format.blockalign=buf[20]|(buf[21]<<8); |
293 | /* wBitsPerSample */ | 170 | /* wBitsPerSample */ |
294 | bitspersample=buf[22]|(buf[23]<<8); | 171 | format.bitspersample=buf[22]|(buf[23]<<8); |
295 | if (formattag != WAVE_FORMAT_PCM) { | 172 | if (format.formattag != WAVE_FORMAT_PCM) { |
296 | uint16_t size; | ||
297 | if (i < 18) { | 173 | if (i < 18) { |
298 | /* this is not a fatal error with some formats, | 174 | /* this is not a fatal error with some formats, |
299 | * we'll see later if we can't decode it */ | 175 | * we'll see later if we can't decode it */ |
300 | DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) " | 176 | DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) " |
301 | "doesn't have ext. fmt descr (chunksize=%ld<18).\n", | 177 | "doesn't have ext. fmt descr (chunksize=%ld<18).\n", |
302 | formattag, (long)i); | 178 | format.formattag, (long)i); |
303 | } | 179 | } |
304 | size = buf[24]|(buf[25]<<8); | 180 | else |
305 | if (formattag == WAVE_FORMAT_DVI_ADPCM) { | 181 | { |
306 | if (size < 2) { | 182 | format.size = buf[24]|(buf[25]<<8); |
307 | DEBUGF("CODEC_ERROR: dvi_adpcm is missing " | 183 | if (format.formattag != WAVE_FORMAT_EXTENSIBLE) |
308 | "SamplesPerBlock value\n"); | 184 | format.samplesperblock = buf[26]|(buf[27]<<8); |
309 | i = CODEC_ERROR; | 185 | else { |
310 | goto done; | 186 | if (format.size < 22) { |
311 | } | 187 | DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is " |
312 | samplesperblock = buf[26]|(buf[27]<<8); | 188 | "missing extension\n"); |
313 | } else if (formattag == WAVE_FORMAT_EXTENSIBLE) { | 189 | status = CODEC_ERROR; |
314 | if (size < 22) { | 190 | goto done; |
315 | DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is " | 191 | } |
316 | "missing extension\n"); | 192 | /* wValidBitsPerSample */ |
317 | i = CODEC_ERROR; | 193 | format.bitspersample = buf[26]|(buf[27]<<8); |
318 | goto done; | 194 | /* skipping dwChannelMask (4bytes) */ |
195 | /* SubFormat (only get the first two bytes) */ | ||
196 | format.formattag = buf[32]|(buf[33]<<8); | ||
319 | } | 197 | } |
320 | /* wValidBitsPerSample */ | ||
321 | bitspersample = buf[26]|(buf[27]<<8); | ||
322 | /* skipping dwChannelMask (4bytes) */ | ||
323 | /* SubFormat (only get the first two bytes) */ | ||
324 | formattag = buf[32]|(buf[33]<<8); | ||
325 | } | 198 | } |
326 | } | 199 | } |
200 | |||
201 | /* get codec */ | ||
202 | codec = get_wave_codec(format.formattag); | ||
203 | if (!codec) | ||
204 | { | ||
205 | DEBUGF("CODEC_ERROR: unsupport wave format %x\n", format.formattag); | ||
206 | status = CODEC_ERROR; | ||
207 | goto done; | ||
208 | } | ||
209 | |||
210 | /* riff 8bit linear pcm is unsigned */ | ||
211 | if (format.formattag == WAVE_FORMAT_PCM && format.bitspersample == 8) | ||
212 | format.is_signed = false; | ||
213 | |||
214 | /* set format, parse codec specific tag, check format, and calculate chunk size */ | ||
215 | if (!codec->set_format(&format, buf)) | ||
216 | { | ||
217 | status = CODEC_ERROR; | ||
218 | goto done; | ||
219 | } | ||
327 | } else if (memcmp(buf, "data", 4) == 0) { | 220 | } else if (memcmp(buf, "data", 4) == 0) { |
328 | numbytes = i; | 221 | format.numbytes = i; |
329 | /* advance to start of data */ | 222 | /* advance to start of data */ |
330 | ci->advance_buffer(8); | 223 | ci->advance_buffer(8); |
331 | firstblockposn += 8; | 224 | firstblockposn += 8; |
@@ -333,7 +226,8 @@ next_track: | |||
333 | } else if (memcmp(buf, "fact", 4) == 0) { | 226 | } else if (memcmp(buf, "fact", 4) == 0) { |
334 | /* dwSampleLength */ | 227 | /* dwSampleLength */ |
335 | if (i >= 4) | 228 | if (i >= 4) |
336 | totalsamples = (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24)); | 229 | format.totalsamples = |
230 | (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24)); | ||
337 | } else { | 231 | } else { |
338 | DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", | 232 | DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", |
339 | buf[0], buf[1], buf[2], buf[3], (unsigned long)i); | 233 | buf[0], buf[1], buf[2], buf[3], (unsigned long)i); |
@@ -346,71 +240,40 @@ next_track: | |||
346 | firstblockposn += i + 8; | 240 | firstblockposn += i + 8; |
347 | } | 241 | } |
348 | 242 | ||
349 | if (channels == 0) { | 243 | if (!codec) |
350 | DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n"); | 244 | { |
351 | i = CODEC_ERROR; | 245 | DEBUGF("CODEC_ERROR: 'fmt ' chunk not found\n"); |
246 | status = CODEC_ERROR; | ||
352 | goto done; | 247 | goto done; |
353 | } | 248 | } |
354 | if (numbytes == 0) { | 249 | |
355 | DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); | 250 | /* common format check */ |
356 | i = CODEC_ERROR; | 251 | if (format.channels == 0) { |
357 | goto done; | 252 | DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n"); |
358 | } | 253 | status = CODEC_ERROR; |
359 | if (formattag != WAVE_FORMAT_PCM && totalsamples == 0) { | ||
360 | /* This is non-fatal for some formats */ | ||
361 | DEBUGF("CODEC_WARNING: non-PCM WAVE doesn't have a 'fact' chunk\n"); | ||
362 | } | ||
363 | if (formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || | ||
364 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
365 | if (bitspersample != 8) { | ||
366 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); | ||
367 | i = CODEC_ERROR; | ||
368 | goto done; | ||
369 | } | ||
370 | bytespersample = channels; | ||
371 | } | ||
372 | if (formattag == WAVE_FORMAT_DVI_ADPCM | ||
373 | && bitspersample != 4 && bitspersample != 3) { | ||
374 | DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n"); | ||
375 | i = CODEC_ERROR; | ||
376 | goto done; | 254 | goto done; |
377 | } | 255 | } |
378 | if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) { | 256 | if (format.numbytes == 0) { |
379 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | 257 | DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); |
380 | "is unsupported\n"); | 258 | status = CODEC_ERROR; |
381 | i = CODEC_ERROR; | ||
382 | goto done; | 259 | goto done; |
383 | } | 260 | } |
384 | 261 | ||
385 | ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); | 262 | ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); |
386 | if (channels == 2) { | 263 | if (format.channels == 2) { |
387 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); | 264 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); |
388 | } else if (channels == 1) { | 265 | } else if (format.channels == 1) { |
389 | ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); | 266 | ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); |
390 | } else { | 267 | } else { |
391 | DEBUGF("CODEC_ERROR: more than 2 channels\n"); | 268 | DEBUGF("CODEC_ERROR: more than 2 channels\n"); |
392 | i = CODEC_ERROR; | 269 | status = CODEC_ERROR; |
393 | goto done; | 270 | goto done; |
394 | } | 271 | } |
395 | 272 | ||
396 | if (totalsamples == 0) { | ||
397 | if (formattag == WAVE_FORMAT_PCM || | ||
398 | formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || | ||
399 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
400 | /* for PCM and derived formats only */ | ||
401 | bytespersample = (((bitspersample - 1)/8 + 1)*channels); | ||
402 | totalsamples = numbytes/bytespersample; | ||
403 | } else { | ||
404 | DEBUGF("CODEC_ERROR: cannot compute totalsamples\n"); | ||
405 | i = CODEC_ERROR; | ||
406 | goto done; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | /* make sure we're at the correct offset */ | 273 | /* make sure we're at the correct offset */ |
411 | if (bytesdone > (uint32_t) firstblockposn) { | 274 | if (bytesdone > (uint32_t) firstblockposn) { |
412 | /* Round down to previous block */ | 275 | /* Round down to previous block */ |
413 | uint32_t offset = bytesdone - bytesdone % blockalign; | 276 | uint32_t offset = bytesdone - bytesdone % format.blockalign; |
414 | 277 | ||
415 | ci->advance_buffer(offset-firstblockposn); | 278 | ci->advance_buffer(offset-firstblockposn); |
416 | bytesdone = offset - firstblockposn; | 279 | bytesdone = offset - firstblockposn; |
@@ -421,18 +284,6 @@ next_track: | |||
421 | 284 | ||
422 | /* The main decoder loop */ | 285 | /* The main decoder loop */ |
423 | endofstream = 0; | 286 | endofstream = 0; |
424 | /* chunksize is computed so that one chunk is about 1/50s. | ||
425 | * this make 4096 for 44.1kHz 16bits stereo. | ||
426 | * It also has to be a multiple of blockalign */ | ||
427 | chunksize = (1 + avgbytespersec / (50*blockalign))*blockalign; | ||
428 | /* check that the output buffer is big enough (convert to samplespersec, | ||
429 | then round to the blockalign multiple below) */ | ||
430 | if (((uint64_t)chunksize*ci->id3->frequency*channels*2) | ||
431 | /(uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) { | ||
432 | chunksize = ((uint64_t)WAV_CHUNK_SIZE*avgbytespersec | ||
433 | /((uint64_t)ci->id3->frequency*channels*2 | ||
434 | *blockalign))*blockalign; | ||
435 | } | ||
436 | 287 | ||
437 | while (!endofstream) { | 288 | while (!endofstream) { |
438 | ci->yield(); | 289 | ci->yield(); |
@@ -441,286 +292,47 @@ next_track: | |||
441 | } | 292 | } |
442 | 293 | ||
443 | if (ci->seek_time) { | 294 | if (ci->seek_time) { |
444 | uint32_t newpos; | 295 | uint32_t newpos = codec->get_seek_pos(ci->seek_time); |
445 | 296 | ||
446 | /* use avgbytespersec to round to the closest blockalign multiple, | 297 | if (newpos > format.numbytes) |
447 | add firstblockposn. 64-bit casts to avoid overflows. */ | ||
448 | newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1)) | ||
449 | / (1000LL*blockalign))*blockalign; | ||
450 | if (newpos > numbytes) | ||
451 | break; | 298 | break; |
452 | if (ci->seek_buffer(firstblockposn + newpos)) | 299 | if (ci->seek_buffer(firstblockposn + newpos)) |
300 | { | ||
453 | bytesdone = newpos; | 301 | bytesdone = newpos; |
302 | } | ||
454 | ci->seek_complete(); | 303 | ci->seek_complete(); |
455 | } | 304 | } |
456 | wavbuf = (uint8_t *)ci->request_buffer(&n, chunksize); | ||
457 | 305 | ||
306 | wavbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize); | ||
458 | if (n == 0) | 307 | if (n == 0) |
459 | break; /* End of stream */ | 308 | break; /* End of stream */ |
460 | 309 | if (bytesdone + n > format.numbytes) { | |
461 | if (bytesdone + n > numbytes) { | 310 | n = format.numbytes - bytesdone; |
462 | n = numbytes - bytesdone; | ||
463 | endofstream = 1; | 311 | endofstream = 1; |
464 | } | 312 | } |
465 | 313 | ||
466 | if (formattag == WAVE_FORMAT_PCM) { | 314 | status = codec->decode(wavbuf, n, samples, &bufcount); |
467 | if (bitspersample > 24) { | 315 | if (status == CODEC_ERROR) |
468 | for (i = 0; i < n; i += 4) { | 316 | { |
469 | samples[i/4] = (wavbuf[i] >> 3)| | 317 | DEBUGF("codec error\n"); |
470 | (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)| | ||
471 | (SE(wavbuf[i + 3])<<21); | ||
472 | } | ||
473 | bufcount = n >> 2; | ||
474 | } else if (bitspersample > 16) { | ||
475 | for (i = 0; i < n; i += 3) { | ||
476 | samples[i/3] = (wavbuf[i]<<5)| | ||
477 | (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21); | ||
478 | } | ||
479 | bufcount = n/3; | ||
480 | } else if (bitspersample > 8) { | ||
481 | for (i = 0; i < n; i += 2) { | ||
482 | samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21); | ||
483 | } | ||
484 | bufcount = n >> 1; | ||
485 | } else { | ||
486 | for (i = 0; i < n; i++) { | ||
487 | samples[i] = (wavbuf[i] - 0x80)<<21; | ||
488 | } | ||
489 | bufcount = n; | ||
490 | } | ||
491 | |||
492 | if (channels == 2) | ||
493 | bufcount >>= 1; | ||
494 | } else if (formattag == WAVE_FORMAT_ALAW | ||
495 | || formattag == IBM_FORMAT_ALAW) { | ||
496 | for (i = 0; i < n; i++) | ||
497 | samples[i] = alaw2linear16[wavbuf[i]] << 13; | ||
498 | |||
499 | bufcount = (channels == 2) ? (n >> 1) : n; | ||
500 | } else if (formattag == WAVE_FORMAT_MULAW | ||
501 | || formattag == IBM_FORMAT_MULAW) { | ||
502 | for (i = 0; i < n; i++) | ||
503 | samples[i] = ulaw2linear16[wavbuf[i]] << 13; | ||
504 | |||
505 | bufcount = (channels == 2) ? (n >> 1) : n; | ||
506 | } | ||
507 | else if (formattag == WAVE_FORMAT_DVI_ADPCM) { | ||
508 | unsigned int nblocks = chunksize/blockalign; | ||
509 | |||
510 | for (i = 0; i < nblocks; i++) { | ||
511 | size_t decodedsize = samplesperblock*channels; | ||
512 | if (decode_dvi_adpcm(ci, wavbuf + i*blockalign, | ||
513 | blockalign, channels, bitspersample, | ||
514 | samples + i*samplesperblock*channels, | ||
515 | &decodedsize) != CODEC_OK) { | ||
516 | i = CODEC_ERROR; | ||
517 | goto done; | ||
518 | } | ||
519 | } | ||
520 | bufcount = nblocks*samplesperblock; | ||
521 | } else { | ||
522 | DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); | ||
523 | i = CODEC_ERROR; | ||
524 | goto done; | 318 | goto done; |
525 | } | 319 | } |
526 | 320 | ||
527 | ci->pcmbuf_insert(samples, NULL, bufcount); | 321 | ci->pcmbuf_insert(samples, NULL, bufcount); |
528 | |||
529 | ci->advance_buffer(n); | 322 | ci->advance_buffer(n); |
530 | bytesdone += n; | 323 | bytesdone += n; |
531 | if (bytesdone >= numbytes) | 324 | decodedbytes += bufcount; |
325 | |||
326 | if (bytesdone >= format.numbytes) | ||
532 | endofstream = 1; | 327 | endofstream = 1; |
533 | ci->set_elapsed(bytesdone*1000LL/avgbytespersec); | 328 | ci->set_elapsed(decodedbytes*1000LL/ci->id3->frequency); |
534 | } | 329 | } |
535 | i = CODEC_OK; | 330 | status = CODEC_OK; |
536 | 331 | ||
537 | done: | 332 | done: |
538 | if (ci->request_next_track()) | 333 | if (ci->request_next_track()) |
539 | goto next_track; | 334 | goto next_track; |
540 | 335 | ||
541 | exit: | 336 | exit: |
542 | return i; | 337 | return status; |
543 | } | 338 | } |
544 | |||
545 | static enum codec_status | ||
546 | decode_dvi_adpcm(struct codec_api *ci, | ||
547 | const uint8_t *buf, | ||
548 | int n, | ||
549 | uint16_t channels, uint16_t bitspersample, | ||
550 | int32_t *pcmout, | ||
551 | size_t *pcmoutsize) | ||
552 | { | ||
553 | size_t nsamples = 0; | ||
554 | int sample[2]; | ||
555 | int samplecode[32][2]; | ||
556 | int i; | ||
557 | int stepindex[2]; | ||
558 | int c; | ||
559 | int diff; | ||
560 | int step; | ||
561 | int codem; | ||
562 | int code; | ||
563 | |||
564 | (void)ci; | ||
565 | if (bitspersample != 4 && bitspersample != 3) { | ||
566 | DEBUGF("decode_dvi_adpcm: wrong bitspersample\n"); | ||
567 | return CODEC_ERROR; | ||
568 | } | ||
569 | |||
570 | /* decode block header */ | ||
571 | for (c = 0; c < channels && n >= 4; c++) { | ||
572 | /* decode + push first sample */ | ||
573 | sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */ | ||
574 | pcmout[c] = sample[c] << 13; | ||
575 | nsamples++; | ||
576 | stepindex[c] = buf[2]; | ||
577 | /* check for step table index overflow */ | ||
578 | if (stepindex[c] > 88) { | ||
579 | DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]); | ||
580 | return CODEC_ERROR; | ||
581 | } | ||
582 | |||
583 | buf += 4; | ||
584 | n -= 4; | ||
585 | } | ||
586 | if (bitspersample == 4) { | ||
587 | while (n>= channels*4 && (nsamples + 8*channels) <= *pcmoutsize) { | ||
588 | for (c = 0; c < channels; c++) { | ||
589 | samplecode[0][c] = buf[0]&0xf; | ||
590 | samplecode[1][c] = buf[0]>>4; | ||
591 | samplecode[2][c] = buf[1]&0xf; | ||
592 | samplecode[3][c] = buf[1]>>4; | ||
593 | samplecode[4][c] = buf[2]&0xf; | ||
594 | samplecode[5][c] = buf[2]>>4; | ||
595 | samplecode[6][c] = buf[3]&0xf; | ||
596 | samplecode[7][c] = buf[3]>>4; | ||
597 | buf += 4; | ||
598 | n -= 4; | ||
599 | } | ||
600 | for (i = 0; i < 8; i++) { | ||
601 | for (c = 0; c < channels; c++) { | ||
602 | step = dvi_adpcm_steptab[stepindex[c]]; | ||
603 | codem = samplecode[i][c]; | ||
604 | code = codem & 0x07; | ||
605 | |||
606 | /* adjust the step table index */ | ||
607 | stepindex[c] += dvi_adpcm_indextab4[code]; | ||
608 | /* check for step table index overflow and underflow */ | ||
609 | if (stepindex[c] > 88) | ||
610 | stepindex[c] = 88; | ||
611 | else if (stepindex[c] < 0) | ||
612 | stepindex[c] = 0; | ||
613 | /* calculate the difference */ | ||
614 | #ifdef STRICT_IMA | ||
615 | diff = 0; | ||
616 | if (code & 4) | ||
617 | diff += step; | ||
618 | step = step >> 1; | ||
619 | if (code & 2) | ||
620 | diff += step; | ||
621 | step = step >> 1; | ||
622 | if (code & 1) | ||
623 | diff += step; | ||
624 | step = step >> 1; | ||
625 | diff += step; | ||
626 | #else | ||
627 | diff = ((code + code + 1) * step) >> 3; /* faster */ | ||
628 | #endif | ||
629 | /* check the sign bit */ | ||
630 | /* check for overflow and underflow errors */ | ||
631 | if (code != codem) { | ||
632 | sample[c] -= diff; | ||
633 | if (sample[c] < -32768) | ||
634 | sample[c] = -32768; | ||
635 | } else { | ||
636 | sample[c] += diff; | ||
637 | if (sample[c] > 32767) | ||
638 | sample[c] = 32767; | ||
639 | } | ||
640 | /* output the new sample */ | ||
641 | pcmout[nsamples] = sample[c] << 13; | ||
642 | nsamples++; | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | } else { /* bitspersample == 3 */ | ||
647 | while (n >= channels*12 && (nsamples + 32*channels) <= *pcmoutsize) { | ||
648 | for (c = 0; c < channels; c++) { | ||
649 | uint16_t bitstream = 0; | ||
650 | int bitsread = 0; | ||
651 | for (i = 0; i < 32 && n > 0; i++) { | ||
652 | if (bitsread < 3) { | ||
653 | /* read 8 more bits */ | ||
654 | bitstream |= buf[0]<<bitsread; | ||
655 | bitsread += 8; | ||
656 | n--; | ||
657 | buf++; | ||
658 | } | ||
659 | samplecode[i][c] = bitstream & 7; | ||
660 | bitstream = bitstream>>3; | ||
661 | bitsread -= 3; | ||
662 | } | ||
663 | if (bitsread != 0) { | ||
664 | /* 32*3 = 3 words, so we should end with bitsread==0 */ | ||
665 | DEBUGF("decode_dvi_adpcm: error in implementation\n"); | ||
666 | return CODEC_ERROR; | ||
667 | } | ||
668 | } | ||
669 | |||
670 | for (i = 0; i < 32; i++) { | ||
671 | for (c = 0; c < channels; c++) { | ||
672 | step = dvi_adpcm_steptab[stepindex[c]]; | ||
673 | codem = samplecode[i][c]; | ||
674 | code = codem & 0x03; | ||
675 | |||
676 | /* adjust the step table index */ | ||
677 | stepindex[c] += dvi_adpcm_indextab3[code]; | ||
678 | /* check for step table index overflow and underflow */ | ||
679 | if (stepindex[c] > 88) | ||
680 | stepindex[c] = 88; | ||
681 | else if (stepindex[c] < 0) | ||
682 | stepindex[c] = 0; | ||
683 | /* calculate the difference */ | ||
684 | #ifdef STRICT_IMA | ||
685 | diff = 0; | ||
686 | if (code & 2) | ||
687 | diff += step; | ||
688 | step = step >> 1; | ||
689 | if (code & 1) | ||
690 | diff += step; | ||
691 | step = step >> 1; | ||
692 | diff += step; | ||
693 | #else | ||
694 | diff = ((code + code + 1) * step) >> 3; /* faster */ | ||
695 | #endif | ||
696 | /* check the sign bit */ | ||
697 | /* check for overflow and underflow errors */ | ||
698 | if (code != codem) { | ||
699 | sample[c] -= diff; | ||
700 | if (sample[c] < -32768) | ||
701 | sample[c] = -32768; | ||
702 | } | ||
703 | else { | ||
704 | sample[c] += diff; | ||
705 | if (sample[c] > 32767) | ||
706 | sample[c] = 32767; | ||
707 | } | ||
708 | /* output the new sample */ | ||
709 | pcmout[nsamples] = sample[c] << 13; | ||
710 | nsamples++; | ||
711 | } | ||
712 | } | ||
713 | } | ||
714 | } | ||
715 | |||
716 | if (nsamples > *pcmoutsize) { | ||
717 | DEBUGF("decode_dvi_adpcm: output buffer overflow!\n"); | ||
718 | return CODEC_ERROR; | ||
719 | } | ||
720 | *pcmoutsize = nsamples; | ||
721 | if (n != 0) { | ||
722 | DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n); | ||
723 | } | ||
724 | return CODEC_OK; | ||
725 | } | ||
726 | |||