diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/wav.c | 679 |
1 files changed, 319 insertions, 360 deletions
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index f6daf25564..32cff6a758 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c | |||
@@ -22,12 +22,15 @@ | |||
22 | 22 | ||
23 | CODEC_HEADER | 23 | CODEC_HEADER |
24 | 24 | ||
25 | struct codec_api* rb; | 25 | /* Macro that sign extends an unsigned byte */ |
26 | #define SE(x) ((int32_t)((int8_t)(x))) | ||
27 | |||
28 | struct codec_api *rb; | ||
26 | 29 | ||
27 | /* This codec support WAVE files with the following formats: | 30 | /* This codec support WAVE files with the following formats: |
28 | * - PCM, up to 32 bits, supporting 32 bits playback when useful. | 31 | * - PCM, up to 32 bits, supporting 32 bits playback when useful. |
29 | * - ALAW and MULAW (16 bits compressed on 8 bits). | 32 | * - ALAW and MULAW (16 bits compressed on 8 bits). |
30 | * - DVI_ADPCM (16 bits compressed on 4 bits). | 33 | * - DVI_ADPCM (16 bits compressed on 3 or 4 bits). |
31 | * | 34 | * |
32 | * For a good documentation on WAVE files, see: | 35 | * For a good documentation on WAVE files, see: |
33 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html | 36 | * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html |
@@ -100,8 +103,6 @@ extern char iedata[]; | |||
100 | extern char iend[]; | 103 | extern char iend[]; |
101 | #endif | 104 | #endif |
102 | 105 | ||
103 | /* Those are lookup tables, so they should be in the idata section | ||
104 | * (fast but small RAM on the coldfire processor) */ | ||
105 | static const int16_t alaw2linear16[256] ICONST_ATTR = { | 106 | static const int16_t alaw2linear16[256] ICONST_ATTR = { |
106 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, | 107 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, |
107 | -4736, -7552, -7296, -8064, -7808, -6528, -6272, | 108 | -4736, -7552, -7296, -8064, -7808, -6528, -6272, |
@@ -182,7 +183,7 @@ static const int16_t ulaw2linear16[256] ICONST_ATTR = { | |||
182 | 24, 16, 8, 0 | 183 | 24, 16, 8, 0 |
183 | }; | 184 | }; |
184 | 185 | ||
185 | static const uint16_t dvi_adpcm_steptab[ 89 ] ICONST_ATTR = { | 186 | static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = { |
186 | 7, 8, 9, 10, 11, 12, 13, 14, | 187 | 7, 8, 9, 10, 11, 12, 13, 14, |
187 | 16, 17, 19, 21, 23, 25, 28, 31, | 188 | 16, 17, 19, 21, 23, 25, 28, 31, |
188 | 34, 37, 41, 45, 50, 55, 60, 66, | 189 | 34, 37, 41, 45, 50, 55, 60, 66, |
@@ -195,387 +196,348 @@ static const uint16_t dvi_adpcm_steptab[ 89 ] ICONST_ATTR = { | |||
195 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | 196 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, |
196 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, | 197 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, |
197 | 32767 }; | 198 | 32767 }; |
198 | static const int dvi_adpcm_indextab4[ 8 ] ICONST_ATTR = { -1, -1, -1, -1, 2, 4, 6, 8 }; | ||
199 | static const int dvi_adpcm_indextab3[ 4 ] ICONST_ATTR = { -1, -1, 1, 2 }; | ||
200 | 199 | ||
201 | static int16_t int16_samples[WAV_CHUNK_SIZE] IBSS_ATTR; | 200 | static const int dvi_adpcm_indextab4[8] ICONST_ATTR = { |
201 | -1, -1, -1, -1, 2, 4, 6, 8 }; | ||
202 | |||
203 | static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 }; | ||
204 | |||
205 | static int32_t samples[WAV_CHUNK_SIZE] IBSS_ATTR; | ||
202 | 206 | ||
203 | static enum codec_status | 207 | static enum codec_status |
204 | decode_dvi_adpcm(struct codec_api* ci, | 208 | decode_dvi_adpcm(struct codec_api *ci, |
205 | const uint8_t *buf, | 209 | const uint8_t *buf, |
206 | int n, | 210 | int n, |
207 | uint16_t channels, uint16_t bitspersample, | 211 | uint16_t channels, uint16_t bitspersample, |
208 | int16_t *pcmout, | 212 | int32_t *pcmout, |
209 | size_t *pcmoutsize); | 213 | size_t *pcmoutsize); |
210 | 214 | ||
211 | /* this is the codec entry point */ | 215 | /* this is the codec entry point */ |
212 | enum codec_status codec_start(struct codec_api* api) | 216 | enum codec_status codec_start(struct codec_api *api) |
213 | { | 217 | { |
214 | struct codec_api* ci; | 218 | struct codec_api *ci; |
215 | uint32_t numbytes, bytesdone; | 219 | uint32_t numbytes, bytesdone; |
216 | uint32_t totalsamples = 0; | 220 | uint32_t totalsamples = 0; |
217 | uint16_t channels=0; | 221 | uint16_t channels = 0; |
218 | uint16_t samplesperblock = 0; | 222 | uint16_t samplesperblock = 0; |
219 | int bytespersample=0; | 223 | int bytespersample = 0; |
220 | uint16_t bitspersample; | 224 | uint16_t bitspersample; |
221 | uint32_t i; | 225 | uint32_t i; |
222 | size_t n, wavbufsize; | 226 | size_t n, bufsize; |
223 | int endofstream; | 227 | int endofstream; |
224 | unsigned char* buf; | 228 | unsigned char *buf; |
225 | uint16_t* wavbuf; | 229 | uint8_t *wavbuf; |
226 | long chunksize; | 230 | long chunksize; |
227 | uint16_t formattag = 0; | 231 | uint16_t formattag = 0; |
228 | uint16_t blockalign = 0; | 232 | uint16_t blockalign = 0; |
229 | uint32_t avgbytespersec = 0; | 233 | uint32_t avgbytespersec = 0; |
230 | off_t firstblockposn; /* position of the first block in file */ | 234 | off_t firstblockposn; /* position of the first block in file */ |
231 | int shortorlong = 1; /* do we output shorts (1) or longs (2)? */ | 235 | |
232 | int32_t * const int32_samples = (int32_t*)int16_samples; | 236 | /* Generic codec initialisation */ |
233 | 237 | rb = api; | |
234 | /* Generic codec initialisation */ | 238 | ci = api; |
235 | rb = api; | ||
236 | ci = api; | ||
237 | 239 | ||
238 | #ifdef USE_IRAM | 240 | #ifdef USE_IRAM |
239 | ci->memcpy(iramstart, iramcopy, iramend-iramstart); | 241 | ci->memcpy(iramstart, iramcopy, iramend - iramstart); |
240 | ci->memset(iedata, 0, iend - iedata); | 242 | ci->memset(iedata, 0, iend - iedata); |
241 | #endif | 243 | #endif |
242 | 244 | ||
243 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); | 245 | ci->configure(CODEC_DSP_ENABLE, (bool *)true); |
244 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*256)); | 246 | ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)28); |
245 | 247 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); | |
246 | ci->configure(DSP_DITHER, (bool *)false); | 248 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*256)); |
249 | ci->configure(DSP_DITHER, (bool *)false); | ||
247 | 250 | ||
248 | next_track: | 251 | next_track: |
249 | 252 | if (codec_init(api)) { | |
250 | if (codec_init(api)) { | 253 | i = CODEC_ERROR; |
251 | i = CODEC_ERROR; | 254 | goto exit; |
252 | goto exit; | 255 | } |
253 | } | ||
254 | 256 | ||
255 | while (!*ci->taginfo_ready) | 257 | while (!*ci->taginfo_ready) |
256 | ci->yield(); | 258 | ci->yield(); |
257 | 259 | ||
258 | /* assume the WAV header is less than 1024 bytes */ | 260 | /* assume the WAV header is less than 1024 bytes */ |
259 | buf=ci->request_buffer((long *)&n,1024); | 261 | buf = ci->request_buffer((long *)&n, 1024); |
260 | if (n<44) { | 262 | if (n < 44) { |
261 | i = CODEC_ERROR; | 263 | i = CODEC_ERROR; |
262 | goto exit; | 264 | goto exit; |
263 | } | 265 | } |
264 | if ((memcmp(buf,"RIFF",4)!=0) || (memcmp(&buf[8],"WAVE",4)!=0)) { | 266 | if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) { |
265 | i = CODEC_ERROR; | 267 | i = CODEC_ERROR; |
266 | goto exit; | 268 | goto exit; |
267 | } | ||
268 | |||
269 | buf += 12; | ||
270 | n -= 12; | ||
271 | bitspersample = 0; | ||
272 | numbytes = 0; | ||
273 | totalsamples = 0; | ||
274 | /* read until the data chunk, which should be last */ | ||
275 | while(numbytes == 0 && n >= 8) { | ||
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",i); | ||
281 | i = CODEC_ERROR; | ||
282 | goto exit; | ||
283 | } | ||
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=%d<18).\n", | ||
302 | formattag, i); | ||
303 | } | ||
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 exit; | ||
311 | } | ||
312 | samplesperblock = buf[26]|(buf[27]<<8); | ||
313 | } | ||
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 exit; | ||
320 | } | ||
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 | } | ||
329 | else if (memcmp(buf,"data",4)==0) { | ||
330 | numbytes=i; | ||
331 | i=0; /* advance to the beginning of data */ | ||
332 | } | ||
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 | } | ||
338 | } | ||
339 | else { | ||
340 | DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", | ||
341 | buf[0], buf[1], buf[2], buf[3],i); | ||
342 | } | ||
343 | /* go to next chunk (even chunk sizes must be padded) */ | ||
344 | if (i & 0x01) | ||
345 | i++; | ||
346 | buf += i+8; | ||
347 | if (n < (i+8)) { | ||
348 | DEBUGF("CODEC_ERROR: WAVE header size > 1024\n"); | ||
349 | i = CODEC_ERROR; | ||
350 | goto exit; | ||
351 | } | ||
352 | n -= i+8; | ||
353 | } | ||
354 | |||
355 | if (channels == 0) { | ||
356 | DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n"); | ||
357 | i = CODEC_ERROR; | ||
358 | goto exit; | ||
359 | } | ||
360 | if (numbytes == 0) { | ||
361 | DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); | ||
362 | i = CODEC_ERROR; | ||
363 | goto exit; | ||
364 | } | ||
365 | if (formattag != WAVE_FORMAT_PCM && totalsamples == 0) { | ||
366 | /* This is non-fatal for some formats */ | ||
367 | DEBUGF("CODEC_WARNING: non-PCM WAVE doesn't have a 'fact' chunk\n"); | ||
368 | } | ||
369 | if (formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || | ||
370 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
371 | if (bitspersample != 8) { | ||
372 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); | ||
373 | i = CODEC_ERROR; | ||
374 | goto exit; | ||
375 | } | ||
376 | bytespersample = channels; | ||
377 | } | ||
378 | if ( formattag == WAVE_FORMAT_DVI_ADPCM | ||
379 | && bitspersample != 4 && bitspersample != 3) { | ||
380 | DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n"); | ||
381 | i = CODEC_ERROR; | ||
382 | goto exit; | ||
383 | } | ||
384 | if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) { | ||
385 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | ||
386 | "is unsupported\n"); | ||
387 | i = CODEC_ERROR; | ||
388 | goto exit; | ||
389 | } | ||
390 | |||
391 | ci->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
392 | ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); | ||
393 | |||
394 | if (bitspersample <= 16) { | ||
395 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
396 | } else { | ||
397 | shortorlong = 2; | ||
398 | ci->configure(DSP_DITHER, (bool *)false); | ||
399 | ci->configure(DSP_SET_SAMPLE_DEPTH, (long *) (32)); | ||
400 | ci->configure(DSP_SET_CLIP_MAX, (long *) (2147483647)); | ||
401 | ci->configure(DSP_SET_CLIP_MIN, (long *) (-2147483647-1)); | ||
402 | } | ||
403 | |||
404 | if (channels == 2) { | ||
405 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
406 | } else if (channels == 1) { | ||
407 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_MONO); | ||
408 | } else { | ||
409 | DEBUGF("CODEC_ERROR: more than 2 channels\n"); | ||
410 | i = CODEC_ERROR; | ||
411 | goto exit; | ||
412 | } | ||
413 | |||
414 | if (totalsamples == 0) { | ||
415 | if (formattag == WAVE_FORMAT_PCM || | ||
416 | formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || | ||
417 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
418 | /* for PCM and derived formats only */ | ||
419 | bytespersample=(((bitspersample-1)/8+1)*channels); | ||
420 | totalsamples=numbytes/bytespersample; | ||
421 | } | ||
422 | else { | ||
423 | DEBUGF("CODEC_ERROR: cannot compute totalsamples\n"); | ||
424 | i = CODEC_ERROR; | ||
425 | goto exit; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | firstblockposn = (1024-n); | ||
430 | ci->advance_buffer(firstblockposn); | ||
431 | |||
432 | /* The main decoder loop */ | ||
433 | |||
434 | bytesdone=0; | ||
435 | ci->set_elapsed(0); | ||
436 | endofstream=0; | ||
437 | /* chunksize is computed so that one chunk is about 1/50s. | ||
438 | * this make 4096 for 44.1kHz 16bits stereo. | ||
439 | * It also has to be a multiple of blockalign */ | ||
440 | chunksize = (1 + avgbytespersec / (50*blockalign)) * blockalign; | ||
441 | /* check that the output buffer is big enough (convert to samplespersec, | ||
442 | then round to the blockalign multiple below) */ | ||
443 | if (((uint64_t)chunksize*ci->id3->frequency*channels*shortorlong) | ||
444 | / (uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) { | ||
445 | chunksize = ((uint64_t)WAV_CHUNK_SIZE * avgbytespersec | ||
446 | / ((uint64_t)ci->id3->frequency * channels * shortorlong | ||
447 | * blockalign)) * blockalign; | ||
448 | } | ||
449 | |||
450 | while (!endofstream) { | ||
451 | uint8_t *wavbuf8; | ||
452 | |||
453 | ci->yield(); | ||
454 | if (ci->stop_codec || ci->reload_codec) { | ||
455 | break; | ||
456 | } | 269 | } |
457 | 270 | ||
458 | if (ci->seek_time) { | 271 | buf += 12; |
459 | uint32_t newpos; | 272 | n -= 12; |
273 | bitspersample = 0; | ||
274 | numbytes = 0; | ||
275 | totalsamples = 0; | ||
276 | /* read until the data chunk, which should be last */ | ||
277 | while (numbytes == 0 && n >= 8) { | ||
278 | /* chunkSize */ | ||
279 | i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24)); | ||
280 | if (memcmp(buf, "fmt ", 4) == 0) { | ||
281 | if (i < 16) { | ||
282 | DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n", i); | ||
283 | i = CODEC_ERROR; | ||
284 | goto exit; | ||
285 | } | ||
286 | /* wFormatTag */ | ||
287 | formattag=buf[8]|(buf[9]<<8); | ||
288 | /* wChannels */ | ||
289 | channels=buf[10]|(buf[11]<<8); | ||
290 | /* skipping dwSamplesPerSec */ | ||
291 | /* dwAvgBytesPerSec */ | ||
292 | avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24); | ||
293 | /* wBlockAlign */ | ||
294 | blockalign=buf[20]|(buf[21]<<8); | ||
295 | /* wBitsPerSample */ | ||
296 | bitspersample=buf[22]|(buf[23]<<8); | ||
297 | if (formattag != WAVE_FORMAT_PCM) { | ||
298 | uint16_t size; | ||
299 | if (i < 18) { | ||
300 | /* this is not a fatal error with some formats, | ||
301 | * we'll see later if we can't decode it */ | ||
302 | DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) " | ||
303 | "doesn't have ext. fmt descr (chunksize=%d<18).\n", | ||
304 | formattag, i); | ||
305 | } | ||
306 | size = buf[24]|(buf[25]<<8); | ||
307 | if (formattag == WAVE_FORMAT_DVI_ADPCM) { | ||
308 | if (size < 2) { | ||
309 | DEBUGF("CODEC_ERROR: dvi_adpcm is missing " | ||
310 | "SamplesPerBlock value\n"); | ||
311 | i = CODEC_ERROR; | ||
312 | goto exit; | ||
313 | } | ||
314 | samplesperblock = buf[26]|(buf[27]<<8); | ||
315 | } else if (formattag == WAVE_FORMAT_EXTENSIBLE) { | ||
316 | if (size < 22) { | ||
317 | DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is " | ||
318 | "missing extension\n"); | ||
319 | i = CODEC_ERROR; | ||
320 | goto exit; | ||
321 | } | ||
322 | /* wValidBitsPerSample */ | ||
323 | bitspersample = buf[26]|(buf[27]<<8); | ||
324 | /* skipping dwChannelMask (4bytes) */ | ||
325 | /* SubFormat (only get the first two bytes) */ | ||
326 | formattag = buf[32]|(buf[33]<<8); | ||
327 | } | ||
328 | } | ||
329 | } else if (memcmp(buf, "data", 4) == 0) { | ||
330 | numbytes = i; | ||
331 | i = 0; /* advance to the beginning of data */ | ||
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], i); | ||
339 | } | ||
340 | /* go to next chunk (even chunk sizes must be padded) */ | ||
341 | if (i & 0x01) | ||
342 | i++; | ||
343 | buf += i + 8; | ||
344 | if (n < (i + 8)) { | ||
345 | DEBUGF("CODEC_ERROR: WAVE header size > 1024\n"); | ||
346 | i = CODEC_ERROR; | ||
347 | goto exit; | ||
348 | } | ||
349 | n -= i + 8; | ||
350 | } | ||
460 | 351 | ||
461 | /* use avgbytespersec to round to the closest blockalign multiple, | 352 | if (channels == 0) { |
462 | add firstblockposn. 64-bit casts to avoid overflows. */ | 353 | DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n"); |
463 | newpos = (((uint64_t)avgbytespersec * (ci->seek_time - 1)) | 354 | i = CODEC_ERROR; |
464 | / (1000LL*blockalign)) * blockalign; | 355 | goto exit; |
465 | if (newpos > numbytes) | 356 | } |
466 | break; | 357 | if (numbytes == 0) { |
467 | if (ci->seek_buffer(firstblockposn + newpos)) { | 358 | DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); |
468 | bytesdone = newpos; | 359 | i = CODEC_ERROR; |
360 | goto exit; | ||
361 | } | ||
362 | if (formattag != WAVE_FORMAT_PCM && totalsamples == 0) { | ||
363 | /* This is non-fatal for some formats */ | ||
364 | DEBUGF("CODEC_WARNING: non-PCM WAVE doesn't have a 'fact' chunk\n"); | ||
365 | } | ||
366 | if (formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || | ||
367 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
368 | if (bitspersample != 8) { | ||
369 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); | ||
370 | i = CODEC_ERROR; | ||
371 | goto exit; | ||
469 | } | 372 | } |
470 | ci->seek_complete(); | 373 | bytespersample = channels; |
374 | } | ||
375 | if (formattag == WAVE_FORMAT_DVI_ADPCM | ||
376 | && bitspersample != 4 && bitspersample != 3) { | ||
377 | DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n"); | ||
378 | i = CODEC_ERROR; | ||
379 | goto exit; | ||
380 | } | ||
381 | if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) { | ||
382 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | ||
383 | "is unsupported\n"); | ||
384 | i = CODEC_ERROR; | ||
385 | goto exit; | ||
471 | } | 386 | } |
472 | wavbuf=ci->request_buffer((long *)&n,chunksize); | ||
473 | wavbuf8 = (uint8_t*)wavbuf; | ||
474 | 387 | ||
475 | if (n==0) | 388 | ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); |
476 | break; /* End of stream */ | 389 | if (channels == 2) { |
390 | ci->configure(DSP_SET_STEREO_MODE, (long *)STEREO_INTERLEAVED); | ||
391 | } else if (channels == 1) { | ||
392 | ci->configure(DSP_SET_STEREO_MODE, (long *)STEREO_MONO); | ||
393 | } else { | ||
394 | DEBUGF("CODEC_ERROR: more than 2 channels\n"); | ||
395 | i = CODEC_ERROR; | ||
396 | goto exit; | ||
397 | } | ||
477 | 398 | ||
478 | if (bytesdone + n > numbytes) { | 399 | if (totalsamples == 0) { |
479 | n = numbytes - bytesdone; | 400 | if (formattag == WAVE_FORMAT_PCM || |
480 | endofstream = 1; | 401 | formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW || |
402 | formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) { | ||
403 | /* for PCM and derived formats only */ | ||
404 | bytespersample = (((bitspersample - 1)/8 + 1)*channels); | ||
405 | totalsamples = numbytes/bytespersample; | ||
406 | } else { | ||
407 | DEBUGF("CODEC_ERROR: cannot compute totalsamples\n"); | ||
408 | i = CODEC_ERROR; | ||
409 | goto exit; | ||
410 | } | ||
481 | } | 411 | } |
482 | 412 | ||
483 | wavbufsize = sizeof(int16_samples); | 413 | firstblockposn = 1024 - n; |
414 | ci->advance_buffer(firstblockposn); | ||
415 | |||
416 | /* The main decoder loop */ | ||
417 | bytesdone = 0; | ||
418 | ci->set_elapsed(0); | ||
419 | endofstream = 0; | ||
420 | /* chunksize is computed so that one chunk is about 1/50s. | ||
421 | * this make 4096 for 44.1kHz 16bits stereo. | ||
422 | * It also has to be a multiple of blockalign */ | ||
423 | chunksize = (1 + avgbytespersec / (50*blockalign))*blockalign; | ||
424 | /* check that the output buffer is big enough (convert to samplespersec, | ||
425 | then round to the blockalign multiple below) */ | ||
426 | if (((uint64_t)chunksize*ci->id3->frequency*channels*sizeof(long)) | ||
427 | /(uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) { | ||
428 | chunksize = ((uint64_t)WAV_CHUNK_SIZE*avgbytespersec | ||
429 | /((uint64_t)ci->id3->frequency*channels*sizeof(long) | ||
430 | *blockalign))*blockalign; | ||
431 | } | ||
484 | 432 | ||
485 | if (formattag == WAVE_FORMAT_PCM) { | 433 | while (!endofstream) { |
486 | if (bitspersample > 24) { | 434 | ci->yield(); |
487 | for (i=0;i<n;i+=4) { | 435 | if (ci->stop_codec || ci->reload_codec) { |
488 | int32_samples[i/4]=(int32_t)(wavbuf8[i]|(wavbuf8[i+1]<<8)| | 436 | break; |
489 | (wavbuf8[i+2]<<16)|(wavbuf8[i+3]<<24)); | ||
490 | } | ||
491 | wavbufsize = n; | ||
492 | } | 437 | } |
493 | else if (bitspersample > 16) { | 438 | |
494 | for (i=0;i<n;i+=3) { | 439 | if (ci->seek_time) { |
495 | int32_samples[i/3]=(int32_t)((wavbuf8[i]<<8)| | 440 | uint32_t newpos; |
496 | (wavbuf8[i+1]<<16)|(wavbuf8[i+2]<<24)); | 441 | |
497 | } | 442 | /* use avgbytespersec to round to the closest blockalign multiple, |
498 | wavbufsize = n*4/3; | 443 | add firstblockposn. 64-bit casts to avoid overflows. */ |
444 | newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1)) | ||
445 | / (1000LL*blockalign))*blockalign; | ||
446 | if (newpos > numbytes) | ||
447 | break; | ||
448 | if (ci->seek_buffer(firstblockposn + newpos)) | ||
449 | bytesdone = newpos; | ||
450 | ci->seek_complete(); | ||
499 | } | 451 | } |
500 | else if (bitspersample > 8) { | 452 | wavbuf = (uint8_t *)ci->request_buffer((long *)&n, chunksize); |
501 | /* Byte-swap data. */ | 453 | |
502 | for (i=0;i<n/2;i++) { | 454 | if (n == 0) |
503 | int16_samples[i]=(int16_t)letoh16(wavbuf[i]); | 455 | break; /* End of stream */ |
504 | } | 456 | |
505 | wavbufsize = n; | 457 | if (bytesdone + n > numbytes) { |
458 | n = numbytes - bytesdone; | ||
459 | endofstream = 1; | ||
506 | } | 460 | } |
507 | else { | 461 | |
508 | for (i=0;i<n;i++) { | 462 | if (formattag == WAVE_FORMAT_PCM) { |
509 | int16_samples[i] = (wavbuf8[i]<<8) - 0x8000; | 463 | if (bitspersample > 24) { |
464 | for (i = 0; i < n; i += 4) { | ||
465 | samples[i/4] = (wavbuf[i] >> 3)| | ||
466 | (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)| | ||
467 | (SE(wavbuf[i + 3])<<21); | ||
468 | } | ||
469 | bufsize = n; | ||
470 | } else if (bitspersample > 16) { | ||
471 | for (i = 0; i < n; i += 3) { | ||
472 | samples[i/3] = (wavbuf[i]<<5)| | ||
473 | (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21); | ||
474 | } | ||
475 | bufsize = n*4/3; | ||
476 | } else if (bitspersample > 8) { | ||
477 | for (i = 0; i < n; i += 2) { | ||
478 | samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21); | ||
479 | } | ||
480 | bufsize = n*2; | ||
481 | } else { | ||
482 | for (i = 0; i < n; i++) { | ||
483 | samples[i] = (wavbuf[i] - 0x80)<<21; | ||
484 | } | ||
485 | bufsize = n*4; | ||
510 | } | 486 | } |
511 | wavbufsize = n*2; | 487 | } else if (formattag == WAVE_FORMAT_ALAW |
512 | } | 488 | || formattag == IBM_FORMAT_ALAW) { |
513 | } | 489 | for (i = 0; i < n; i++) |
514 | else if (formattag == WAVE_FORMAT_ALAW || formattag == IBM_FORMAT_ALAW) { | 490 | samples[i] = alaw2linear16[wavbuf[i]] << 13; |
515 | for (i=0;i<n;i++) { | 491 | bufsize = n*4; |
516 | int16_samples[i] = alaw2linear16[wavbuf8[i]]; | 492 | } else if (formattag == WAVE_FORMAT_MULAW |
517 | } | 493 | || formattag == IBM_FORMAT_MULAW) { |
518 | wavbufsize = n*2; | 494 | for (i = 0; i < n; i++) |
519 | } | 495 | samples[i] = ulaw2linear16[wavbuf[i]] << 13; |
520 | else if (formattag == WAVE_FORMAT_MULAW || formattag == IBM_FORMAT_MULAW) { | 496 | bufsize = n*4; |
521 | for (i=0;i<n;i++) { | ||
522 | int16_samples[i] = ulaw2linear16[wavbuf8[i]]; | ||
523 | } | 497 | } |
524 | wavbufsize = n*2; | 498 | else if (formattag == WAVE_FORMAT_DVI_ADPCM) { |
525 | } | 499 | unsigned int nblocks = chunksize/blockalign; |
526 | else if (formattag == WAVE_FORMAT_DVI_ADPCM) { | 500 | |
527 | unsigned int nblocks = chunksize/blockalign; | 501 | for (i = 0; i < nblocks; i++) { |
528 | 502 | size_t decodedsize = samplesperblock*channels; | |
529 | for (i=0; i<nblocks; i++) { | 503 | if (decode_dvi_adpcm(ci, ((uint8_t *)wavbuf) + i*blockalign, |
530 | size_t decodedsize = samplesperblock*channels; | 504 | blockalign, channels, bitspersample, |
531 | if (decode_dvi_adpcm(ci, ((uint8_t*)wavbuf)+i*blockalign, | 505 | samples + i*samplesperblock*channels, |
532 | blockalign, channels, bitspersample, | 506 | &decodedsize) != CODEC_OK) |
533 | int16_samples+i*samplesperblock*channels, | 507 | i = CODEC_ERROR; |
534 | &decodedsize) | ||
535 | != CODEC_OK) { | ||
536 | i = CODEC_ERROR; | ||
537 | goto exit; | ||
538 | } | ||
539 | if (decodedsize != samplesperblock) { | ||
540 | i = CODEC_ERROR; | ||
541 | goto exit; | 508 | goto exit; |
542 | } | 509 | } |
510 | bufsize = nblocks*samplesperblock*channels*2; | ||
511 | } else { | ||
512 | DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); | ||
513 | i = CODEC_ERROR; | ||
514 | goto exit; | ||
543 | } | 515 | } |
544 | wavbufsize = nblocks*samplesperblock*channels*2; | ||
545 | } | ||
546 | else { | ||
547 | DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); | ||
548 | i = CODEC_ERROR; | ||
549 | goto exit; | ||
550 | } | ||
551 | 516 | ||
552 | while (!ci->pcmbuf_insert((char*)int16_samples, wavbufsize)) { | 517 | while (!ci->pcmbuf_insert((char *)samples, bufsize)) |
553 | ci->yield(); | 518 | ci->yield(); |
554 | } | ||
555 | 519 | ||
556 | ci->advance_buffer(n); | 520 | ci->advance_buffer(n); |
557 | bytesdone += n; | 521 | bytesdone += n; |
558 | if (bytesdone >= numbytes) { | 522 | if (bytesdone >= numbytes) |
559 | endofstream=1; | 523 | endofstream = 1; |
524 | ci->set_elapsed(bytesdone*1000LL/avgbytespersec); | ||
560 | } | 525 | } |
561 | 526 | ||
562 | ci->set_elapsed(bytesdone*1000LL/avgbytespersec); | 527 | if (ci->request_next_track()) |
563 | } | 528 | goto next_track; |
564 | |||
565 | if (ci->request_next_track()) | ||
566 | goto next_track; | ||
567 | 529 | ||
568 | i = CODEC_OK; | 530 | i = CODEC_OK; |
569 | exit: | 531 | exit: |
570 | return i; | 532 | return i; |
571 | } | 533 | } |
572 | 534 | ||
573 | static enum codec_status | 535 | static enum codec_status |
574 | decode_dvi_adpcm(struct codec_api* ci, | 536 | decode_dvi_adpcm(struct codec_api *ci, |
575 | const uint8_t *buf, | 537 | const uint8_t *buf, |
576 | int n, | 538 | int n, |
577 | uint16_t channels, uint16_t bitspersample, | 539 | uint16_t channels, uint16_t bitspersample, |
578 | int16_t *pcmout, | 540 | int32_t *pcmout, |
579 | size_t *pcmoutsize) | 541 | size_t *pcmoutsize) |
580 | { | 542 | { |
581 | size_t nsamples = 0; | 543 | size_t nsamples = 0; |
@@ -596,7 +558,7 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
596 | } | 558 | } |
597 | 559 | ||
598 | /* decode block header */ | 560 | /* decode block header */ |
599 | for(c=0; c<channels && n>=4; c++) { | 561 | for (c = 0; c < channels && n >= 4; c++) { |
600 | /* decode + push first sample */ | 562 | /* decode + push first sample */ |
601 | sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */ | 563 | sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */ |
602 | pcmout[c] = sample[c]; | 564 | pcmout[c] = sample[c]; |
@@ -612,8 +574,8 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
612 | n -= 4; | 574 | n -= 4; |
613 | } | 575 | } |
614 | if (bitspersample == 4) { | 576 | if (bitspersample == 4) { |
615 | while( n>= channels*4 && (nsamples+8*channels) <= *pcmoutsize ) { | 577 | while (n>= channels*4 && (nsamples + 8*channels) <= *pcmoutsize) { |
616 | for (c=0; c<channels; c++) { | 578 | for (c = 0; c < channels; c++) { |
617 | samplecode[0][c] = buf[0]&0xf; | 579 | samplecode[0][c] = buf[0]&0xf; |
618 | samplecode[1][c] = buf[0]>>4; | 580 | samplecode[1][c] = buf[0]>>4; |
619 | samplecode[2][c] = buf[1]&0xf; | 581 | samplecode[2][c] = buf[1]&0xf; |
@@ -625,9 +587,8 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
625 | buf += 4; | 587 | buf += 4; |
626 | n -= 4; | 588 | n -= 4; |
627 | } | 589 | } |
628 | 590 | for (i = 0; i < 8; i++) { | |
629 | for (i=0; i<8; i++) { | 591 | for (c = 0; c < channels; c++) { |
630 | for (c=0; c<channels; c++) { | ||
631 | step = dvi_adpcm_steptab[stepindex[c]]; | 592 | step = dvi_adpcm_steptab[stepindex[c]]; |
632 | codem = samplecode[i][c]; | 593 | codem = samplecode[i][c]; |
633 | code = codem & 0x07; | 594 | code = codem & 0x07; |
@@ -653,7 +614,7 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
653 | step = step >> 1; | 614 | step = step >> 1; |
654 | diff += step; | 615 | diff += step; |
655 | #else | 616 | #else |
656 | diff = ((code+code+1) * step) >> 3; /* faster */ | 617 | diff = ((code + code + 1) * step) >> 3; /* faster */ |
657 | #endif | 618 | #endif |
658 | /* check the sign bit */ | 619 | /* check the sign bit */ |
659 | /* check for overflow and underflow errors */ | 620 | /* check for overflow and underflow errors */ |
@@ -661,25 +622,23 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
661 | sample[c] -= diff; | 622 | sample[c] -= diff; |
662 | if (sample[c] < -32768) | 623 | if (sample[c] < -32768) |
663 | sample[c] = -32768; | 624 | sample[c] = -32768; |
664 | } | 625 | } else { |
665 | else { | ||
666 | sample[c] += diff; | 626 | sample[c] += diff; |
667 | if (sample[c] > 32767) | 627 | if (sample[c] > 32767) |
668 | sample[c] = 32767; | 628 | sample[c] = 32767; |
669 | } | 629 | } |
670 | /* output the new sample */ | 630 | /* output the new sample */ |
671 | pcmout[nsamples] = sample[c]; | 631 | pcmout[nsamples] = sample[c] << 13; |
672 | nsamples++; | 632 | nsamples++; |
673 | } | 633 | } |
674 | } | 634 | } |
675 | } | 635 | } |
676 | } | 636 | } else { /* bitspersample == 3 */ |
677 | else { /* bitspersample == 3 */ | 637 | while (n >= channels*12 && (nsamples + 32*channels) <= *pcmoutsize) { |
678 | while( n>= channels*12 && (nsamples+32*channels) <= *pcmoutsize) { | 638 | for (c = 0; c < channels; c++) { |
679 | for (c=0; c<channels; c++) { | ||
680 | uint16_t bitstream = 0; | 639 | uint16_t bitstream = 0; |
681 | int bitsread = 0; | 640 | int bitsread = 0; |
682 | for (i=0; i<32 && n>0; i++) { | 641 | for (i = 0; i < 32 && n > 0; i++) { |
683 | if (bitsread < 3) { | 642 | if (bitsread < 3) { |
684 | /* read 8 more bits */ | 643 | /* read 8 more bits */ |
685 | bitstream |= buf[0]<<bitsread; | 644 | bitstream |= buf[0]<<bitsread; |
@@ -698,8 +657,8 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
698 | } | 657 | } |
699 | } | 658 | } |
700 | 659 | ||
701 | for (i=0; i<32; i++) { | 660 | for (i = 0; i < 32; i++) { |
702 | for (c=0; c<channels; c++) { | 661 | for (c = 0; c < channels; c++) { |
703 | step = dvi_adpcm_steptab[stepindex[c]]; | 662 | step = dvi_adpcm_steptab[stepindex[c]]; |
704 | codem = samplecode[i][c]; | 663 | codem = samplecode[i][c]; |
705 | code = codem & 0x03; | 664 | code = codem & 0x03; |
@@ -722,7 +681,7 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
722 | step = step >> 1; | 681 | step = step >> 1; |
723 | diff += step; | 682 | diff += step; |
724 | #else | 683 | #else |
725 | diff = ((code+code+1) * step) >> 3; /* faster */ | 684 | diff = ((code + code + 1) * step) >> 3; /* faster */ |
726 | #endif | 685 | #endif |
727 | /* check the sign bit */ | 686 | /* check the sign bit */ |
728 | /* check for overflow and underflow errors */ | 687 | /* check for overflow and underflow errors */ |
@@ -737,7 +696,7 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
737 | sample[c] = 32767; | 696 | sample[c] = 32767; |
738 | } | 697 | } |
739 | /* output the new sample */ | 698 | /* output the new sample */ |
740 | pcmout[nsamples] = sample[c]; | 699 | pcmout[nsamples] = sample[c] << 13; |
741 | nsamples++; | 700 | nsamples++; |
742 | } | 701 | } |
743 | } | 702 | } |
@@ -749,8 +708,8 @@ decode_dvi_adpcm(struct codec_api* ci, | |||
749 | return CODEC_ERROR; | 708 | return CODEC_ERROR; |
750 | } | 709 | } |
751 | *pcmoutsize = nsamples; | 710 | *pcmoutsize = nsamples; |
752 | if (n!=0) { | 711 | if (n != 0) { |
753 | DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n",n); | 712 | DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n); |
754 | } | 713 | } |
755 | return CODEC_OK; | 714 | return CODEC_OK; |
756 | } | 715 | } |