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.zip
rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.gz
rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.bz2
rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.xz
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 a8e386a..ab4a808 100644
--- a/apps/codecs/wma.c
+++ b/apps/codecs/wma.c
@@ -23,16 +23,15 @@
CODEC_HEADER
-#define MAX_BLOCKSIZE 2048
+/* The output buffer containing the decoded samples (channels 0 and 1)
+ BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2.
+ */
-/* The output buffers containing the decoded samples (channels 0 and 1) */
+static uint16_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS];
/* NOTE: WMADecodeContext is 142688 bytes (on x86) */
static WMADecodeContext wmadec;
-/* TODO: Check the size of this */
-#define OUTBUF_SIZE 256*1024
-
enum asf_error_e {
ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
@@ -286,8 +285,8 @@ enum codec_status codec_main(void)
unsigned char* inbuffer;
size_t resume_offset;
size_t n;
- int wmares, res, padding, outbufsize;
- uint8_t* outbuf;
+ int i;
+ int wmares, res, padding;
/* Generic codec initialisation */
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
@@ -313,8 +312,6 @@ enum codec_status codec_main(void)
goto exit;
}
- outbuf = codec_malloc(OUTBUF_SIZE);
-
/* Copy the format metadata we've stored in the id3 TOC field. This
saves us from parsing it again here. */
memcpy(&wfx, ci->id3->toc, sizeof(wfx));
@@ -355,21 +352,31 @@ enum codec_status codec_main(void)
if (res > 0) {
inbuffer = ci->request_buffer(&n, res - padding);
- wmares = wma_decode_superframe(&wmadec,
- outbuf,&outbufsize,
- inbuffer,res - padding);
-
- ci->advance_buffer(res);
-
- if (wmares > 0) {
- ci->pcmbuf_insert(outbuf, NULL, outbufsize / (wfx.channels * 2));
- samplesdone += (outbufsize / (wfx.channels * 2));
- DEBUGF("Decoded %d samples\n",(outbufsize / (wfx.channels * 2)));
- elapsedtime = (samplesdone*10)/(wfx.rate/100);
- ci->set_elapsed(elapsedtime);
+ wma_decode_superframe_init(&wmadec,
+ inbuffer,res - padding);
+
+ for (i=0; i < wmadec.nb_frames; i++)
+ {
+ wmares = wma_decode_superframe_frame(&wmadec,
+ decoded,
+ inbuffer,res - padding);
+
+ ci->yield ();
+
+ if (wmares < 0)
+ {
+ LOGF("WMA decode error %d\n",wmares);
+ goto done;
+ } else if (wmares > 0) {
+ ci->pcmbuf_insert(decoded, NULL, wmares);
+ samplesdone += wmares;
+ elapsedtime = (samplesdone*10)/(wfx.rate/100);
+ ci->set_elapsed(elapsedtime);
+ }
+ ci->yield ();
}
- ci->yield ();
+ ci->advance_buffer(res);
}
}
retval = CODEC_OK;