From b1fefcf3e957c2ddd763cb8d52614309ca014a67 Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Wed, 28 Jul 2010 12:45:21 +0000 Subject: Modify WMA to produce non-interleaved stereo output (FS#11503 by me). speeds up wma by 3.5MHz on CF and 2.2MHz on ARM. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27591 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libwma/wmadec.h | 1 - apps/codecs/libwma/wmadeci.c | 55 +++++++++++++++++--------------------------- apps/codecs/wma.c | 11 ++------- 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/apps/codecs/libwma/wmadec.h b/apps/codecs/libwma/wmadec.h index ec295fa472..d84485ca0f 100644 --- a/apps/codecs/libwma/wmadec.h +++ b/apps/codecs/libwma/wmadec.h @@ -166,6 +166,5 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx); int wma_decode_superframe_init(WMADecodeContext* s, const uint8_t *buf, int buf_size); int wma_decode_superframe_frame(WMADecodeContext* s, - int32_t *samples, const uint8_t *buf, int buf_size); #endif diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c index bd085080d8..9e448f4b93 100644 --- a/apps/codecs/libwma/wmadeci.c +++ b/apps/codecs/libwma/wmadeci.c @@ -768,7 +768,7 @@ static int decode_exp_vlc(WMADecodeContext *s, int ch) /* return 0 if OK. return 1 if last block of frame. return -1 if unrecorrable error. */ -static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) +static int wma_decode_block(WMADecodeContext *s) { int n, v, a, ch, code, bsize; int coef_nb_bits, total_gain; @@ -1236,20 +1236,22 @@ static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) } for(ch = 0; ch < s->nb_channels; ++ch) - { + { + /* BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. */ + static uint32_t scratch_buf[BLOCK_MAX_SIZE * MAX_CHANNELS] IBSS_ATTR; if (s->channel_coded[ch]) { int n4, index; n4 = s->block_len >>1; - ff_imdct_calc( (s->frame_len_bits - bsize + 1), - (int32_t*)scratch_buffer, + ff_imdct_calc((s->frame_len_bits - bsize + 1), + scratch_buf, (*(s->coefs))[ch]); /* add in the frame */ index = (s->frame_len / 2) + s->block_pos - n4; - wma_window(s, scratch_buffer, &((*s->frame_out)[ch][index])); + wma_window(s, scratch_buf, &((*s->frame_out)[ch][index])); @@ -1257,7 +1259,7 @@ static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) channel if it is not coded */ if (s->ms_stereo && !s->channel_coded[1]) { - wma_window(s, scratch_buffer, &((*s->frame_out)[1][index])); + wma_window(s, scratch_buf, &((*s->frame_out)[1][index])); } } } @@ -1276,11 +1278,9 @@ next: } /* decode a frame of frame_len samples */ -static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) +static int wma_decode_frame(WMADecodeContext *s) { - int ret, i, n, ch, incr; - int32_t *ptr; - fixed32 *iptr; + int ret; /* read each block */ s->block_num = 0; @@ -1289,7 +1289,7 @@ static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) for(;;) { - ret = wma_decode_block(s, samples); + ret = wma_decode_block(s); if (ret < 0) { @@ -1301,25 +1301,7 @@ static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) break; } } - - /* return frame with full 30-bit precision */ - n = s->frame_len; - incr = s->nb_channels; - for(ch = 0; ch < s->nb_channels; ++ch) - { - ptr = samples + ch; - iptr = &((*s->frame_out)[ch][0]); - - for (i=0;iframe_out)[ch][0]), &((*s->frame_out)[ch][s->frame_len]), - s->frame_len * sizeof(fixed32)); - } - + return 0; } @@ -1364,13 +1346,18 @@ int wma_decode_superframe_init(WMADecodeContext* s, */ int wma_decode_superframe_frame(WMADecodeContext* s, - int32_t* samples, /*output*/ const uint8_t *buf, /*input*/ int buf_size) { - int pos, len; + int pos, len, ch; uint8_t *q; int done = 0; + + for(ch = 0; ch < s->nb_channels; ch++) + memmove(&((*s->frame_out)[ch][0]), + &((*s->frame_out)[ch][s->frame_len]), + s->frame_len * sizeof(fixed32)); + if ((s->use_bit_reservoir) && (s->current_frame == 0)) { if (s->last_superframe_len > 0) @@ -1402,7 +1389,7 @@ int wma_decode_superframe_frame(WMADecodeContext* s, /* this frame is stored in the last superframe and in the current one */ - if (wma_decode_frame(s, samples) < 0) + if (wma_decode_frame(s) < 0) { goto fail; } @@ -1422,7 +1409,7 @@ int wma_decode_superframe_frame(WMADecodeContext* s, /* If we haven't decoded a frame yet, do it now */ if (!done) { - if (wma_decode_frame(s, samples) < 0) + if (wma_decode_frame(s) < 0) { goto fail; } diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c index ed413e8c32..4c535689d8 100644 --- a/apps/codecs/wma.c +++ b/apps/codecs/wma.c @@ -25,12 +25,6 @@ CODEC_HEADER -/* The output buffer containing the decoded samples (channels 0 and 1) - BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. - */ - -static uint32_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS] IBSS_ATTR; - /* NOTE: WMADecodeContext is 120152 bytes (on x86) */ static WMADecodeContext wmadec; @@ -100,7 +94,7 @@ restart_track: resume_offset = 0; ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate); ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ? - STEREO_MONO : STEREO_INTERLEAVED); + STEREO_MONO : STEREO_NONINTERLEAVED); codec_set_replaygain(ci->id3); /* The main decoding loop */ @@ -157,7 +151,6 @@ new_packet: for (i=0; i < wmadec.nb_frames; i++) { wmares = wma_decode_superframe_frame(&wmadec, - decoded, audiobuf, audiobufsize); ci->yield (); @@ -173,7 +166,7 @@ new_packet: goto new_packet; } } else if (wmares > 0) { - ci->pcmbuf_insert(decoded, NULL, wmares); + ci->pcmbuf_insert((*wmadec.frame_out)[0], (*wmadec.frame_out)[1], wmares); elapsedtime += (wmares*10)/(wfx.rate/100); ci->set_elapsed(elapsedtime); } -- cgit v1.2.3