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