Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /********************************  Fraunhofer IIS  ***************************
     85 
     86    Author(s):   Markus Lohwasser, Josef Hoepfl, Manuel Jander
     87    Description: QMF filterbank
     88 
     89 ******************************************************************************/
     90 
     91 /*!
     92   \file
     93   \brief  Complex qmf analysis/synthesis,
     94   This module contains the qmf filterbank for analysis [ cplxAnalysisQmfFiltering() ] and
     95   synthesis [ cplxSynthesisQmfFiltering() ]. It is a polyphase implementation of a complex
     96   exponential modulated filter bank. The analysis part usually runs at half the sample rate
     97   than the synthesis part. (So called "dual-rate" mode.)
     98 
     99   The coefficients of the prototype filter are specified in #sbr_qmf_64_640 (in sbr_rom.cpp).
    100   Thus only a 64 channel version (32 on the analysis side) with a 640 tap prototype filter
    101   are used.
    102 
    103   \anchor PolyphaseFiltering <h2>About polyphase filtering</h2>
    104   The polyphase implementation of a filterbank requires filtering at the input and output.
    105   This is implemented as part of cplxAnalysisQmfFiltering() and cplxSynthesisQmfFiltering().
    106   The implementation requires the filter coefficients in a specific structure as described in
    107   #sbr_qmf_64_640_qmf (in sbr_rom.cpp).
    108 
    109   This module comprises the computationally most expensive functions of the SBR decoder. The accuracy of
    110   computations is also important and has a direct impact on the overall sound quality. Therefore a special
    111   test program is available which can be used to only test the filterbank: main_audio.cpp
    112 
    113   This modules also uses scaling of data to provide better SNR on fixed-point processors. See #QMF_SCALE_FACTOR (in sbr_scale.h) for details.
    114   An interesting note: The function getScalefactor() can constitute a significant amount of computational complexity - very much depending on the
    115   bitrate. Since it is a rather small function, effective assembler optimization might be possible.
    116 
    117 */
    118 
    119 #include "qmf.h"
    120 
    121 
    122 #include "fixpoint_math.h"
    123 #include "dct.h"
    124 
    125 #ifdef QMFSYN_STATES_16BIT
    126 #define QSSCALE (7)
    127 #define FX_DBL2FX_QSS(x) ((FIXP_QSS) ((x)>>(DFRACT_BITS-QSS_BITS-QSSCALE) ))
    128 #define FX_QSS2FX_DBL(x) ((FIXP_DBL)((LONG)x)<<(DFRACT_BITS-QSS_BITS-QSSCALE))
    129 #else
    130 #define QSSCALE (0)
    131 #define FX_DBL2FX_QSS(x) (x)
    132 #define FX_QSS2FX_DBL(x) (x)
    133 #endif
    134 
    135 
    136 #if defined(__arm__)
    137 #include "arm/qmf_arm.cpp"
    138 
    139 #endif
    140 
    141 /*!
    142  * \brief Algorithmic scaling in sbrForwardModulation()
    143  *
    144  * The scaling in sbrForwardModulation() is caused by:
    145  *
    146  *   \li 1 R_SHIFT in sbrForwardModulation()
    147  *   \li 5/6 R_SHIFT in dct3() if using 32/64 Bands
    148  *   \li 1 ommited gain of 2.0 in qmfForwardModulation()
    149  */
    150 #define ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK 7
    151 
    152 /*!
    153  * \brief Algorithmic scaling in cplxSynthesisQmfFiltering()
    154  *
    155  * The scaling in cplxSynthesisQmfFiltering() is caused by:
    156  *
    157  *   \li  5/6 R_SHIFT in dct2() if using 32/64 Bands
    158  *   \li  1 ommited gain of 2.0 in qmfInverseModulation()
    159  *   \li -6 division by 64 in synthesis filterbank
    160  *   \li x bits external influence
    161  */
    162 #define ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK 1
    163 
    164 
    165 /*!
    166   \brief Perform Synthesis Prototype Filtering on a single slot of input data.
    167 
    168   The filter takes 2 * qmf->no_channels of input data and
    169   generates qmf->no_channels time domain output samples.
    170 */
    171 static
    172 #ifndef FUNCTION_qmfSynPrototypeFirSlot
    173 void qmfSynPrototypeFirSlot(
    174 #else
    175 void qmfSynPrototypeFirSlot_fallback(
    176 #endif
    177                              HANDLE_QMF_FILTER_BANK qmf,
    178                              FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */
    179                              FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */
    180                              INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */
    181                              int       stride
    182                             )
    183 {
    184   FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates;
    185   int       no_channels = qmf->no_channels;
    186   const FIXP_PFT *p_Filter = qmf->p_filter;
    187   int p_stride = qmf->p_stride;
    188   int j;
    189   FIXP_QSS *RESTRICT sta = FilterStates;
    190   const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
    191   int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor);
    192 
    193   p_flt  = p_Filter+p_stride*QMF_NO_POLY;          /*                     5-ter von 330 */
    194   p_fltm = p_Filter+(qmf->FilterSize/2)-p_stride*QMF_NO_POLY;  /* 5 + (320 - 2*5) = 315-ter von 330 */
    195 
    196   FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0);
    197 
    198   for (j = no_channels-1; j >= 0; j--) {  /* ---- luft ueber alle Linien eines Slots ---- */
    199     FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0
    200     FIXP_QMF real  =  realSlot[j];  // ~~"~~
    201     {
    202       INT_PCM tmp;
    203       FIXP_DBL Are = FX_QSS2FX_DBL(sta[0]) + fMultDiv2( p_fltm[0] , real);
    204 
    205       if (qmf->outGain!=(FIXP_DBL)0x80000000) {
    206         Are = fMult(Are,qmf->outGain);
    207       }
    208 
    209   #if SAMPLE_BITS > 16
    210       tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
    211   #else
    212       tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
    213   #endif
    214       if (Are < (FIXP_QMF)0) {
    215         tmp = -tmp;
    216       }
    217       timeOut[ (j)*stride ] = tmp;
    218     }
    219 
    220     sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag ));
    221     sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real ));
    222     sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag ));
    223     sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real ));
    224     sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag ));
    225     sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real ));
    226     sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag ));
    227     sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real ));
    228     sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag ));
    229 
    230     p_flt  += (p_stride*QMF_NO_POLY);
    231     p_fltm -= (p_stride*QMF_NO_POLY);
    232     sta    += 9; // = (2*QMF_NO_POLY-1);
    233   }
    234 }
    235 
    236 #ifndef FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric
    237 /*!
    238   \brief Perform Synthesis Prototype Filtering on a single slot of input data.
    239 
    240   The filter takes 2 * qmf->no_channels of input data and
    241   generates qmf->no_channels time domain output samples.
    242 */
    243 static
    244 void qmfSynPrototypeFirSlot_NonSymmetric(
    245                              HANDLE_QMF_FILTER_BANK qmf,
    246                              FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */
    247                              FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */
    248                              INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */
    249                              int       stride
    250                             )
    251 {
    252   FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates;
    253   int       no_channels = qmf->no_channels;
    254   const FIXP_PFT *p_Filter = qmf->p_filter;
    255   int p_stride = qmf->p_stride;
    256   int j;
    257   FIXP_QSS *RESTRICT sta = FilterStates;
    258   const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
    259   int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor);
    260 
    261   p_flt  = p_Filter;                           /*!< Pointer to first half of filter coefficients */
    262   p_fltm = &p_flt[qmf->FilterSize/2];  /* at index 320, overall 640 coefficients */
    263 
    264   FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0);
    265 
    266   for (j = no_channels-1; j >= 0; j--) {  /* ---- luft ueber alle Linien eines Slots ---- */
    267 
    268     FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0
    269     FIXP_QMF real  =  realSlot[j];  // ~~"~~
    270     {
    271       INT_PCM tmp;
    272       FIXP_QMF Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real ));
    273 
    274   #if SAMPLE_BITS > 16
    275       tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
    276   #else
    277       tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
    278   #endif
    279       if (Are < (FIXP_QMF)0) {
    280         tmp = -tmp;
    281       }
    282       timeOut[j*stride] = tmp;
    283     }
    284 
    285     sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag ));
    286     sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real ));
    287     sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag ));
    288 
    289     sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real ));
    290     sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag ));
    291     sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real ));
    292     sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag ));
    293 
    294     sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[0] , real ));
    295     sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag ));
    296 
    297     p_flt  += (p_stride*QMF_NO_POLY);
    298     p_fltm += (p_stride*QMF_NO_POLY);
    299     sta    += 9; // = (2*QMF_NO_POLY-1);
    300   }
    301 
    302 }
    303 #endif /* FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric */
    304 
    305 #ifndef FUNCTION_qmfAnaPrototypeFirSlot
    306 /*!
    307   \brief Perform Analysis Prototype Filtering on a single slot of input data.
    308 */
    309 static
    310 void qmfAnaPrototypeFirSlot( FIXP_QMF *analysisBuffer,
    311                              int       no_channels,             /*!< Number channels of analysis filter */
    312                              const FIXP_PFT *p_filter,
    313                              int       p_stride,                /*!< Stide of analysis filter    */
    314                              FIXP_QAS *RESTRICT pFilterStates
    315                             )
    316 {
    317     int k;
    318 
    319     FIXP_DBL accu;
    320     const FIXP_PFT *RESTRICT p_flt = p_filter;
    321     FIXP_QMF *RESTRICT pData_0 = analysisBuffer + 2*no_channels - 1;
    322     FIXP_QMF *RESTRICT pData_1 = analysisBuffer;
    323 
    324     FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
    325     FIXP_QAS *RESTRICT sta_1 = (FIXP_QAS *)pFilterStates + (2*QMF_NO_POLY*no_channels) - 1;
    326     int pfltStep = QMF_NO_POLY * (p_stride);
    327     int staStep1 = no_channels<<1;
    328     int staStep2 = (no_channels<<3) - 1; /* Rewind one less */
    329 
    330     /* FIR filter 0 */
    331     accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1;
    332     accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1;
    333     accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1;
    334     accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1;
    335     accu +=  fMultDiv2( p_flt[4], *sta_1);
    336     *pData_1++ = FX_DBL2FX_QMF(accu<<1);
    337     sta_1 += staStep2;
    338 
    339     p_flt += pfltStep;
    340 
    341     /* FIR filters 1..63 127..65 */
    342     for (k=0; k<no_channels-1; k++)
    343     {
    344       accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1;
    345       accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1;
    346       accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1;
    347       accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1;
    348       accu += fMultDiv2( p_flt[4], *sta_0);
    349       *pData_0-- = FX_DBL2FX_QMF(accu<<1);
    350       sta_0 -= staStep2;
    351 
    352       accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1;
    353       accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1;
    354       accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1;
    355       accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1;
    356       accu +=  fMultDiv2( p_flt[4], *sta_1);
    357       *pData_1++ = FX_DBL2FX_QMF(accu<<1);
    358       sta_1 += staStep2;
    359 
    360       p_flt += pfltStep;
    361     }
    362 
    363     /* FIR filter 64 */
    364     accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1;
    365     accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1;
    366     accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1;
    367     accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1;
    368     accu += fMultDiv2( p_flt[4], *sta_0);
    369     *pData_0-- = FX_DBL2FX_QMF(accu<<1);
    370     sta_0 -= staStep2;
    371 }
    372 #endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
    373 
    374 
    375 #ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
    376 /*!
    377   \brief Perform Analysis Prototype Filtering on a single slot of input data.
    378 */
    379 static
    380 void qmfAnaPrototypeFirSlot_NonSymmetric(
    381                                         FIXP_QMF *analysisBuffer,
    382                                         int       no_channels,             /*!< Number channels of analysis filter */
    383                                         const FIXP_PFT *p_filter,
    384                                         int       p_stride,                /*!< Stide of analysis filter    */
    385                                         FIXP_QAS *RESTRICT pFilterStates
    386                                        )
    387 {
    388   const FIXP_PFT *RESTRICT p_flt = p_filter;
    389   int  p, k;
    390 
    391   for (k = 0; k < 2*no_channels; k++)
    392   {
    393     FIXP_DBL accu = (FIXP_DBL)0;
    394 
    395     p_flt += QMF_NO_POLY * (p_stride - 1);
    396 
    397     /*
    398       Perform FIR-Filter
    399     */
    400     for (p = 0; p < QMF_NO_POLY; p++) {
    401       accu +=  fMultDiv2(*p_flt++, pFilterStates[2*no_channels * p]);
    402     }
    403     analysisBuffer[2*no_channels - 1 - k] = FX_DBL2FX_QMF(accu<<1);
    404     pFilterStates++;
    405   }
    406 }
    407 #endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
    408 
    409 /*!
    410  *
    411  * \brief Perform real-valued forward modulation of the time domain
    412  *        data of timeIn and stores the real part of the subband
    413  *        samples in rSubband
    414  *
    415  */
    416 static void
    417 qmfForwardModulationLP_even( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */
    418                              FIXP_QMF *timeIn,              /*!< Time Signal */
    419                              FIXP_QMF *rSubband )           /*!< Real Output */
    420 {
    421   int i;
    422   int L = anaQmf->no_channels;
    423   int M = L>>1;
    424   int scale;
    425   FIXP_QMF accu;
    426 
    427   const FIXP_QMF *timeInTmp1 = (FIXP_QMF *) &timeIn[3 * M];
    428   const FIXP_QMF *timeInTmp2 = timeInTmp1;
    429   FIXP_QMF *rSubbandTmp = rSubband;
    430 
    431   rSubband[0] = timeIn[3 * M] >> 1;
    432 
    433   for (i = M-1; i != 0; i--) {
    434     accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1);
    435     *++rSubbandTmp = accu;
    436   }
    437 
    438   timeInTmp1 = &timeIn[2 * M];
    439   timeInTmp2 = &timeIn[0];
    440   rSubbandTmp = &rSubband[M];
    441 
    442   for (i = L-M; i != 0; i--) {
    443     accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1);
    444     *rSubbandTmp++ = accu;
    445   }
    446 
    447   dct_III(rSubband, timeIn, L, &scale);
    448 }
    449 
    450 #if !defined(FUNCTION_qmfForwardModulationLP_odd)
    451 static void
    452 qmfForwardModulationLP_odd( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */
    453                             const FIXP_QMF *timeIn,        /*!< Time Signal */
    454                             FIXP_QMF *rSubband )           /*!< Real Output */
    455 {
    456   int i;
    457   int L = anaQmf->no_channels;
    458   int M = L>>1;
    459   int shift = (anaQmf->no_channels>>6) + 1;
    460 
    461   for (i = 0; i < M; i++) {
    462     rSubband[M + i]     = (timeIn[L - 1 - i]>>1) - (timeIn[i]>>shift);
    463     rSubband[M - 1 - i] = (timeIn[L + i]>>1)     + (timeIn[2 * L - 1 - i]>>shift);
    464   }
    465 
    466   dct_IV(rSubband, L, &shift);
    467 }
    468 #endif /* !defined(FUNCTION_qmfForwardModulationLP_odd) */
    469 
    470 
    471 
    472 /*!
    473  *
    474  * \brief Perform complex-valued forward modulation of the time domain
    475  *        data of timeIn and stores the real part of the subband
    476  *        samples in rSubband, and the imaginary part in iSubband
    477  *
    478  *        Only the lower bands are obtained (upto anaQmf->lsb). For
    479  *        a full bandwidth analysis it is required to set both anaQmf->lsb
    480  *        and anaQmf->usb to the amount of QMF bands.
    481  *
    482  */
    483 static void
    484 qmfForwardModulationHQ( HANDLE_QMF_FILTER_BANK anaQmf,     /*!< Handle of Qmf Analysis Bank  */
    485                         const FIXP_QMF *RESTRICT timeIn,   /*!< Time Signal */
    486                         FIXP_QMF *RESTRICT rSubband,       /*!< Real Output */
    487                         FIXP_QMF *RESTRICT iSubband        /*!< Imaginary Output */
    488                        )
    489 {
    490   int i;
    491   int L = anaQmf->no_channels;
    492   int L2 = L<<1;
    493   int shift = 0;
    494 
    495   for (i = 0; i < L; i+=2) {
    496     FIXP_QMF x0, x1, y0, y1;
    497 
    498     x0 = timeIn[i] >> 1;
    499     x1 = timeIn[i+1] >> 1;
    500     y0 = timeIn[L2 - 1 - i] >> 1;
    501     y1 = timeIn[L2 - 2 - i] >> 1;
    502 
    503     rSubband[i] = x0 - y0;
    504     rSubband[i+1] = x1 - y1;
    505     iSubband[i] = x0 + y0;
    506     iSubband[i+1] = x1 + y1;
    507   }
    508 
    509   dct_IV(rSubband, L, &shift);
    510   dst_IV(iSubband, L, &shift);
    511 
    512   {
    513     {
    514       const FIXP_QTW *RESTRICT sbr_t_cos;
    515       const FIXP_QTW *RESTRICT sbr_t_sin;
    516       sbr_t_cos = anaQmf->t_cos;
    517       sbr_t_sin = anaQmf->t_sin;
    518 
    519       for (i = 0; i < anaQmf->lsb; i++) {
    520         cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i], sbr_t_cos[i], sbr_t_sin[i]);
    521       }
    522     }
    523   }
    524 }
    525 
    526 /*
    527  * \brief Perform one QMF slot analysis of the time domain data of timeIn
    528  *        with specified stride and stores the real part of the subband
    529  *        samples in rSubband, and the imaginary part in iSubband
    530  *
    531  *        Only the lower bands are obtained (upto anaQmf->lsb). For
    532  *        a full bandwidth analysis it is required to set both anaQmf->lsb
    533  *        and anaQmf->usb to the amount of QMF bands.
    534  */
    535 void
    536 qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf,  /*!< Handle of Qmf Synthesis Bank  */
    537                           FIXP_QMF      *qmfReal,         /*!< Low and High band, real */
    538                           FIXP_QMF      *qmfImag,         /*!< Low and High band, imag */
    539                           const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
    540                           const int      stride,          /*!< stride factor of input */
    541                           FIXP_QMF      *pWorkBuffer      /*!< pointer to temporal working buffer */
    542                          )
    543 {
    544     int i;
    545     int offset = anaQmf->no_channels*(QMF_NO_POLY*2-1);
    546     /*
    547       Feed time signal into oldest anaQmf->no_channels states
    548     */
    549     {
    550       FIXP_QAS *RESTRICT FilterStatesAnaTmp = ((FIXP_QAS*)anaQmf->FilterStates)+offset;
    551 
    552       /* Feed and scale actual time in slot */
    553       for(i=anaQmf->no_channels>>1; i!=0; i--) {
    554         /* Place INT_PCM value left aligned in scaledTimeIn */
    555 #if (QAS_BITS==SAMPLE_BITS)
    556         *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride;
    557         *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride;
    558 #elif (QAS_BITS>SAMPLE_BITS)
    559         *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride;
    560         *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride;
    561 #else
    562         *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride;
    563         *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride;
    564 #endif
    565       }
    566     }
    567 
    568     if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
    569       qmfAnaPrototypeFirSlot_NonSymmetric(
    570                               pWorkBuffer,
    571                               anaQmf->no_channels,
    572                               anaQmf->p_filter,
    573                               anaQmf->p_stride,
    574                               (FIXP_QAS*)anaQmf->FilterStates
    575                             );
    576     } else {
    577       qmfAnaPrototypeFirSlot( pWorkBuffer,
    578                               anaQmf->no_channels,
    579                               anaQmf->p_filter,
    580                               anaQmf->p_stride,
    581                               (FIXP_QAS*)anaQmf->FilterStates
    582                             );
    583     }
    584 
    585     if (anaQmf->flags & QMF_FLAG_LP) {
    586       if (anaQmf->flags & QMF_FLAG_CLDFB)
    587         qmfForwardModulationLP_odd( anaQmf,
    588                                     pWorkBuffer,
    589                                     qmfReal );
    590       else
    591         qmfForwardModulationLP_even( anaQmf,
    592                                      pWorkBuffer,
    593                                      qmfReal );
    594 
    595     } else {
    596       qmfForwardModulationHQ( anaQmf,
    597                               pWorkBuffer,
    598                               qmfReal,
    599                               qmfImag
    600                              );
    601     }
    602     /*
    603       Shift filter states
    604 
    605       Should be realized with modulo adressing on a DSP instead of a true buffer shift
    606     */
    607     FDKmemmove ((FIXP_QAS*)anaQmf->FilterStates, (FIXP_QAS*)anaQmf->FilterStates+anaQmf->no_channels, offset*sizeof(FIXP_QAS));
    608 }
    609 
    610 
    611 /*!
    612  *
    613  * \brief Perform complex-valued subband filtering of the time domain
    614  *        data of timeIn and stores the real part of the subband
    615  *        samples in rAnalysis, and the imaginary part in iAnalysis
    616  * The qmf coefficient table is symmetric. The symmetry is expoited by
    617  * shrinking the coefficient table to half the size. The addressing mode
    618  * takes care of the symmetries.
    619  *
    620  * Only the lower bands are obtained (upto anaQmf->lsb). For
    621  * a full bandwidth analysis it is required to set both anaQmf->lsb
    622  * and anaQmf->usb to the amount of QMF bands.
    623  *
    624  * \sa PolyphaseFiltering
    625  */
    626 
    627 void
    628 qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf,    /*!< Handle of Qmf Analysis Bank */
    629                       FIXP_QMF **qmfReal,               /*!< Pointer to real subband slots */
    630                       FIXP_QMF **qmfImag,               /*!< Pointer to imag subband slots */
    631                       QMF_SCALE_FACTOR *scaleFactor,
    632                       const INT_PCM *timeIn,            /*!< Time signal */
    633                       const int  stride,
    634                       FIXP_QMF  *pWorkBuffer            /*!< pointer to temporal working buffer */
    635                       )
    636 {
    637   int i;
    638   int no_channels = anaQmf->no_channels;
    639 
    640   scaleFactor->lb_scale = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK;
    641   scaleFactor->lb_scale -= anaQmf->filterScale;
    642 
    643   for (i = 0; i < anaQmf->no_col; i++)
    644   {
    645       FIXP_QMF *qmfImagSlot = NULL;
    646 
    647       if (!(anaQmf->flags & QMF_FLAG_LP)) {
    648         qmfImagSlot = qmfImag[i];
    649       }
    650 
    651       qmfAnalysisFilteringSlot( anaQmf, qmfReal[i], qmfImagSlot, timeIn , stride, pWorkBuffer );
    652 
    653       timeIn += no_channels*stride;
    654 
    655   } /* no_col loop  i  */
    656 }
    657 
    658 /*!
    659  *
    660  * \brief Perform low power inverse modulation of the subband
    661  *        samples stored in rSubband (real part) and iSubband (imaginary
    662  *        part) and stores the result in pWorkBuffer.
    663  *
    664  */
    665 inline
    666 static void
    667 qmfInverseModulationLP_even( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */
    668                              const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */
    669                              const int   scaleFactorLowBand,  /*!< Scalefactor for Low band */
    670                              const int   scaleFactorHighBand, /*!< Scalefactor for High band */
    671                              FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/
    672                            )
    673 {
    674   int i;
    675   int L = synQmf->no_channels;
    676   int M = L>>1;
    677   int scale;
    678   FIXP_QMF tmp;
    679   FIXP_QMF *RESTRICT tReal = pTimeOut;
    680   FIXP_QMF *RESTRICT tImag = pTimeOut + L;
    681 
    682   /* Move input to output vector with offset */
    683   scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand);
    684   scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
    685   FDKmemclear(&tReal[0+synQmf->usb], (L-synQmf->usb)*sizeof(FIXP_QMF));
    686 
    687   /* Dct type-2 transform */
    688   dct_II(tReal, tImag, L, &scale);
    689 
    690   /* Expand output and replace inplace the output buffers */
    691   tImag[0] = tReal[M];
    692   tImag[M] = (FIXP_QMF)0;
    693   tmp = tReal [0];
    694   tReal [0] = tReal[M];
    695   tReal [M] = tmp;
    696 
    697   for (i = 1; i < M/2; i++) {
    698     /* Imag */
    699     tmp = tReal[L - i];
    700     tImag[M - i] =  tmp;
    701     tImag[i + M] = -tmp;
    702 
    703     tmp = tReal[M + i];
    704     tImag[i] =  tmp;
    705     tImag[L - i] = -tmp;
    706 
    707     /* Real */
    708     tReal [M + i] = tReal[i];
    709     tReal [L - i] = tReal[M - i];
    710     tmp = tReal[i];
    711     tReal[i] = tReal [M - i];
    712     tReal [M - i] = tmp;
    713 
    714   }
    715   /* Remaining odd terms */
    716   tmp = tReal[M + M/2];
    717   tImag[M/2]     =  tmp;
    718   tImag[M/2 + M] = -tmp;
    719 
    720   tReal [M + M/2] = tReal[M/2];
    721 }
    722 
    723 inline
    724 static void
    725 qmfInverseModulationLP_odd( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */
    726                             const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */
    727                             const int scaleFactorLowBand,    /*!< Scalefactor for Low band */
    728                             const int scaleFactorHighBand,   /*!< Scalefactor for High band */
    729                             FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/
    730                           )
    731 {
    732   int i;
    733   int L = synQmf->no_channels;
    734   int M = L>>1;
    735   int shift = 0;
    736 
    737   /* Move input to output vector with offset */
    738   scaleValues(pTimeOut+M,              qmfReal,             synQmf->lsb,             scaleFactorLowBand);
    739   scaleValues(pTimeOut+M+synQmf->lsb,  qmfReal+synQmf->lsb, synQmf->usb-synQmf->lsb, scaleFactorHighBand);
    740   FDKmemclear(pTimeOut+M+synQmf->usb, (L-synQmf->usb)*sizeof(FIXP_QMF));
    741 
    742   dct_IV(pTimeOut+M, L, &shift);
    743   for (i = 0; i < M; i++) {
    744     pTimeOut[i]             =  pTimeOut[L - 1 - i];
    745     pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i];
    746   }
    747 }
    748 
    749 
    750 /*!
    751  *
    752  * \brief Perform complex-valued inverse modulation of the subband
    753  *        samples stored in rSubband (real part) and iSubband (imaginary
    754  *        part) and stores the result in pWorkBuffer.
    755  *
    756  */
    757 inline
    758 static void
    759 qmfInverseModulationHQ( HANDLE_QMF_FILTER_BANK synQmf,  /*!< Handle of Qmf Synthesis Bank     */
    760                         const FIXP_QMF *qmfReal,        /*!< Pointer to qmf real subband slot */
    761                         const FIXP_QMF *qmfImag,        /*!< Pointer to qmf imag subband slot */
    762                         const int   scaleFactorLowBand, /*!< Scalefactor for Low band         */
    763                         const int   scaleFactorHighBand,/*!< Scalefactor for High band        */
    764                         FIXP_QMF  *pWorkBuffer          /*!< WorkBuffer (output)              */
    765                       )
    766 {
    767   int i;
    768   int L = synQmf->no_channels;
    769   int M = L>>1;
    770   int shift = 0;
    771   FIXP_QMF *RESTRICT tReal = pWorkBuffer;
    772   FIXP_QMF *RESTRICT tImag = pWorkBuffer+L;
    773 
    774   if (synQmf->flags & QMF_FLAG_CLDFB){
    775     for (i = 0; i < synQmf->lsb; i++) {
    776       cplxMult(&tImag[i], &tReal[i],
    777                 scaleValue(qmfImag[i],scaleFactorLowBand), scaleValue(qmfReal[i],scaleFactorLowBand),
    778                 synQmf->t_cos[i], synQmf->t_sin[i]);
    779     }
    780     for (; i < synQmf->usb; i++) {
    781       cplxMult(&tImag[i], &tReal[i],
    782                 scaleValue(qmfImag[i],scaleFactorHighBand), scaleValue(qmfReal[i],scaleFactorHighBand),
    783                 synQmf->t_cos[i], synQmf->t_sin[i]);
    784     }
    785   }
    786 
    787   if ( (synQmf->flags & QMF_FLAG_CLDFB) == 0) {
    788     scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand);
    789     scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
    790     scaleValues(&tImag[0],             &qmfImag[0],             synQmf->lsb,             scaleFactorLowBand);
    791     scaleValues(&tImag[0+synQmf->lsb], &qmfImag[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
    792   }
    793 
    794   FDKmemclear(&tReal[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF));
    795   FDKmemclear(&tImag[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF));
    796 
    797   dct_IV(tReal, L, &shift);
    798   dst_IV(tImag, L, &shift);
    799 
    800   if (synQmf->flags & QMF_FLAG_CLDFB){
    801     for (i = 0; i < M; i++) {
    802       FIXP_QMF r1, i1, r2, i2;
    803       r1 = tReal[i];
    804       i2 = tImag[L - 1 - i];
    805       r2 = tReal[L - i - 1];
    806       i1 = tImag[i];
    807 
    808       tReal[i] = (r1 - i1)>>1;
    809       tImag[L - 1 - i] = -(r1 + i1)>>1;
    810       tReal[L - i - 1] =  (r2 - i2)>>1;
    811       tImag[i] = -(r2 + i2)>>1;
    812     }
    813   } else
    814   {
    815     /* The array accesses are negative to compensate the missing minus sign in the low and hi band gain. */
    816     /* 26 cycles on ARM926 */
    817     for (i = 0; i < M; i++) {
    818       FIXP_QMF r1, i1, r2, i2;
    819       r1 = -tReal[i];
    820       i2 = -tImag[L - 1 - i];
    821       r2 = -tReal[L - i - 1];
    822       i1 = -tImag[i];
    823 
    824       tReal[i] = (r1 - i1)>>1;
    825       tImag[L - 1 - i] = -(r1 + i1)>>1;
    826       tReal[L - i - 1] =  (r2 - i2)>>1;
    827       tImag[i] = -(r2 + i2)>>1;
    828     }
    829   }
    830 }
    831 
    832 void qmfSynthesisFilteringSlot( HANDLE_QMF_FILTER_BANK  synQmf,
    833                                 const FIXP_QMF  *realSlot,
    834                                 const FIXP_QMF  *imagSlot,
    835                                 const int        scaleFactorLowBand,
    836                                 const int        scaleFactorHighBand,
    837                                 INT_PCM         *timeOut,
    838                                 const int        stride,
    839                                 FIXP_QMF        *pWorkBuffer)
    840 {
    841     if (!(synQmf->flags & QMF_FLAG_LP))
    842       qmfInverseModulationHQ ( synQmf,
    843                                realSlot,
    844                                imagSlot,
    845                                scaleFactorLowBand,
    846                                scaleFactorHighBand,
    847                                pWorkBuffer
    848                              );
    849     else
    850     {
    851       if (synQmf->flags & QMF_FLAG_CLDFB) {
    852         qmfInverseModulationLP_odd ( synQmf,
    853                                  realSlot,
    854                                  scaleFactorLowBand,
    855                                  scaleFactorHighBand,
    856                                  pWorkBuffer
    857                                );
    858       } else {
    859         qmfInverseModulationLP_even ( synQmf,
    860                                  realSlot,
    861                                  scaleFactorLowBand,
    862                                  scaleFactorHighBand,
    863                                  pWorkBuffer
    864                                );
    865       }
    866     }
    867 
    868     if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) {
    869         qmfSynPrototypeFirSlot_NonSymmetric (
    870                                  synQmf,
    871                                  pWorkBuffer,
    872                                  pWorkBuffer+synQmf->no_channels,
    873                                  timeOut,
    874                                  stride
    875                                );
    876     } else {
    877         qmfSynPrototypeFirSlot ( synQmf,
    878                                  pWorkBuffer,
    879                                  pWorkBuffer+synQmf->no_channels,
    880                                  timeOut,
    881                                  stride
    882                                );
    883     }
    884 }
    885 
    886 
    887 /*!
    888  *
    889  *
    890  * \brief Perform complex-valued subband synthesis of the
    891  *        low band and the high band and store the
    892  *        time domain data in timeOut
    893  *
    894  * First step: Calculate the proper scaling factor of current
    895  * spectral data in qmfReal/qmfImag, old spectral data in the overlap
    896  * range and filter states.
    897  *
    898  * Second step: Perform Frequency-to-Time mapping with inverse
    899  * Modulation slot-wise.
    900  *
    901  * Third step: Perform FIR-filter slot-wise. To save space for filter
    902  * states, the MAC operations are executed directly on the filter states
    903  * instead of accumulating several products in the accumulator. The
    904  * buffer shift at the end of the function should be replaced by a
    905  * modulo operation, which is available on some DSPs.
    906  *
    907  * Last step: Copy the upper part of the spectral data to the overlap buffer.
    908  *
    909  * The qmf coefficient table is symmetric. The symmetry is exploited by
    910  * shrinking the coefficient table to half the size. The addressing mode
    911  * takes care of the symmetries.  If the #define #QMFTABLE_FULL is set,
    912  * coefficient addressing works on the full table size. The code will be
    913  * slightly faster and slightly more compact.
    914  *
    915  * Workbuffer requirement: 2 x sizeof(**QmfBufferReal) * synQmf->no_channels
    916  */
    917 void
    918 qmfSynthesisFiltering( HANDLE_QMF_FILTER_BANK synQmf,       /*!< Handle of Qmf Synthesis Bank  */
    919                        FIXP_QMF  **QmfBufferReal,           /*!< Low and High band, real */
    920                        FIXP_QMF  **QmfBufferImag,           /*!< Low and High band, imag */
    921                        const QMF_SCALE_FACTOR *scaleFactor,
    922                        const INT   ov_len,                  /*!< split Slot of overlap and actual slots */
    923                        INT_PCM    *timeOut,                 /*!< Pointer to output */
    924                        const INT   stride,                  /*!< stride factor of output */
    925                        FIXP_QMF   *pWorkBuffer              /*!< pointer to temporal working buffer */
    926                       )
    927 {
    928   int i;
    929   int L = synQmf->no_channels;
    930   SCHAR scaleFactorHighBand;
    931   SCHAR scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;
    932 
    933   /* adapt scaling */
    934   scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->hb_scale;
    935   scaleFactorLowBand_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->ov_lb_scale;
    936   scaleFactorLowBand_no_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->lb_scale;
    937 
    938   for (i = 0; i < synQmf->no_col; i++)  /* ----- no_col loop ----- */
    939   {
    940     const FIXP_DBL *QmfBufferImagSlot = NULL;
    941 
    942     SCHAR scaleFactorLowBand = (i<ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov;
    943 
    944     if (!(synQmf->flags & QMF_FLAG_LP))
    945         QmfBufferImagSlot = QmfBufferImag[i];
    946 
    947     qmfSynthesisFilteringSlot(  synQmf,
    948                                 QmfBufferReal[i],
    949                                 QmfBufferImagSlot,
    950                                 scaleFactorLowBand,
    951                                 scaleFactorHighBand,
    952                                 timeOut+(i*L*stride),
    953                                 stride,
    954                                 pWorkBuffer);
    955   } /* no_col loop  i  */
    956 
    957 }
    958 
    959 
    960 /*!
    961  *
    962  * \brief Create QMF filter bank instance
    963  *
    964  * \return 0 if successful
    965  *
    966  */
    967 static int
    968 qmfInitFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,     /*!< Handle to return */
    969                    void *pFilterStates,              /*!< Handle to filter states */
    970                    int noCols,                       /*!< Number of timeslots per frame */
    971                    int lsb,                          /*!< Lower end of QMF frequency range */
    972                    int usb,                          /*!< Upper end of QMF frequency range */
    973                    int no_channels,                  /*!< Number of channels (bands) */
    974                    UINT flags)                       /*!< flags */
    975 {
    976   FDKmemclear(h_Qmf,sizeof(QMF_FILTER_BANK));
    977 
    978   if (flags & QMF_FLAG_MPSLDFB)
    979   {
    980     return -1;
    981   }
    982 
    983   if ( !(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB) )
    984   {
    985     flags |= QMF_FLAG_NONSYMMETRIC;
    986     h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE;
    987 
    988     h_Qmf->p_stride = 1;
    989     switch (no_channels) {
    990       case 64:
    991         h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb;
    992         h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb;
    993         h_Qmf->p_filter = qmf_cldfb_640;
    994         h_Qmf->FilterSize = 640;
    995         break;
    996       case 32:
    997         h_Qmf->t_cos = qmf_phaseshift_cos32_cldfb;
    998         h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb;
    999         h_Qmf->p_filter = qmf_cldfb_320;
   1000         h_Qmf->FilterSize = 320;
   1001         break;
   1002       default:
   1003         return -1;
   1004     }
   1005   }
   1006 
   1007   if ( !(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0) )
   1008   {
   1009     switch (no_channels) {
   1010       case 64:
   1011         h_Qmf->p_filter = qmf_64;
   1012         h_Qmf->t_cos = qmf_phaseshift_cos64;
   1013         h_Qmf->t_sin = qmf_phaseshift_sin64;
   1014         h_Qmf->p_stride = 1;
   1015         h_Qmf->FilterSize = 640;
   1016         h_Qmf->filterScale = 0;
   1017         break;
   1018       case 32:
   1019         h_Qmf->p_filter = qmf_64;
   1020         h_Qmf->t_cos = qmf_phaseshift_cos32;
   1021         h_Qmf->t_sin = qmf_phaseshift_sin32;
   1022         h_Qmf->p_stride = 2;
   1023         h_Qmf->FilterSize = 640;
   1024         h_Qmf->filterScale = 0;
   1025         break;
   1026       default:
   1027         return -1;
   1028     }
   1029   }
   1030 
   1031   h_Qmf->flags = flags;
   1032 
   1033   h_Qmf->no_channels = no_channels;
   1034   h_Qmf->no_col = noCols;
   1035 
   1036   h_Qmf->lsb = lsb;
   1037   h_Qmf->usb = fMin(usb, h_Qmf->no_channels);
   1038 
   1039   h_Qmf->FilterStates = (void*)pFilterStates;
   1040 
   1041   h_Qmf->outScalefactor = ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + h_Qmf->filterScale;
   1042 
   1043   if (h_Qmf->p_stride == 2) {
   1044     h_Qmf->outScalefactor -= 1;
   1045   }
   1046   h_Qmf->outGain = (FIXP_DBL)0x80000000; /* default init value will be not applied */
   1047 
   1048   return (0);
   1049 }
   1050 
   1051 /*!
   1052  *
   1053  * \brief Adjust synthesis qmf filter states
   1054  *
   1055  * \return void
   1056  *
   1057  */
   1058 static inline void
   1059 qmfAdaptFilterStates (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Filter Bank */
   1060                       int scaleFactorDiff)               /*!< Scale factor difference to be applied */
   1061 {
   1062   if (synQmf == NULL || synQmf->FilterStates == NULL) {
   1063     return;
   1064   }
   1065   scaleValues((FIXP_QSS*)synQmf->FilterStates, synQmf->no_channels*(QMF_NO_POLY*2 - 1), scaleFactorDiff);
   1066 }
   1067 
   1068 /*!
   1069  *
   1070  * \brief Create QMF filter bank instance
   1071  *
   1072  * Only the lower bands are obtained (upto anaQmf->lsb). For
   1073  * a full bandwidth analysis it is required to set both anaQmf->lsb
   1074  * and anaQmf->usb to the amount of QMF bands.
   1075  *
   1076  * \return 0 if succesful
   1077  *
   1078  */
   1079 int
   1080 qmfInitAnalysisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */
   1081                            FIXP_QAS *pFilterStates,        /*!< Handle to filter states */
   1082                            int noCols,                     /*!< Number of timeslots per frame */
   1083                            int lsb,                        /*!< lower end of QMF */
   1084                            int usb,                        /*!< upper end of QMF */
   1085                            int no_channels,                /*!< Number of channels (bands) */
   1086                            int flags)                      /*!< Low Power flag */
   1087 {
   1088   int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags);
   1089   if ( !(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL) ) {
   1090     FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QAS));
   1091   }
   1092 
   1093   return err;
   1094 }
   1095 
   1096 /*!
   1097  *
   1098  * \brief Create QMF filter bank instance
   1099  *
   1100  * Only the lower bands are obtained (upto anaQmf->lsb). For
   1101  * a full bandwidth analysis it is required to set both anaQmf->lsb
   1102  * and anaQmf->usb to the amount of QMF bands.
   1103  *
   1104  * \return 0 if succesful
   1105  *
   1106  */
   1107 int
   1108 qmfInitSynthesisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */
   1109                             FIXP_QSS *pFilterStates,        /*!< Handle to filter states */
   1110                             int noCols,                     /*!< Number of timeslots per frame */
   1111                             int lsb,                        /*!< lower end of QMF */
   1112                             int usb,                        /*!< upper end of QMF */
   1113                             int no_channels,                /*!< Number of channels (bands) */
   1114                             int flags)                      /*!< Low Power flag */
   1115 {
   1116   int oldOutScale = h_Qmf->outScalefactor;
   1117   int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags);
   1118   if ( h_Qmf->FilterStates != NULL ) {
   1119     if ( !(flags & QMF_FLAG_KEEP_STATES) ) {
   1120       FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QSS));
   1121     } else {
   1122       qmfAdaptFilterStates(h_Qmf, oldOutScale-h_Qmf->outScalefactor);
   1123     }
   1124   }
   1125   return err;
   1126 }
   1127 
   1128 
   1129 
   1130 
   1131 /*!
   1132  *
   1133  * \brief Change scale factor for output data and adjust qmf filter states
   1134  *
   1135  * \return void
   1136  *
   1137  */
   1138 void
   1139 qmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */
   1140                          int outScalefactor                 /*!< New scaling factor for output data */
   1141                         )
   1142 {
   1143   if (synQmf == NULL || synQmf->FilterStates == NULL) {
   1144     return;
   1145   }
   1146 
   1147   /* Add internal filterbank scale */
   1148   outScalefactor += ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + synQmf->filterScale;
   1149 
   1150   if (synQmf->p_stride == 2) {
   1151     outScalefactor -= 1;
   1152   }
   1153 
   1154   /* adjust filter states when scale factor has been changed */
   1155   if (synQmf->outScalefactor != outScalefactor)
   1156   {
   1157     int diff;
   1158 
   1159     if (outScalefactor > (SAMPLE_BITS - 1)) {
   1160       outScalefactor = SAMPLE_BITS - 1;
   1161     } else if (outScalefactor < (1 - SAMPLE_BITS)) {
   1162       outScalefactor = 1 - SAMPLE_BITS;
   1163     }
   1164 
   1165     diff = synQmf->outScalefactor - outScalefactor;
   1166 
   1167     qmfAdaptFilterStates(synQmf, diff);
   1168 
   1169     /* save new scale factor */
   1170     synQmf->outScalefactor = outScalefactor;
   1171   }
   1172 }
   1173 
   1174 /*!
   1175  *
   1176  * \brief Change gain for output data
   1177  *
   1178  * \return void
   1179  *
   1180  */
   1181 void
   1182 qmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */
   1183                   FIXP_DBL outputGain                /*!< New gain for output data */
   1184                  )
   1185 {
   1186   synQmf->outGain = outputGain;
   1187 }
   1188 
   1189