summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-07-28 12:45:21 +0000
committerMohamed Tarek <mt@rockbox.org>2010-07-28 12:45:21 +0000
commitb1fefcf3e957c2ddd763cb8d52614309ca014a67 (patch)
tree412b66018c7d161d7f85fd919fad11cb49141515
parent1c372492adf8a6a8dfc0c6e512c02f19995128c2 (diff)
downloadrockbox-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.h1
-rw-r--r--apps/codecs/libwma/wmadeci.c55
-rw-r--r--apps/codecs/wma.c11
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);
166int wma_decode_superframe_init(WMADecodeContext* s, 166int wma_decode_superframe_init(WMADecodeContext* s,
167 const uint8_t *buf, int buf_size); 167 const uint8_t *buf, int buf_size);
168int wma_decode_superframe_frame(WMADecodeContext* s, 168int 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. */
771static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer) 771static 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 */
1279static int wma_decode_frame(WMADecodeContext *s, int32_t *samples) 1281static 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
1366int wma_decode_superframe_frame(WMADecodeContext* s, 1348int 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
26CODEC_HEADER 26CODEC_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
32static 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) */
35static WMADecodeContext wmadec; 29static 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 }