summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2010-02-21 19:47:05 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2010-02-21 19:47:05 +0000
commit3d6faa08bf95da6e0f65a070a11f014e78c0b682 (patch)
treefdffd82b1972b735b5e82b1258d578f61f64b2bb
parenta31624e76e45230aa9f94b16709f86e0042bad91 (diff)
downloadrockbox-3d6faa08bf95da6e0f65a070a11f014e78c0b682.tar.gz
rockbox-3d6faa08bf95da6e0f65a070a11f014e78c0b682.zip
Optimization for cook codec. Rework sample output to be able to use highly optimized dsp routines. Moved some functions to iram. Speeds up codec by 1.3 MHz on PP5022.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24815 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/cook.c14
-rw-r--r--apps/codecs/libcook/cook.c12
-rw-r--r--apps/codecs/libcook/cook.h2
-rw-r--r--apps/codecs/libcook/cook_fixpoint.h60
-rw-r--r--apps/codecs/libcook/main.c2
5 files changed, 34 insertions, 56 deletions
diff --git a/apps/codecs/cook.c b/apps/codecs/cook.c
index 4214d30f38..30255d4fd7 100644
--- a/apps/codecs/cook.c
+++ b/apps/codecs/cook.c
@@ -31,6 +31,7 @@ CODEC_HEADER
31RMContext rmctx; 31RMContext rmctx;
32RMPacket pkt; 32RMPacket pkt;
33COOKContext q IBSS_ATTR; 33COOKContext q IBSS_ATTR;
34int32_t rm_outbuf[2048];
34 35
35static void init_rm(RMContext *rmctx) 36static void init_rm(RMContext *rmctx)
36{ 37{
@@ -43,7 +44,6 @@ enum codec_status codec_main(void)
43 static size_t buff_size; 44 static size_t buff_size;
44 int datasize, res, consumed, i, time_offset; 45 int datasize, res, consumed, i, time_offset;
45 uint8_t *bit_buffer; 46 uint8_t *bit_buffer;
46 int16_t outbuf[2048] __attribute__((aligned(32)));
47 uint16_t fs,sps,h; 47 uint16_t fs,sps,h;
48 uint32_t packet_count; 48 uint32_t packet_count;
49 int scrambling_unit_size, num_units; 49 int scrambling_unit_size, num_units;
@@ -65,9 +65,11 @@ next_track:
65 init_rm(&rmctx); 65 init_rm(&rmctx);
66 66
67 ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); 67 ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
68 ci->configure(DSP_SET_SAMPLE_DEPTH, 16); 68 /* cook's sample representation is 21.11
69 * DSP_SET_SAMPLE_DEPTH = 11 (FRACT) + 16 (NATIVE) - 1 (SIGN) = 26 */
70 ci->configure(DSP_SET_SAMPLE_DEPTH, 26);
69 ci->configure(DSP_SET_STEREO_MODE, rmctx.nb_channels == 1 ? 71 ci->configure(DSP_SET_STEREO_MODE, rmctx.nb_channels == 1 ?
70 STEREO_MONO : STEREO_INTERLEAVED); 72 STEREO_MONO : STEREO_NONINTERLEAVED);
71 73
72 packet_count = rmctx.nb_packets; 74 packet_count = rmctx.nb_packets;
73 rmctx.audio_framesize = rmctx.block_align; 75 rmctx.audio_framesize = rmctx.block_align;
@@ -155,7 +157,7 @@ seek_start :
155 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); 157 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i);
156 ci->seek_complete(); 158 ci->seek_complete();
157 } 159 }
158 res = cook_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i], rmctx.block_align); 160 res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align);
159 rmctx.frame_number++; 161 rmctx.frame_number++;
160 162
161 /* skip the first two frames; no valid audio */ 163 /* skip the first two frames; no valid audio */
@@ -166,7 +168,9 @@ seek_start :
166 return CODEC_ERROR; 168 return CODEC_ERROR;
167 } 169 }
168 170
169 ci->pcmbuf_insert(outbuf, NULL, q.samples_per_frame / rmctx.nb_channels); 171 ci->pcmbuf_insert(rm_outbuf,
172 rm_outbuf+q.samples_per_channel,
173 q.samples_per_channel);
170 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); 174 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i);
171 } 175 }
172 packet_count -= rmctx.audio_pkt_cnt; 176 packet_count -= rmctx.audio_pkt_cnt;
diff --git a/apps/codecs/libcook/cook.c b/apps/codecs/libcook/cook.c
index 8d9611c4d9..814250ea32 100644
--- a/apps/codecs/libcook/cook.c
+++ b/apps/codecs/libcook/cook.c
@@ -598,7 +598,7 @@ decode_bytes_and_gain(COOKContext *q, const uint8_t *inbuffer,
598static void 598static void
599mlt_compensate_output(COOKContext *q, REAL_T *decode_buffer, 599mlt_compensate_output(COOKContext *q, REAL_T *decode_buffer,
600 cook_gains *gains, REAL_T *previous_buffer, 600 cook_gains *gains, REAL_T *previous_buffer,
601 int16_t *out, int chan) 601 int32_t *out, int chan)
602{ 602{
603 REAL_T *buffer = q->mono_mdct_output; 603 REAL_T *buffer = q->mono_mdct_output;
604 int i; 604 int i;
@@ -618,7 +618,9 @@ mlt_compensate_output(COOKContext *q, REAL_T *decode_buffer,
618 memcpy(previous_buffer, buffer+q->samples_per_channel, 618 memcpy(previous_buffer, buffer+q->samples_per_channel,
619 sizeof(REAL_T)*q->samples_per_channel); 619 sizeof(REAL_T)*q->samples_per_channel);
620 620
621 output_math(q, out, chan); 621 /* Copy output to non-interleaved sample buffer */
622 memcpy(out + (chan * q->samples_per_channel), buffer,
623 sizeof(REAL_T)*q->samples_per_channel);
622} 624}
623 625
624 626
@@ -634,7 +636,7 @@ mlt_compensate_output(COOKContext *q, REAL_T *decode_buffer,
634 636
635 637
636static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer, 638static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer,
637 int sub_packet_size, int16_t *outbuffer) { 639 int sub_packet_size, int32_t *outbuffer) {
638 /* packet dump */ 640 /* packet dump */
639// for (i=0 ; i<sub_packet_size ; i++) { 641// for (i=0 ; i<sub_packet_size ; i++) {
640// DEBUGF("%02x", inbuffer[i]); 642// DEBUGF("%02x", inbuffer[i]);
@@ -666,7 +668,7 @@ static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer,
666 q->mono_previous_buffer2, outbuffer, 1); 668 q->mono_previous_buffer2, outbuffer, 1);
667 } 669 }
668 } 670 }
669 return q->samples_per_frame * sizeof(int16_t); 671 return q->samples_per_frame * sizeof(int32_t);
670} 672}
671 673
672 674
@@ -677,7 +679,7 @@ static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer,
677 */ 679 */
678 680
679int cook_decode_frame(RMContext *rmctx,COOKContext *q, 681int cook_decode_frame(RMContext *rmctx,COOKContext *q,
680 int16_t *outbuffer, int *data_size, 682 int32_t *outbuffer, int *data_size,
681 const uint8_t *inbuffer, int buf_size) { 683 const uint8_t *inbuffer, int buf_size) {
682 //COOKContext *q = avctx->priv_data; 684 //COOKContext *q = avctx->priv_data;
683 //COOKContext *q; 685 //COOKContext *q;
diff --git a/apps/codecs/libcook/cook.h b/apps/codecs/libcook/cook.h
index 0672553895..93abf9a52d 100644
--- a/apps/codecs/libcook/cook.h
+++ b/apps/codecs/libcook/cook.h
@@ -97,6 +97,6 @@ typedef struct cook {
97 97
98int cook_decode_init(RMContext *rmctx, COOKContext *q); 98int cook_decode_init(RMContext *rmctx, COOKContext *q);
99int cook_decode_frame(RMContext *rmctx,COOKContext *q, 99int cook_decode_frame(RMContext *rmctx,COOKContext *q,
100 int16_t *outbuffer, int *data_size, 100 int32_t *outbuffer, int *data_size,
101 const uint8_t *inbuffer, int buf_size); 101 const uint8_t *inbuffer, int buf_size);
102#endif /*_COOK_H */ 102#endif /*_COOK_H */
diff --git a/apps/codecs/libcook/cook_fixpoint.h b/apps/codecs/libcook/cook_fixpoint.h
index 30e5a3eee2..57c217dc43 100644
--- a/apps/codecs/libcook/cook_fixpoint.h
+++ b/apps/codecs/libcook/cook_fixpoint.h
@@ -79,28 +79,28 @@ static inline FIXP fixp_pow2_neg(FIXP x, int i)
79#else 79#else
80static inline FIXP fixp_mult_su(FIXP a, FIXPU b) 80static inline FIXP fixp_mult_su(FIXP a, FIXPU b)
81{ 81{
82 int32_t hb = (a >> 16) * b; 82 int32_t hb = (a >> 16) * b;
83 uint32_t lb = (a & 0xffff) * b; 83 uint32_t lb = (a & 0xffff) * b;
84 84
85 return hb + (lb >> 16) + ((lb & 0x8000) >> 15); 85 return hb + (lb >> 16) + ((lb & 0x8000) >> 15);
86} 86}
87#endif 87#endif
88 88
89/* Faster version of the above using 32x32=64 bit multiply */ 89/* Faster version of the above using 32x32=64 bit multiply */
90#ifdef ROCKBOX 90#ifdef ROCKBOX
91#define fixmul31(x,y) (MULT31(x,y)) 91#define fixmul31(x,y) (MULT31(x,y))
92#else 92#else
93static inline int32_t fixmul31(int32_t x, int32_t y) 93static inline int32_t fixmul31(int32_t x, int32_t y)
94{ 94{
95 int64_t temp; 95 int64_t temp;
96 96
97 temp = x; 97 temp = x;
98 temp *= y; 98 temp *= y;
99 99
100 temp >>= 31; //16+31-16 = 31 bits 100 temp >>= 31; //16+31-16 = 31 bits
101 101
102 return (int32_t)temp; 102 return (int32_t)temp;
103} 103}
104#endif 104#endif
105 105
106/** 106/**
@@ -166,7 +166,8 @@ static void scalar_dequant_math(COOKContext *q, int index,
166 */ 166 */
167#include "../lib/mdct_lookup.h" 167#include "../lib/mdct_lookup.h"
168 168
169static inline void imlt_math(COOKContext *q, FIXP *in) 169void imlt_math(COOKContext *q, FIXP *in) ICODE_ATTR;
170void imlt_math(COOKContext *q, FIXP *in)
170{ 171{
171 const int n = q->samples_per_channel; 172 const int n = q->samples_per_channel;
172 const int step = 2 << (10 - av_log2(n)); 173 const int step = 2 << (10 - av_log2(n));
@@ -203,7 +204,8 @@ static inline void imlt_math(COOKContext *q, FIXP *in)
203 * @param gain gain correction to apply first to output buffer 204 * @param gain gain correction to apply first to output buffer
204 * @param buffer data to overlap 205 * @param buffer data to overlap
205 */ 206 */
206static inline void overlap_math(COOKContext *q, int gain, FIXP buffer[]) 207void overlap_math(COOKContext *q, int gain, FIXP buffer[]) ICODE_ATTR;
208void overlap_math(COOKContext *q, int gain, FIXP buffer[])
207{ 209{
208 int i; 210 int i;
209#ifdef ROCKBOX 211#ifdef ROCKBOX
@@ -280,33 +282,3 @@ static inline FIXP cplscale_math(FIXP x, int table, int i)
280{ 282{
281 return fixp_mult_su(x, cplscales[table-2][i]); 283 return fixp_mult_su(x, cplscales[table-2][i]);
282} 284}
283
284
285/**
286 * Final converion from floating point values to
287 * signed, 16 bit sound samples. Round and clip.
288 *
289 * @param q pointer to the COOKContext
290 * @param out pointer to the output buffer
291 * @param chan 0: left or single channel, 1: right channel
292 */
293static inline void output_math(COOKContext *q, register int16_t *out, int chan)
294{
295#ifdef ROCKBOX
296 register REAL_T * mono_output_ptr = q->mono_mdct_output;
297 register REAL_T * mono_output_end = mono_output_ptr + q->samples_per_channel;
298 out += chan;
299 const int STEP = q->nb_channels;
300 while( mono_output_ptr < mono_output_end )
301 {
302 *out = CLIP_TO_15(fixp_pow2_neg(*mono_output_ptr++, 11));
303 out += STEP;
304 }
305#else
306 int j;
307 for (j = 0; j < q->samples_per_channel; j++) {
308 out[chan + q->nb_channels * j] =
309 av_clip(fixp_pow2(q->mono_mdct_output[j], -11), -32768, 32767);
310 }
311#endif
312}
diff --git a/apps/codecs/libcook/main.c b/apps/codecs/libcook/main.c
index 3f5d3e8528..71d02fb736 100644
--- a/apps/codecs/libcook/main.c
+++ b/apps/codecs/libcook/main.c
@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
120 char filename[15]; 120 char filename[15];
121 int fd_out; 121 int fd_out;
122#endif 122#endif
123 int16_t outbuf[2048]; 123 int32_t outbuf[2048];
124 uint16_t fs,sps,h; 124 uint16_t fs,sps,h;
125 uint32_t packet_count; 125 uint32_t packet_count;
126 COOKContext q; 126 COOKContext q;