/src/speex/libspeex/stereo.c
Line | Count | Source |
1 | | /* Copyright (C) 2002 Jean-Marc Valin |
2 | | File: stereo.c |
3 | | |
4 | | Redistribution and use in source and binary forms, with or without |
5 | | modification, are permitted provided that the following conditions |
6 | | are met: |
7 | | |
8 | | - Redistributions of source code must retain the above copyright |
9 | | notice, this list of conditions and the following disclaimer. |
10 | | |
11 | | - Redistributions in binary form must reproduce the above copyright |
12 | | notice, this list of conditions and the following disclaimer in the |
13 | | documentation and/or other materials provided with the distribution. |
14 | | |
15 | | - Neither the name of the Xiph.org Foundation nor the names of its |
16 | | contributors may be used to endorse or promote products derived from |
17 | | this software without specific prior written permission. |
18 | | |
19 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
23 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
24 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
25 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
26 | | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
27 | | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
28 | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
29 | | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | | */ |
31 | | |
32 | | #ifdef HAVE_CONFIG_H |
33 | | #include "config.h" |
34 | | #endif |
35 | | |
36 | | #include "speex/speex_stereo.h" |
37 | | #include "speex/speex_callbacks.h" |
38 | | #include "math_approx.h" |
39 | | #include "vq.h" |
40 | | #include <math.h> |
41 | | #include "os_support.h" |
42 | | |
43 | | typedef struct RealSpeexStereoState { |
44 | | spx_word32_t balance; /**< Left/right balance info */ |
45 | | spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ |
46 | | spx_word32_t smooth_left; /**< Smoothed left channel gain */ |
47 | | spx_word32_t smooth_right; /**< Smoothed right channel gain */ |
48 | | spx_uint32_t reserved1; /**< Reserved for future use */ |
49 | | spx_int32_t reserved2; /**< Reserved for future use */ |
50 | | } RealSpeexStereoState; |
51 | | |
52 | | |
53 | | /*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ |
54 | | #ifndef FIXED_POINT |
55 | | static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; |
56 | | static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f}; |
57 | | #else |
58 | | static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384}; |
59 | | static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696}; |
60 | | static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104, |
61 | | 134, 172, 221, 284, 364, 468, 600, 771, |
62 | | 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696, |
63 | | 7314, 9392, 12059, 15484, 19882, 25529, 32766}; |
64 | | #endif |
65 | | |
66 | | /* This is an ugly compatibility hack that properly resets the stereo state |
67 | | In case it it compiled in fixed-point, but initialised with the deprecated |
68 | | floating point static initialiser */ |
69 | | #ifdef FIXED_POINT |
70 | 6.46k | #define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0); |
71 | | #else |
72 | | #define COMPATIBILITY_HACK(s) |
73 | | #endif |
74 | | |
75 | | EXPORT SpeexStereoState *speex_stereo_state_init() |
76 | 0 | { |
77 | 0 | SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState)); |
78 | 0 | speex_stereo_state_reset(stereo); |
79 | 0 | return stereo; |
80 | 0 | } |
81 | | |
82 | | EXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo) |
83 | 531 | { |
84 | 531 | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; |
85 | | #ifdef FIXED_POINT |
86 | | stereo->balance = 65536; |
87 | | stereo->e_ratio = 16384; |
88 | | stereo->smooth_left = 16384; |
89 | | stereo->smooth_right = 16384; |
90 | | stereo->reserved1 = 0xdeadbeef; |
91 | | stereo->reserved2 = 0; |
92 | | #else |
93 | 531 | stereo->balance = 1.0f; |
94 | 531 | stereo->e_ratio = .5f; |
95 | 531 | stereo->smooth_left = 1.f; |
96 | 531 | stereo->smooth_right = 1.f; |
97 | 531 | stereo->reserved1 = 0; |
98 | 531 | stereo->reserved2 = 0; |
99 | 531 | #endif |
100 | 531 | } |
101 | | |
102 | | EXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo) |
103 | 0 | { |
104 | 0 | speex_free(stereo); |
105 | 0 | } |
106 | | |
107 | | #ifndef DISABLE_ENCODER |
108 | | #ifndef DISABLE_FLOAT_API |
109 | | EXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) |
110 | 0 | { |
111 | 0 | int i, tmp; |
112 | 0 | float e_left=0, e_right=0, e_tot=0; |
113 | 0 | float balance, e_ratio; |
114 | 0 | for (i=0;i<frame_size;i++) |
115 | 0 | { |
116 | 0 | e_left += ((float)data[2*i])*data[2*i]; |
117 | 0 | e_right += ((float)data[2*i+1])*data[2*i+1]; |
118 | 0 | data[i] = .5*(((float)data[2*i])+data[2*i+1]); |
119 | 0 | e_tot += ((float)data[i])*data[i]; |
120 | 0 | } |
121 | 0 | balance=(e_left+1)/(e_right+1); |
122 | 0 | e_ratio = e_tot/(1+e_left+e_right); |
123 | | |
124 | | /*Quantization*/ |
125 | 0 | speex_bits_pack(bits, 14, 5); |
126 | 0 | speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); |
127 | |
|
128 | 0 | balance=4*log(balance); |
129 | | |
130 | | /*Pack sign*/ |
131 | 0 | if (balance>0) |
132 | 0 | speex_bits_pack(bits, 0, 1); |
133 | 0 | else |
134 | 0 | speex_bits_pack(bits, 1, 1); |
135 | 0 | balance=floor(.5+fabs(balance)); |
136 | 0 | if (balance>30) |
137 | 0 | balance=31; |
138 | |
|
139 | 0 | speex_bits_pack(bits, (int)balance, 5); |
140 | | |
141 | | /* FIXME: this is a hack */ |
142 | 0 | tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4); |
143 | 0 | speex_bits_pack(bits, tmp, 2); |
144 | 0 | } |
145 | | #endif /* #ifndef DISABLE_FLOAT_API */ |
146 | | |
147 | | EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits) |
148 | 2.03k | { |
149 | 2.03k | int i, tmp; |
150 | 2.03k | spx_word32_t e_left=0, e_right=0, e_tot=0; |
151 | 2.03k | spx_word32_t balance, e_ratio; |
152 | 2.03k | spx_word32_t largest, smallest; |
153 | 2.03k | int balance_id; |
154 | | #ifdef FIXED_POINT |
155 | | int shift; |
156 | | int sqr_shift; |
157 | | |
158 | | /* Avoid overflows when summing squares */ |
159 | 514 | sqr_shift = frame_size >= 512 ? 9 : 8; |
160 | | #endif |
161 | | |
162 | | /* In band marker */ |
163 | 2.03k | speex_bits_pack(bits, 14, 5); |
164 | | /* Stereo marker */ |
165 | 2.03k | speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); |
166 | | |
167 | 549k | for (i=0;i<frame_size;i++) |
168 | 547k | { |
169 | 547k | e_left += SHR32(MULT16_16(data[2*i],data[2*i]),sqr_shift); |
170 | 547k | e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),sqr_shift); |
171 | | #ifdef FIXED_POINT |
172 | | /* I think this is actually unbiased */ |
173 | 104k | data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1); |
174 | | #else |
175 | | data[i] = .5*(((float)data[2*i])+data[2*i+1]); |
176 | | #endif |
177 | 547k | e_tot += SHR32(MULT16_16(data[i],data[i]),sqr_shift); |
178 | 547k | } |
179 | 2.03k | if (e_left > e_right) |
180 | 477 | { |
181 | 477 | speex_bits_pack(bits, 0, 1); |
182 | 477 | largest = e_left; |
183 | 477 | smallest = e_right; |
184 | 1.56k | } else { |
185 | 1.56k | speex_bits_pack(bits, 1, 1); |
186 | 1.56k | largest = e_right; |
187 | 1.56k | smallest = e_left; |
188 | 1.56k | } |
189 | | |
190 | | /* Balance quantization */ |
191 | | #ifdef FIXED_POINT |
192 | | shift = spx_ilog2(largest)-15; |
193 | 514 | largest = VSHR32(largest, shift-4); |
194 | 514 | smallest = VSHR32(smallest, shift); |
195 | 514 | balance = DIV32(largest, ADD32(smallest, 1)); |
196 | 514 | if (balance > 32767) |
197 | 32 | balance = 32767; |
198 | 514 | balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); |
199 | | #else |
200 | | balance=(largest+1.)/(smallest+1.); |
201 | | balance=4*log(balance); |
202 | | balance_id=floor(.5+fabs(balance)); |
203 | 1.52k | if (balance_id>30) |
204 | 79 | balance_id=31; |
205 | | #endif |
206 | | |
207 | 2.03k | speex_bits_pack(bits, balance_id, 5); |
208 | | |
209 | | /* "coherence" quantisation */ |
210 | | #ifdef FIXED_POINT |
211 | | shift = spx_ilog2(e_tot); |
212 | 514 | e_tot = VSHR32(e_tot, shift-25); |
213 | 514 | e_left = VSHR32(e_left, shift-10); |
214 | 514 | e_right = VSHR32(e_right, shift-10); |
215 | 514 | if (e_left > 32767) |
216 | 30 | e_left = 32767; |
217 | 514 | if (e_right > 32767) |
218 | 28 | e_right = 32767; |
219 | 514 | e_ratio = DIV32(e_tot, e_left+e_right+1); |
220 | | #else |
221 | | e_ratio = e_tot/(1.+e_left+e_right); |
222 | | #endif |
223 | | |
224 | 2.03k | tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4); |
225 | | /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/ |
226 | 2.03k | speex_bits_pack(bits, tmp, 2); |
227 | 2.03k | } Line | Count | Source | 148 | 1.52k | { | 149 | 1.52k | int i, tmp; | 150 | 1.52k | spx_word32_t e_left=0, e_right=0, e_tot=0; | 151 | 1.52k | spx_word32_t balance, e_ratio; | 152 | 1.52k | spx_word32_t largest, smallest; | 153 | 1.52k | int balance_id; | 154 | | #ifdef FIXED_POINT | 155 | | int shift; | 156 | | int sqr_shift; | 157 | | | 158 | | /* Avoid overflows when summing squares */ | 159 | | sqr_shift = frame_size >= 512 ? 9 : 8; | 160 | | #endif | 161 | | | 162 | | /* In band marker */ | 163 | 1.52k | speex_bits_pack(bits, 14, 5); | 164 | | /* Stereo marker */ | 165 | 1.52k | speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); | 166 | | | 167 | 444k | for (i=0;i<frame_size;i++) | 168 | 442k | { | 169 | 442k | e_left += SHR32(MULT16_16(data[2*i],data[2*i]),sqr_shift); | 170 | 442k | e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),sqr_shift); | 171 | | #ifdef FIXED_POINT | 172 | | /* I think this is actually unbiased */ | 173 | | data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1); | 174 | | #else | 175 | 442k | data[i] = .5*(((float)data[2*i])+data[2*i+1]); | 176 | 442k | #endif | 177 | 442k | e_tot += SHR32(MULT16_16(data[i],data[i]),sqr_shift); | 178 | 442k | } | 179 | 1.52k | if (e_left > e_right) | 180 | 233 | { | 181 | 233 | speex_bits_pack(bits, 0, 1); | 182 | 233 | largest = e_left; | 183 | 233 | smallest = e_right; | 184 | 1.29k | } else { | 185 | 1.29k | speex_bits_pack(bits, 1, 1); | 186 | 1.29k | largest = e_right; | 187 | 1.29k | smallest = e_left; | 188 | 1.29k | } | 189 | | | 190 | | /* Balance quantization */ | 191 | | #ifdef FIXED_POINT | 192 | | shift = spx_ilog2(largest)-15; | 193 | | largest = VSHR32(largest, shift-4); | 194 | | smallest = VSHR32(smallest, shift); | 195 | | balance = DIV32(largest, ADD32(smallest, 1)); | 196 | | if (balance > 32767) | 197 | | balance = 32767; | 198 | | balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); | 199 | | #else | 200 | 1.52k | balance=(largest+1.)/(smallest+1.); | 201 | 1.52k | balance=4*log(balance); | 202 | 1.52k | balance_id=floor(.5+fabs(balance)); | 203 | 1.52k | if (balance_id>30) | 204 | 79 | balance_id=31; | 205 | 1.52k | #endif | 206 | | | 207 | 1.52k | speex_bits_pack(bits, balance_id, 5); | 208 | | | 209 | | /* "coherence" quantisation */ | 210 | | #ifdef FIXED_POINT | 211 | | shift = spx_ilog2(e_tot); | 212 | | e_tot = VSHR32(e_tot, shift-25); | 213 | | e_left = VSHR32(e_left, shift-10); | 214 | | e_right = VSHR32(e_right, shift-10); | 215 | | if (e_left > 32767) | 216 | | e_left = 32767; | 217 | | if (e_right > 32767) | 218 | | e_right = 32767; | 219 | | e_ratio = DIV32(e_tot, e_left+e_right+1); | 220 | | #else | 221 | 1.52k | e_ratio = e_tot/(1.+e_left+e_right); | 222 | 1.52k | #endif | 223 | | | 224 | 1.52k | tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4); | 225 | | /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/ | 226 | 1.52k | speex_bits_pack(bits, tmp, 2); | 227 | 1.52k | } |
Line | Count | Source | 148 | 514 | { | 149 | 514 | int i, tmp; | 150 | 514 | spx_word32_t e_left=0, e_right=0, e_tot=0; | 151 | 514 | spx_word32_t balance, e_ratio; | 152 | 514 | spx_word32_t largest, smallest; | 153 | 514 | int balance_id; | 154 | 514 | #ifdef FIXED_POINT | 155 | 514 | int shift; | 156 | 514 | int sqr_shift; | 157 | | | 158 | | /* Avoid overflows when summing squares */ | 159 | 514 | sqr_shift = frame_size >= 512 ? 9 : 8; | 160 | 514 | #endif | 161 | | | 162 | | /* In band marker */ | 163 | 514 | speex_bits_pack(bits, 14, 5); | 164 | | /* Stereo marker */ | 165 | 514 | speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); | 166 | | | 167 | 105k | for (i=0;i<frame_size;i++) | 168 | 104k | { | 169 | 104k | e_left += SHR32(MULT16_16(data[2*i],data[2*i]),sqr_shift); | 170 | 104k | e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),sqr_shift); | 171 | 104k | #ifdef FIXED_POINT | 172 | | /* I think this is actually unbiased */ | 173 | 104k | data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1); | 174 | | #else | 175 | | data[i] = .5*(((float)data[2*i])+data[2*i+1]); | 176 | | #endif | 177 | 104k | e_tot += SHR32(MULT16_16(data[i],data[i]),sqr_shift); | 178 | 104k | } | 179 | 514 | if (e_left > e_right) | 180 | 244 | { | 181 | 244 | speex_bits_pack(bits, 0, 1); | 182 | 244 | largest = e_left; | 183 | 244 | smallest = e_right; | 184 | 270 | } else { | 185 | 270 | speex_bits_pack(bits, 1, 1); | 186 | 270 | largest = e_right; | 187 | 270 | smallest = e_left; | 188 | 270 | } | 189 | | | 190 | | /* Balance quantization */ | 191 | 514 | #ifdef FIXED_POINT | 192 | 514 | shift = spx_ilog2(largest)-15; | 193 | 514 | largest = VSHR32(largest, shift-4); | 194 | 514 | smallest = VSHR32(smallest, shift); | 195 | 514 | balance = DIV32(largest, ADD32(smallest, 1)); | 196 | 514 | if (balance > 32767) | 197 | 32 | balance = 32767; | 198 | 514 | balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); | 199 | | #else | 200 | | balance=(largest+1.)/(smallest+1.); | 201 | | balance=4*log(balance); | 202 | | balance_id=floor(.5+fabs(balance)); | 203 | | if (balance_id>30) | 204 | | balance_id=31; | 205 | | #endif | 206 | | | 207 | 514 | speex_bits_pack(bits, balance_id, 5); | 208 | | | 209 | | /* "coherence" quantisation */ | 210 | 514 | #ifdef FIXED_POINT | 211 | 514 | shift = spx_ilog2(e_tot); | 212 | 514 | e_tot = VSHR32(e_tot, shift-25); | 213 | 514 | e_left = VSHR32(e_left, shift-10); | 214 | 514 | e_right = VSHR32(e_right, shift-10); | 215 | 514 | if (e_left > 32767) | 216 | 30 | e_left = 32767; | 217 | 514 | if (e_right > 32767) | 218 | 28 | e_right = 32767; | 219 | 514 | e_ratio = DIV32(e_tot, e_left+e_right+1); | 220 | | #else | 221 | | e_ratio = e_tot/(1.+e_left+e_right); | 222 | | #endif | 223 | | | 224 | 514 | tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4); | 225 | | /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/ | 226 | 514 | speex_bits_pack(bits, tmp, 2); | 227 | 514 | } |
|
228 | | #else /* DISABLE_ENCODER */ |
229 | | EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits) |
230 | | { |
231 | | } |
232 | | #endif /* DISABLE_ENCODER */ |
233 | | |
234 | | |
235 | | #ifndef DISABLE_FLOAT_API |
236 | | EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo) |
237 | 11.0k | { |
238 | 11.0k | int i; |
239 | 11.0k | spx_word32_t balance; |
240 | 11.0k | spx_word16_t e_left, e_right, e_ratio; |
241 | 11.0k | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; |
242 | | |
243 | 11.0k | COMPATIBILITY_HACK(stereo); |
244 | | |
245 | 11.0k | balance=stereo->balance; |
246 | 11.0k | e_ratio=stereo->e_ratio; |
247 | | |
248 | | /* These two are Q14, with max value just below 2. */ |
249 | 11.0k | e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); |
250 | 11.0k | e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); |
251 | | |
252 | 4.45M | for (i=frame_size-1;i>=0;i--) |
253 | 4.44M | { |
254 | 4.44M | spx_word16_t tmp=data[i]; |
255 | 4.44M | stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); |
256 | 4.44M | stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); |
257 | 4.44M | data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp); |
258 | 4.44M | data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp); |
259 | 4.44M | } |
260 | 11.0k | } Line | Count | Source | 237 | 5.11k | { | 238 | 5.11k | int i; | 239 | 5.11k | spx_word32_t balance; | 240 | 5.11k | spx_word16_t e_left, e_right, e_ratio; | 241 | 5.11k | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; | 242 | | | 243 | 5.11k | COMPATIBILITY_HACK(stereo); | 244 | | | 245 | 5.11k | balance=stereo->balance; | 246 | 5.11k | e_ratio=stereo->e_ratio; | 247 | | | 248 | | /* These two are Q14, with max value just below 2. */ | 249 | 5.11k | e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); | 250 | 5.11k | e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); | 251 | | | 252 | 2.26M | for (i=frame_size-1;i>=0;i--) | 253 | 2.26M | { | 254 | 2.26M | spx_word16_t tmp=data[i]; | 255 | 2.26M | stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); | 256 | 2.26M | stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); | 257 | 2.26M | data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp); | 258 | 2.26M | data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp); | 259 | 2.26M | } | 260 | 5.11k | } |
Line | Count | Source | 237 | 5.92k | { | 238 | 5.92k | int i; | 239 | 5.92k | spx_word32_t balance; | 240 | 5.92k | spx_word16_t e_left, e_right, e_ratio; | 241 | 5.92k | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; | 242 | | | 243 | 5.92k | COMPATIBILITY_HACK(stereo); | 244 | | | 245 | 5.92k | balance=stereo->balance; | 246 | 5.92k | e_ratio=stereo->e_ratio; | 247 | | | 248 | | /* These two are Q14, with max value just below 2. */ | 249 | 5.92k | e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); | 250 | 5.92k | e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); | 251 | | | 252 | 2.19M | for (i=frame_size-1;i>=0;i--) | 253 | 2.18M | { | 254 | 2.18M | spx_word16_t tmp=data[i]; | 255 | 2.18M | stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); | 256 | 2.18M | stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); | 257 | 2.18M | data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp); | 258 | 2.18M | data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp); | 259 | 2.18M | } | 260 | 5.92k | } |
|
261 | | #endif /* #ifndef DISABLE_FLOAT_API */ |
262 | | |
263 | | EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo) |
264 | 0 | { |
265 | 0 | int i; |
266 | 0 | spx_word32_t balance; |
267 | 0 | spx_word16_t e_left, e_right, e_ratio; |
268 | 0 | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; |
269 | |
|
270 | 0 | COMPATIBILITY_HACK(stereo); |
271 | |
|
272 | 0 | balance=stereo->balance; |
273 | 0 | e_ratio=stereo->e_ratio; |
274 | | |
275 | | /* These two are Q14, with max value just below 2. */ |
276 | 0 | e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); |
277 | 0 | e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); |
278 | |
|
279 | 0 | for (i=frame_size-1;i>=0;i--) |
280 | 0 | { |
281 | 0 | spx_int16_t tmp=data[i]; |
282 | 0 | stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); |
283 | 0 | stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); |
284 | 0 | data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp); |
285 | 0 | data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp); |
286 | 0 | } |
287 | 0 | } Unexecuted instantiation: speex_decode_stereo_int Unexecuted instantiation: speex_decode_stereo_int |
288 | | |
289 | | EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) |
290 | 1.01k | { |
291 | 1.01k | RealSpeexStereoState *stereo; |
292 | 1.01k | spx_word16_t sign=1, dexp; |
293 | 1.01k | int tmp; |
294 | | |
295 | 1.01k | stereo = (RealSpeexStereoState*)data; |
296 | | |
297 | 1.01k | COMPATIBILITY_HACK(stereo); |
298 | | |
299 | 1.01k | if (speex_bits_unpack_unsigned(bits, 1)) |
300 | 498 | sign=-1; |
301 | 1.01k | dexp = speex_bits_unpack_unsigned(bits, 5); |
302 | | #ifndef FIXED_POINT |
303 | | stereo->balance = exp(sign*.25*dexp); |
304 | | #else |
305 | 534 | stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9))); |
306 | | #endif |
307 | 1.01k | tmp = speex_bits_unpack_unsigned(bits, 2); |
308 | 1.01k | stereo->e_ratio = e_ratio_quant[tmp]; |
309 | | |
310 | 1.01k | return 0; |
311 | 1.01k | } speex_std_stereo_request_handler Line | Count | Source | 290 | 483 | { | 291 | 483 | RealSpeexStereoState *stereo; | 292 | 483 | spx_word16_t sign=1, dexp; | 293 | 483 | int tmp; | 294 | | | 295 | 483 | stereo = (RealSpeexStereoState*)data; | 296 | | | 297 | 483 | COMPATIBILITY_HACK(stereo); | 298 | | | 299 | 483 | if (speex_bits_unpack_unsigned(bits, 1)) | 300 | 239 | sign=-1; | 301 | 483 | dexp = speex_bits_unpack_unsigned(bits, 5); | 302 | 483 | #ifndef FIXED_POINT | 303 | 483 | stereo->balance = exp(sign*.25*dexp); | 304 | | #else | 305 | | stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9))); | 306 | | #endif | 307 | 483 | tmp = speex_bits_unpack_unsigned(bits, 2); | 308 | 483 | stereo->e_ratio = e_ratio_quant[tmp]; | 309 | | | 310 | 483 | return 0; | 311 | 483 | } |
speex_std_stereo_request_handler Line | Count | Source | 290 | 534 | { | 291 | 534 | RealSpeexStereoState *stereo; | 292 | 534 | spx_word16_t sign=1, dexp; | 293 | 534 | int tmp; | 294 | | | 295 | 534 | stereo = (RealSpeexStereoState*)data; | 296 | | | 297 | 534 | COMPATIBILITY_HACK(stereo); | 298 | | | 299 | 534 | if (speex_bits_unpack_unsigned(bits, 1)) | 300 | 259 | sign=-1; | 301 | 534 | dexp = speex_bits_unpack_unsigned(bits, 5); | 302 | | #ifndef FIXED_POINT | 303 | | stereo->balance = exp(sign*.25*dexp); | 304 | | #else | 305 | 534 | stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9))); | 306 | 534 | #endif | 307 | 534 | tmp = speex_bits_unpack_unsigned(bits, 2); | 308 | 534 | stereo->e_ratio = e_ratio_quant[tmp]; | 309 | | | 310 | 534 | return 0; | 311 | 534 | } |
|