Colour targets: Revert an optimisation from almost 18 months ago that actually turned...
[Rockbox.git] / apps / codecs / wav.c
blob4657891595c8b1b6eda10ee8bb988f4c0d706a0c
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Dave Chapman
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "codeclib.h"
23 #include "inttypes.h"
25 CODEC_HEADER
27 /* Macro that sign extends an unsigned byte */
28 #define SE(x) ((int32_t)((int8_t)(x)))
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).
35 * For a good documentation on WAVE files, see:
36 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html
37 * and
38 * http://www.sonicspot.com/guide/wavefiles.html
40 * For sample WAV files, see:
41 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html
43 * The most common formats seem to be PCM, ADPCM, DVI_ADPCM, IEEE_FLOAT,
44 * ALAW and MULAW
47 /* These constants are from RFC 2361. */
48 enum
50 WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */
51 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 */
57 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
58 WAVE_FORMAT_OKI_ADPCM = 0x0010, /* OKI ADPCM */
59 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 */
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 */
85 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
86 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
87 IBM_FORMAT_ADPCM = 0x0103,
89 WAVE_FORMAT_CREATIVE_ADPCM = 0x0200,
91 WAVE_FORMAT_EXTENSIBLE = 0xFFFE
94 /* Maximum number of bytes to process in one iteration */
95 /* for 44.1kHz stereo 16bits, this represents 0.023s ~= 1/50s */
96 #define WAV_CHUNK_SIZE (1024*2)
98 static const int16_t alaw2linear16[256] ICONST_ATTR = {
99 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
100 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
101 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
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
138 static const int16_t ulaw2linear16[256] ICONST_ATTR = {
139 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
140 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
141 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
142 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
143 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
144 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
145 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
146 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
147 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
148 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
149 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
150 -1052, -988, -924, -876, -844, -812, -780,
151 -748, -716, -684, -652, -620, -588, -556,
152 -524, -492, -460, -428, -396, -372, -356,
153 -340, -324, -308, -292, -276, -260, -244,
154 -228, -212, -196, -180, -164, -148, -132,
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
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 };
192 static const int dvi_adpcm_indextab4[8] ICONST_ATTR = {
193 -1, -1, -1, -1, 2, 4, 6, 8 };
195 static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 };
197 static int32_t samples[WAV_CHUNK_SIZE] IBSS_ATTR;
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);
207 /* this is the codec entry point */
208 enum codec_status codec_main(void)
210 uint32_t numbytes, bytesdone;
211 uint32_t totalsamples = 0;
212 uint16_t channels = 0;
213 uint16_t samplesperblock = 0;
214 int bytespersample = 0;
215 uint16_t bitspersample;
216 uint32_t i;
217 size_t n;
218 int bufcount;
219 int endofstream;
220 unsigned char *buf;
221 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 */
229 /* Generic codec initialisation */
230 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
231 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
233 next_track:
234 if (codec_init()) {
235 i = CODEC_ERROR;
236 goto exit;
239 while (!*ci->taginfo_ready && !ci->stop_codec)
240 ci->sleep(1);
242 codec_set_replaygain(ci->id3);
244 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
245 bytesdone = ci->id3->offset;
247 /* get RIFF chunk header */
248 buf = ci->request_buffer(&n, 12);
249 if (n < 12) {
250 i = CODEC_ERROR;
251 goto done;
253 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
254 i = CODEC_ERROR;
255 goto done;
258 /* advance to first WAVE chunk */
259 ci->advance_buffer(12);
261 firstblockposn = 12;
262 bitspersample = 0;
263 numbytes = 0;
264 totalsamples = 0;
266 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */
267 while (true) {
268 /* get WAVE chunk header */
269 buf = ci->request_buffer(&n, 1024);
270 if (n < 8) {
271 /* no more chunks, 'data' chunk must not have been found */
272 i = CODEC_ERROR;
273 goto done;
276 /* chunkSize */
277 i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24));
278 if (memcmp(buf, "fmt ", 4) == 0) {
279 if (i < 16) {
280 DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n",
281 (unsigned long)i);
282 i = CODEC_ERROR;
283 goto done;
285 /* wFormatTag */
286 formattag=buf[8]|(buf[9]<<8);
287 /* wChannels */
288 channels=buf[10]|(buf[11]<<8);
289 /* skipping dwSamplesPerSec */
290 /* dwAvgBytesPerSec */
291 avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24);
292 /* wBlockAlign */
293 blockalign=buf[20]|(buf[21]<<8);
294 /* wBitsPerSample */
295 bitspersample=buf[22]|(buf[23]<<8);
296 if (formattag != WAVE_FORMAT_PCM) {
297 uint16_t size;
298 if (i < 18) {
299 /* this is not a fatal error with some formats,
300 * we'll see later if we can't decode it */
301 DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) "
302 "doesn't have ext. fmt descr (chunksize=%ld<18).\n",
303 formattag, (long)i);
305 size = buf[24]|(buf[25]<<8);
306 if (formattag == WAVE_FORMAT_DVI_ADPCM) {
307 if (size < 2) {
308 DEBUGF("CODEC_ERROR: dvi_adpcm is missing "
309 "SamplesPerBlock value\n");
310 i = CODEC_ERROR;
311 goto done;
313 samplesperblock = buf[26]|(buf[27]<<8);
314 } else if (formattag == WAVE_FORMAT_EXTENSIBLE) {
315 if (size < 22) {
316 DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is "
317 "missing extension\n");
318 i = CODEC_ERROR;
319 goto done;
321 /* wValidBitsPerSample */
322 bitspersample = buf[26]|(buf[27]<<8);
323 /* skipping dwChannelMask (4bytes) */
324 /* SubFormat (only get the first two bytes) */
325 formattag = buf[32]|(buf[33]<<8);
328 } else if (memcmp(buf, "data", 4) == 0) {
329 numbytes = i;
330 /* advance to start of data */
331 ci->advance_buffer(8);
332 firstblockposn += 8;
333 break;
334 } else if (memcmp(buf, "fact", 4) == 0) {
335 /* dwSampleLength */
336 if (i >= 4)
337 totalsamples = (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24));
338 } else {
339 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n",
340 buf[0], buf[1], buf[2], buf[3], (unsigned long)i);
343 /* go to next chunk (even chunk sizes must be padded) */
344 if (i & 0x01)
345 i++;
346 ci->advance_buffer(i+8);
347 firstblockposn += i + 8;
350 if (channels == 0) {
351 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
352 i = CODEC_ERROR;
353 goto done;
355 if (numbytes == 0) {
356 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
357 i = CODEC_ERROR;
358 goto done;
360 if (formattag != WAVE_FORMAT_PCM && totalsamples == 0) {
361 /* This is non-fatal for some formats */
362 DEBUGF("CODEC_WARNING: non-PCM WAVE doesn't have a 'fact' chunk\n");
364 if (formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW ||
365 formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) {
366 if (bitspersample != 8) {
367 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n");
368 i = CODEC_ERROR;
369 goto done;
371 bytespersample = channels;
373 if (formattag == WAVE_FORMAT_DVI_ADPCM
374 && bitspersample != 4 && bitspersample != 3) {
375 DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n");
376 i = CODEC_ERROR;
377 goto done;
379 if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) {
380 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
381 "is unsupported\n");
382 i = CODEC_ERROR;
383 goto done;
386 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
387 if (channels == 2) {
388 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
389 } else if (channels == 1) {
390 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
391 } else {
392 DEBUGF("CODEC_ERROR: more than 2 channels\n");
393 i = CODEC_ERROR;
394 goto done;
397 if (totalsamples == 0) {
398 if (formattag == WAVE_FORMAT_PCM ||
399 formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW ||
400 formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) {
401 /* for PCM and derived formats only */
402 bytespersample = (((bitspersample - 1)/8 + 1)*channels);
403 totalsamples = numbytes/bytespersample;
404 } else {
405 DEBUGF("CODEC_ERROR: cannot compute totalsamples\n");
406 i = CODEC_ERROR;
407 goto done;
411 /* make sure we're at the correct offset */
412 if (bytesdone > (uint32_t) firstblockposn) {
413 /* Round down to previous block */
414 uint32_t offset = bytesdone - bytesdone % blockalign;
416 ci->advance_buffer(offset-firstblockposn);
417 bytesdone = offset - firstblockposn;
418 } else {
419 /* already where we need to be */
420 bytesdone = 0;
423 /* The main decoder loop */
424 endofstream = 0;
425 /* chunksize is computed so that one chunk is about 1/50s.
426 * this make 4096 for 44.1kHz 16bits stereo.
427 * It also has to be a multiple of blockalign */
428 chunksize = (1 + avgbytespersec / (50*blockalign))*blockalign;
429 /* check that the output buffer is big enough (convert to samplespersec,
430 then round to the blockalign multiple below) */
431 if (((uint64_t)chunksize*ci->id3->frequency*channels*2)
432 /(uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) {
433 chunksize = ((uint64_t)WAV_CHUNK_SIZE*avgbytespersec
434 /((uint64_t)ci->id3->frequency*channels*2
435 *blockalign))*blockalign;
438 while (!endofstream) {
439 ci->yield();
440 if (ci->stop_codec || ci->new_track) {
441 break;
444 if (ci->seek_time) {
445 uint32_t newpos;
447 /* use avgbytespersec to round to the closest blockalign multiple,
448 add firstblockposn. 64-bit casts to avoid overflows. */
449 newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1))
450 / (1000LL*blockalign))*blockalign;
451 if (newpos > numbytes)
452 break;
453 if (ci->seek_buffer(firstblockposn + newpos))
454 bytesdone = newpos;
455 ci->seek_complete();
457 wavbuf = (uint8_t *)ci->request_buffer(&n, chunksize);
459 if (n == 0)
460 break; /* End of stream */
462 if (bytesdone + n > numbytes) {
463 n = numbytes - bytesdone;
464 endofstream = 1;
467 if (formattag == WAVE_FORMAT_PCM) {
468 if (bitspersample > 24) {
469 for (i = 0; i < n; i += 4) {
470 samples[i/4] = (wavbuf[i] >> 3)|
471 (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)|
472 (SE(wavbuf[i + 3])<<21);
474 bufcount = n >> 2;
475 } else if (bitspersample > 16) {
476 for (i = 0; i < n; i += 3) {
477 samples[i/3] = (wavbuf[i]<<5)|
478 (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21);
480 bufcount = n/3;
481 } else if (bitspersample > 8) {
482 for (i = 0; i < n; i += 2) {
483 samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21);
485 bufcount = n >> 1;
486 } else {
487 for (i = 0; i < n; i++) {
488 samples[i] = (wavbuf[i] - 0x80)<<21;
490 bufcount = n;
493 if (channels == 2)
494 bufcount >>= 1;
495 } else if (formattag == WAVE_FORMAT_ALAW
496 || formattag == IBM_FORMAT_ALAW) {
497 for (i = 0; i < n; i++)
498 samples[i] = alaw2linear16[wavbuf[i]] << 13;
500 bufcount = (channels == 2) ? (n >> 1) : n;
501 } else if (formattag == WAVE_FORMAT_MULAW
502 || formattag == IBM_FORMAT_MULAW) {
503 for (i = 0; i < n; i++)
504 samples[i] = ulaw2linear16[wavbuf[i]] << 13;
506 bufcount = (channels == 2) ? (n >> 1) : n;
508 else if (formattag == WAVE_FORMAT_DVI_ADPCM) {
509 unsigned int nblocks = chunksize/blockalign;
511 for (i = 0; i < nblocks; i++) {
512 size_t decodedsize = samplesperblock*channels;
513 if (decode_dvi_adpcm(ci, wavbuf + i*blockalign,
514 blockalign, channels, bitspersample,
515 samples + i*samplesperblock*channels,
516 &decodedsize) != CODEC_OK) {
517 i = CODEC_ERROR;
518 goto done;
521 bufcount = nblocks*samplesperblock;
522 } else {
523 DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag);
524 i = CODEC_ERROR;
525 goto done;
528 ci->pcmbuf_insert(samples, NULL, bufcount);
530 ci->advance_buffer(n);
531 bytesdone += n;
532 if (bytesdone >= numbytes)
533 endofstream = 1;
534 ci->set_elapsed(bytesdone*1000LL/avgbytespersec);
536 i = CODEC_OK;
538 done:
539 if (ci->request_next_track())
540 goto next_track;
542 exit:
543 return i;
546 static enum codec_status
547 decode_dvi_adpcm(struct codec_api *ci,
548 const uint8_t *buf,
549 int n,
550 uint16_t channels, uint16_t bitspersample,
551 int32_t *pcmout,
552 size_t *pcmoutsize)
554 size_t nsamples = 0;
555 int sample[2];
556 int samplecode[32][2];
557 int i;
558 int stepindex[2];
559 int c;
560 int diff;
561 int step;
562 int codem;
563 int code;
565 (void)ci;
566 if (bitspersample != 4 && bitspersample != 3) {
567 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n");
568 return CODEC_ERROR;
571 /* decode block header */
572 for (c = 0; c < channels && n >= 4; c++) {
573 /* decode + push first sample */
574 sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */
575 pcmout[c] = sample[c] << 13;
576 nsamples++;
577 stepindex[c] = buf[2];
578 /* check for step table index overflow */
579 if (stepindex[c] > 88) {
580 DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]);
581 return CODEC_ERROR;
584 buf += 4;
585 n -= 4;
587 if (bitspersample == 4) {
588 while (n>= channels*4 && (nsamples + 8*channels) <= *pcmoutsize) {
589 for (c = 0; c < channels; c++) {
590 samplecode[0][c] = buf[0]&0xf;
591 samplecode[1][c] = buf[0]>>4;
592 samplecode[2][c] = buf[1]&0xf;
593 samplecode[3][c] = buf[1]>>4;
594 samplecode[4][c] = buf[2]&0xf;
595 samplecode[5][c] = buf[2]>>4;
596 samplecode[6][c] = buf[3]&0xf;
597 samplecode[7][c] = buf[3]>>4;
598 buf += 4;
599 n -= 4;
601 for (i = 0; i < 8; i++) {
602 for (c = 0; c < channels; c++) {
603 step = dvi_adpcm_steptab[stepindex[c]];
604 codem = samplecode[i][c];
605 code = codem & 0x07;
607 /* adjust the step table index */
608 stepindex[c] += dvi_adpcm_indextab4[code];
609 /* check for step table index overflow and underflow */
610 if (stepindex[c] > 88)
611 stepindex[c] = 88;
612 else if (stepindex[c] < 0)
613 stepindex[c] = 0;
614 /* calculate the difference */
615 #ifdef STRICT_IMA
616 diff = 0;
617 if (code & 4)
618 diff += step;
619 step = step >> 1;
620 if (code & 2)
621 diff += step;
622 step = step >> 1;
623 if (code & 1)
624 diff += step;
625 step = step >> 1;
626 diff += step;
627 #else
628 diff = ((code + code + 1) * step) >> 3; /* faster */
629 #endif
630 /* check the sign bit */
631 /* check for overflow and underflow errors */
632 if (code != codem) {
633 sample[c] -= diff;
634 if (sample[c] < -32768)
635 sample[c] = -32768;
636 } else {
637 sample[c] += diff;
638 if (sample[c] > 32767)
639 sample[c] = 32767;
641 /* output the new sample */
642 pcmout[nsamples] = sample[c] << 13;
643 nsamples++;
647 } else { /* bitspersample == 3 */
648 while (n >= channels*12 && (nsamples + 32*channels) <= *pcmoutsize) {
649 for (c = 0; c < channels; c++) {
650 uint16_t bitstream = 0;
651 int bitsread = 0;
652 for (i = 0; i < 32 && n > 0; i++) {
653 if (bitsread < 3) {
654 /* read 8 more bits */
655 bitstream |= buf[0]<<bitsread;
656 bitsread += 8;
657 n--;
658 buf++;
660 samplecode[i][c] = bitstream & 7;
661 bitstream = bitstream>>3;
662 bitsread -= 3;
664 if (bitsread != 0) {
665 /* 32*3 = 3 words, so we should end with bitsread==0 */
666 DEBUGF("decode_dvi_adpcm: error in implementation\n");
667 return CODEC_ERROR;
671 for (i = 0; i < 32; i++) {
672 for (c = 0; c < channels; c++) {
673 step = dvi_adpcm_steptab[stepindex[c]];
674 codem = samplecode[i][c];
675 code = codem & 0x03;
677 /* adjust the step table index */
678 stepindex[c] += dvi_adpcm_indextab3[code];
679 /* check for step table index overflow and underflow */
680 if (stepindex[c] > 88)
681 stepindex[c] = 88;
682 else if (stepindex[c] < 0)
683 stepindex[c] = 0;
684 /* calculate the difference */
685 #ifdef STRICT_IMA
686 diff = 0;
687 if (code & 2)
688 diff += step;
689 step = step >> 1;
690 if (code & 1)
691 diff += step;
692 step = step >> 1;
693 diff += step;
694 #else
695 diff = ((code + code + 1) * step) >> 3; /* faster */
696 #endif
697 /* check the sign bit */
698 /* check for overflow and underflow errors */
699 if (code != codem) {
700 sample[c] -= diff;
701 if (sample[c] < -32768)
702 sample[c] = -32768;
704 else {
705 sample[c] += diff;
706 if (sample[c] > 32767)
707 sample[c] = 32767;
709 /* output the new sample */
710 pcmout[nsamples] = sample[c] << 13;
711 nsamples++;
717 if (nsamples > *pcmoutsize) {
718 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n");
719 return CODEC_ERROR;
721 *pcmoutsize = nsamples;
722 if (n != 0) {
723 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n);
725 return CODEC_OK;