FS#8961 - Anti-Aliased Fonts.
[kugel-rb/myfork.git] / apps / codecs / wav.c
blobb3efbc10ce144f2b06345c5e8230fd951823ca05
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);
232 next_track:
233 if (codec_init()) {
234 i = CODEC_ERROR;
235 goto exit;
238 while (!*ci->taginfo_ready && !ci->stop_codec)
239 ci->sleep(1);
241 codec_set_replaygain(ci->id3);
243 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
244 bytesdone = ci->id3->offset;
246 /* get RIFF chunk header */
247 buf = ci->request_buffer(&n, 12);
248 if (n < 12) {
249 i = CODEC_ERROR;
250 goto done;
252 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
253 i = CODEC_ERROR;
254 goto done;
257 /* advance to first WAVE chunk */
258 ci->advance_buffer(12);
260 firstblockposn = 12;
261 bitspersample = 0;
262 numbytes = 0;
263 totalsamples = 0;
265 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */
266 while (true) {
267 /* get WAVE chunk header */
268 buf = ci->request_buffer(&n, 1024);
269 if (n < 8) {
270 /* no more chunks, 'data' chunk must not have been found */
271 i = CODEC_ERROR;
272 goto done;
275 /* chunkSize */
276 i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24));
277 if (memcmp(buf, "fmt ", 4) == 0) {
278 if (i < 16) {
279 DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n",
280 (unsigned long)i);
281 i = CODEC_ERROR;
282 goto done;
284 /* wFormatTag */
285 formattag=buf[8]|(buf[9]<<8);
286 /* wChannels */
287 channels=buf[10]|(buf[11]<<8);
288 /* skipping dwSamplesPerSec */
289 /* dwAvgBytesPerSec */
290 avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24);
291 /* wBlockAlign */
292 blockalign=buf[20]|(buf[21]<<8);
293 /* wBitsPerSample */
294 bitspersample=buf[22]|(buf[23]<<8);
295 if (formattag != WAVE_FORMAT_PCM) {
296 uint16_t size;
297 if (i < 18) {
298 /* this is not a fatal error with some formats,
299 * we'll see later if we can't decode it */
300 DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) "
301 "doesn't have ext. fmt descr (chunksize=%ld<18).\n",
302 formattag, (long)i);
304 size = buf[24]|(buf[25]<<8);
305 if (formattag == WAVE_FORMAT_DVI_ADPCM) {
306 if (size < 2) {
307 DEBUGF("CODEC_ERROR: dvi_adpcm is missing "
308 "SamplesPerBlock value\n");
309 i = CODEC_ERROR;
310 goto done;
312 samplesperblock = buf[26]|(buf[27]<<8);
313 } else if (formattag == WAVE_FORMAT_EXTENSIBLE) {
314 if (size < 22) {
315 DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is "
316 "missing extension\n");
317 i = CODEC_ERROR;
318 goto done;
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);
327 } else if (memcmp(buf, "data", 4) == 0) {
328 numbytes = i;
329 /* advance to start of data */
330 ci->advance_buffer(8);
331 firstblockposn += 8;
332 break;
333 } else if (memcmp(buf, "fact", 4) == 0) {
334 /* dwSampleLength */
335 if (i >= 4)
336 totalsamples = (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24));
337 } else {
338 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n",
339 buf[0], buf[1], buf[2], buf[3], (unsigned long)i);
342 /* go to next chunk (even chunk sizes must be padded) */
343 if (i & 0x01)
344 i++;
345 ci->advance_buffer(i+8);
346 firstblockposn += i + 8;
349 if (channels == 0) {
350 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
351 i = CODEC_ERROR;
352 goto done;
354 if (numbytes == 0) {
355 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
356 i = CODEC_ERROR;
357 goto done;
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");
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;
370 bytespersample = channels;
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;
378 if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) {
379 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
380 "is unsupported\n");
381 i = CODEC_ERROR;
382 goto done;
385 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
386 if (channels == 2) {
387 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
388 } else if (channels == 1) {
389 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
390 } else {
391 DEBUGF("CODEC_ERROR: more than 2 channels\n");
392 i = CODEC_ERROR;
393 goto done;
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;
410 /* make sure we're at the correct offset */
411 if (bytesdone > (uint32_t) firstblockposn) {
412 /* Round down to previous block */
413 uint32_t offset = bytesdone - bytesdone % blockalign;
415 ci->advance_buffer(offset-firstblockposn);
416 bytesdone = offset - firstblockposn;
417 } else {
418 /* already where we need to be */
419 bytesdone = 0;
422 /* The main decoder loop */
423 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;
437 while (!endofstream) {
438 ci->yield();
439 if (ci->stop_codec || ci->new_track) {
440 break;
443 if (ci->seek_time) {
444 uint32_t newpos;
446 /* use avgbytespersec to round to the closest blockalign multiple,
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;
452 if (ci->seek_buffer(firstblockposn + newpos))
453 bytesdone = newpos;
454 ci->seek_complete();
456 wavbuf = (uint8_t *)ci->request_buffer(&n, chunksize);
458 if (n == 0)
459 break; /* End of stream */
461 if (bytesdone + n > numbytes) {
462 n = numbytes - bytesdone;
463 endofstream = 1;
466 if (formattag == WAVE_FORMAT_PCM) {
467 if (bitspersample > 24) {
468 for (i = 0; i < n; i += 4) {
469 samples[i/4] = (wavbuf[i] >> 3)|
470 (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)|
471 (SE(wavbuf[i + 3])<<21);
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);
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);
484 bufcount = n >> 1;
485 } else {
486 for (i = 0; i < n; i++) {
487 samples[i] = (wavbuf[i] - 0x80)<<21;
489 bufcount = n;
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;
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;
505 bufcount = (channels == 2) ? (n >> 1) : n;
507 else if (formattag == WAVE_FORMAT_DVI_ADPCM) {
508 unsigned int nblocks = chunksize/blockalign;
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;
520 bufcount = nblocks*samplesperblock;
521 } else {
522 DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag);
523 i = CODEC_ERROR;
524 goto done;
527 ci->pcmbuf_insert(samples, NULL, bufcount);
529 ci->advance_buffer(n);
530 bytesdone += n;
531 if (bytesdone >= numbytes)
532 endofstream = 1;
533 ci->set_elapsed(bytesdone*1000LL/avgbytespersec);
535 i = CODEC_OK;
537 done:
538 if (ci->request_next_track())
539 goto next_track;
541 exit:
542 return i;
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)
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;
564 (void)ci;
565 if (bitspersample != 4 && bitspersample != 3) {
566 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n");
567 return CODEC_ERROR;
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;
583 buf += 4;
584 n -= 4;
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;
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;
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;
640 /* output the new sample */
641 pcmout[nsamples] = sample[c] << 13;
642 nsamples++;
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++;
659 samplecode[i][c] = bitstream & 7;
660 bitstream = bitstream>>3;
661 bitsread -= 3;
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;
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;
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;
703 else {
704 sample[c] += diff;
705 if (sample[c] > 32767)
706 sample[c] = 32767;
708 /* output the new sample */
709 pcmout[nsamples] = sample[c] << 13;
710 nsamples++;
716 if (nsamples > *pcmoutsize) {
717 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n");
718 return CODEC_ERROR;
720 *pcmoutsize = nsamples;
721 if (n != 0) {
722 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n);
724 return CODEC_OK;