summaryrefslogtreecommitdiff
path: root/apps/codecs/wma.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-07-09 17:24:00 +0000
committerDave Chapman <dave@dchapman.com>2007-07-09 17:24:00 +0000
commit88e32c2fc66544dfe55c2e307461ee01d590fef3 (patch)
tree9b192ebacf8b12c6bcbb24335c32207113af56f8 /apps/codecs/wma.c
parent01e8fce28760ab32c45ca330a8506c5cf45abf14 (diff)
downloadrockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.gz
rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.zip
Reorganise the wma_decode_superframe() function - split into a separate init and decode functions. Each call to the decode function now decodes a single frame (2048 samples) instead of an entire superframe (which typically contained about 7 or 8 frames and can in theory contain up to 16 frames). This allows us to replace the 256KB output buffer with a 8KB buffer, and also perform more yields in the main decoding loop.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13833 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/wma.c')
-rw-r--r--apps/codecs/wma.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c
index a8e386a177..ab4a808f92 100644
--- a/apps/codecs/wma.c
+++ b/apps/codecs/wma.c
@@ -23,16 +23,15 @@
23 23
24CODEC_HEADER 24CODEC_HEADER
25 25
26#define MAX_BLOCKSIZE 2048 26/* The output buffer containing the decoded samples (channels 0 and 1)
27 BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2.
28 */
27 29
28/* The output buffers containing the decoded samples (channels 0 and 1) */ 30static uint16_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS];
29 31
30/* NOTE: WMADecodeContext is 142688 bytes (on x86) */ 32/* NOTE: WMADecodeContext is 142688 bytes (on x86) */
31static WMADecodeContext wmadec; 33static WMADecodeContext wmadec;
32 34
33/* TODO: Check the size of this */
34#define OUTBUF_SIZE 256*1024
35
36enum asf_error_e { 35enum asf_error_e {
37 ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ 36 ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
38 ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */ 37 ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
@@ -286,8 +285,8 @@ enum codec_status codec_main(void)
286 unsigned char* inbuffer; 285 unsigned char* inbuffer;
287 size_t resume_offset; 286 size_t resume_offset;
288 size_t n; 287 size_t n;
289 int wmares, res, padding, outbufsize; 288 int i;
290 uint8_t* outbuf; 289 int wmares, res, padding;
291 290
292 /* Generic codec initialisation */ 291 /* Generic codec initialisation */
293 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512); 292 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
@@ -313,8 +312,6 @@ enum codec_status codec_main(void)
313 goto exit; 312 goto exit;
314 } 313 }
315 314
316 outbuf = codec_malloc(OUTBUF_SIZE);
317
318 /* Copy the format metadata we've stored in the id3 TOC field. This 315 /* Copy the format metadata we've stored in the id3 TOC field. This
319 saves us from parsing it again here. */ 316 saves us from parsing it again here. */
320 memcpy(&wfx, ci->id3->toc, sizeof(wfx)); 317 memcpy(&wfx, ci->id3->toc, sizeof(wfx));
@@ -355,21 +352,31 @@ enum codec_status codec_main(void)
355 if (res > 0) { 352 if (res > 0) {
356 inbuffer = ci->request_buffer(&n, res - padding); 353 inbuffer = ci->request_buffer(&n, res - padding);
357 354
358 wmares = wma_decode_superframe(&wmadec, 355 wma_decode_superframe_init(&wmadec,
359 outbuf,&outbufsize, 356 inbuffer,res - padding);
360 inbuffer,res - padding); 357
361 358 for (i=0; i < wmadec.nb_frames; i++)
362 ci->advance_buffer(res); 359 {
363 360 wmares = wma_decode_superframe_frame(&wmadec,
364 if (wmares > 0) { 361 decoded,
365 ci->pcmbuf_insert(outbuf, NULL, outbufsize / (wfx.channels * 2)); 362 inbuffer,res - padding);
366 samplesdone += (outbufsize / (wfx.channels * 2)); 363
367 DEBUGF("Decoded %d samples\n",(outbufsize / (wfx.channels * 2))); 364 ci->yield ();
368 elapsedtime = (samplesdone*10)/(wfx.rate/100); 365
369 ci->set_elapsed(elapsedtime); 366 if (wmares < 0)
367 {
368 LOGF("WMA decode error %d\n",wmares);
369 goto done;
370 } else if (wmares > 0) {
371 ci->pcmbuf_insert(decoded, NULL, wmares);
372 samplesdone += wmares;
373 elapsedtime = (samplesdone*10)/(wfx.rate/100);
374 ci->set_elapsed(elapsedtime);
375 }
376 ci->yield ();
370 } 377 }
371 378
372 ci->yield (); 379 ci->advance_buffer(res);
373 } 380 }
374 } 381 }
375 retval = CODEC_OK; 382 retval = CODEC_OK;