Home | History | Annotate | Download | only in aacdec
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /*
     19 
     20  Filename: sbr_aliasing_reduction.c
     21 
     22 ------------------------------------------------------------------------------
     23  REVISION HISTORY
     24 
     25 
     26  Who:                                   Date: MM/DD/YYYY
     27  Description:
     28 
     29 ------------------------------------------------------------------------------
     30  INPUT AND OUTPUT DEFINITIONS
     31 
     32 
     33 
     34 ------------------------------------------------------------------------------
     35  FUNCTION DESCRIPTION
     36 
     37 
     38 ------------------------------------------------------------------------------
     39  REQUIREMENTS
     40 
     41 
     42 ------------------------------------------------------------------------------
     43  REFERENCES
     44 
     45 SC 29 Software Copyright Licencing Disclaimer:
     46 
     47 This software module was originally developed by
     48   Coding Technologies
     49 
     50 and edited by
     51   -
     52 
     53 in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3
     54 standards for reference purposes and its performance may not have been
     55 optimized. This software module is an implementation of one or more tools as
     56 specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards.
     57 ISO/IEC gives users free license to this software module or modifications
     58 thereof for use in products claiming conformance to audiovisual and
     59 image-coding related ITU Recommendations and/or ISO/IEC International
     60 Standards. ISO/IEC gives users the same free license to this software module or
     61 modifications thereof for research purposes and further ISO/IEC standardisation.
     62 Those intending to use this software module in products are advised that its
     63 use may infringe existing patents. ISO/IEC have no liability for use of this
     64 software module or modifications thereof. Copyright is not released for
     65 products that do not conform to audiovisual and image-coding related ITU
     66 Recommendations and/or ISO/IEC International Standards.
     67 The original developer retains full right to modify and use the code for its
     68 own purpose, assign or donate the code to a third party and to inhibit third
     69 parties from using the code for products that do not conform to audiovisual and
     70 image-coding related ITU Recommendations and/or ISO/IEC International Standards.
     71 This copyright notice must be included in all copies or derivative works.
     72 Copyright (c) ISO/IEC 2002.
     73 
     74 ------------------------------------------------------------------------------
     75  PSEUDO-CODE
     76 
     77 ------------------------------------------------------------------------------
     78 */
     79 
     80 
     81 /*----------------------------------------------------------------------------
     82 ; INCLUDES
     83 ----------------------------------------------------------------------------*/
     84 
     85 #ifdef AAC_PLUS
     86 
     87 
     88 
     89 #include    "sbr_aliasing_reduction.h"
     90 #include    "pv_sqrt.h"
     91 
     92 #include    "aac_mem_funcs.h"
     93 
     94 #include    "pv_div.h"
     95 #include    "fxp_mul32.h"
     96 
     97 
     98 /*----------------------------------------------------------------------------
     99 ; MACROS
    100 ; Define module specific macros here
    101 ----------------------------------------------------------------------------*/
    102 
    103 
    104 /*----------------------------------------------------------------------------
    105 ; DEFINES
    106 ; Include all pre-processor statements here. Include conditional
    107 ; compile variables also.
    108 ----------------------------------------------------------------------------*/
    109 
    110 #define Q30fmt(x)   (Int32)(x*((Int32)1<<30) + (x>=0?0.5F:-0.5F))
    111 
    112 /*----------------------------------------------------------------------------
    113 ; LOCAL FUNCTION DEFINITIONS
    114 ; Function Prototype declaration
    115 ----------------------------------------------------------------------------*/
    116 
    117 /*----------------------------------------------------------------------------
    118 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    119 ; Variable declaration - defined here and used outside this module
    120 ----------------------------------------------------------------------------*/
    121 
    122 /*----------------------------------------------------------------------------
    123 ; EXTERNAL FUNCTION REFERENCES
    124 ; Declare functions defined elsewhere and referenced in this module
    125 ----------------------------------------------------------------------------*/
    126 
    127 /*----------------------------------------------------------------------------
    128 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    129 ; Declare variables used in this module but defined elsewhere
    130 ----------------------------------------------------------------------------*/
    131 
    132 /*----------------------------------------------------------------------------
    133 ; FUNCTION CODE
    134 ----------------------------------------------------------------------------*/
    135 
    136 #include "pv_normalize.h"
    137 #include  "sbr_constants.h"
    138 
    139 /*******************************************************************************
    140  Functionname:  sbr_aliasing_reduction
    141  *******************************************************************************
    142  Description:
    143  Arguments:
    144 
    145  Return:        none
    146 *******************************************************************************/
    147 void sbr_aliasing_reduction(Int32 *degreeAlias,
    148                             Int32  * nrg_gain_man,
    149                             Int32  * nrg_gain_exp,
    150                             Int32  * nrg_est_man,
    151                             Int32  * nrg_est_exp,
    152                             Int32  * dontUseTheseGainValues,
    153                             Int32    noSubbands,
    154                             Int32    lowSubband,
    155                             Int32  sqrt_cache[][4],
    156                             Int32 * groupVector)
    157 {
    158 
    159     Int32 temp1;
    160     Int32 est_total;
    161     Int32 ref_total_man;
    162     Int32 ref_total_exp;
    163     Int32 tmp_q1;
    164     Int32 tmp_q2;
    165     Int32 tmp_q3;
    166     Int32 tmp_q4;
    167     Int32 bst_man;
    168     Int32 bst_exp;
    169     struct intg_div   quotient;
    170     struct intg_sqrt  root_sq;
    171     Int32 group;
    172     Int32 grouping = 0;
    173     Int32 index = 0;
    174     Int32 noGroups;
    175     Int32 k;
    176 
    177 
    178     /* Calculate grouping*/
    179     for (k = 0; k < noSubbands - 1; k++)
    180     {
    181         if (degreeAlias[k + lowSubband + 1] && dontUseTheseGainValues[k] == 0)
    182         {
    183             if (grouping == 0)
    184             {
    185                 groupVector[index] = k + lowSubband;
    186                 grouping = 1;
    187                 index++;
    188             }
    189         }
    190         else
    191         {
    192             if (grouping)
    193             {
    194                 groupVector[index] = k + lowSubband;
    195 
    196                 if (! dontUseTheseGainValues[k])
    197                 {
    198                     (groupVector[index])++;
    199                 }
    200                 grouping = 0;
    201                 index++;
    202             }
    203         }
    204     }
    205 
    206     if (grouping)
    207     {
    208         groupVector[index] = noSubbands + lowSubband;
    209         index++;
    210     }
    211     noGroups = (index >> 1);
    212 
    213 
    214 
    215     /*Calculate new gain*/
    216     for (group = 0; group < noGroups; group ++)
    217     {
    218 
    219         int startGroup = groupVector[(group<<1)] - lowSubband;
    220         int stopGroup  = groupVector[(group<<1)+1] - lowSubband;
    221 
    222 
    223         est_total = 0;
    224         ref_total_man = 0;
    225 
    226         tmp_q1 = -100;
    227         tmp_q2 = -100;
    228 
    229         for (k = startGroup; k < stopGroup; k++)
    230         {
    231             if (tmp_q1 < nrg_est_exp[k])
    232             {
    233                 tmp_q1 = nrg_est_exp[k];    /* max */
    234             }
    235             if (tmp_q2 < (nrg_est_exp[k] + (nrg_gain_exp[k] << 1)))
    236             {
    237                 tmp_q2 = (nrg_est_exp[k] + (nrg_gain_exp[k] << 1));  /* max */
    238             }
    239         }
    240 
    241 
    242         k -= startGroup;        /*  number of element used in the addition */
    243         /* adjust Q format */
    244         tmp_q2 += 59 - pv_normalize(k);
    245 
    246         for (k = startGroup; k < stopGroup; k++)
    247         {
    248             /*
    249              *  est_total += nrg_est[k]
    250              *  ref_total += nrg_est[k]*nrg_gain[k]*nrg_gain[k
    251              */
    252             est_total += nrg_est_man[k] >> (tmp_q1 - nrg_est_exp[k]);
    253 
    254             if (tmp_q2 - (nrg_est_exp[k] + (nrg_gain_exp[k] << 1)) < 60)
    255             {
    256                 nrg_gain_man[k] = fxp_mul32_Q28(nrg_gain_man[k], nrg_gain_man[k]);
    257                 nrg_gain_exp[k] = (nrg_gain_exp[k] << 1) + 28;
    258                 tmp_q3          = fxp_mul32_Q28(nrg_gain_man[k], nrg_est_man[k]);
    259                 ref_total_man    += tmp_q3 >> (tmp_q2 - (nrg_est_exp[k] + nrg_gain_exp[k]));
    260             }
    261         }
    262 
    263         ref_total_exp = tmp_q2 + 28;
    264 
    265         pv_div(ref_total_man, est_total, &quotient);
    266 
    267         tmp_q2 += - tmp_q1 - quotient.shift_factor - 2;
    268 
    269 
    270 
    271         for (k = startGroup; k < stopGroup; k++)
    272         {
    273             Int32 alpha;
    274             temp1 = k + lowSubband;
    275             if (k < noSubbands - 1)
    276             {
    277                 alpha = degreeAlias[temp1 + 1] > degreeAlias[temp1 ] ?
    278                         degreeAlias[temp1 + 1] : degreeAlias[temp1 ];
    279             }
    280             else
    281             {
    282                 alpha = degreeAlias[temp1];
    283             }
    284 
    285             /*
    286              *  nrg_gain[k] = alpha*newGain + (1.0f-alpha)*nrg_gain[k]*nrg_gain[k];
    287              */
    288 
    289             tmp_q1 = tmp_q2 > nrg_gain_exp[k] ? tmp_q2 : nrg_gain_exp[k];
    290             tmp_q1++;
    291 
    292             tmp_q3 = fxp_mul32_Q30(alpha, quotient.quotient);
    293             tmp_q4 = fxp_mul32_Q30(Q30fmt(1.0f) - alpha, nrg_gain_man[k]);
    294 
    295             nrg_gain_man[k] = (tmp_q3 >> (tmp_q1 - tmp_q2)) +
    296                               (tmp_q4 >> (tmp_q1 - nrg_gain_exp[k]));
    297 
    298             nrg_gain_exp[k] = tmp_q1;
    299         }
    300 
    301 
    302         bst_exp = -100;
    303 
    304         for (k = startGroup; k < stopGroup; k++)
    305         {
    306             if (bst_exp < nrg_gain_exp[k] + nrg_est_exp[k])
    307             {
    308                 bst_exp = nrg_gain_exp[k] + nrg_est_exp[k];    /* max */
    309             }
    310         }
    311 
    312         k -= startGroup;        /*  number of element used in the addition */
    313 
    314         while (k != 0)          /*  bit guard protection depends on log2(k)  */
    315         {
    316             k >>= 1;
    317             bst_exp++;           /*  add extra bit-overflow-guard */
    318         }
    319 
    320         bst_man = 0;
    321 
    322         for (k = startGroup; k < stopGroup; k++)
    323         {
    324             tmp_q2 =  fxp_mul32_Q28(nrg_gain_man[k], nrg_est_man[k]);
    325             bst_man +=  tmp_q2 >> (bst_exp - nrg_gain_exp[k] - nrg_est_exp[k]);
    326         }
    327 
    328         bst_exp += 28;  /* compensate for shift down */
    329 
    330         if (bst_man)
    331         {
    332             /*
    333              *  bst = ref_total / bst
    334              */
    335 
    336             pv_div(ref_total_man, bst_man, &quotient);
    337             bst_exp = ref_total_exp - bst_exp - quotient.shift_factor - 30;
    338             bst_man = quotient.quotient;      /*  Q30 */
    339 
    340             for (k = startGroup; k < stopGroup; k++)
    341             {
    342                 tmp_q1 = fxp_mul32_Q30(bst_man, nrg_gain_man[k]);
    343                 pv_sqrt(tmp_q1, (bst_exp + nrg_gain_exp[k] + 60), &root_sq, sqrt_cache[0]);
    344                 nrg_gain_man[k] = root_sq.root;
    345                 nrg_gain_exp[k] = root_sq.shift_factor;
    346             }
    347         }
    348         else
    349         {
    350             pv_memset((void *)&nrg_gain_man[startGroup],
    351                       0,
    352                       (stopGroup - startGroup)*sizeof(nrg_gain_man[0]));
    353 
    354             pv_memset((void *)&nrg_gain_exp[startGroup],
    355                       0,
    356                       (stopGroup - startGroup)*sizeof(nrg_gain_exp[0]));
    357 
    358         }
    359 
    360     }
    361 }
    362 
    363 #endif
    364 
    365 
    366 
    367