diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2010-09-14 19:53:13 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2010-09-14 19:53:13 +0000 |
commit | 82c143c4e1fb248ada018663f1d5b675d2174aea (patch) | |
tree | dc7f4f2b1b3819b19db352ffe01e124a5ca3ac3c | |
parent | c8da311de4224e48da5099bc9adec046710f75c6 (diff) | |
download | rockbox-82c143c4e1fb248ada018663f1d5b675d2174aea.tar.gz rockbox-82c143c4e1fb248ada018663f1d5b675d2174aea.zip |
Also correct autocorrelation for yet undefined SBR_LOW_POWER. Unify FIXED_POINT and FLOAT implementation.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28083 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libfaad/sbr_hfgen.c | 138 |
1 files changed, 36 insertions, 102 deletions
diff --git a/apps/codecs/libfaad/sbr_hfgen.c b/apps/codecs/libfaad/sbr_hfgen.c index 5c346f1c92..2f9583cd6a 100644 --- a/apps/codecs/libfaad/sbr_hfgen.c +++ b/apps/codecs/libfaad/sbr_hfgen.c | |||
@@ -196,85 +196,65 @@ static void auto_correlation(sbr_info *sbr, acorr_coef *ac, | |||
196 | uint8_t offset = sbr->tHFAdj; | 196 | uint8_t offset = sbr->tHFAdj; |
197 | #ifdef FIXED_POINT | 197 | #ifdef FIXED_POINT |
198 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | 198 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); |
199 | uint32_t exp = 2; | ||
200 | #else | ||
201 | const real_t rel = 1 / (1 + 1e-6f); | ||
202 | #endif | ||
203 | |||
204 | |||
205 | #ifdef FIXED_POINT | ||
206 | /* A pre-shift of >>2 is needed to avoid overflow when multiply-adding | 199 | /* A pre-shift of >>2 is needed to avoid overflow when multiply-adding |
207 | * the FRACT-variables buffer -- FRACT part is 31 bits. After the | 200 | * the FRACT-variables buffer -- FRACT part is 31 bits. After the |
208 | * calculation has been finished the result 'ac.det' needs to be | 201 | * calculation has been finished the result 'ac.det' needs to be |
209 | * post-shifted by <<(4*exp). */ | 202 | * post-shifted by <<(4*exp). */ |
203 | const uint32_t exp = 2; | ||
204 | #else | ||
205 | const real_t rel = 1 / (1 + 1e-6f); | ||
206 | const uint32_t exp = 0; | ||
207 | #endif | ||
210 | 208 | ||
211 | for (j = offset; j < len + offset; j++) | 209 | for (j = offset; j < len + offset; j++) |
212 | { | 210 | { |
213 | real_t buf_j = (QMF_RE(buffer[j ][bd]))>>exp); | 211 | real_t buf_j = QMF_RE(buffer[j ][bd]) >> exp; |
214 | real_t buf_j_1 = (QMF_RE(buffer[j-1][bd]))>>exp); | 212 | real_t buf_j_1 = QMF_RE(buffer[j-1][bd]) >> exp; |
215 | real_t buf_j_2 = (QMF_RE(buffer[j-2][bd]))>>exp); | 213 | real_t buf_j_2 = QMF_RE(buffer[j-2][bd]) >> exp; |
216 | |||
217 | /* normalisation with rounding */ | ||
218 | r01 += MUL_R(buf_j , buf_j_1); | ||
219 | r02 += MUL_R(buf_j , buf_j_2); | ||
220 | r11 += MUL_R(buf_j_1, buf_j_1); | ||
221 | } | ||
222 | tmp1 = (QMF_RE(buffer[len+offset-1][bd]))>>exp; | ||
223 | tmp2 = (QMF_RE(buffer[ offset-1][bd]))>>exp; | ||
224 | RE(ac->r12) = r01 - MUL_R(tmp1, tmp1) + MUL_R(tmp2, tmp2); | ||
225 | 214 | ||
226 | tmp1 = (QMF_RE(buffer[len+offset-2][bd]))>>exp; | 215 | r01 += MUL_F(buf_j , buf_j_1); |
227 | tmp2 = (QMF_RE(buffer[ offset-2][bd]))>>exp; | 216 | r02 += MUL_F(buf_j , buf_j_2); |
228 | RE(ac->r22) = r11 - MUL_R(tmp1, tmp1) + MUL_R(tmp2, tmp2); | 217 | r11 += MUL_F(buf_j_1, buf_j_1); |
229 | #else | ||
230 | for (j = offset; j < len + offset; j++) | ||
231 | { | ||
232 | r01 += QMF_RE(buffer[j ][bd]) * QMF_RE(buffer[j-1][bd]); | ||
233 | r02 += QMF_RE(buffer[j ][bd]) * QMF_RE(buffer[j-2][bd]); | ||
234 | r11 += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]); | ||
235 | } | 218 | } |
236 | tmp1 = (QMF_RE(buffer[len+offset-1][bd])); | 219 | tmp1 = QMF_RE(buffer[len+offset-1][bd]) >> exp; |
237 | tmp2 = (QMF_RE(buffer[ offset-1][bd])); | 220 | tmp2 = QMF_RE(buffer[ offset-1][bd]) >> exp; |
238 | RE(ac->r12) = r01 - tmp1*tmp1 + tmp2*tmp2; | 221 | RE(ac->r12) = r01 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); |
239 | 222 | ||
240 | tmp1 = (QMF_RE(buffer[len+offset-2][bd])); | 223 | tmp1 = QMF_RE(buffer[len+offset-2][bd]) >> exp; |
241 | tmp2 = (QMF_RE(buffer[ offset-2][bd])); | 224 | tmp2 = QMF_RE(buffer[ offset-2][bd]) >> exp; |
242 | RE(ac->r22) = r11 - tmp1*tmp1 + tmp2*tmp2; | 225 | RE(ac->r22) = r11 - MUL_F(tmp1, tmp1) + MUL_F(tmp2, tmp2); |
243 | #endif | ||
244 | RE(ac->r01) = r01; | 226 | RE(ac->r01) = r01; |
245 | RE(ac->r02) = r02; | 227 | RE(ac->r02) = r02; |
246 | RE(ac->r11) = r11; | 228 | RE(ac->r11) = r11; |
247 | 229 | ||
248 | ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_R(RE(ac->r12), RE(ac->r12)), rel); | 230 | ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_F(RE(ac->r12), RE(ac->r12)), rel); |
249 | #ifdef FIXED_POINT | 231 | ac->det <<= (4*exp); /* Post-shift as described above. */ |
250 | ac->det <<= (4*exp); | ||
251 | #endif | ||
252 | } | 232 | } |
253 | #else | 233 | #else |
254 | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], | 234 | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], |
255 | uint8_t bd, uint8_t len) | 235 | uint8_t bd, uint8_t len) |
256 | { | 236 | { |
257 | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; | 237 | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; |
258 | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i; | 238 | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i; |
259 | #ifdef FIXED_POINT | 239 | real_t temp4_r, temp4_i, temp5_r, temp5_i; |
260 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | ||
261 | uint32_t exp = 2; | ||
262 | #else | ||
263 | const real_t rel = 1 / (1 + 1e-6f); | ||
264 | #endif | ||
265 | int8_t j; | 240 | int8_t j; |
266 | uint8_t offset = sbr->tHFAdj; | 241 | uint8_t offset = sbr->tHFAdj; |
267 | |||
268 | #ifdef FIXED_POINT | 242 | #ifdef FIXED_POINT |
243 | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | ||
269 | /* A pre-shift of >>2 is needed to avoid overflow when multiply-adding | 244 | /* A pre-shift of >>2 is needed to avoid overflow when multiply-adding |
270 | * the FRACT-variables buffer -- FRACT part is 31 bits. After the | 245 | * the FRACT-variables buffer -- FRACT part is 31 bits. After the |
271 | * calculation has been finished the result 'ac.det' needs to be | 246 | * calculation has been finished the result 'ac.det' needs to be |
272 | * post-shifted by <<(4*exp). */ | 247 | * post-shifted by <<(4*exp). */ |
248 | const uint32_t exp = 2; | ||
249 | #else | ||
250 | const real_t rel = 1 / (1 + 1e-6f); | ||
251 | const uint32_t exp = 0; | ||
252 | #endif | ||
273 | 253 | ||
274 | temp2_r = (QMF_RE(buffer[offset-2][bd])) >> exp; | 254 | temp2_r = QMF_RE(buffer[offset-2][bd]) >> exp; |
275 | temp2_i = (QMF_IM(buffer[offset-2][bd])) >> exp; | 255 | temp2_i = QMF_IM(buffer[offset-2][bd]) >> exp; |
276 | temp3_r = (QMF_RE(buffer[offset-1][bd])) >> exp; | 256 | temp3_r = QMF_RE(buffer[offset-1][bd]) >> exp; |
277 | temp3_i = (QMF_IM(buffer[offset-1][bd])) >> exp; | 257 | temp3_i = QMF_IM(buffer[offset-1][bd]) >> exp; |
278 | // Save these because they are needed after loop | 258 | // Save these because they are needed after loop |
279 | temp4_r = temp2_r; | 259 | temp4_r = temp2_r; |
280 | temp4_i = temp2_i; | 260 | temp4_i = temp2_i; |
@@ -287,8 +267,8 @@ static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTS | |||
287 | temp1_i = temp2_i; | 267 | temp1_i = temp2_i; |
288 | temp2_r = temp3_r; | 268 | temp2_r = temp3_r; |
289 | temp2_i = temp3_i; | 269 | temp2_i = temp3_i; |
290 | temp3_r = (QMF_RE(buffer[j][bd])) >> exp; | 270 | temp3_r = QMF_RE(buffer[j][bd]) >> exp; |
291 | temp3_i = (QMF_IM(buffer[j][bd])) >> exp; | 271 | temp3_i = QMF_IM(buffer[j][bd]) >> exp; |
292 | r01r += MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i); | 272 | r01r += MUL_F(temp3_r, temp2_r) + MUL_F(temp3_i, temp2_i); |
293 | r01i += MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i); | 273 | r01i += MUL_F(temp3_i, temp2_r) - MUL_F(temp3_r, temp2_i); |
294 | r02r += MUL_F(temp3_r, temp1_r) + MUL_F(temp3_i, temp1_i); | 274 | r02r += MUL_F(temp3_r, temp1_r) + MUL_F(temp3_i, temp1_i); |
@@ -302,49 +282,15 @@ static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTS | |||
302 | (MUL_F(temp5_i, temp4_r) - MUL_F(temp5_r, temp4_i)); | 282 | (MUL_F(temp5_i, temp4_r) - MUL_F(temp5_r, temp4_i)); |
303 | RE(ac->r22) = r11r - (MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i)) + | 283 | RE(ac->r22) = r11r - (MUL_F(temp2_r, temp2_r) + MUL_F(temp2_i, temp2_i)) + |
304 | (MUL_F(temp4_r, temp4_r) + MUL_F(temp4_i, temp4_i)); | 284 | (MUL_F(temp4_r, temp4_r) + MUL_F(temp4_i, temp4_i)); |
305 | #else | ||
306 | temp2_r = QMF_RE(buffer[offset-2][bd]); | ||
307 | temp2_i = QMF_IM(buffer[offset-2][bd]); | ||
308 | temp3_r = QMF_RE(buffer[offset-1][bd]); | ||
309 | temp3_i = QMF_IM(buffer[offset-1][bd]); | ||
310 | // Save these because they are needed after loop | ||
311 | temp4_r = temp2_r; | ||
312 | temp4_i = temp2_i; | ||
313 | temp5_r = temp3_r; | ||
314 | temp5_i = temp3_i; | ||
315 | |||
316 | for (j = offset; j < len + offset; j++) | ||
317 | { | ||
318 | temp1_r = temp2_r; | ||
319 | temp1_i = temp2_i; | ||
320 | temp2_r = temp3_r; | ||
321 | temp2_i = temp3_i; | ||
322 | temp3_r = QMF_RE(buffer[j][bd]); | ||
323 | temp3_i = QMF_IM(buffer[j][bd]); | ||
324 | r01r += temp3_r * temp2_r + temp3_i * temp2_i; | ||
325 | r01i += temp3_i * temp2_r - temp3_r * temp2_i; | ||
326 | r02r += temp3_r * temp1_r + temp3_i * temp1_i; | ||
327 | r02i += temp3_i * temp1_r - temp3_r * temp1_i; | ||
328 | r11r += temp2_r * temp2_r + temp2_i * temp2_i; | ||
329 | } | ||
330 | |||
331 | RE(ac->r12) = r01r - (temp3_r * temp2_r + temp3_i * temp2_i) + | ||
332 | (temp5_r * temp4_r + temp5_i * temp4_i); | ||
333 | IM(ac->r12) = r01i - (temp3_i * temp2_r - temp3_r * temp2_i) + | ||
334 | (temp5_i * temp4_r - temp5_r * temp4_i); | ||
335 | RE(ac->r22) = r11r - (temp2_r * temp2_r + temp2_i * temp2_i) + | ||
336 | (temp4_r * temp4_r + temp4_i * temp4_i); | ||
337 | #endif | ||
338 | RE(ac->r01) = r01r; | 285 | RE(ac->r01) = r01r; |
339 | IM(ac->r01) = r01i; | 286 | IM(ac->r01) = r01i; |
340 | RE(ac->r02) = r02r; | 287 | RE(ac->r02) = r02r; |
341 | IM(ac->r02) = r02i; | 288 | IM(ac->r02) = r02i; |
342 | RE(ac->r11) = r11r; | 289 | RE(ac->r11) = r11r; |
343 | 290 | ||
344 | ac->det = MUL_F(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_F(RE(ac->r12), RE(ac->r12)) + MUL_F(IM(ac->r12), IM(ac->r12)))); | 291 | 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); |
345 | #ifdef FIXED_POINT | 292 | ac->det <<= (4*exp); /* Post-shift as described above. */ |
346 | ac->det <<= (4*exp); | 293 | |
347 | #endif | ||
348 | } | 294 | } |
349 | #endif | 295 | #endif |
350 | 296 | ||
@@ -363,17 +309,11 @@ static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | |||
363 | RE(alpha_1[k]) = 0; | 309 | RE(alpha_1[k]) = 0; |
364 | IM(alpha_1[k]) = 0; | 310 | IM(alpha_1[k]) = 0; |
365 | } else { | 311 | } else { |
366 | #ifdef FIXED_POINT | ||
367 | mul = DIV_R(REAL_CONST(1.0), ac.det); | 312 | mul = DIV_R(REAL_CONST(1.0), ac.det); |
368 | 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))); | 313 | 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))); |
369 | RE(alpha_1[k]) = MUL_R(tmp, mul); | 314 | RE(alpha_1[k]) = MUL_R(tmp, mul); |
370 | 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))); | 315 | 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))); |
371 | IM(alpha_1[k]) = MUL_R(tmp, mul); | 316 | IM(alpha_1[k]) = MUL_R(tmp, mul); |
372 | #else | ||
373 | mul = REAL_CONST(1.0) / ac.det; | ||
374 | RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * mul; | ||
375 | IM(alpha_1[k]) = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))) * mul; | ||
376 | #endif | ||
377 | } | 317 | } |
378 | 318 | ||
379 | if (RE(ac.r11) == 0) | 319 | if (RE(ac.r11) == 0) |
@@ -381,17 +321,11 @@ static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], | |||
381 | RE(alpha_0[k]) = 0; | 321 | RE(alpha_0[k]) = 0; |
382 | IM(alpha_0[k]) = 0; | 322 | IM(alpha_0[k]) = 0; |
383 | } else { | 323 | } else { |
384 | #ifdef FIXED_POINT | ||
385 | mul = DIV_R(REAL_CONST(1.0), RE(ac.r11)); | 324 | mul = DIV_R(REAL_CONST(1.0), RE(ac.r11)); |
386 | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); | 325 | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); |
387 | RE(alpha_0[k]) = MUL_R(tmp, mul); | 326 | RE(alpha_0[k]) = MUL_R(tmp, mul); |
388 | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); | 327 | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); |
389 | IM(alpha_0[k]) = MUL_R(tmp, mul); | 328 | IM(alpha_0[k]) = MUL_R(tmp, mul); |
390 | #else | ||
391 | tmp = 1.0f / RE(ac.r11); | ||
392 | RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp; | ||
393 | IM(alpha_0[k]) = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))) * tmp; | ||
394 | #endif | ||
395 | } | 329 | } |
396 | 330 | ||
397 | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) >= REAL_CONST(16)) || | 331 | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) >= REAL_CONST(16)) || |