diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libfaad/sbr_hfgen.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libfaad/sbr_hfgen.c')
-rw-r--r-- | lib/rbcodec/codecs/libfaad/sbr_hfgen.c | 539 |
1 files changed, 539 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libfaad/sbr_hfgen.c b/lib/rbcodec/codecs/libfaad/sbr_hfgen.c new file mode 100644 index 0000000000..3a5b250aa7 --- /dev/null +++ b/lib/rbcodec/codecs/libfaad/sbr_hfgen.c | |||
@@ -0,0 +1,539 @@ | |||
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 | /* High Frequency generation */ | ||
29 | |||
30 | #include "common.h" | ||
31 | #include "structs.h" | ||
32 | |||
33 | #ifdef SBR_DEC | ||
34 | |||
35 | #include "sbr_syntax.h" | ||
36 | #include "sbr_hfgen.h" | ||
37 | #include "sbr_fbt.h" | ||
38 | |||
39 | |||
40 | /* static function declarations */ | ||
41 | #ifdef SBR_LOW_POWER | ||
42 | static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | ||
43 | complex_t *alpha_0, complex_t *alpha_1, real_t *rxx); | ||
44 | static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg); | ||
45 | #else | ||
46 | static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | ||
47 | complex_t *alpha_0, complex_t *alpha_1, uint8_t k); | ||
48 | #endif | ||
49 | static void calc_chirp_factors(sbr_info *sbr, uint8_t ch); | ||
50 | static void patch_construction(sbr_info *sbr); | ||
51 | |||
52 | |||
53 | void hf_generation(sbr_info *sbr, | ||
54 | qmf_t Xlow[MAX_NTSRHFG][64], | ||
55 | qmf_t Xhigh[MAX_NTSRHFG][64] | ||
56 | #ifdef SBR_LOW_POWER | ||
57 | ,real_t *deg | ||
58 | #endif | ||
59 | ,uint8_t ch) | ||
60 | { | ||
61 | uint8_t l, i, x; | ||
62 | complex_t alpha_0[64] MEM_ALIGN_ATTR; | ||
63 | complex_t alpha_1[64] MEM_ALIGN_ATTR; | ||
64 | #ifdef SBR_LOW_POWER | ||
65 | real_t rxx[64]; | ||
66 | #endif | ||
67 | |||
68 | uint8_t offset = sbr->tHFAdj; | ||
69 | uint8_t first = sbr->t_E[ch][0]; | ||
70 | uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; | ||
71 | |||
72 | calc_chirp_factors(sbr, ch); | ||
73 | |||
74 | #ifdef SBR_LOW_POWER | ||
75 | memset(deg, 0, 64*sizeof(real_t)); | ||
76 | #endif | ||
77 | |||
78 | if ((ch == 0) && (sbr->Reset)) | ||
79 | patch_construction(sbr); | ||
80 | |||
81 | /* calculate the prediction coefficients */ | ||
82 | #ifdef SBR_LOW_POWER | ||
83 | calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); | ||
84 | calc_aliasing_degree(sbr, rxx, deg); | ||
85 | #endif | ||
86 | |||
87 | /* actual HF generation */ | ||
88 | for (i = 0; i < sbr->noPatches; i++) | ||
89 | { | ||
90 | for (x = 0; x < sbr->patchNoSubbands[i]; x++) | ||
91 | { | ||
92 | real_t a0_r, a0_i, a1_r, a1_i; | ||
93 | real_t bw, bw2; | ||
94 | uint8_t q, p, k, g; | ||
95 | |||
96 | /* find the low and high band for patching */ | ||
97 | k = sbr->kx + x; | ||
98 | for (q = 0; q < i; q++) | ||
99 | { | ||
100 | k += sbr->patchNoSubbands[q]; | ||
101 | } | ||
102 | p = sbr->patchStartSubband[i] + x; | ||
103 | |||
104 | #ifdef SBR_LOW_POWER | ||
105 | if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) | ||
106 | deg[k] = deg[p]; | ||
107 | else | ||
108 | deg[k] = 0; | ||
109 | #endif | ||
110 | |||
111 | g = sbr->table_map_k_to_g[k]; | ||
112 | |||
113 | bw = sbr->bwArray[ch][g]; | ||
114 | bw2 = MUL_C(bw, bw); | ||
115 | |||
116 | /* do the patching */ | ||
117 | /* with or without filtering */ | ||
118 | if (bw2 > 0) | ||
119 | { | ||
120 | real_t temp1_r, temp2_r, temp3_r; | ||
121 | #ifndef SBR_LOW_POWER | ||
122 | real_t temp1_i, temp2_i, temp3_i; | ||
123 | calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); | ||
124 | #endif | ||
125 | |||
126 | a0_r = MUL_C(RE(alpha_0[p]), bw); | ||
127 | a1_r = MUL_C(RE(alpha_1[p]), bw2); | ||
128 | #ifndef SBR_LOW_POWER | ||
129 | a0_i = MUL_C(IM(alpha_0[p]), bw); | ||
130 | a1_i = MUL_C(IM(alpha_1[p]), bw2); | ||
131 | #endif | ||
132 | |||
133 | temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); | ||
134 | temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); | ||
135 | #ifndef SBR_LOW_POWER | ||
136 | temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); | ||
137 | temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); | ||
138 | #endif | ||
139 | for (l = first; l < last; l++) | ||
140 | { | ||
141 | temp1_r = temp2_r; | ||
142 | temp2_r = temp3_r; | ||
143 | temp3_r = QMF_RE(Xlow[l + offset][p]); | ||
144 | #ifndef SBR_LOW_POWER | ||
145 | temp1_i = temp2_i; | ||
146 | temp2_i = temp3_i; | ||
147 | temp3_i = QMF_IM(Xlow[l + offset][p]); | ||
148 | #endif | ||
149 | |||
150 | #ifdef SBR_LOW_POWER | ||
151 | QMF_RE(Xhigh[l + offset][k]) = temp3_r + | ||
152 | (MUL_R(a0_r, temp2_r) + MUL_R(a1_r, temp1_r)); | ||
153 | #else | ||
154 | QMF_RE(Xhigh[l + offset][k]) = temp3_r + | ||
155 | (MUL_R(a0_r, temp2_r) - MUL_R(a0_i, temp2_i) + | ||
156 | MUL_R(a1_r, temp1_r) - MUL_R(a1_i, temp1_i)); | ||
157 | QMF_IM(Xhigh[l + offset][k]) = temp3_i + | ||
158 | (MUL_R(a0_i, temp2_r) + MUL_R(a0_r, temp2_i) + | ||
159 | MUL_R(a1_i, temp1_r) + MUL_R(a1_r, temp1_i)); | ||
160 | #endif | ||
161 | } | ||
162 | } else { | ||
163 | for (l = first; l < last; l++) | ||
164 | { | ||
165 | QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); | ||
166 | #ifndef SBR_LOW_POWER | ||
167 | QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); | ||
168 | #endif | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | if (sbr->Reset) | ||
175 | { | ||
176 | limiter_frequency_table(sbr); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | typedef struct | ||
181 | { | ||
182 | complex_t r01; | ||
183 | complex_t r02; | ||
184 | complex_t r11; | ||
185 | complex_t r12; | ||
186 | complex_t r22; | ||
187 | real_t det; | ||
188 | } acorr_coef; | ||
189 | |||
190 | /* Within auto_correlation(...) a pre-shift of >>ACDET_EXP is needed to avoid | ||
191 | * overflow when multiply-adding the FRACT-variables -- FRACT part is 31 bits. | ||
192 | * After the calculation has been finished the result 'ac->det' needs to be | ||
193 | * post-shifted by <<(4*ACDET_EXP). This pre-/post-shifting is needed for | ||
194 | * FIXED_POINT only. */ | ||
195 | #ifdef FIXED_POINT | ||
196 | #define ACDET_EXP 3 | ||
197 | #define ACDET_PRE(A) (A)>>ACDET_EXP | ||
198 | #define ACDET_POST(A) (A)<<(4*ACDET_EXP) | ||
199 | #else | ||
200 | #define ACDET_PRE(A) (A) | ||
201 | #define ACDET_POST(A) (A) | ||
202 | #endif | ||
203 | |||
204 | #ifdef SBR_LOW_POWER | ||
205 | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, | ||
206 | qmf_t buffer[MAX_NTSRHFG][64], | ||
207 | uint8_t bd, uint8_t len) | ||
208 | { | ||
209 | real_t r01 = 0, r02 = 0, r11 = 0; | ||
210 | real_t tmp1, tmp2; | ||
211 | int8_t j; | ||
212 | uint8_t offset = sbr->tHFAdj; | ||
213 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | ||
214 | |||
215 | for (j = offset; j < len + offset; j++) | ||
216 | { | ||
217 | real_t buf_j = ACDET_PRE(QMF_RE(buffer[j ][bd])); | ||
218 | real_t buf_j_1 = ACDET_PRE(QMF_RE(buffer[j-1][bd])); | ||
219 | real_t buf_j_2 = ACDET_PRE(QMF_RE(buffer[j-2][bd])); | ||
220 | |||
221 | r01 += MUL_F(buf_j , buf_j_1); | ||
222 | r02 += MUL_F(buf_j , buf_j_2); | ||
223 | r11 += MUL_F(buf_j_1, buf_j_1); | ||
224 | } | ||
225 | tmp1 = ACDET_PRE(QMF_RE(buffer[len+offset-1][bd])); | ||
226 | tmp2 = ACDET_PRE(QMF_RE(buffer[ offset-1][bd])); | ||
227 | RE(ac->r12) = r01 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); | ||
228 | |||
229 | tmp1 = ACDET_PRE(QMF_RE(buffer[len+offset-2][bd])); | ||
230 | tmp2 = ACDET_PRE(QMF_RE(buffer[ offset-2][bd])); | ||
231 | RE(ac->r22) = r11 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); | ||
232 | RE(ac->r01) = r01; | ||
233 | RE(ac->r02) = r02; | ||
234 | RE(ac->r11) = r11; | ||
235 | |||
236 | ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_F(RE(ac->r12), RE(ac->r12)), rel); | ||
237 | ac->det = ACDET_POST(ac->det); | ||
238 | } | ||
239 | #else | ||
240 | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], | ||
241 | uint8_t bd, uint8_t len) | ||
242 | { | ||
243 | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; | ||
244 | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i; | ||
245 | real_t temp4_r, temp4_i, temp5_r, temp5_i; | ||
246 | int8_t j; | ||
247 | uint8_t offset = sbr->tHFAdj; | ||
248 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | ||
249 | |||
250 | temp2_r = ACDET_PRE(QMF_RE(buffer[offset-2][bd])); | ||
251 | temp2_i = ACDET_PRE(QMF_IM(buffer[offset-2][bd])); | ||
252 | temp3_r = ACDET_PRE(QMF_RE(buffer[offset-1][bd])); | ||
253 | temp3_i = ACDET_PRE(QMF_IM(buffer[offset-1][bd])); | ||
254 | // Save these because they are needed after loop | ||
255 | temp4_r = temp2_r; | ||
256 | temp4_i = temp2_i; | ||
257 | temp5_r = temp3_r; | ||
258 | temp5_i = temp3_i; | ||
259 | |||
260 | for (j = offset; j < len + offset; j++) | ||
261 | { | ||
262 | temp1_r = temp2_r; | ||
263 | temp1_i = temp2_i; | ||
264 | temp2_r = temp3_r; | ||
265 | temp2_i = temp3_i; | ||
266 | temp3_r = ACDET_PRE(QMF_RE(buffer[j][bd])); | ||
267 | temp3_i = ACDET_PRE(QMF_IM(buffer[j][bd])); | ||
268 | r01r += MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i); | ||
269 | r01i += MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i); | ||
270 | r02r += MUL_F(temp3_r, temp1_r) + MUL_F(temp3_i, temp1_i); | ||
271 | r02i += MUL_F(temp3_i, temp1_r) - MUL_F(temp3_r, temp1_i); | ||
272 | r11r += MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i); | ||
273 | } | ||
274 | |||
275 | RE(ac->r12) = r01r - (MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i)) + | ||
276 | (MUL_F(temp5_r, temp4_r) + MUL_F(temp5_i, temp4_i)); | ||
277 | IM(ac->r12) = r01i - (MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i)) + | ||
278 | (MUL_F(temp5_i, temp4_r) - MUL_F(temp5_r, temp4_i)); | ||
279 | RE(ac->r22) = r11r - (MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i)) + | ||
280 | (MUL_F(temp4_r, temp4_r) + MUL_F(temp4_i, temp4_i)); | ||
281 | RE(ac->r01) = r01r; | ||
282 | IM(ac->r01) = r01i; | ||
283 | RE(ac->r02) = r02r; | ||
284 | IM(ac->r02) = r02i; | ||
285 | RE(ac->r11) = r11r; | ||
286 | |||
287 | ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F((MUL_F(RE(ac->r12), RE(ac->r12)) + MUL_F(IM(ac->r12), IM(ac->r12))), rel); | ||
288 | ac->det = ACDET_POST(ac->det); | ||
289 | |||
290 | } | ||
291 | #endif | ||
292 | |||
293 | /* calculate linear prediction coefficients using the covariance method */ | ||
294 | #ifndef SBR_LOW_POWER | ||
295 | static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | ||
296 | complex_t *alpha_0, complex_t *alpha_1, uint8_t k) | ||
297 | { | ||
298 | real_t tmp, mul; | ||
299 | acorr_coef ac; | ||
300 | |||
301 | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); | ||
302 | |||
303 | if (ac.det == 0) | ||
304 | { | ||
305 | RE(alpha_1[k]) = 0; | ||
306 | IM(alpha_1[k]) = 0; | ||
307 | } else { | ||
308 | mul = DIV_R(REAL_CONST(1.0), ac.det); | ||
309 | tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))); | ||
310 | RE(alpha_1[k]) = MUL_R(tmp, mul); | ||
311 | tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))); | ||
312 | IM(alpha_1[k]) = MUL_R(tmp, mul); | ||
313 | } | ||
314 | |||
315 | if (RE(ac.r11) == 0) | ||
316 | { | ||
317 | RE(alpha_0[k]) = 0; | ||
318 | IM(alpha_0[k]) = 0; | ||
319 | } else { | ||
320 | mul = DIV_R(REAL_CONST(1.0), RE(ac.r11)); | ||
321 | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); | ||
322 | RE(alpha_0[k]) = MUL_R(tmp, mul); | ||
323 | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); | ||
324 | IM(alpha_0[k]) = MUL_R(tmp, mul); | ||
325 | } | ||
326 | |||
327 | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) >= REAL_CONST(16)) || | ||
328 | (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) >= REAL_CONST(16))) | ||
329 | { | ||
330 | RE(alpha_0[k]) = 0; | ||
331 | IM(alpha_0[k]) = 0; | ||
332 | RE(alpha_1[k]) = 0; | ||
333 | IM(alpha_1[k]) = 0; | ||
334 | } | ||
335 | } | ||
336 | #else | ||
337 | static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | ||
338 | complex_t *alpha_0, complex_t *alpha_1, real_t *rxx) | ||
339 | { | ||
340 | uint8_t k; | ||
341 | real_t tmp, mul; | ||
342 | acorr_coef ac; | ||
343 | |||
344 | for (k = 1; k < sbr->f_master[0]; k++) | ||
345 | { | ||
346 | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); | ||
347 | |||
348 | if (ac.det == 0) | ||
349 | { | ||
350 | RE(alpha_0[k]) = 0; | ||
351 | RE(alpha_1[k]) = 0; | ||
352 | } else { | ||
353 | mul = DIV_R(REAL_CONST(1.0), ac.det); | ||
354 | tmp = MUL_R(RE(ac.r01), RE(ac.r22)) - MUL_R(RE(ac.r12), RE(ac.r02)); | ||
355 | RE(alpha_0[k]) = -MUL_R(tmp, mul); | ||
356 | tmp = MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11)); | ||
357 | RE(alpha_1[k]) = MUL_R(tmp, mul); | ||
358 | } | ||
359 | |||
360 | if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4))) | ||
361 | { | ||
362 | RE(alpha_0[k]) = REAL_CONST(0); | ||
363 | RE(alpha_1[k]) = REAL_CONST(0); | ||
364 | } | ||
365 | |||
366 | /* reflection coefficient */ | ||
367 | if (RE(ac.r11) == 0) | ||
368 | { | ||
369 | rxx[k] = COEF_CONST(0.0); | ||
370 | } else { | ||
371 | rxx[k] = DIV_C(RE(ac.r01), RE(ac.r11)); | ||
372 | rxx[k] = -rxx[k]; | ||
373 | if (rxx[k] > COEF_CONST( 1.0)) rxx[k] = COEF_CONST(1.0); | ||
374 | if (rxx[k] < COEF_CONST(-1.0)) rxx[k] = COEF_CONST(-1.0); | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg) | ||
380 | { | ||
381 | uint8_t k; | ||
382 | |||
383 | rxx[0] = COEF_CONST(0.0); | ||
384 | deg[1] = COEF_CONST(0.0); | ||
385 | |||
386 | for (k = 2; k < sbr->k0; k++) | ||
387 | { | ||
388 | deg[k] = COEF_CONST(0.0); | ||
389 | |||
390 | if ((k % 2 == 0) && (rxx[k] < COEF_CONST(0.0))) | ||
391 | { | ||
392 | if (rxx[k-1] < COEF_CONST(0.0)) | ||
393 | { | ||
394 | deg[k] = COEF_CONST(1.0); | ||
395 | |||
396 | if (rxx[k-2] > COEF_CONST(0.0)) | ||
397 | { | ||
398 | deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); | ||
399 | } | ||
400 | } else if (rxx[k-2] > COEF_CONST(0.0)) { | ||
401 | deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if ((k % 2 == 1) && (rxx[k] > COEF_CONST(0.0))) | ||
406 | { | ||
407 | if (rxx[k-1] > COEF_CONST(0.0)) | ||
408 | { | ||
409 | deg[k] = COEF_CONST(1.0); | ||
410 | |||
411 | if (rxx[k-2] < COEF_CONST(0.0)) | ||
412 | { | ||
413 | deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); | ||
414 | } | ||
415 | } else if (rxx[k-2] < COEF_CONST(0.0)) { | ||
416 | deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | #endif | ||
422 | |||
423 | /* FIXED POINT: bwArray = COEF */ | ||
424 | static real_t mapNewBw(uint8_t invf_mode, uint8_t invf_mode_prev) | ||
425 | { | ||
426 | switch (invf_mode) | ||
427 | { | ||
428 | case 1: /* LOW */ | ||
429 | if (invf_mode_prev == 0) /* NONE */ | ||
430 | return COEF_CONST(0.6); | ||
431 | else | ||
432 | return COEF_CONST(0.75); | ||
433 | |||
434 | case 2: /* MID */ | ||
435 | return COEF_CONST(0.9); | ||
436 | |||
437 | case 3: /* HIGH */ | ||
438 | return COEF_CONST(0.98); | ||
439 | |||
440 | default: /* NONE */ | ||
441 | if (invf_mode_prev == 1) /* LOW */ | ||
442 | return COEF_CONST(0.6); | ||
443 | else | ||
444 | return COEF_CONST(0.0); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | /* FIXED POINT: bwArray = COEF */ | ||
449 | static void calc_chirp_factors(sbr_info *sbr, uint8_t ch) | ||
450 | { | ||
451 | uint8_t i; | ||
452 | |||
453 | for (i = 0; i < sbr->N_Q; i++) | ||
454 | { | ||
455 | sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]); | ||
456 | |||
457 | if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i]) | ||
458 | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.75)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.25)); | ||
459 | else | ||
460 | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.90625)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.09375)); | ||
461 | |||
462 | if (sbr->bwArray[ch][i] < COEF_CONST(0.015625)) | ||
463 | sbr->bwArray[ch][i] = COEF_CONST(0.0); | ||
464 | |||
465 | if (sbr->bwArray[ch][i] > COEF_CONST(0.99609375)) | ||
466 | sbr->bwArray[ch][i] = COEF_CONST(0.99609375); | ||
467 | |||
468 | sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i]; | ||
469 | sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i]; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | static void patch_construction(sbr_info *sbr) | ||
474 | { | ||
475 | uint8_t i, k; | ||
476 | uint8_t odd, sb; | ||
477 | uint8_t msb = sbr->k0; | ||
478 | uint8_t usb = sbr->kx; | ||
479 | uint8_t goalSbTab[] = { 21, 23, 32, 43, 46, 64, 85, 93, 128, 0, 0, 0 }; | ||
480 | /* (uint8_t)(2.048e6/sbr->sample_rate + 0.5); */ | ||
481 | uint8_t goalSb = goalSbTab[get_sr_index(sbr->sample_rate)]; | ||
482 | |||
483 | sbr->noPatches = 0; | ||
484 | |||
485 | if (goalSb < (sbr->kx + sbr->M)) | ||
486 | { | ||
487 | for (i = 0, k = 0; sbr->f_master[i] < goalSb; i++) | ||
488 | k = i+1; | ||
489 | } else { | ||
490 | k = sbr->N_master; | ||
491 | } | ||
492 | |||
493 | if (sbr->N_master == 0) | ||
494 | { | ||
495 | sbr->noPatches = 0; | ||
496 | sbr->patchNoSubbands[0] = 0; | ||
497 | sbr->patchStartSubband[0] = 0; | ||
498 | |||
499 | return; | ||
500 | } | ||
501 | |||
502 | do | ||
503 | { | ||
504 | int8_t j = k + 1; | ||
505 | |||
506 | do | ||
507 | { | ||
508 | j--; | ||
509 | sb = sbr->f_master[j]; | ||
510 | odd = (sb - 2 + sbr->k0) % 2; | ||
511 | |||
512 | } while (sb > (sbr->k0 - 1 + msb - odd)); | ||
513 | |||
514 | sbr->patchNoSubbands[sbr->noPatches] = max(sb - usb, 0); | ||
515 | sbr->patchStartSubband[sbr->noPatches] = sbr->k0 - odd - | ||
516 | sbr->patchNoSubbands[sbr->noPatches]; | ||
517 | |||
518 | if (sbr->patchNoSubbands[sbr->noPatches] > 0) | ||
519 | { | ||
520 | usb = sb; | ||
521 | msb = sb; | ||
522 | sbr->noPatches++; | ||
523 | } else { | ||
524 | msb = sbr->kx; | ||
525 | } | ||
526 | |||
527 | if (sbr->f_master[k] - sb < 3) | ||
528 | k = sbr->N_master; | ||
529 | } while (sb != (sbr->kx + sbr->M)); | ||
530 | |||
531 | if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) && (sbr->noPatches > 1)) | ||
532 | { | ||
533 | sbr->noPatches--; | ||
534 | } | ||
535 | |||
536 | sbr->noPatches = min(sbr->noPatches, 5); | ||
537 | } | ||
538 | |||
539 | #endif | ||