diff options
-rw-r--r-- | apps/codecs/libspeex/speex/speex_stereo.h | 14 | ||||
-rw-r--r-- | apps/codecs/libspeex/stereo.c | 43 | ||||
-rw-r--r-- | apps/codecs/speex.c | 20 |
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 */ |
50 | typedef struct SpeexStereoState { | 50 | typedef 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' */ |
63 | void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); | 75 | void 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 | ||
42 | static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; | 44 | static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; |
45 | #else | ||
46 | static 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 |
45 | void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) | 50 | void 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 | ||
120 | void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo) | 127 | void 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 | ||
149 | void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo) | 157 | void 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 | ||
178 | int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) | 180 | int 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 | } |