diff options
author | Dave Chapman <dave@dchapman.com> | 2005-10-31 18:56:29 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-10-31 18:56:29 +0000 |
commit | 65de1cc6af31f547bd36d320f09cbcc6e6975421 (patch) | |
tree | d1ab6e97adfacb3ef8ca95cdf1c90fcb025271b0 /apps/codecs/libfaad/sbr_qmf.c | |
parent | b83dc3861e5552a802767f37cb97d6b41c9f01cc (diff) | |
download | rockbox-65de1cc6af31f547bd36d320f09cbcc6e6975421.tar.gz rockbox-65de1cc6af31f547bd36d320f09cbcc6e6975421.zip |
Initial check-in of unmodified libfaad (part of the FAAD2 project). This is the last version of libfaad available under the GPL - the state of FAAD2 CVS at midnight on 2005-02-01
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7699 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libfaad/sbr_qmf.c')
-rw-r--r-- | apps/codecs/libfaad/sbr_qmf.c | 633 |
1 files changed, 633 insertions, 0 deletions
diff --git a/apps/codecs/libfaad/sbr_qmf.c b/apps/codecs/libfaad/sbr_qmf.c new file mode 100644 index 0000000000..e99adb4a16 --- /dev/null +++ b/apps/codecs/libfaad/sbr_qmf.c | |||
@@ -0,0 +1,633 @@ | |||
1 | /* | ||
2 | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | ||
3 | ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com | ||
4 | ** | ||
5 | ** This program is free software; you can redistribute it and/or modify | ||
6 | ** it under the terms of the GNU General Public License as published by | ||
7 | ** the Free Software Foundation; either version 2 of the License, or | ||
8 | ** (at your option) any later version. | ||
9 | ** | ||
10 | ** This program is distributed in the hope that it will be useful, | ||
11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | ** GNU General Public License for more details. | ||
14 | ** | ||
15 | ** You should have received a copy of the GNU General Public License | ||
16 | ** along with this program; if not, write to the Free Software | ||
17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | ** | ||
19 | ** Any non-GPL usage of this software or parts of this software is strictly | ||
20 | ** forbidden. | ||
21 | ** | ||
22 | ** Commercial non-GPL licensing of this software is possible. | ||
23 | ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | ||
24 | ** | ||
25 | ** $Id$ | ||
26 | **/ | ||
27 | |||
28 | #include "common.h" | ||
29 | #include "structs.h" | ||
30 | |||
31 | #ifdef SBR_DEC | ||
32 | |||
33 | |||
34 | #include <stdlib.h> | ||
35 | #include <string.h> | ||
36 | #include "sbr_dct.h" | ||
37 | #include "sbr_qmf.h" | ||
38 | #include "sbr_qmf_c.h" | ||
39 | #include "sbr_syntax.h" | ||
40 | |||
41 | qmfa_info *qmfa_init(uint8_t channels) | ||
42 | { | ||
43 | qmfa_info *qmfa = (qmfa_info*)faad_malloc(sizeof(qmfa_info)); | ||
44 | |||
45 | /* x is implemented as double ringbuffer */ | ||
46 | qmfa->x = (real_t*)faad_malloc(2 * channels * 10 * sizeof(real_t)); | ||
47 | memset(qmfa->x, 0, 2 * channels * 10 * sizeof(real_t)); | ||
48 | |||
49 | /* ringbuffer index */ | ||
50 | qmfa->x_index = 0; | ||
51 | |||
52 | qmfa->channels = channels; | ||
53 | |||
54 | return qmfa; | ||
55 | } | ||
56 | |||
57 | void qmfa_end(qmfa_info *qmfa) | ||
58 | { | ||
59 | if (qmfa) | ||
60 | { | ||
61 | if (qmfa->x) faad_free(qmfa->x); | ||
62 | faad_free(qmfa); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void sbr_qmf_analysis_32(sbr_info *sbr, qmfa_info *qmfa, const real_t *input, | ||
67 | qmf_t X[MAX_NTSRHFG][64], uint8_t offset, uint8_t kx) | ||
68 | { | ||
69 | ALIGN real_t u[64]; | ||
70 | #ifndef SBR_LOW_POWER | ||
71 | ALIGN real_t in_real[32], in_imag[32], out_real[32], out_imag[32]; | ||
72 | #else | ||
73 | ALIGN real_t y[32]; | ||
74 | #endif | ||
75 | uint16_t in = 0; | ||
76 | uint8_t l; | ||
77 | |||
78 | /* qmf subsample l */ | ||
79 | for (l = 0; l < sbr->numTimeSlotsRate; l++) | ||
80 | { | ||
81 | int16_t n; | ||
82 | |||
83 | /* shift input buffer x */ | ||
84 | /* input buffer is not shifted anymore, x is implemented as double ringbuffer */ | ||
85 | //memmove(qmfa->x + 32, qmfa->x, (320-32)*sizeof(real_t)); | ||
86 | |||
87 | /* add new samples to input buffer x */ | ||
88 | for (n = 32 - 1; n >= 0; n--) | ||
89 | { | ||
90 | #ifdef FIXED_POINT | ||
91 | qmfa->x[qmfa->x_index + n] = qmfa->x[qmfa->x_index + n + 320] = (input[in++]) >> 4; | ||
92 | #else | ||
93 | qmfa->x[qmfa->x_index + n] = qmfa->x[qmfa->x_index + n + 320] = input[in++]; | ||
94 | #endif | ||
95 | } | ||
96 | |||
97 | /* window and summation to create array u */ | ||
98 | for (n = 0; n < 64; n++) | ||
99 | { | ||
100 | u[n] = MUL_F(qmfa->x[qmfa->x_index + n], qmf_c[2*n]) + | ||
101 | MUL_F(qmfa->x[qmfa->x_index + n + 64], qmf_c[2*(n + 64)]) + | ||
102 | MUL_F(qmfa->x[qmfa->x_index + n + 128], qmf_c[2*(n + 128)]) + | ||
103 | MUL_F(qmfa->x[qmfa->x_index + n + 192], qmf_c[2*(n + 192)]) + | ||
104 | MUL_F(qmfa->x[qmfa->x_index + n + 256], qmf_c[2*(n + 256)]); | ||
105 | } | ||
106 | |||
107 | /* update ringbuffer index */ | ||
108 | qmfa->x_index -= 32; | ||
109 | if (qmfa->x_index < 0) | ||
110 | qmfa->x_index = (320-32); | ||
111 | |||
112 | /* calculate 32 subband samples by introducing X */ | ||
113 | #ifdef SBR_LOW_POWER | ||
114 | y[0] = u[48]; | ||
115 | for (n = 1; n < 16; n++) | ||
116 | y[n] = u[n+48] + u[48-n]; | ||
117 | for (n = 16; n < 32; n++) | ||
118 | y[n] = -u[n-16] + u[48-n]; | ||
119 | |||
120 | DCT3_32_unscaled(u, y); | ||
121 | |||
122 | for (n = 0; n < 32; n++) | ||
123 | { | ||
124 | if (n < kx) | ||
125 | { | ||
126 | #ifdef FIXED_POINT | ||
127 | QMF_RE(X[l + offset][n]) = u[n] /*<< 1*/; | ||
128 | #else | ||
129 | QMF_RE(X[l + offset][n]) = 2. * u[n]; | ||
130 | #endif | ||
131 | } else { | ||
132 | QMF_RE(X[l + offset][n]) = 0; | ||
133 | } | ||
134 | } | ||
135 | #else | ||
136 | |||
137 | // Reordering of data moved from DCT_IV to here | ||
138 | in_imag[31] = u[1]; | ||
139 | in_real[0] = u[0]; | ||
140 | for (n = 1; n < 31; n++) | ||
141 | { | ||
142 | in_imag[31 - n] = u[n+1]; | ||
143 | in_real[n] = -u[64-n]; | ||
144 | } | ||
145 | in_imag[0] = u[32]; | ||
146 | in_real[31] = -u[33]; | ||
147 | |||
148 | // dct4_kernel is DCT_IV without reordering which is done before and after FFT | ||
149 | dct4_kernel(in_real, in_imag, out_real, out_imag); | ||
150 | |||
151 | // Reordering of data moved from DCT_IV to here | ||
152 | for (n = 0; n < 16; n++) { | ||
153 | if (2*n+1 < kx) { | ||
154 | #ifdef FIXED_POINT | ||
155 | QMF_RE(X[l + offset][2*n]) = out_real[n]; | ||
156 | QMF_IM(X[l + offset][2*n]) = out_imag[n]; | ||
157 | QMF_RE(X[l + offset][2*n+1]) = -out_imag[31-n]; | ||
158 | QMF_IM(X[l + offset][2*n+1]) = -out_real[31-n]; | ||
159 | #else | ||
160 | QMF_RE(X[l + offset][2*n]) = 2. * out_real[n]; | ||
161 | QMF_IM(X[l + offset][2*n]) = 2. * out_imag[n]; | ||
162 | QMF_RE(X[l + offset][2*n+1]) = -2. * out_imag[31-n]; | ||
163 | QMF_IM(X[l + offset][2*n+1]) = -2. * out_real[31-n]; | ||
164 | #endif | ||
165 | } else { | ||
166 | if (2*n < kx) { | ||
167 | #ifdef FIXED_POINT | ||
168 | QMF_RE(X[l + offset][2*n]) = out_real[n]; | ||
169 | QMF_IM(X[l + offset][2*n]) = out_imag[n]; | ||
170 | #else | ||
171 | QMF_RE(X[l + offset][2*n]) = 2. * out_real[n]; | ||
172 | QMF_IM(X[l + offset][2*n]) = 2. * out_imag[n]; | ||
173 | #endif | ||
174 | } | ||
175 | else { | ||
176 | QMF_RE(X[l + offset][2*n]) = 0; | ||
177 | QMF_IM(X[l + offset][2*n]) = 0; | ||
178 | } | ||
179 | QMF_RE(X[l + offset][2*n+1]) = 0; | ||
180 | QMF_IM(X[l + offset][2*n+1]) = 0; | ||
181 | } | ||
182 | } | ||
183 | #endif | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static const complex_t qmf32_pre_twiddle[] = | ||
188 | { | ||
189 | { FRAC_CONST(0.999924701839145), FRAC_CONST(-0.012271538285720) }, | ||
190 | { FRAC_CONST(0.999322384588350), FRAC_CONST(-0.036807222941359) }, | ||
191 | { FRAC_CONST(0.998118112900149), FRAC_CONST(-0.061320736302209) }, | ||
192 | { FRAC_CONST(0.996312612182778), FRAC_CONST(-0.085797312344440) }, | ||
193 | { FRAC_CONST(0.993906970002356), FRAC_CONST(-0.110222207293883) }, | ||
194 | { FRAC_CONST(0.990902635427780), FRAC_CONST(-0.134580708507126) }, | ||
195 | { FRAC_CONST(0.987301418157858), FRAC_CONST(-0.158858143333861) }, | ||
196 | { FRAC_CONST(0.983105487431216), FRAC_CONST(-0.183039887955141) }, | ||
197 | { FRAC_CONST(0.978317370719628), FRAC_CONST(-0.207111376192219) }, | ||
198 | { FRAC_CONST(0.972939952205560), FRAC_CONST(-0.231058108280671) }, | ||
199 | { FRAC_CONST(0.966976471044852), FRAC_CONST(-0.254865659604515) }, | ||
200 | { FRAC_CONST(0.960430519415566), FRAC_CONST(-0.278519689385053) }, | ||
201 | { FRAC_CONST(0.953306040354194), FRAC_CONST(-0.302005949319228) }, | ||
202 | { FRAC_CONST(0.945607325380521), FRAC_CONST(-0.325310292162263) }, | ||
203 | { FRAC_CONST(0.937339011912575), FRAC_CONST(-0.348418680249435) }, | ||
204 | { FRAC_CONST(0.928506080473216), FRAC_CONST(-0.371317193951838) }, | ||
205 | { FRAC_CONST(0.919113851690058), FRAC_CONST(-0.393992040061048) }, | ||
206 | { FRAC_CONST(0.909167983090522), FRAC_CONST(-0.416429560097637) }, | ||
207 | { FRAC_CONST(0.898674465693954), FRAC_CONST(-0.438616238538528) }, | ||
208 | { FRAC_CONST(0.887639620402854), FRAC_CONST(-0.460538710958240) }, | ||
209 | { FRAC_CONST(0.876070094195407), FRAC_CONST(-0.482183772079123) }, | ||
210 | { FRAC_CONST(0.863972856121587), FRAC_CONST(-0.503538383725718) }, | ||
211 | { FRAC_CONST(0.851355193105265), FRAC_CONST(-0.524589682678469) }, | ||
212 | { FRAC_CONST(0.838224705554838), FRAC_CONST(-0.545324988422046) }, | ||
213 | { FRAC_CONST(0.824589302785025), FRAC_CONST(-0.565731810783613) }, | ||
214 | { FRAC_CONST(0.810457198252595), FRAC_CONST(-0.585797857456439) }, | ||
215 | { FRAC_CONST(0.795836904608884), FRAC_CONST(-0.605511041404326) }, | ||
216 | { FRAC_CONST(0.780737228572094), FRAC_CONST(-0.624859488142386) }, | ||
217 | { FRAC_CONST(0.765167265622459), FRAC_CONST(-0.643831542889791) }, | ||
218 | { FRAC_CONST(0.749136394523459), FRAC_CONST(-0.662415777590172) }, | ||
219 | { FRAC_CONST(0.732654271672413), FRAC_CONST(-0.680600997795453) }, | ||
220 | { FRAC_CONST(0.715730825283819), FRAC_CONST(-0.698376249408973) } | ||
221 | }; | ||
222 | |||
223 | qmfs_info *qmfs_init(uint8_t channels) | ||
224 | { | ||
225 | qmfs_info *qmfs = (qmfs_info*)faad_malloc(sizeof(qmfs_info)); | ||
226 | |||
227 | /* v is a double ringbuffer */ | ||
228 | qmfs->v = (real_t*)faad_malloc(2 * channels * 20 * sizeof(real_t)); | ||
229 | memset(qmfs->v, 0, 2 * channels * 20 * sizeof(real_t)); | ||
230 | |||
231 | qmfs->v_index = 0; | ||
232 | |||
233 | qmfs->channels = channels; | ||
234 | |||
235 | return qmfs; | ||
236 | } | ||
237 | |||
238 | void qmfs_end(qmfs_info *qmfs) | ||
239 | { | ||
240 | if (qmfs) | ||
241 | { | ||
242 | if (qmfs->v) faad_free(qmfs->v); | ||
243 | faad_free(qmfs); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | #ifdef SBR_LOW_POWER | ||
248 | |||
249 | void sbr_qmf_synthesis_32(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][64], | ||
250 | real_t *output) | ||
251 | { | ||
252 | ALIGN real_t x[16]; | ||
253 | ALIGN real_t y[16]; | ||
254 | int16_t n, k, out = 0; | ||
255 | uint8_t l; | ||
256 | |||
257 | /* qmf subsample l */ | ||
258 | for (l = 0; l < sbr->numTimeSlotsRate; l++) | ||
259 | { | ||
260 | /* shift buffers */ | ||
261 | /* we are not shifting v, it is a double ringbuffer */ | ||
262 | //memmove(qmfs->v + 64, qmfs->v, (640-64)*sizeof(real_t)); | ||
263 | |||
264 | /* calculate 64 samples */ | ||
265 | for (k = 0; k < 16; k++) | ||
266 | { | ||
267 | #ifdef FIXED_POINT | ||
268 | y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][31 - k])); | ||
269 | x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][31 - k])); | ||
270 | #else | ||
271 | y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][31 - k])) / 32.0; | ||
272 | x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][31 - k])) / 32.0; | ||
273 | #endif | ||
274 | } | ||
275 | |||
276 | /* even n samples */ | ||
277 | DCT2_16_unscaled(x, x); | ||
278 | /* odd n samples */ | ||
279 | DCT4_16(y, y); | ||
280 | |||
281 | for (n = 8; n < 24; n++) | ||
282 | { | ||
283 | qmfs->v[qmfs->v_index + n*2] = qmfs->v[qmfs->v_index + 640 + n*2] = x[n-8]; | ||
284 | qmfs->v[qmfs->v_index + n*2+1] = qmfs->v[qmfs->v_index + 640 + n*2+1] = y[n-8]; | ||
285 | } | ||
286 | for (n = 0; n < 16; n++) | ||
287 | { | ||
288 | qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 640 + n] = qmfs->v[qmfs->v_index + 32-n]; | ||
289 | } | ||
290 | qmfs->v[qmfs->v_index + 48] = qmfs->v[qmfs->v_index + 640 + 48] = 0; | ||
291 | for (n = 1; n < 16; n++) | ||
292 | { | ||
293 | qmfs->v[qmfs->v_index + 48+n] = qmfs->v[qmfs->v_index + 640 + 48+n] = -qmfs->v[qmfs->v_index + 48-n]; | ||
294 | } | ||
295 | |||
296 | /* calculate 32 output samples and window */ | ||
297 | for (k = 0; k < 32; k++) | ||
298 | { | ||
299 | output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[2*k]) + | ||
300 | MUL_F(qmfs->v[qmfs->v_index + 96 + k], qmf_c[64 + 2*k]) + | ||
301 | MUL_F(qmfs->v[qmfs->v_index + 128 + k], qmf_c[128 + 2*k]) + | ||
302 | MUL_F(qmfs->v[qmfs->v_index + 224 + k], qmf_c[192 + 2*k]) + | ||
303 | MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[256 + 2*k]) + | ||
304 | MUL_F(qmfs->v[qmfs->v_index + 352 + k], qmf_c[320 + 2*k]) + | ||
305 | MUL_F(qmfs->v[qmfs->v_index + 384 + k], qmf_c[384 + 2*k]) + | ||
306 | MUL_F(qmfs->v[qmfs->v_index + 480 + k], qmf_c[448 + 2*k]) + | ||
307 | MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[512 + 2*k]) + | ||
308 | MUL_F(qmfs->v[qmfs->v_index + 608 + k], qmf_c[576 + 2*k]); | ||
309 | } | ||
310 | |||
311 | /* update the ringbuffer index */ | ||
312 | qmfs->v_index -= 64; | ||
313 | if (qmfs->v_index < 0) | ||
314 | qmfs->v_index = (640-64); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][64], | ||
319 | real_t *output) | ||
320 | { | ||
321 | ALIGN real_t x[64]; | ||
322 | ALIGN real_t y[64]; | ||
323 | int16_t n, k, out = 0; | ||
324 | uint8_t l; | ||
325 | |||
326 | |||
327 | /* qmf subsample l */ | ||
328 | for (l = 0; l < sbr->numTimeSlotsRate; l++) | ||
329 | { | ||
330 | /* shift buffers */ | ||
331 | /* we are not shifting v, it is a double ringbuffer */ | ||
332 | //memmove(qmfs->v + 128, qmfs->v, (1280-128)*sizeof(real_t)); | ||
333 | |||
334 | /* calculate 128 samples */ | ||
335 | for (k = 0; k < 32; k++) | ||
336 | { | ||
337 | #ifdef FIXED_POINT | ||
338 | y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][63 - k])); | ||
339 | x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][63 - k])); | ||
340 | #else | ||
341 | y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][63 - k])) / 32.0; | ||
342 | x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][63 - k])) / 32.0; | ||
343 | #endif | ||
344 | } | ||
345 | |||
346 | /* even n samples */ | ||
347 | DCT2_32_unscaled(x, x); | ||
348 | /* odd n samples */ | ||
349 | DCT4_32(y, y); | ||
350 | |||
351 | for (n = 16; n < 48; n++) | ||
352 | { | ||
353 | qmfs->v[qmfs->v_index + n*2] = qmfs->v[qmfs->v_index + 1280 + n*2] = x[n-16]; | ||
354 | qmfs->v[qmfs->v_index + n*2+1] = qmfs->v[qmfs->v_index + 1280 + n*2+1] = y[n-16]; | ||
355 | } | ||
356 | for (n = 0; n < 32; n++) | ||
357 | { | ||
358 | qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 1280 + n] = qmfs->v[qmfs->v_index + 64-n]; | ||
359 | } | ||
360 | qmfs->v[qmfs->v_index + 96] = qmfs->v[qmfs->v_index + 1280 + 96] = 0; | ||
361 | for (n = 1; n < 32; n++) | ||
362 | { | ||
363 | qmfs->v[qmfs->v_index + 96+n] = qmfs->v[qmfs->v_index + 1280 + 96+n] = -qmfs->v[qmfs->v_index + 96-n]; | ||
364 | } | ||
365 | |||
366 | /* calculate 64 output samples and window */ | ||
367 | for (k = 0; k < 64; k++) | ||
368 | { | ||
369 | output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[k]) + | ||
370 | MUL_F(qmfs->v[qmfs->v_index + 192 + k], qmf_c[64 + k]) + | ||
371 | MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[128 + k]) + | ||
372 | MUL_F(qmfs->v[qmfs->v_index + 256 + 192 + k], qmf_c[128 + 64 + k]) + | ||
373 | MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[256 + k]) + | ||
374 | MUL_F(qmfs->v[qmfs->v_index + 512 + 192 + k], qmf_c[256 + 64 + k]) + | ||
375 | MUL_F(qmfs->v[qmfs->v_index + 768 + k], qmf_c[384 + k]) + | ||
376 | MUL_F(qmfs->v[qmfs->v_index + 768 + 192 + k], qmf_c[384 + 64 + k]) + | ||
377 | MUL_F(qmfs->v[qmfs->v_index + 1024 + k], qmf_c[512 + k]) + | ||
378 | MUL_F(qmfs->v[qmfs->v_index + 1024 + 192 + k], qmf_c[512 + 64 + k]); | ||
379 | } | ||
380 | |||
381 | /* update the ringbuffer index */ | ||
382 | qmfs->v_index -= 128; | ||
383 | if (qmfs->v_index < 0) | ||
384 | qmfs->v_index = (1280-128); | ||
385 | } | ||
386 | } | ||
387 | #else | ||
388 | void sbr_qmf_synthesis_32(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][64], | ||
389 | real_t *output) | ||
390 | { | ||
391 | ALIGN real_t x1[32], x2[32]; | ||
392 | #ifndef FIXED_POINT | ||
393 | real_t scale = 1.f/64.f; | ||
394 | #endif | ||
395 | int16_t n, k, out = 0; | ||
396 | uint8_t l; | ||
397 | |||
398 | |||
399 | /* qmf subsample l */ | ||
400 | for (l = 0; l < sbr->numTimeSlotsRate; l++) | ||
401 | { | ||
402 | /* shift buffer v */ | ||
403 | /* buffer is not shifted, we are using a ringbuffer */ | ||
404 | //memmove(qmfs->v + 64, qmfs->v, (640-64)*sizeof(real_t)); | ||
405 | |||
406 | /* calculate 64 samples */ | ||
407 | /* complex pre-twiddle */ | ||
408 | for (k = 0; k < 32; k++) | ||
409 | { | ||
410 | x1[k] = MUL_F(QMF_RE(X[l][k]), RE(qmf32_pre_twiddle[k])) - MUL_F(QMF_IM(X[l][k]), IM(qmf32_pre_twiddle[k])); | ||
411 | x2[k] = MUL_F(QMF_IM(X[l][k]), RE(qmf32_pre_twiddle[k])) + MUL_F(QMF_RE(X[l][k]), IM(qmf32_pre_twiddle[k])); | ||
412 | |||
413 | #ifndef FIXED_POINT | ||
414 | x1[k] *= scale; | ||
415 | x2[k] *= scale; | ||
416 | #else | ||
417 | x1[k] >>= 1; | ||
418 | x2[k] >>= 1; | ||
419 | #endif | ||
420 | } | ||
421 | |||
422 | /* transform */ | ||
423 | DCT4_32(x1, x1); | ||
424 | DST4_32(x2, x2); | ||
425 | |||
426 | for (n = 0; n < 32; n++) | ||
427 | { | ||
428 | qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 640 + n] = -x1[n] + x2[n]; | ||
429 | qmfs->v[qmfs->v_index + 63 - n] = qmfs->v[qmfs->v_index + 640 + 63 - n] = x1[n] + x2[n]; | ||
430 | } | ||
431 | |||
432 | /* calculate 32 output samples and window */ | ||
433 | for (k = 0; k < 32; k++) | ||
434 | { | ||
435 | output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[2*k]) + | ||
436 | MUL_F(qmfs->v[qmfs->v_index + 96 + k], qmf_c[64 + 2*k]) + | ||
437 | MUL_F(qmfs->v[qmfs->v_index + 128 + k], qmf_c[128 + 2*k]) + | ||
438 | MUL_F(qmfs->v[qmfs->v_index + 224 + k], qmf_c[192 + 2*k]) + | ||
439 | MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[256 + 2*k]) + | ||
440 | MUL_F(qmfs->v[qmfs->v_index + 352 + k], qmf_c[320 + 2*k]) + | ||
441 | MUL_F(qmfs->v[qmfs->v_index + 384 + k], qmf_c[384 + 2*k]) + | ||
442 | MUL_F(qmfs->v[qmfs->v_index + 480 + k], qmf_c[448 + 2*k]) + | ||
443 | MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[512 + 2*k]) + | ||
444 | MUL_F(qmfs->v[qmfs->v_index + 608 + k], qmf_c[576 + 2*k]); | ||
445 | } | ||
446 | |||
447 | /* update ringbuffer index */ | ||
448 | qmfs->v_index -= 64; | ||
449 | if (qmfs->v_index < 0) | ||
450 | qmfs->v_index = (640 - 64); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][64], | ||
455 | real_t *output) | ||
456 | { | ||
457 | // ALIGN real_t x1[64], x2[64]; | ||
458 | #ifndef SBR_LOW_POWER | ||
459 | ALIGN real_t in_real1[32], in_imag1[32], out_real1[32], out_imag1[32]; | ||
460 | ALIGN real_t in_real2[32], in_imag2[32], out_real2[32], out_imag2[32]; | ||
461 | #endif | ||
462 | qmf_t * pX; | ||
463 | real_t * pring_buffer_1, * pring_buffer_3; | ||
464 | // real_t * ptemp_1, * ptemp_2; | ||
465 | #ifdef PREFER_POINTERS | ||
466 | // These pointers are used if target platform has autoinc address generators | ||
467 | real_t * pring_buffer_2, * pring_buffer_4; | ||
468 | real_t * pring_buffer_5, * pring_buffer_6; | ||
469 | real_t * pring_buffer_7, * pring_buffer_8; | ||
470 | real_t * pring_buffer_9, * pring_buffer_10; | ||
471 | const real_t * pqmf_c_1, * pqmf_c_2, * pqmf_c_3, * pqmf_c_4; | ||
472 | const real_t * pqmf_c_5, * pqmf_c_6, * pqmf_c_7, * pqmf_c_8; | ||
473 | const real_t * pqmf_c_9, * pqmf_c_10; | ||
474 | #endif // #ifdef PREFER_POINTERS | ||
475 | #ifndef FIXED_POINT | ||
476 | real_t scale = 1.f/64.f; | ||
477 | #endif | ||
478 | int16_t n, k, out = 0; | ||
479 | uint8_t l; | ||
480 | |||
481 | |||
482 | /* qmf subsample l */ | ||
483 | for (l = 0; l < sbr->numTimeSlotsRate; l++) | ||
484 | { | ||
485 | /* shift buffer v */ | ||
486 | /* buffer is not shifted, we use double ringbuffer */ | ||
487 | //memmove(qmfs->v + 128, qmfs->v, (1280-128)*sizeof(real_t)); | ||
488 | |||
489 | /* calculate 128 samples */ | ||
490 | #ifndef FIXED_POINT | ||
491 | |||
492 | pX = X[l]; | ||
493 | |||
494 | in_imag1[31] = scale*QMF_RE(pX[1]); | ||
495 | in_real1[0] = scale*QMF_RE(pX[0]); | ||
496 | in_imag2[31] = scale*QMF_IM(pX[63-1]); | ||
497 | in_real2[0] = scale*QMF_IM(pX[63-0]); | ||
498 | for (k = 1; k < 31; k++) | ||
499 | { | ||
500 | in_imag1[31 - k] = scale*QMF_RE(pX[2*k + 1]); | ||
501 | in_real1[ k] = scale*QMF_RE(pX[2*k ]); | ||
502 | in_imag2[31 - k] = scale*QMF_IM(pX[63 - (2*k + 1)]); | ||
503 | in_real2[ k] = scale*QMF_IM(pX[63 - (2*k )]); | ||
504 | } | ||
505 | in_imag1[0] = scale*QMF_RE(pX[63]); | ||
506 | in_real1[31] = scale*QMF_RE(pX[62]); | ||
507 | in_imag2[0] = scale*QMF_IM(pX[63-63]); | ||
508 | in_real2[31] = scale*QMF_IM(pX[63-62]); | ||
509 | |||
510 | #else | ||
511 | |||
512 | pX = X[l]; | ||
513 | |||
514 | in_imag1[31] = QMF_RE(pX[1]) >> 1; | ||
515 | in_real1[0] = QMF_RE(pX[0]) >> 1; | ||
516 | in_imag2[31] = QMF_IM(pX[62]) >> 1; | ||
517 | in_real2[0] = QMF_IM(pX[63]) >> 1; | ||
518 | for (k = 1; k < 31; k++) | ||
519 | { | ||
520 | in_imag1[31 - k] = QMF_RE(pX[2*k + 1]) >> 1; | ||
521 | in_real1[ k] = QMF_RE(pX[2*k ]) >> 1; | ||
522 | in_imag2[31 - k] = QMF_IM(pX[63 - (2*k + 1)]) >> 1; | ||
523 | in_real2[ k] = QMF_IM(pX[63 - (2*k )]) >> 1; | ||
524 | } | ||
525 | in_imag1[0] = QMF_RE(pX[63]) >> 1; | ||
526 | in_real1[31] = QMF_RE(pX[62]) >> 1; | ||
527 | in_imag2[0] = QMF_IM(pX[0]) >> 1; | ||
528 | in_real2[31] = QMF_IM(pX[1]) >> 1; | ||
529 | |||
530 | #endif | ||
531 | |||
532 | |||
533 | // dct4_kernel is DCT_IV without reordering which is done before and after FFT | ||
534 | dct4_kernel(in_real1, in_imag1, out_real1, out_imag1); | ||
535 | dct4_kernel(in_real2, in_imag2, out_real2, out_imag2); | ||
536 | |||
537 | |||
538 | pring_buffer_1 = qmfs->v + qmfs->v_index; | ||
539 | pring_buffer_3 = pring_buffer_1 + 1280; | ||
540 | #ifdef PREFER_POINTERS | ||
541 | pring_buffer_2 = pring_buffer_1 + 127; | ||
542 | pring_buffer_4 = pring_buffer_1 + (1280 + 127); | ||
543 | #endif // #ifdef PREFER_POINTERS | ||
544 | // ptemp_1 = x1; | ||
545 | // ptemp_2 = x2; | ||
546 | #ifdef PREFER_POINTERS | ||
547 | for (n = 0; n < 32; n ++) | ||
548 | { | ||
549 | //real_t x1 = *ptemp_1++; | ||
550 | //real_t x2 = *ptemp_2++; | ||
551 | // pring_buffer_3 and pring_buffer_4 are needed only for double ring buffer | ||
552 | *pring_buffer_1++ = *pring_buffer_3++ = out_real2[n] - out_real1[n]; | ||
553 | *pring_buffer_2-- = *pring_buffer_4-- = out_real2[n] + out_real1[n]; | ||
554 | //x1 = *ptemp_1++; | ||
555 | //x2 = *ptemp_2++; | ||
556 | *pring_buffer_1++ = *pring_buffer_3++ = out_imag2[31-n] + out_imag1[31-n]; | ||
557 | *pring_buffer_2-- = *pring_buffer_4-- = out_imag2[31-n] - out_imag1[31-n]; | ||
558 | } | ||
559 | #else // #ifdef PREFER_POINTERS | ||
560 | |||
561 | for (n = 0; n < 32; n++) | ||
562 | { | ||
563 | // pring_buffer_3 and pring_buffer_4 are needed only for double ring buffer | ||
564 | pring_buffer_1[2*n] = pring_buffer_3[2*n] = out_real2[n] - out_real1[n]; | ||
565 | pring_buffer_1[127-2*n] = pring_buffer_3[127-2*n] = out_real2[n] + out_real1[n]; | ||
566 | pring_buffer_1[2*n+1] = pring_buffer_3[2*n+1] = out_imag2[31-n] + out_imag1[31-n]; | ||
567 | pring_buffer_1[127-(2*n+1)] = pring_buffer_3[127-(2*n+1)] = out_imag2[31-n] - out_imag1[31-n]; | ||
568 | } | ||
569 | |||
570 | #endif // #ifdef PREFER_POINTERS | ||
571 | |||
572 | pring_buffer_1 = qmfs->v + qmfs->v_index; | ||
573 | #ifdef PREFER_POINTERS | ||
574 | pring_buffer_2 = pring_buffer_1 + 192; | ||
575 | pring_buffer_3 = pring_buffer_1 + 256; | ||
576 | pring_buffer_4 = pring_buffer_1 + (256 + 192); | ||
577 | pring_buffer_5 = pring_buffer_1 + 512; | ||
578 | pring_buffer_6 = pring_buffer_1 + (512 + 192); | ||
579 | pring_buffer_7 = pring_buffer_1 + 768; | ||
580 | pring_buffer_8 = pring_buffer_1 + (768 + 192); | ||
581 | pring_buffer_9 = pring_buffer_1 + 1024; | ||
582 | pring_buffer_10 = pring_buffer_1 + (1024 + 192); | ||
583 | pqmf_c_1 = qmf_c; | ||
584 | pqmf_c_2 = qmf_c + 64; | ||
585 | pqmf_c_3 = qmf_c + 128; | ||
586 | pqmf_c_4 = qmf_c + 192; | ||
587 | pqmf_c_5 = qmf_c + 256; | ||
588 | pqmf_c_6 = qmf_c + 320; | ||
589 | pqmf_c_7 = qmf_c + 384; | ||
590 | pqmf_c_8 = qmf_c + 448; | ||
591 | pqmf_c_9 = qmf_c + 512; | ||
592 | pqmf_c_10 = qmf_c + 576; | ||
593 | #endif // #ifdef PREFER_POINTERS | ||
594 | |||
595 | /* calculate 64 output samples and window */ | ||
596 | for (k = 0; k < 64; k++) | ||
597 | { | ||
598 | #ifdef PREFER_POINTERS | ||
599 | output[out++] = | ||
600 | MUL_F(*pring_buffer_1++, *pqmf_c_1++) + | ||
601 | MUL_F(*pring_buffer_2++, *pqmf_c_2++) + | ||
602 | MUL_F(*pring_buffer_3++, *pqmf_c_3++) + | ||
603 | MUL_F(*pring_buffer_4++, *pqmf_c_4++) + | ||
604 | MUL_F(*pring_buffer_5++, *pqmf_c_5++) + | ||
605 | MUL_F(*pring_buffer_6++, *pqmf_c_6++) + | ||
606 | MUL_F(*pring_buffer_7++, *pqmf_c_7++) + | ||
607 | MUL_F(*pring_buffer_8++, *pqmf_c_8++) + | ||
608 | MUL_F(*pring_buffer_9++, *pqmf_c_9++) + | ||
609 | MUL_F(*pring_buffer_10++, *pqmf_c_10++); | ||
610 | #else // #ifdef PREFER_POINTERS | ||
611 | output[out++] = | ||
612 | MUL_F(pring_buffer_1[k+0], qmf_c[k+0]) + | ||
613 | MUL_F(pring_buffer_1[k+192], qmf_c[k+64]) + | ||
614 | MUL_F(pring_buffer_1[k+256], qmf_c[k+128]) + | ||
615 | MUL_F(pring_buffer_1[k+(256+192)], qmf_c[k+192]) + | ||
616 | MUL_F(pring_buffer_1[k+512], qmf_c[k+256]) + | ||
617 | MUL_F(pring_buffer_1[k+(512+192)], qmf_c[k+320]) + | ||
618 | MUL_F(pring_buffer_1[k+768], qmf_c[k+384]) + | ||
619 | MUL_F(pring_buffer_1[k+(768+192)], qmf_c[k+448]) + | ||
620 | MUL_F(pring_buffer_1[k+1024], qmf_c[k+512]) + | ||
621 | MUL_F(pring_buffer_1[k+(1024+192)], qmf_c[k+576]); | ||
622 | #endif // #ifdef PREFER_POINTERS | ||
623 | } | ||
624 | |||
625 | /* update ringbuffer index */ | ||
626 | qmfs->v_index -= 128; | ||
627 | if (qmfs->v_index < 0) | ||
628 | qmfs->v_index = (1280 - 128); | ||
629 | } | ||
630 | } | ||
631 | #endif | ||
632 | |||
633 | #endif | ||