diff options
author | Mohamed Tarek <mt@rockbox.org> | 2010-07-28 12:45:21 +0000 |
---|---|---|
committer | Mohamed Tarek <mt@rockbox.org> | 2010-07-28 12:45:21 +0000 |
commit | b1fefcf3e957c2ddd763cb8d52614309ca014a67 (patch) | |
tree | 412b66018c7d161d7f85fd919fad11cb49141515 | |
parent | 1c372492adf8a6a8dfc0c6e512c02f19995128c2 (diff) | |
download | rockbox-b1fefcf3e957c2ddd763cb8d52614309ca014a67.tar.gz rockbox-b1fefcf3e957c2ddd763cb8d52614309ca014a67.zip |
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
-rw-r--r-- | apps/codecs/libwma/wmadec.h | 1 | ||||
-rw-r--r-- | apps/codecs/libwma/wmadeci.c | 55 | ||||
-rw-r--r-- | 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); | |||
166 | int wma_decode_superframe_init(WMADecodeContext* s, | 166 | int wma_decode_superframe_init(WMADecodeContext* s, |
167 | const uint8_t *buf, int buf_size); | 167 | const uint8_t *buf, int buf_size); |
168 | int wma_decode_superframe_frame(WMADecodeContext* s, | 168 | int wma_decode_superframe_frame(WMADecodeContext* s, |
169 | int32_t *samples, | ||
170 | const uint8_t *buf, int buf_size); | 169 | const uint8_t *buf, int buf_size); |
171 | #endif | 170 | #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) | |||
768 | 768 | ||
769 | /* return 0 if OK. return 1 if last block of frame. return -1 if | 769 | /* return 0 if OK. return 1 if last block of frame. return -1 if |
770 | unrecorrable error. */ | 770 | unrecorrable error. */ |
771 | static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) | 771 | static int wma_decode_block(WMADecodeContext *s) |
772 | { | 772 | { |
773 | int n, v, a, ch, code, bsize; | 773 | int n, v, a, ch, code, bsize; |
774 | int coef_nb_bits, total_gain; | 774 | int coef_nb_bits, total_gain; |
@@ -1236,20 +1236,22 @@ static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) | |||
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | for(ch = 0; ch < s->nb_channels; ++ch) | 1238 | for(ch = 0; ch < s->nb_channels; ++ch) |
1239 | { | 1239 | { |
1240 | /* BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. */ | ||
1241 | static uint32_t scratch_buf[BLOCK_MAX_SIZE * MAX_CHANNELS] IBSS_ATTR; | ||
1240 | if (s->channel_coded[ch]) | 1242 | if (s->channel_coded[ch]) |
1241 | { | 1243 | { |
1242 | int n4, index; | 1244 | int n4, index; |
1243 | 1245 | ||
1244 | n4 = s->block_len >>1; | 1246 | n4 = s->block_len >>1; |
1245 | 1247 | ||
1246 | ff_imdct_calc( (s->frame_len_bits - bsize + 1), | 1248 | ff_imdct_calc((s->frame_len_bits - bsize + 1), |
1247 | (int32_t*)scratch_buffer, | 1249 | scratch_buf, |
1248 | (*(s->coefs))[ch]); | 1250 | (*(s->coefs))[ch]); |
1249 | 1251 | ||
1250 | /* add in the frame */ | 1252 | /* add in the frame */ |
1251 | index = (s->frame_len / 2) + s->block_pos - n4; | 1253 | index = (s->frame_len / 2) + s->block_pos - n4; |
1252 | wma_window(s, scratch_buffer, &((*s->frame_out)[ch][index])); | 1254 | wma_window(s, scratch_buf, &((*s->frame_out)[ch][index])); |
1253 | 1255 | ||
1254 | 1256 | ||
1255 | 1257 | ||
@@ -1257,7 +1259,7 @@ static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) | |||
1257 | channel if it is not coded */ | 1259 | channel if it is not coded */ |
1258 | if (s->ms_stereo && !s->channel_coded[1]) | 1260 | if (s->ms_stereo && !s->channel_coded[1]) |
1259 | { | 1261 | { |
1260 | wma_window(s, scratch_buffer, &((*s->frame_out)[1][index])); | 1262 | wma_window(s, scratch_buf, &((*s->frame_out)[1][index])); |
1261 | } | 1263 | } |
1262 | } | 1264 | } |
1263 | } | 1265 | } |
@@ -1276,11 +1278,9 @@ next: | |||
1276 | } | 1278 | } |
1277 | 1279 | ||
1278 | /* decode a frame of frame_len samples */ | 1280 | /* decode a frame of frame_len samples */ |
1279 | static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) | 1281 | static int wma_decode_frame(WMADecodeContext *s) |
1280 | { | 1282 | { |
1281 | int ret, i, n, ch, incr; | 1283 | int ret; |
1282 | int32_t *ptr; | ||
1283 | fixed32 *iptr; | ||
1284 | 1284 | ||
1285 | /* read each block */ | 1285 | /* read each block */ |
1286 | s->block_num = 0; | 1286 | s->block_num = 0; |
@@ -1289,7 +1289,7 @@ static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) | |||
1289 | 1289 | ||
1290 | for(;;) | 1290 | for(;;) |
1291 | { | 1291 | { |
1292 | ret = wma_decode_block(s, samples); | 1292 | ret = wma_decode_block(s); |
1293 | if (ret < 0) | 1293 | if (ret < 0) |
1294 | { | 1294 | { |
1295 | 1295 | ||
@@ -1301,25 +1301,7 @@ static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) | |||
1301 | break; | 1301 | break; |
1302 | } | 1302 | } |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | /* return frame with full 30-bit precision */ | ||
1306 | n = s->frame_len; | ||
1307 | incr = s->nb_channels; | ||
1308 | for(ch = 0; ch < s->nb_channels; ++ch) | ||
1309 | { | ||
1310 | ptr = samples + ch; | ||
1311 | iptr = &((*s->frame_out)[ch][0]); | ||
1312 | |||
1313 | for (i=0;i<n;++i) | ||
1314 | { | ||
1315 | *ptr = (*iptr++); | ||
1316 | ptr += incr; | ||
1317 | } | ||
1318 | |||
1319 | memmove(&((*s->frame_out)[ch][0]), &((*s->frame_out)[ch][s->frame_len]), | ||
1320 | s->frame_len * sizeof(fixed32)); | ||
1321 | } | ||
1322 | |||
1323 | return 0; | 1305 | return 0; |
1324 | } | 1306 | } |
1325 | 1307 | ||
@@ -1364,13 +1346,18 @@ int wma_decode_superframe_init(WMADecodeContext* s, | |||
1364 | */ | 1346 | */ |
1365 | 1347 | ||
1366 | int wma_decode_superframe_frame(WMADecodeContext* s, | 1348 | int wma_decode_superframe_frame(WMADecodeContext* s, |
1367 | int32_t* samples, /*output*/ | ||
1368 | const uint8_t *buf, /*input*/ | 1349 | const uint8_t *buf, /*input*/ |
1369 | int buf_size) | 1350 | int buf_size) |
1370 | { | 1351 | { |
1371 | int pos, len; | 1352 | int pos, len, ch; |
1372 | uint8_t *q; | 1353 | uint8_t *q; |
1373 | int done = 0; | 1354 | int done = 0; |
1355 | |||
1356 | for(ch = 0; ch < s->nb_channels; ch++) | ||
1357 | memmove(&((*s->frame_out)[ch][0]), | ||
1358 | &((*s->frame_out)[ch][s->frame_len]), | ||
1359 | s->frame_len * sizeof(fixed32)); | ||
1360 | |||
1374 | if ((s->use_bit_reservoir) && (s->current_frame == 0)) | 1361 | if ((s->use_bit_reservoir) && (s->current_frame == 0)) |
1375 | { | 1362 | { |
1376 | if (s->last_superframe_len > 0) | 1363 | if (s->last_superframe_len > 0) |
@@ -1402,7 +1389,7 @@ int wma_decode_superframe_frame(WMADecodeContext* s, | |||
1402 | 1389 | ||
1403 | /* this frame is stored in the last superframe and in the | 1390 | /* this frame is stored in the last superframe and in the |
1404 | current one */ | 1391 | current one */ |
1405 | if (wma_decode_frame(s, samples) < 0) | 1392 | if (wma_decode_frame(s) < 0) |
1406 | { | 1393 | { |
1407 | goto fail; | 1394 | goto fail; |
1408 | } | 1395 | } |
@@ -1422,7 +1409,7 @@ int wma_decode_superframe_frame(WMADecodeContext* s, | |||
1422 | /* If we haven't decoded a frame yet, do it now */ | 1409 | /* If we haven't decoded a frame yet, do it now */ |
1423 | if (!done) | 1410 | if (!done) |
1424 | { | 1411 | { |
1425 | if (wma_decode_frame(s, samples) < 0) | 1412 | if (wma_decode_frame(s) < 0) |
1426 | { | 1413 | { |
1427 | goto fail; | 1414 | goto fail; |
1428 | } | 1415 | } |
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 @@ | |||
25 | 25 | ||
26 | CODEC_HEADER | 26 | CODEC_HEADER |
27 | 27 | ||
28 | /* The output buffer containing the decoded samples (channels 0 and 1) | ||
29 | BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. | ||
30 | */ | ||
31 | |||
32 | static uint32_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS] IBSS_ATTR; | ||
33 | |||
34 | /* NOTE: WMADecodeContext is 120152 bytes (on x86) */ | 28 | /* NOTE: WMADecodeContext is 120152 bytes (on x86) */ |
35 | static WMADecodeContext wmadec; | 29 | static WMADecodeContext wmadec; |
36 | 30 | ||
@@ -100,7 +94,7 @@ restart_track: | |||
100 | resume_offset = 0; | 94 | resume_offset = 0; |
101 | ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate); | 95 | ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate); |
102 | ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ? | 96 | ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ? |
103 | STEREO_MONO : STEREO_INTERLEAVED); | 97 | STEREO_MONO : STEREO_NONINTERLEAVED); |
104 | codec_set_replaygain(ci->id3); | 98 | codec_set_replaygain(ci->id3); |
105 | 99 | ||
106 | /* The main decoding loop */ | 100 | /* The main decoding loop */ |
@@ -157,7 +151,6 @@ new_packet: | |||
157 | for (i=0; i < wmadec.nb_frames; i++) | 151 | for (i=0; i < wmadec.nb_frames; i++) |
158 | { | 152 | { |
159 | wmares = wma_decode_superframe_frame(&wmadec, | 153 | wmares = wma_decode_superframe_frame(&wmadec, |
160 | decoded, | ||
161 | audiobuf, audiobufsize); | 154 | audiobuf, audiobufsize); |
162 | 155 | ||
163 | ci->yield (); | 156 | ci->yield (); |
@@ -173,7 +166,7 @@ new_packet: | |||
173 | goto new_packet; | 166 | goto new_packet; |
174 | } | 167 | } |
175 | } else if (wmares > 0) { | 168 | } else if (wmares > 0) { |
176 | ci->pcmbuf_insert(decoded, NULL, wmares); | 169 | ci->pcmbuf_insert((*wmadec.frame_out)[0], (*wmadec.frame_out)[1], wmares); |
177 | elapsedtime += (wmares*10)/(wfx.rate/100); | 170 | elapsedtime += (wmares*10)/(wfx.rate/100); |
178 | ci->set_elapsed(elapsedtime); | 171 | ci->set_elapsed(elapsedtime); |
179 | } | 172 | } |