summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2007-11-10 14:57:49 +0000
committerThom Johansen <thomj@rockbox.org>2007-11-10 14:57:49 +0000
commit1730e406ed8f1db32e9755bbfedcb192ff153cb7 (patch)
treea49cb4371cb94031126b401136451bd8103cecfd /apps/codecs
parentec6569ed22d27eb6eb5a3902502eecc59d83de7a (diff)
downloadrockbox-1730e406ed8f1db32e9755bbfedcb192ff153cb7.tar.gz
rockbox-1730e406ed8f1db32e9755bbfedcb192ff153cb7.zip
Strip out a large unneeded portion of the Speex stereo decoding function, and port the rest of it to fixed point. Disable the unneeded stereo float decoding function. Correct the output buffer size and change some minor syntactic stuff in speex.c
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15554 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/libspeex/speex/speex_stereo.h14
-rw-r--r--apps/codecs/libspeex/stereo.c43
-rw-r--r--apps/codecs/speex.c20
3 files changed, 46 insertions, 31 deletions
diff --git a/apps/codecs/libspeex/speex/speex_stereo.h b/apps/codecs/libspeex/speex/speex_stereo.h
index ea2f976a26..904e9b092e 100644
--- a/apps/codecs/libspeex/speex/speex_stereo.h
+++ b/apps/codecs/libspeex/speex/speex_stereo.h
@@ -48,17 +48,29 @@ extern "C" {
48 48
49/** State used for decoding (intensity) stereo information */ 49/** State used for decoding (intensity) stereo information */
50typedef struct SpeexStereoState { 50typedef struct SpeexStereoState {
51#ifndef FIXED_POINT
51 float balance; /**< Left/right balance info */ 52 float balance; /**< Left/right balance info */
52 float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ 53 float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
53 float smooth_left; /**< Smoothed left channel gain */ 54 float smooth_left; /**< Smoothed left channel gain */
54 float smooth_right; /**< Smoothed right channel gain */ 55 float smooth_right; /**< Smoothed right channel gain */
55 float reserved1; /**< Reserved for future use */ 56 float reserved1; /**< Reserved for future use */
56 float reserved2; /**< Reserved for future use */ 57 float reserved2; /**< Reserved for future use */
58#else
59 spx_int32_t balance; /**< Left/right balance info */
60 spx_int16_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */
61 spx_int16_t smooth_left; /**< Smoothed left channel gain */
62 spx_int16_t smooth_right; /**< Smoothed right channel gain */
63 spx_int32_t reserved1; /**< Reserved for future use */
64 spx_int32_t reserved2; /**< Reserved for future use */
65#endif
57} SpeexStereoState; 66} SpeexStereoState;
58 67
59/** Initialization value for a stereo state */ 68/** Initialization value for a stereo state */
69#ifndef FIXED_POINT
60#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} 70#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}
61 71#else
72#define SPEEX_STEREO_STATE_INIT {65536,16384,16384,16384,0,0}
73#endif
62/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ 74/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
63void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); 75void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
64 76
diff --git a/apps/codecs/libspeex/stereo.c b/apps/codecs/libspeex/stereo.c
index b0c65b812f..695dfe0fb0 100644
--- a/apps/codecs/libspeex/stereo.c
+++ b/apps/codecs/libspeex/stereo.c
@@ -35,11 +35,16 @@
35 35
36#include <speex/speex_stereo.h> 36#include <speex/speex_stereo.h>
37#include <speex/speex_callbacks.h> 37#include <speex/speex_callbacks.h>
38#include "math_approx.h"
38#include "vq.h" 39#include "vq.h"
39#include <math.h> 40#include <math.h>
40 41
41/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ 42/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
43#ifndef FIXED_POINT
42static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; 44static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
45#else
46static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
47#endif
43 48
44#ifndef SPEEX_DISABLE_ENCODER 49#ifndef SPEEX_DISABLE_ENCODER
45void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) 50void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
@@ -115,8 +120,10 @@ void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
115 tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); 120 tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
116 speex_bits_pack(bits, tmp, 2); 121 speex_bits_pack(bits, tmp, 2);
117} 122}
118#endif 123#endif /* SPEEX_DISABLE_ENCODER */
119 124
125/* We don't want to decode to floats yet, disable */
126#if 0
120void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo) 127void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
121{ 128{
122 float balance, e_ratio; 129 float balance, e_ratio;
@@ -145,48 +152,46 @@ void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
145 data[2*i+1] = stereo->smooth_right*ftmp; 152 data[2*i+1] = stereo->smooth_right*ftmp;
146 } 153 }
147} 154}
155#endif
148 156
149void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo) 157void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo)
150{ 158{
151 float balance, e_ratio;
152 int i; 159 int i;
153 float e_tot=0, e_left, e_right, e_sum; 160 spx_word32_t balance;
161 spx_word16_t e_left, e_right, e_ratio;
154 162
155 balance=stereo->balance; 163 balance=stereo->balance;
156 e_ratio=stereo->e_ratio; 164 e_ratio=stereo->e_ratio;
157 for (i=frame_size-1;i>=0;i--)
158 {
159 e_tot += ((float)data[i])*data[i];
160 }
161 e_sum=e_tot/e_ratio;
162 e_left = e_sum*balance / (1+balance);
163 e_right = e_sum-e_left;
164 165
165 e_left = sqrt(e_left/(e_tot+.01)); 166 /* These two are Q14, with max value just below 2. */
166 e_right = sqrt(e_right/(e_tot+.01)); 167 e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
168 e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);
167 169
168 for (i=frame_size-1;i>=0;i--) 170 for (i=frame_size-1;i>=0;i--)
169 { 171 {
170 float ftmp=data[i]; 172 spx_word16_t tmp=data[i];
171 stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; 173 stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
172 stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; 174 stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
173 data[2*i] = stereo->smooth_left*ftmp; 175 data[2*i] = MULT16_16_P14(stereo->smooth_left, tmp);
174 data[2*i+1] = stereo->smooth_right*ftmp; 176 data[2*i+1] = MULT16_16_P14(stereo->smooth_right, tmp);
175 } 177 }
176} 178}
177 179
178int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) 180int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
179{ 181{
180 SpeexStereoState *stereo; 182 SpeexStereoState *stereo;
181 float sign=1; 183 spx_word16_t sign=1;
182 int tmp; 184 int tmp;
183 185
184 stereo = (SpeexStereoState*)data; 186 stereo = (SpeexStereoState*)data;
185 if (speex_bits_unpack_unsigned(bits, 1)) 187 if (speex_bits_unpack_unsigned(bits, 1))
186 sign=-1; 188 sign=-1;
187 tmp = speex_bits_unpack_unsigned(bits, 5); 189 tmp = speex_bits_unpack_unsigned(bits, 5);
190#ifndef FIXED_POINT
188 stereo->balance = exp(sign*.25*tmp); 191 stereo->balance = exp(sign*.25*tmp);
189 192#else
193 stereo->balance = spx_exp(MULT16_16(sign, SHL16(tmp, 9)));
194#endif
190 tmp = speex_bits_unpack_unsigned(bits, 2); 195 tmp = speex_bits_unpack_unsigned(bits, 2);
191 stereo->e_ratio = e_ratio_quant[tmp]; 196 stereo->e_ratio = e_ratio_quant[tmp];
192 197
diff --git a/apps/codecs/speex.c b/apps/codecs/speex.c
index 7edda4b6db..2cd547a84d 100644
--- a/apps/codecs/speex.c
+++ b/apps/codecs/speex.c
@@ -26,7 +26,8 @@
26#include "libspeex/speex/speex_config_types.h" 26#include "libspeex/speex/speex_config_types.h"
27#include "codeclib.h" 27#include "codeclib.h"
28 28
29#define MAX_FRAME_SIZE 2000 29// Room for one stereo frame of max size, 2*640
30#define MAX_FRAME_SIZE 1280
30#define CHUNKSIZE 10000 /*2kb*/ 31#define CHUNKSIZE 10000 /*2kb*/
31#define SEEK_CHUNKSIZE 7*CHUNKSIZE 32#define SEEK_CHUNKSIZE 7*CHUNKSIZE
32 33
@@ -346,7 +347,7 @@ static void *process_header(spx_ogg_packet *op,
346 speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled); 347 speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
347 speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size); 348 speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
348 349
349 if (!(*channels==1)){ 350 if (*channels!=1){
350 callback.callback_id = SPEEX_INBAND_STEREO; 351 callback.callback_id = SPEEX_INBAND_STEREO;
351 callback.func = speex_std_stereo_request_handler; 352 callback.func = speex_std_stereo_request_handler;
352 callback.data = stereo; 353 callback.data = stereo;
@@ -381,7 +382,8 @@ enum codec_status codec_main(void)
381 int enh_enabled = 1; 382 int enh_enabled = 1;
382 int nframes = 2; 383 int nframes = 2;
383 int eos = 0; 384 int eos = 0;
384 SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; 385 static const SpeexStereoState stereo_init = SPEEX_STEREO_STATE_INIT;
386 SpeexStereoState stereo = stereo_init;
385 int channels = -1; 387 int channels = -1;
386 int rate = 0, samplerate = 0; 388 int rate = 0, samplerate = 0;
387 int extra_headers = 0; 389 int extra_headers = 0;
@@ -531,13 +533,11 @@ next_page:
531 if (channels == 2) 533 if (channels == 2)
532 speex_decode_stereo_int(output, frame_size, &stereo); 534 speex_decode_stereo_int(output, frame_size, &stereo);
533 535
534 int new_frame_size = frame_size; 536 if (frame_size > 0) {
535 537 ci->pcmbuf_insert(output, NULL, frame_size);
536 if (new_frame_size > 0) {
537 ci->pcmbuf_insert(output, NULL, new_frame_size);
538 538
539 /* 2 bytes/sample */ 539 /* 2 bytes/sample */
540 cur_granule += new_frame_size / 2; 540 cur_granule += frame_size / 2;
541 541
542 ci->set_offset((long) ci->curpos); 542 ci->set_offset((long) ci->curpos);
543 543
@@ -566,9 +566,7 @@ done:
566 cur_granule = stream_init = rate = samplerate = headerssize 566 cur_granule = stream_init = rate = samplerate = headerssize
567 = packet_count = eos = 0; 567 = packet_count = eos = 0;
568 568
569 stereo.balance = stereo.smooth_left = stereo.smooth_right = 1; 569 stereo = stereo_init;
570 stereo.e_ratio = .5;
571 stereo.reserved1 = stereo.reserved2 = 0;
572 570
573 goto next_track; 571 goto next_track;
574 } 572 }