blob: 4657891595c8b1b6eda10ee8bb988f4c0d706a0c [file] [log] [blame]
Dave Chapman3c2c2f52005-06-10 18:08:08 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Dave Chapman3c2c2f52005-06-10 18:08:08 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
Thom Johansenc91e0bb2005-10-13 11:32:52 +000022#include "codeclib.h"
Magnus Holmgrenb5f33652005-09-22 19:36:25 +000023#include "inttypes.h"
Dave Chapman3c2c2f52005-06-10 18:08:08 +000024
Jens Arnoldb8749fd2006-01-18 00:05:14 +000025CODEC_HEADER
26
Thom Johansen09685362006-03-20 20:32:19 +000027/* Macro that sign extends an unsigned byte */
28#define SE(x) ((int32_t)((int8_t)(x)))
29
Magnus Holmgrenb5f33652005-09-22 19:36:25 +000030/* 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).
Thom Johansen09685362006-03-20 20:32:19 +000033 * - DVI_ADPCM (16 bits compressed on 3 or 4 bits).
Magnus Holmgrenb5f33652005-09-22 19:36:25 +000034 *
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
39 *
40 * For sample WAV files, see:
41 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html
42 *
43 * The most common formats seem to be PCM, ADPCM, DVI_ADPCM, IEEE_FLOAT,
44 * ALAW and MULAW
45 */
Dave Chapmanab815022005-06-10 19:12:58 +000046
Magnus Holmgrenb5f33652005-09-22 19:36:25 +000047/* These constants are from RFC 2361. */
48enum
49{
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 */
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 */
86 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
92};
93
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)
Dave Chapmanab815022005-06-10 19:12:58 +000097
Dave Chapman62e9e892005-11-02 01:29:35 +000098static const int16_t alaw2linear16[256] ICONST_ATTR = {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +000099 -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
136};
137
Dave Chapman62e9e892005-11-02 01:29:35 +0000138static const int16_t ulaw2linear16[256] ICONST_ATTR = {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000139 -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
176};
177
Thom Johansen09685362006-03-20 20:32:19 +0000178static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000179 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 };
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000191
Thom Johansen09685362006-03-20 20:32:19 +0000192static const int dvi_adpcm_indextab4[8] ICONST_ATTR = {
193 -1, -1, -1, -1, 2, 4, 6, 8 };
194
195static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 };
196
197static int32_t samples[WAV_CHUNK_SIZE] IBSS_ATTR;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000198
199static enum codec_status
Thom Johansen09685362006-03-20 20:32:19 +0000200decode_dvi_adpcm(struct codec_api *ci,
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000201 const uint8_t *buf,
202 int n,
203 uint16_t channels, uint16_t bitspersample,
Thom Johansen09685362006-03-20 20:32:19 +0000204 int32_t *pcmout,
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000205 size_t *pcmoutsize);
206
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000207/* this is the codec entry point */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +0000208enum codec_status codec_main(void)
Dave Chapman3c2c2f52005-06-10 18:08:08 +0000209{
Thom Johansen09685362006-03-20 20:32:19 +0000210 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;
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000217 size_t n;
218 int bufcount;
Thom Johansen09685362006-03-20 20:32:19 +0000219 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 */
Magnus Holmgren8a3b6da2006-08-23 08:19:29 +0000227
Thom Johansen09685362006-03-20 20:32:19 +0000228
229 /* Generic codec initialisation */
Michael Sevakis97f369a2007-02-10 16:34:16 +0000230 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
231 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
Miika Pekkarinend8cb7032005-06-26 19:41:29 +0000232
Thom Johansen09685362006-03-20 20:32:19 +0000233next_track:
Tomasz Malesinski80da8b12006-11-26 18:31:41 +0000234 if (codec_init()) {
Brandon Low1060e442006-01-18 20:22:03 +0000235 i = CODEC_ERROR;
236 goto exit;
Dave Chapman3c2c2f52005-06-10 18:08:08 +0000237 }
238
Magnus Holmgren8a3b6da2006-08-23 08:19:29 +0000239 while (!*ci->taginfo_ready && !ci->stop_codec)
240 ci->sleep(1);
Michael Sevakis9b9e2272007-02-26 17:15:04 +0000241
242 codec_set_replaygain(ci->id3);
Thom Johansen09685362006-03-20 20:32:19 +0000243
Magnus Holmgren8a3b6da2006-08-23 08:19:29 +0000244 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
245 bytesdone = ci->id3->offset;
246
Adam Boot71cf6042006-06-27 22:27:21 +0000247 /* get RIFF chunk header */
248 buf = ci->request_buffer(&n, 12);
249 if (n < 12) {
Thom Johansen09685362006-03-20 20:32:19 +0000250 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000251 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000252 }
253 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
254 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000255 goto done;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000256 }
Dave Chapmanab815022005-06-10 19:12:58 +0000257
Adam Boot71cf6042006-06-27 22:27:21 +0000258 /* advance to first WAVE chunk */
259 ci->advance_buffer(12);
260
261 firstblockposn = 12;
Thom Johansen09685362006-03-20 20:32:19 +0000262 bitspersample = 0;
263 numbytes = 0;
264 totalsamples = 0;
Adam Boot71cf6042006-06-27 22:27:21 +0000265
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;
274 }
275
Thom Johansen09685362006-03-20 20:32:19 +0000276 /* 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) {
Jens Arnoldbd5c0ad2007-03-17 10:50:58 +0000280 DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n",
281 (unsigned long)i);
Thom Johansen09685362006-03-20 20:32:19 +0000282 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000283 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000284 }
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) "
Jens Arnoldf68362a2007-03-17 09:54:28 +0000302 "doesn't have ext. fmt descr (chunksize=%ld<18).\n",
Jens Arnoldbd5c0ad2007-03-17 10:50:58 +0000303 formattag, (long)i);
Thom Johansen09685362006-03-20 20:32:19 +0000304 }
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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000311 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000312 }
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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000319 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000320 }
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);
326 }
327 }
328 } else if (memcmp(buf, "data", 4) == 0) {
329 numbytes = i;
Adam Boot71cf6042006-06-27 22:27:21 +0000330 /* advance to start of data */
331 ci->advance_buffer(8);
332 firstblockposn += 8;
333 break;
Thom Johansen09685362006-03-20 20:32:19 +0000334 } 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",
Jens Arnoldbd5c0ad2007-03-17 10:50:58 +0000340 buf[0], buf[1], buf[2], buf[3], (unsigned long)i);
Thom Johansen09685362006-03-20 20:32:19 +0000341 }
Adam Boot71cf6042006-06-27 22:27:21 +0000342
Thom Johansen09685362006-03-20 20:32:19 +0000343 /* go to next chunk (even chunk sizes must be padded) */
344 if (i & 0x01)
345 i++;
Adam Boot71cf6042006-06-27 22:27:21 +0000346 ci->advance_buffer(i+8);
347 firstblockposn += i + 8;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000348 }
349
Thom Johansen09685362006-03-20 20:32:19 +0000350 if (channels == 0) {
351 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
352 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000353 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000354 }
355 if (numbytes == 0) {
356 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
357 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000358 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000359 }
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");
363 }
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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000369 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000370 }
371 bytespersample = channels;
372 }
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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000377 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000378 }
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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000383 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000384 }
Dave Chapman3c2c2f52005-06-10 18:08:08 +0000385
Michael Sevakis97f369a2007-02-10 16:34:16 +0000386 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
Thom Johansen09685362006-03-20 20:32:19 +0000387 if (channels == 2) {
Michael Sevakis97f369a2007-02-10 16:34:16 +0000388 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
Thom Johansen09685362006-03-20 20:32:19 +0000389 } else if (channels == 1) {
Michael Sevakis97f369a2007-02-10 16:34:16 +0000390 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
Thom Johansen09685362006-03-20 20:32:19 +0000391 } else {
392 DEBUGF("CODEC_ERROR: more than 2 channels\n");
393 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000394 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000395 }
Dave Chapman3c2c2f52005-06-10 18:08:08 +0000396
Thom Johansen09685362006-03-20 20:32:19 +0000397 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;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000407 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000408 }
409 }
410
Adam Boot71cf6042006-06-27 22:27:21 +0000411 /* make sure we're at the correct offset */
Magnus Holmgren8a3b6da2006-08-23 08:19:29 +0000412 if (bytesdone > (uint32_t) firstblockposn) {
Magnus Holmgrenf95dd562006-06-04 15:04:03 +0000413 /* Round down to previous block */
Magnus Holmgren8a3b6da2006-08-23 08:19:29 +0000414 uint32_t offset = bytesdone - bytesdone % blockalign;
Magnus Holmgrenf95dd562006-06-04 15:04:03 +0000415
Adam Boot71cf6042006-06-27 22:27:21 +0000416 ci->advance_buffer(offset-firstblockposn);
Magnus Holmgrenf95dd562006-06-04 15:04:03 +0000417 bytesdone = offset - firstblockposn;
418 } else {
Adam Boot71cf6042006-06-27 22:27:21 +0000419 /* already where we need to be */
Magnus Holmgrenf95dd562006-06-04 15:04:03 +0000420 bytesdone = 0;
421 }
Thom Johansen09685362006-03-20 20:32:19 +0000422
423 /* The main decoder loop */
Thom Johansen09685362006-03-20 20:32:19 +0000424 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) */
Thom Johansen09ed0d62006-03-22 21:52:48 +0000431 if (((uint64_t)chunksize*ci->id3->frequency*channels*2)
Thom Johansen09685362006-03-20 20:32:19 +0000432 /(uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) {
433 chunksize = ((uint64_t)WAV_CHUNK_SIZE*avgbytespersec
Thom Johansen09ed0d62006-03-22 21:52:48 +0000434 /((uint64_t)ci->id3->frequency*channels*2
Thom Johansen09685362006-03-20 20:32:19 +0000435 *blockalign))*blockalign;
436 }
437
438 while (!endofstream) {
439 ci->yield();
Brandon Lowebadcc62006-04-15 02:03:11 +0000440 if (ci->stop_codec || ci->new_track) {
Thom Johansen09685362006-03-20 20:32:19 +0000441 break;
442 }
443
444 if (ci->seek_time) {
445 uint32_t newpos;
446
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();
456 }
Brandon Lowc76904b2006-03-24 14:02:27 +0000457 wavbuf = (uint8_t *)ci->request_buffer(&n, chunksize);
Thom Johansen09685362006-03-20 20:32:19 +0000458
459 if (n == 0)
460 break; /* End of stream */
461
462 if (bytesdone + n > numbytes) {
463 n = numbytes - bytesdone;
464 endofstream = 1;
465 }
466
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);
473 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000474 bufcount = n >> 2;
Thom Johansen09685362006-03-20 20:32:19 +0000475 } 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);
479 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000480 bufcount = n/3;
Thom Johansen09685362006-03-20 20:32:19 +0000481 } else if (bitspersample > 8) {
482 for (i = 0; i < n; i += 2) {
483 samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21);
484 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000485 bufcount = n >> 1;
Thom Johansen09685362006-03-20 20:32:19 +0000486 } else {
487 for (i = 0; i < n; i++) {
488 samples[i] = (wavbuf[i] - 0x80)<<21;
489 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000490 bufcount = n;
Thom Johansen09685362006-03-20 20:32:19 +0000491 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000492
493 if (channels == 2)
494 bufcount >>= 1;
Thom Johansen09685362006-03-20 20:32:19 +0000495 } 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;
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000499
500 bufcount = (channels == 2) ? (n >> 1) : n;
Thom Johansen09685362006-03-20 20:32:19 +0000501 } 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;
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000505
506 bufcount = (channels == 2) ? (n >> 1) : n;
Thom Johansen09685362006-03-20 20:32:19 +0000507 }
508 else if (formattag == WAVE_FORMAT_DVI_ADPCM) {
509 unsigned int nblocks = chunksize/blockalign;
510
511 for (i = 0; i < nblocks; i++) {
512 size_t decodedsize = samplesperblock*channels;
Thom Johansen09ed0d62006-03-22 21:52:48 +0000513 if (decode_dvi_adpcm(ci, wavbuf + i*blockalign,
Thom Johansen09685362006-03-20 20:32:19 +0000514 blockalign, channels, bitspersample,
515 samples + i*samplesperblock*channels,
Thom Johansen09ed0d62006-03-22 21:52:48 +0000516 &decodedsize) != CODEC_OK) {
Thom Johansen09685362006-03-20 20:32:19 +0000517 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000518 goto done;
Thom Johansen09ed0d62006-03-22 21:52:48 +0000519 }
Thom Johansen09685362006-03-20 20:32:19 +0000520 }
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000521 bufcount = nblocks*samplesperblock;
Thom Johansen09685362006-03-20 20:32:19 +0000522 } else {
523 DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag);
524 i = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000525 goto done;
Thom Johansen09685362006-03-20 20:32:19 +0000526 }
527
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000528 ci->pcmbuf_insert(samples, NULL, bufcount);
Thom Johansen09685362006-03-20 20:32:19 +0000529
530 ci->advance_buffer(n);
531 bytesdone += n;
532 if (bytesdone >= numbytes)
533 endofstream = 1;
534 ci->set_elapsed(bytesdone*1000LL/avgbytespersec);
535 }
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000536 i = CODEC_OK;
Thom Johansen09685362006-03-20 20:32:19 +0000537
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000538done:
Thom Johansen09685362006-03-20 20:32:19 +0000539 if (ci->request_next_track())
540 goto next_track;
541
Brandon Low1060e442006-01-18 20:22:03 +0000542exit:
Thom Johansen09685362006-03-20 20:32:19 +0000543 return i;
Dave Chapman3c2c2f52005-06-10 18:08:08 +0000544}
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000545
546static enum codec_status
Thom Johansen09685362006-03-20 20:32:19 +0000547decode_dvi_adpcm(struct codec_api *ci,
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000548 const uint8_t *buf,
549 int n,
550 uint16_t channels, uint16_t bitspersample,
Thom Johansen09685362006-03-20 20:32:19 +0000551 int32_t *pcmout,
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000552 size_t *pcmoutsize)
553{
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;
564
Dave Chapman0eb67542005-11-02 01:24:45 +0000565 (void)ci;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000566 if (bitspersample != 4 && bitspersample != 3) {
567 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n");
568 return CODEC_ERROR;
569 }
570
571 /* decode block header */
Thom Johansen09685362006-03-20 20:32:19 +0000572 for (c = 0; c < channels && n >= 4; c++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000573 /* decode + push first sample */
574 sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */
Thom Johansen09ed0d62006-03-22 21:52:48 +0000575 pcmout[c] = sample[c] << 13;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000576 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;
582 }
583
584 buf += 4;
585 n -= 4;
586 }
587 if (bitspersample == 4) {
Thom Johansen09685362006-03-20 20:32:19 +0000588 while (n>= channels*4 && (nsamples + 8*channels) <= *pcmoutsize) {
589 for (c = 0; c < channels; c++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000590 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;
600 }
Thom Johansen09685362006-03-20 20:32:19 +0000601 for (i = 0; i < 8; i++) {
602 for (c = 0; c < channels; c++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000603 step = dvi_adpcm_steptab[stepindex[c]];
604 codem = samplecode[i][c];
605 code = codem & 0x07;
606
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
Thom Johansen09685362006-03-20 20:32:19 +0000628 diff = ((code + code + 1) * step) >> 3; /* faster */
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000629#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;
Thom Johansen09685362006-03-20 20:32:19 +0000636 } else {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000637 sample[c] += diff;
638 if (sample[c] > 32767)
639 sample[c] = 32767;
640 }
641 /* output the new sample */
Thom Johansen09685362006-03-20 20:32:19 +0000642 pcmout[nsamples] = sample[c] << 13;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000643 nsamples++;
644 }
645 }
646 }
Thom Johansen09685362006-03-20 20:32:19 +0000647 } else { /* bitspersample == 3 */
648 while (n >= channels*12 && (nsamples + 32*channels) <= *pcmoutsize) {
649 for (c = 0; c < channels; c++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000650 uint16_t bitstream = 0;
651 int bitsread = 0;
Thom Johansen09685362006-03-20 20:32:19 +0000652 for (i = 0; i < 32 && n > 0; i++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000653 if (bitsread < 3) {
654 /* read 8 more bits */
655 bitstream |= buf[0]<<bitsread;
656 bitsread += 8;
657 n--;
658 buf++;
659 }
660 samplecode[i][c] = bitstream & 7;
661 bitstream = bitstream>>3;
662 bitsread -= 3;
663 }
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;
668 }
669 }
670
Thom Johansen09685362006-03-20 20:32:19 +0000671 for (i = 0; i < 32; i++) {
672 for (c = 0; c < channels; c++) {
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000673 step = dvi_adpcm_steptab[stepindex[c]];
674 codem = samplecode[i][c];
675 code = codem & 0x03;
676
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
Thom Johansen09685362006-03-20 20:32:19 +0000695 diff = ((code + code + 1) * step) >> 3; /* faster */
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000696#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;
703 }
704 else {
705 sample[c] += diff;
706 if (sample[c] > 32767)
707 sample[c] = 32767;
708 }
709 /* output the new sample */
Thom Johansen09685362006-03-20 20:32:19 +0000710 pcmout[nsamples] = sample[c] << 13;
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000711 nsamples++;
712 }
713 }
714 }
715 }
716
717 if (nsamples > *pcmoutsize) {
718 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n");
719 return CODEC_ERROR;
720 }
721 *pcmoutsize = nsamples;
Thom Johansen09685362006-03-20 20:32:19 +0000722 if (n != 0) {
723 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n);
Magnus Holmgrenb5f33652005-09-22 19:36:25 +0000724 }
725 return CODEC_OK;
726}
727