sbr_hfgen.c

00001 /*
00002 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
00003 ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
00004 **  
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 ** 
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 ** 
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software 
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 **
00019 ** Any non-GPL usage of this software or parts of this software is strictly
00020 ** forbidden.
00021 **
00022 ** Software using this code must display the following message visibly in the
00023 ** software:
00024 ** "FAAD2 AAC/HE-AAC/HE-AACv2/DRM decoder (c) Ahead Software, www.nero.com"
00025 ** in, for example, the about-box or help/startup screen.
00026 **
00027 ** Commercial non-GPL licensing of this software is possible.
00028 ** For more info contact Ahead Software through [email protected].
00029 **
00030 ** $Id: sbr_hfgen.c,v 1.2 2005/11/01 21:41:43 gabest Exp $
00031 **/
00032 
00033 /* High Frequency generation */
00034 
00035 #include "common.h"
00036 #include "structs.h"
00037 
00038 #ifdef SBR_DEC
00039 
00040 #include "sbr_syntax.h"
00041 #include "sbr_hfgen.h"
00042 #include "sbr_fbt.h"
00043 
00044 /* static function declarations */
00045 #ifdef SBR_LOW_POWER
00046 static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
00047                                     complex_t *alpha_0, complex_t *alpha_1, real_t *rxx);
00048 static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg);
00049 #else
00050 static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
00051                                  complex_t *alpha_0, complex_t *alpha_1, uint8_t k);
00052 #endif
00053 static void calc_chirp_factors(sbr_info *sbr, uint8_t ch);
00054 static void patch_construction(sbr_info *sbr);
00055 
00056 
00057 void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
00058                    qmf_t Xhigh[MAX_NTSRHFG][64]
00059 #ifdef SBR_LOW_POWER
00060                    ,real_t *deg
00061 #endif
00062                    ,uint8_t ch)
00063 {
00064     uint8_t l, i, x;
00065     ALIGN complex_t alpha_0[64], alpha_1[64];
00066 #ifdef SBR_LOW_POWER
00067     ALIGN real_t rxx[64];
00068 #endif
00069 
00070     uint8_t offset = sbr->tHFAdj;
00071     uint8_t first = sbr->t_E[ch][0];
00072     uint8_t last = sbr->t_E[ch][sbr->L_E[ch]];
00073 
00074     calc_chirp_factors(sbr, ch);
00075 
00076 #ifdef SBR_LOW_POWER
00077     memset(deg, 0, 64*sizeof(real_t));
00078 #endif
00079 
00080     if ((ch == 0) && (sbr->Reset))
00081         patch_construction(sbr);
00082 
00083     /* calculate the prediction coefficients */
00084 #ifdef SBR_LOW_POWER
00085     calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx);
00086     calc_aliasing_degree(sbr, rxx, deg);
00087 #endif
00088 
00089     /* actual HF generation */
00090     for (i = 0; i < sbr->noPatches; i++)
00091     {
00092         for (x = 0; x < sbr->patchNoSubbands[i]; x++)
00093         {
00094             real_t a0_r, a0_i, a1_r, a1_i;
00095             real_t bw, bw2;
00096             uint8_t q, p, k, g;
00097 
00098             /* find the low and high band for patching */
00099             k = sbr->kx + x;
00100             for (q = 0; q < i; q++)
00101             {
00102                 k += sbr->patchNoSubbands[q];
00103             }
00104             p = sbr->patchStartSubband[i] + x;
00105 
00106 #ifdef SBR_LOW_POWER
00107             if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/)
00108                 deg[k] = deg[p];
00109             else
00110                 deg[k] = 0;
00111 #endif
00112 
00113             g = sbr->table_map_k_to_g[k];
00114 
00115             bw = sbr->bwArray[ch][g];
00116             bw2 = MUL_C(bw, bw);
00117 
00118             /* do the patching */
00119             /* with or without filtering */
00120             if (bw2 > 0)
00121             {
00122                 real_t temp1_r, temp2_r, temp3_r;
00123 #ifndef SBR_LOW_POWER
00124                 real_t temp1_i, temp2_i, temp3_i;
00125                 calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p);
00126 #endif
00127 
00128                 a0_r = MUL_C(RE(alpha_0[p]), bw);
00129                 a1_r = MUL_C(RE(alpha_1[p]), bw2);
00130 #ifndef SBR_LOW_POWER
00131                 a0_i = MUL_C(IM(alpha_0[p]), bw);
00132                 a1_i = MUL_C(IM(alpha_1[p]), bw2);
00133 #endif
00134 
00135                 temp2_r = QMF_RE(Xlow[first - 2 + offset][p]);
00136                 temp3_r = QMF_RE(Xlow[first - 1 + offset][p]);
00137 #ifndef SBR_LOW_POWER
00138                 temp2_i = QMF_IM(Xlow[first - 2 + offset][p]);
00139                 temp3_i = QMF_IM(Xlow[first - 1 + offset][p]);
00140 #endif
00141                                 for (l = first; l < last; l++)
00142                 {
00143                         temp1_r = temp2_r;
00144                         temp2_r = temp3_r;
00145                         temp3_r = QMF_RE(Xlow[l + offset][p]);
00146 #ifndef SBR_LOW_POWER
00147                         temp1_i = temp2_i;
00148                         temp2_i = temp3_i;
00149                     temp3_i = QMF_IM(Xlow[l + offset][p]);
00150 #endif
00151 
00152 #ifdef SBR_LOW_POWER
00153                     QMF_RE(Xhigh[l + offset][k]) =
00154                         temp3_r
00155                       +(MUL_R(a0_r, temp2_r) +
00156                         MUL_R(a1_r, temp1_r));
00157 #else
00158                     QMF_RE(Xhigh[l + offset][k]) =
00159                         temp3_r
00160                       +(MUL_R(a0_r, temp2_r) -
00161                         MUL_R(a0_i, temp2_i) +
00162                         MUL_R(a1_r, temp1_r) -
00163                         MUL_R(a1_i, temp1_i));
00164                     QMF_IM(Xhigh[l + offset][k]) =
00165                         temp3_i
00166                       +(MUL_R(a0_i, temp2_r) +
00167                         MUL_R(a0_r, temp2_i) +
00168                         MUL_R(a1_i, temp1_r) +
00169                         MUL_R(a1_r, temp1_i));
00170 #endif
00171                 }
00172             } else {
00173                 for (l = first; l < last; l++)
00174                 {
00175                     QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]);
00176 #ifndef SBR_LOW_POWER
00177                     QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]);
00178 #endif
00179                 }
00180             }
00181         }
00182     }
00183 
00184     if (sbr->Reset)
00185     {
00186         limiter_frequency_table(sbr);
00187     }
00188 }
00189 
00190 typedef struct
00191 {
00192     complex_t r01;
00193     complex_t r02;
00194     complex_t r11;
00195     complex_t r12;
00196     complex_t r22;
00197     real_t det;
00198 } acorr_coef;
00199 
00200 #ifdef SBR_LOW_POWER
00201 static void auto_correlation(sbr_info *sbr, acorr_coef *ac,
00202                              qmf_t buffer[MAX_NTSRHFG][64],
00203                              uint8_t bd, uint8_t len)
00204 {
00205     real_t r01 = 0, r02 = 0, r11 = 0;
00206     int8_t j;
00207     uint8_t offset = sbr->tHFAdj;
00208 #ifdef FIXED_POINT
00209     const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f);
00210     uint32_t maxi = 0;
00211     uint32_t pow2, exp;
00212 #else
00213     const real_t rel = 1 / (1 + 1e-6f);
00214 #endif
00215 
00216 
00217 #ifdef FIXED_POINT
00218     mask = 0;
00219 
00220     for (j = (offset-2); j < (len + offset); j++)
00221     {
00222         real_t x;
00223         x = QMF_RE(buffer[j][bd])>>REAL_BITS;
00224         mask |= x ^ (x >> 31);
00225     }
00226 
00227     exp = wl_min_lzc(mask);
00228 
00229     /* improves accuracy */
00230     if (exp > 0)
00231         exp -= 1;
00232 
00233     for (j = offset; j < len + offset; j++)
00234     {
00235         real_t buf_j = ((QMF_RE(buffer[j][bd])+(1<<(exp-1)))>>exp);
00236         real_t buf_j_1 = ((QMF_RE(buffer[j-1][bd])+(1<<(exp-1)))>>exp);
00237         real_t buf_j_2 = ((QMF_RE(buffer[j-2][bd])+(1<<(exp-1)))>>exp);
00238 
00239         /* normalisation with rounding */
00240         r01 += MUL_R(buf_j, buf_j_1);
00241         r02 += MUL_R(buf_j, buf_j_2);
00242         r11 += MUL_R(buf_j_1, buf_j_1);
00243     }
00244     RE(ac->r12) = r01 -
00245         MUL_R(((QMF_RE(buffer[len+offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) +
00246         MUL_R(((QMF_RE(buffer[offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp));
00247     RE(ac->r22) = r11 -
00248         MUL_R(((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) +
00249         MUL_R(((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp));
00250 #else
00251     for (j = offset; j < len + offset; j++)
00252     {
00253         r01 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]);
00254         r02 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]);
00255         r11 += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]);
00256     }
00257     RE(ac->r12) = r01 -
00258         QMF_RE(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) +
00259         QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]);
00260     RE(ac->r22) = r11 -
00261         QMF_RE(buffer[len+offset-2][bd]) * QMF_RE(buffer[len+offset-2][bd]) +
00262         QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]);
00263 #endif
00264     RE(ac->r01) = r01;
00265     RE(ac->r02) = r02;
00266     RE(ac->r11) = r11;
00267 
00268     ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_R(RE(ac->r12), RE(ac->r12)), rel);
00269 }
00270 #else
00271 static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64],
00272                              uint8_t bd, uint8_t len)
00273 {
00274     real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0;
00275     real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i;
00276 #ifdef FIXED_POINT
00277     const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f);
00278     uint32_t mask, exp;
00279     real_t pow2_to_exp;
00280 #else
00281     const real_t rel = 1 / (1 + 1e-6f);
00282 #endif
00283     int8_t j;
00284     uint8_t offset = sbr->tHFAdj;
00285 
00286 #ifdef FIXED_POINT
00287     mask = 0;
00288 
00289     for (j = (offset-2); j < (len + offset); j++)
00290     {
00291         real_t x;
00292         x = QMF_RE(buffer[j][bd])>>REAL_BITS;
00293         mask |= x ^ (x >> 31);
00294         x = QMF_IM(buffer[j][bd])>>REAL_BITS;
00295         mask |= x ^ (x >> 31);
00296     }
00297 
00298     exp = wl_min_lzc(mask);
00299 
00300     /* improves accuracy */
00301     if (exp > 0)
00302         exp -= 1;
00303    
00304     pow2_to_exp = 1<<(exp-1);
00305 
00306     temp2_r = (QMF_RE(buffer[offset-2][bd]) + pow2_to_exp) >> exp;
00307     temp2_i = (QMF_IM(buffer[offset-2][bd]) + pow2_to_exp) >> exp;
00308     temp3_r = (QMF_RE(buffer[offset-1][bd]) + pow2_to_exp) >> exp;
00309     temp3_i = (QMF_IM(buffer[offset-1][bd]) + pow2_to_exp) >> exp;
00310     // Save these because they are needed after loop
00311     temp4_r = temp2_r;
00312     temp4_i = temp2_i;
00313     temp5_r = temp3_r;
00314     temp5_i = temp3_i;
00315 
00316     for (j = offset; j < len + offset; j++)
00317     {
00318         temp1_r = temp2_r; // temp1_r = (QMF_RE(buffer[offset-2][bd] + (1<<(exp-1))) >> exp;
00319         temp1_i = temp2_i; // temp1_i = (QMF_IM(buffer[offset-2][bd] + (1<<(exp-1))) >> exp;
00320         temp2_r = temp3_r; // temp2_r = (QMF_RE(buffer[offset-1][bd] + (1<<(exp-1))) >> exp;
00321         temp2_i = temp3_i; // temp2_i = (QMF_IM(buffer[offset-1][bd] + (1<<(exp-1))) >> exp;
00322         temp3_r = (QMF_RE(buffer[j][bd]) + pow2_to_exp) >> exp;
00323         temp3_i = (QMF_IM(buffer[j][bd]) + pow2_to_exp) >> exp;
00324         r01r += MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i);
00325         r01i += MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i);
00326         r02r += MUL_R(temp3_r, temp1_r) + MUL_R(temp3_i, temp1_i);
00327         r02i += MUL_R(temp3_i, temp1_r) - MUL_R(temp3_r, temp1_i);
00328         r11r += MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i);
00329     }
00330 
00331     // These are actual values in temporary variable at this point
00332     // temp1_r = (QMF_RE(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp;
00333     // temp1_i = (QMF_IM(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp;
00334     // temp2_r = (QMF_RE(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp;
00335     // temp2_i = (QMF_IM(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp;
00336     // temp3_r = (QMF_RE(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp;
00337     // temp3_i = (QMF_IM(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp;
00338     // temp4_r = (QMF_RE(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp;
00339     // temp4_i = (QMF_IM(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp;
00340     // temp5_r = (QMF_RE(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp;
00341     // temp5_i = (QMF_IM(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp;
00342 
00343     RE(ac->r12) = r01r -
00344         (MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i)) +
00345         (MUL_R(temp5_r, temp4_r) + MUL_R(temp5_i, temp4_i));
00346     IM(ac->r12) = r01i -
00347         (MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i)) +
00348         (MUL_R(temp5_i, temp4_r) - MUL_R(temp5_r, temp4_i));
00349     RE(ac->r22) = r11r -
00350         (MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i)) +
00351         (MUL_R(temp4_r, temp4_r) + MUL_R(temp4_i, temp4_i));
00352 
00353 #else
00354 
00355     temp2_r = QMF_RE(buffer[offset-2][bd]);
00356     temp2_i = QMF_IM(buffer[offset-2][bd]);
00357     temp3_r = QMF_RE(buffer[offset-1][bd]);
00358     temp3_i = QMF_IM(buffer[offset-1][bd]);
00359     // Save these because they are needed after loop
00360     temp4_r = temp2_r;
00361     temp4_i = temp2_i;
00362     temp5_r = temp3_r;
00363     temp5_i = temp3_i;
00364 
00365     for (j = offset; j < len + offset; j++)
00366     {
00367         temp1_r = temp2_r; // temp1_r = QMF_RE(buffer[j-2][bd];
00368         temp1_i = temp2_i; // temp1_i = QMF_IM(buffer[j-2][bd];
00369         temp2_r = temp3_r; // temp2_r = QMF_RE(buffer[j-1][bd];
00370         temp2_i = temp3_i; // temp2_i = QMF_IM(buffer[j-1][bd];
00371         temp3_r = QMF_RE(buffer[j][bd]);
00372         temp3_i = QMF_IM(buffer[j][bd]);
00373         r01r += temp3_r * temp2_r + temp3_i * temp2_i;
00374         r01i += temp3_i * temp2_r - temp3_r * temp2_i;
00375         r02r += temp3_r * temp1_r + temp3_i * temp1_i;
00376         r02i += temp3_i * temp1_r - temp3_r * temp1_i;
00377         r11r += temp2_r * temp2_r + temp2_i * temp2_i;
00378     }
00379 
00380     // These are actual values in temporary variable at this point
00381     // temp1_r = QMF_RE(buffer[len+offset-1-2][bd];
00382     // temp1_i = QMF_IM(buffer[len+offset-1-2][bd];
00383     // temp2_r = QMF_RE(buffer[len+offset-1-1][bd];
00384     // temp2_i = QMF_IM(buffer[len+offset-1-1][bd];
00385     // temp3_r = QMF_RE(buffer[len+offset-1][bd]);
00386     // temp3_i = QMF_IM(buffer[len+offset-1][bd]);
00387     // temp4_r = QMF_RE(buffer[offset-2][bd]);
00388     // temp4_i = QMF_IM(buffer[offset-2][bd]);
00389     // temp5_r = QMF_RE(buffer[offset-1][bd]);
00390     // temp5_i = QMF_IM(buffer[offset-1][bd]);
00391 
00392     RE(ac->r12) = r01r -
00393         (temp3_r * temp2_r + temp3_i * temp2_i) +
00394         (temp5_r * temp4_r + temp5_i * temp4_i);
00395     IM(ac->r12) = r01i -
00396         (temp3_i * temp2_r - temp3_r * temp2_i) +
00397         (temp5_i * temp4_r - temp5_r * temp4_i);
00398     RE(ac->r22) = r11r -
00399         (temp2_r * temp2_r + temp2_i * temp2_i) +
00400         (temp4_r * temp4_r + temp4_i * temp4_i);
00401 
00402 #endif
00403 
00404     RE(ac->r01) = r01r;
00405     IM(ac->r01) = r01i;
00406     RE(ac->r02) = r02r;
00407     IM(ac->r02) = r02i;
00408     RE(ac->r11) = r11r;
00409 
00410     ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_R(RE(ac->r12), RE(ac->r12)) + MUL_R(IM(ac->r12), IM(ac->r12))));
00411 }
00412 #endif
00413 
00414 /* calculate linear prediction coefficients using the covariance method */
00415 #ifndef SBR_LOW_POWER
00416 static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
00417                                  complex_t *alpha_0, complex_t *alpha_1, uint8_t k)
00418 {
00419     real_t tmp;
00420     acorr_coef ac;
00421 
00422     auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6);
00423 
00424     if (ac.det == 0)
00425     {
00426         RE(alpha_1[k]) = 0;
00427         IM(alpha_1[k]) = 0;
00428     } else {
00429 #ifdef FIXED_POINT
00430         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)));
00431         RE(alpha_1[k]) = DIV_R(tmp, ac.det);
00432         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)));
00433         IM(alpha_1[k]) = DIV_R(tmp, ac.det);
00434 #else
00435         tmp = REAL_CONST(1.0) / ac.det;
00436         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))) * tmp;
00437         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))) * tmp;
00438 #endif
00439     }
00440 
00441     if (RE(ac.r11) == 0)
00442     {
00443         RE(alpha_0[k]) = 0;
00444         IM(alpha_0[k]) = 0;
00445     } else {
00446 #ifdef FIXED_POINT
00447         tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12)));
00448         RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11));
00449         tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12)));
00450         IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11));
00451 #else
00452         tmp = 1.0f / RE(ac.r11);
00453         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;
00454         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;
00455 #endif
00456     }
00457 
00458     if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) >= REAL_CONST(16)) ||
00459         (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) >= REAL_CONST(16)))
00460     {
00461         RE(alpha_0[k]) = 0;
00462         IM(alpha_0[k]) = 0;
00463         RE(alpha_1[k]) = 0;
00464         IM(alpha_1[k]) = 0;
00465     }
00466 }
00467 #else
00468 static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
00469                                     complex_t *alpha_0, complex_t *alpha_1, real_t *rxx)
00470 {
00471     uint8_t k;
00472     real_t tmp;
00473     acorr_coef ac;
00474 
00475     for (k = 1; k < sbr->f_master[0]; k++)
00476     {
00477         auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6);
00478 
00479         if (ac.det == 0)
00480         {
00481             RE(alpha_0[k]) = 0;
00482             RE(alpha_1[k]) = 0;
00483         } else {
00484             tmp = MUL_R(RE(ac.r01), RE(ac.r22)) - MUL_R(RE(ac.r12), RE(ac.r02));
00485             RE(alpha_0[k]) = DIV_R(tmp, (-ac.det));
00486 
00487             tmp = MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11));
00488             RE(alpha_1[k]) = DIV_R(tmp, ac.det);
00489         }
00490 
00491         if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4)))
00492         {
00493             RE(alpha_0[k]) = REAL_CONST(0);
00494             RE(alpha_1[k]) = REAL_CONST(0);
00495         }
00496 
00497         /* reflection coefficient */
00498         if (RE(ac.r11) == 0)
00499         {
00500             rxx[k] = COEF_CONST(0.0);
00501         } else {
00502             rxx[k] = DIV_C(RE(ac.r01), RE(ac.r11));
00503             rxx[k] = -rxx[k];
00504             if (rxx[k] > COEF_CONST(1.0)) rxx[k] = COEF_CONST(1.0);
00505             if (rxx[k] < COEF_CONST(-1.0)) rxx[k] = COEF_CONST(-1.0);
00506         }
00507     }
00508 }
00509 
00510 static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg)
00511 {
00512     uint8_t k;
00513 
00514     rxx[0] = COEF_CONST(0.0);
00515     deg[1] = COEF_CONST(0.0);
00516 
00517     for (k = 2; k < sbr->k0; k++)
00518     {
00519         deg[k] = 0.0;
00520 
00521         if ((k % 2 == 0) && (rxx[k] < COEF_CONST(0.0)))
00522         {
00523             if (rxx[k-1] < 0.0)
00524             {
00525                 deg[k] = COEF_CONST(1.0);
00526 
00527                 if (rxx[k-2] > COEF_CONST(0.0))
00528                 {
00529                     deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]);
00530                 }
00531             } else if (rxx[k-2] > COEF_CONST(0.0)) {
00532                 deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]);
00533             }
00534         }
00535 
00536         if ((k % 2 == 1) && (rxx[k] > COEF_CONST(0.0)))
00537         {
00538             if (rxx[k-1] > COEF_CONST(0.0))
00539             {
00540                 deg[k] = COEF_CONST(1.0);
00541 
00542                 if (rxx[k-2] < COEF_CONST(0.0))
00543                 {
00544                     deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]);
00545                 }
00546             } else if (rxx[k-2] < COEF_CONST(0.0)) {
00547                 deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]);
00548             }
00549         }
00550     }
00551 }
00552 #endif
00553 
00554 /* FIXED POINT: bwArray = COEF */
00555 static real_t mapNewBw(uint8_t invf_mode, uint8_t invf_mode_prev)
00556 {
00557     switch (invf_mode)
00558     {
00559     case 1: /* LOW */
00560         if (invf_mode_prev == 0) /* NONE */
00561             return COEF_CONST(0.6);
00562         else
00563             return COEF_CONST(0.75);
00564 
00565     case 2: /* MID */
00566         return COEF_CONST(0.9);
00567 
00568     case 3: /* HIGH */
00569         return COEF_CONST(0.98);
00570 
00571     default: /* NONE */
00572         if (invf_mode_prev == 1) /* LOW */
00573             return COEF_CONST(0.6);
00574         else
00575             return COEF_CONST(0.0);
00576     }
00577 }
00578 
00579 /* FIXED POINT: bwArray = COEF */
00580 static void calc_chirp_factors(sbr_info *sbr, uint8_t ch)
00581 {
00582     uint8_t i;
00583 
00584     for (i = 0; i < sbr->N_Q; i++)
00585     {
00586         sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]);
00587 
00588         if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i])
00589             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));
00590         else
00591             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));
00592 
00593         if (sbr->bwArray[ch][i] < COEF_CONST(0.015625))
00594             sbr->bwArray[ch][i] = COEF_CONST(0.0);
00595 
00596         if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375))
00597             sbr->bwArray[ch][i] = COEF_CONST(0.99609375);
00598 
00599         sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i];
00600         sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i];
00601     }
00602 }
00603 
00604 static void patch_construction(sbr_info *sbr)
00605 {
00606     uint8_t i, k;
00607     uint8_t odd, sb;
00608     uint8_t msb = sbr->k0;
00609     uint8_t usb = sbr->kx;
00610     uint8_t goalSbTab[] = { 21, 23, 32, 43, 46, 64, 85, 93, 128, 0, 0, 0 };
00611     /* (uint8_t)(2.048e6/sbr->sample_rate + 0.5); */
00612     uint8_t goalSb = goalSbTab[get_sr_index(sbr->sample_rate)];
00613 
00614     sbr->noPatches = 0;
00615 
00616     if (goalSb < (sbr->kx + sbr->M))
00617     {
00618         for (i = 0, k = 0; sbr->f_master[i] < goalSb; i++)
00619             k = i+1;
00620     } else {
00621         k = sbr->N_master;
00622     }
00623 
00624     if (sbr->N_master == 0)
00625     {
00626         sbr->noPatches = 0;
00627         sbr->patchNoSubbands[0] = 0;
00628         sbr->patchStartSubband[0] = 0;
00629 
00630         return;
00631     }
00632 
00633     do
00634     {
00635         uint8_t j = k + 1;
00636 
00637         do
00638         {
00639             j--;
00640 
00641             sb = sbr->f_master[j];
00642             odd = (sb - 2 + sbr->k0) % 2;
00643         } while (sb > (sbr->k0 - 1 + msb - odd));
00644 
00645         sbr->patchNoSubbands[sbr->noPatches] = max(sb - usb, 0);
00646         sbr->patchStartSubband[sbr->noPatches] = sbr->k0 - odd -
00647             sbr->patchNoSubbands[sbr->noPatches];
00648 
00649         if (sbr->patchNoSubbands[sbr->noPatches] > 0)
00650         {
00651             usb = sb;
00652             msb = sb;
00653             sbr->noPatches++;
00654         } else {
00655             msb = sbr->kx;
00656         }
00657 
00658         if (sbr->f_master[k] - sb < 3)
00659             k = sbr->N_master;
00660     } while (sb != (sbr->kx + sbr->M));
00661 
00662     if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) && (sbr->noPatches > 1))
00663     {
00664         sbr->noPatches--;
00665     }
00666 
00667     sbr->noPatches = min(sbr->noPatches, 5);
00668 }
00669 
00670 #endif

Generated on Tue Dec 13 14:47:45 2005 for guliverkli by  doxygen 1.4.5