diff options
Diffstat (limited to 'libFDK/src/qmf.cpp')
| -rw-r--r-- | libFDK/src/qmf.cpp | 1196 | 
1 files changed, 0 insertions, 1196 deletions
| diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp deleted file mode 100644 index 54526dd..0000000 --- a/libFDK/src/qmf.cpp +++ /dev/null @@ -1,1196 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. -  All rights reserved. - - 1.    INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. - -2.    COPYRIGHT LICENSE - -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: - -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. - -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your -modifications thereto to recipients of copies in binary form. - -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. - -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. - -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." - -3.    NO PATENT LICENSE - -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. - -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. - -4.    DISCLAIMER - -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. - -5.    CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/********************************  Fraunhofer IIS  *************************** - -   Author(s):   Markus Lohwasser, Josef Hoepfl, Manuel Jander -   Description: QMF filterbank - -******************************************************************************/ - -/*! -  \file -  \brief  Complex qmf analysis/synthesis,   -  This module contains the qmf filterbank for analysis [ cplxAnalysisQmfFiltering() ] and -  synthesis [ cplxSynthesisQmfFiltering() ]. It is a polyphase implementation of a complex -  exponential modulated filter bank. The analysis part usually runs at half the sample rate -  than the synthesis part. (So called "dual-rate" mode.) - -  The coefficients of the prototype filter are specified in #sbr_qmf_64_640 (in sbr_rom.cpp). -  Thus only a 64 channel version (32 on the analysis side) with a 640 tap prototype filter -  are used. - -  \anchor PolyphaseFiltering <h2>About polyphase filtering</h2> -  The polyphase implementation of a filterbank requires filtering at the input and output. -  This is implemented as part of cplxAnalysisQmfFiltering() and cplxSynthesisQmfFiltering(). -  The implementation requires the filter coefficients in a specific structure as described in -  #sbr_qmf_64_640_qmf (in sbr_rom.cpp). - -  This module comprises the computationally most expensive functions of the SBR decoder. The accuracy of -  computations is also important and has a direct impact on the overall sound quality. Therefore a special -  test program is available which can be used to only test the filterbank: main_audio.cpp - -  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. -  An interesting note: The function getScalefactor() can constitute a significant amount of computational complexity - very much depending on the -  bitrate. Since it is a rather small function, effective assembler optimization might be possible. - -*/ - -#include "qmf.h" - - -#include "fixpoint_math.h" -#include "dct.h" - -#ifdef QMFSYN_STATES_16BIT -#define QSSCALE (7) -#define FX_DBL2FX_QSS(x) ((FIXP_QSS) ((x)>>(DFRACT_BITS-QSS_BITS-QSSCALE) )) -#define FX_QSS2FX_DBL(x) ((FIXP_DBL)((LONG)x)<<(DFRACT_BITS-QSS_BITS-QSSCALE)) -#else -#define QSSCALE (0) -#define FX_DBL2FX_QSS(x) (x) -#define FX_QSS2FX_DBL(x) (x) -#endif - - -#if defined(__arm__) -#include "arm/qmf_arm.cpp" - -#endif - -/*! - * \brief Algorithmic scaling in sbrForwardModulation() - * - * The scaling in sbrForwardModulation() is caused by: - * - *   \li 1 R_SHIFT in sbrForwardModulation() - *   \li 5/6 R_SHIFT in dct3() if using 32/64 Bands - *   \li 1 ommited gain of 2.0 in qmfForwardModulation() - */ -#define ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK 7 - -/*! - * \brief Algorithmic scaling in cplxSynthesisQmfFiltering() - * - * The scaling in cplxSynthesisQmfFiltering() is caused by: - * - *   \li  5/6 R_SHIFT in dct2() if using 32/64 Bands - *   \li  1 ommited gain of 2.0 in qmfInverseModulation() - *   \li -6 division by 64 in synthesis filterbank - *   \li x bits external influence - */ -#define ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK 1 - - -/*! -  \brief Perform Synthesis Prototype Filtering on a single slot of input data. - -  The filter takes 2 * qmf->no_channels of input data and -  generates qmf->no_channels time domain output samples. -*/ -static -#ifndef FUNCTION_qmfSynPrototypeFirSlot -void qmfSynPrototypeFirSlot( -#else -void qmfSynPrototypeFirSlot_fallback( -#endif -                             HANDLE_QMF_FILTER_BANK qmf, -                             FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */ -                             FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */ -                             INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */ -                             int       stride -                            ) -{ -  FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates; -  int       no_channels = qmf->no_channels; -  const FIXP_PFT *p_Filter = qmf->p_filter; -  int p_stride = qmf->p_stride; -  int j; -  FIXP_QSS *RESTRICT sta = FilterStates; -  const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; -  int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor); - -  p_flt  = p_Filter+p_stride*QMF_NO_POLY;          /*                     5-ter von 330 */ -  p_fltm = p_Filter+(qmf->FilterSize/2)-p_stride*QMF_NO_POLY;  /* 5 + (320 - 2*5) = 315-ter von 330 */ - -  FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0); - -  for (j = no_channels-1; j >= 0; j--) {  /* ---- läuft ueber alle Linien eines Slots ---- */ -    FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0 -    FIXP_QMF real  =  realSlot[j];  // ~~"~~ -    { -      INT_PCM tmp; -      FIXP_DBL Are = FX_QSS2FX_DBL(sta[0]) + fMultDiv2( p_fltm[0] , real); - -      if (qmf->outGain!=(FIXP_DBL)0x80000000) { -        Are = fMult(Are,qmf->outGain); -      } - -  #if SAMPLE_BITS > 16 -      tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS)); -  #else -      tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS)); -  #endif -      if (Are < (FIXP_QMF)0) { -        tmp = -tmp; -      } -      timeOut[ (j)*stride ] = tmp; -    } - -    sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag )); -    sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real )); -    sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag )); -    sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real )); -    sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag )); -    sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real )); -    sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag )); -    sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real )); -    sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag )); - -    p_flt  += (p_stride*QMF_NO_POLY); -    p_fltm -= (p_stride*QMF_NO_POLY); -    sta    += 9; // = (2*QMF_NO_POLY-1); -  } -} - -#ifndef FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric -/*! -  \brief Perform Synthesis Prototype Filtering on a single slot of input data. - -  The filter takes 2 * qmf->no_channels of input data and -  generates qmf->no_channels time domain output samples. -*/ -static -void qmfSynPrototypeFirSlot_NonSymmetric( -                             HANDLE_QMF_FILTER_BANK qmf, -                             FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */ -                             FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */ -                             INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */ -                             int       stride -                            ) -{ -  FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates; -  int       no_channels = qmf->no_channels; -  const FIXP_PFT *p_Filter = qmf->p_filter; -  int p_stride = qmf->p_stride; -  int j; -  FIXP_QSS *RESTRICT sta = FilterStates; -  const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; -  int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor); - -  p_flt  = p_Filter;                           /*!< Pointer to first half of filter coefficients */ -  p_fltm = &p_flt[qmf->FilterSize/2];  /* at index 320, overall 640 coefficients */ - -  FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0); - -  for (j = no_channels-1; j >= 0; j--) {  /* ---- läuft ueber alle Linien eines Slots ---- */ - -    FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0 -    FIXP_QMF real  =  realSlot[j];  // ~~"~~ -    { -      INT_PCM tmp; -      FIXP_QMF Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real )); - -  #if SAMPLE_BITS > 16 -      tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS)); -  #else -      tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS)); -  #endif -      if (Are < (FIXP_QMF)0) { -        tmp = -tmp; -      } -      timeOut[j*stride] = tmp; -    } - -    sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag )); -    sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real )); -    sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag )); - -    sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real )); -    sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag )); -    sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real )); -    sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag )); - -    sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[0] , real )); -    sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag )); - -    p_flt  += (p_stride*QMF_NO_POLY); -    p_fltm += (p_stride*QMF_NO_POLY); -    sta    += 9; // = (2*QMF_NO_POLY-1); -  } - -} -#endif /* FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric */ - -#ifndef FUNCTION_qmfAnaPrototypeFirSlot -/*! -  \brief Perform Analysis Prototype Filtering on a single slot of input data. -*/ -static -void qmfAnaPrototypeFirSlot( FIXP_QMF *analysisBuffer, -                             int       no_channels,             /*!< Number channels of analysis filter */ -                             const FIXP_PFT *p_filter, -                             int       p_stride,                /*!< Stide of analysis filter    */ -                             FIXP_QAS *RESTRICT pFilterStates -                            ) -{ -    int k; - -    FIXP_DBL accu; -    const FIXP_PFT *RESTRICT p_flt = p_filter; -    FIXP_QMF *RESTRICT pData_0 = analysisBuffer + 2*no_channels - 1; -    FIXP_QMF *RESTRICT pData_1 = analysisBuffer; - -    FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates; -    FIXP_QAS *RESTRICT sta_1 = (FIXP_QAS *)pFilterStates + (2*QMF_NO_POLY*no_channels) - 1; -    int pfltStep = QMF_NO_POLY * (p_stride); -    int staStep1 = no_channels<<1; -    int staStep2 = (no_channels<<3) - 1; /* Rewind one less */ - -    /* FIR filter 0 */ -    accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1; -    accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1; -    accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1; -    accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1; -    accu +=  fMultDiv2( p_flt[4], *sta_1); -    *pData_1++ = FX_DBL2FX_QMF(accu<<1); -    sta_1 += staStep2; - -    p_flt += pfltStep; - -    /* FIR filters 1..63 127..65 */ -    for (k=0; k<no_channels-1; k++) -    { -      accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1; -      accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1; -      accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1; -      accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1; -      accu += fMultDiv2( p_flt[4], *sta_0); -      *pData_0-- = FX_DBL2FX_QMF(accu<<1); -      sta_0 -= staStep2; - -      accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1; -      accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1; -      accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1; -      accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1; -      accu +=  fMultDiv2( p_flt[4], *sta_1); -      *pData_1++ = FX_DBL2FX_QMF(accu<<1); -      sta_1 += staStep2; - -      p_flt += pfltStep; -    } - -    /* FIR filter 64 */ -    accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1; -    accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1; -    accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1; -    accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1; -    accu += fMultDiv2( p_flt[4], *sta_0); -    *pData_0-- = FX_DBL2FX_QMF(accu<<1); -    sta_0 -= staStep2; -} -#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */ - - -#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric -/*! -  \brief Perform Analysis Prototype Filtering on a single slot of input data. -*/ -static -void qmfAnaPrototypeFirSlot_NonSymmetric( -                                        FIXP_QMF *analysisBuffer, -                                        int       no_channels,             /*!< Number channels of analysis filter */ -                                        const FIXP_PFT *p_filter, -                                        int       p_stride,                /*!< Stide of analysis filter    */ -                                        FIXP_QAS *RESTRICT pFilterStates -                                       ) -{ -  const FIXP_PFT *RESTRICT p_flt = p_filter; -  int  p, k; - -  for (k = 0; k < 2*no_channels; k++) -  { -    FIXP_DBL accu = (FIXP_DBL)0; - -    p_flt += QMF_NO_POLY * (p_stride - 1); - -    /* -      Perform FIR-Filter -    */ -    for (p = 0; p < QMF_NO_POLY; p++) { -      accu +=  fMultDiv2(*p_flt++, pFilterStates[2*no_channels * p]); -    } -    analysisBuffer[2*no_channels - 1 - k] = FX_DBL2FX_QMF(accu<<1); -    pFilterStates++; -  } -} -#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */ - -/*! - * - * \brief Perform real-valued forward modulation of the time domain - *        data of timeIn and stores the real part of the subband - *        samples in rSubband - * - */ -static void -qmfForwardModulationLP_even( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */ -                             FIXP_QMF *timeIn,              /*!< Time Signal */ -                             FIXP_QMF *rSubband )           /*!< Real Output */ -{ -  int i; -  int L = anaQmf->no_channels; -  int M = L>>1; -  int scale; -  FIXP_QMF accu; - -  const FIXP_QMF *timeInTmp1 = (FIXP_QMF *) &timeIn[3 * M]; -  const FIXP_QMF *timeInTmp2 = timeInTmp1; -  FIXP_QMF *rSubbandTmp = rSubband; - -  rSubband[0] = timeIn[3 * M] >> 1; - -  for (i = M-1; i != 0; i--) { -    accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1); -    *++rSubbandTmp = accu; -  } - -  timeInTmp1 = &timeIn[2 * M]; -  timeInTmp2 = &timeIn[0]; -  rSubbandTmp = &rSubband[M]; - -  for (i = L-M; i != 0; i--) { -    accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1); -    *rSubbandTmp++ = accu; -  } - -  dct_III(rSubband, timeIn, L, &scale); -} - -#if !defined(FUNCTION_qmfForwardModulationLP_odd) -static void -qmfForwardModulationLP_odd( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */ -                            const FIXP_QMF *timeIn,        /*!< Time Signal */ -                            FIXP_QMF *rSubband )           /*!< Real Output */ -{ -  int i; -  int L = anaQmf->no_channels; -  int M = L>>1; -  int shift = (anaQmf->no_channels>>6) + 1; - -  for (i = 0; i < M; i++) { -    rSubband[M + i]     = (timeIn[L - 1 - i]>>1) - (timeIn[i]>>shift); -    rSubband[M - 1 - i] = (timeIn[L + i]>>1)     + (timeIn[2 * L - 1 - i]>>shift); -  } - -  dct_IV(rSubband, L, &shift); -} -#endif /* !defined(FUNCTION_qmfForwardModulationLP_odd) */ - - - -/*! - * - * \brief Perform complex-valued forward modulation of the time domain - *        data of timeIn and stores the real part of the subband - *        samples in rSubband, and the imaginary part in iSubband - * - *        Only the lower bands are obtained (upto anaQmf->lsb). For - *        a full bandwidth analysis it is required to set both anaQmf->lsb - *        and anaQmf->usb to the amount of QMF bands. - * - */ -static void -qmfForwardModulationHQ( HANDLE_QMF_FILTER_BANK anaQmf,     /*!< Handle of Qmf Analysis Bank  */ -                        const FIXP_QMF *RESTRICT timeIn,   /*!< Time Signal */ -                        FIXP_QMF *RESTRICT rSubband,       /*!< Real Output */ -                        FIXP_QMF *RESTRICT iSubband        /*!< Imaginary Output */ -                       ) -{ -  int i; -  int L = anaQmf->no_channels; -  int L2 = L<<1; -  int shift = 0; - -  for (i = 0; i < L; i+=2) { -    FIXP_QMF x0, x1, y0, y1; - -    x0 = timeIn[i] >> 1; -    x1 = timeIn[i+1] >> 1; -    y0 = timeIn[L2 - 1 - i] >> 1; -    y1 = timeIn[L2 - 2 - i] >> 1; - -    rSubband[i] = x0 - y0; -    rSubband[i+1] = x1 - y1; -    iSubband[i] = x0 + y0; -    iSubband[i+1] = x1 + y1; -  } - -  dct_IV(rSubband, L, &shift); -  dst_IV(iSubband, L, &shift); - -  { -    { -      const FIXP_QTW *RESTRICT sbr_t_cos; -      const FIXP_QTW *RESTRICT sbr_t_sin; -      sbr_t_cos = anaQmf->t_cos; -      sbr_t_sin = anaQmf->t_sin; - -      for (i = 0; i < anaQmf->lsb; i++) { -        cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i], sbr_t_cos[i], sbr_t_sin[i]); -      } -    } -  } -} - -/* - * \brief Perform one QMF slot analysis of the time domain data of timeIn - *        with specified stride and stores the real part of the subband - *        samples in rSubband, and the imaginary part in iSubband - * - *        Only the lower bands are obtained (upto anaQmf->lsb). For - *        a full bandwidth analysis it is required to set both anaQmf->lsb - *        and anaQmf->usb to the amount of QMF bands. - */ -void -qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf,  /*!< Handle of Qmf Synthesis Bank  */ -                          FIXP_QMF      *qmfReal,         /*!< Low and High band, real */ -                          FIXP_QMF      *qmfImag,         /*!< Low and High band, imag */ -                          const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */ -                          const int      stride,          /*!< stride factor of input */ -                          FIXP_QMF      *pWorkBuffer      /*!< pointer to temporal working buffer */ -                         ) -{ -    int i; -    int offset = anaQmf->no_channels*(QMF_NO_POLY*2-1); -    /* -      Feed time signal into oldest anaQmf->no_channels states -    */ -    { -      FIXP_QAS *RESTRICT FilterStatesAnaTmp = ((FIXP_QAS*)anaQmf->FilterStates)+offset; - -      /* Feed and scale actual time in slot */ -      for(i=anaQmf->no_channels>>1; i!=0; i--) { -        /* Place INT_PCM value left aligned in scaledTimeIn */ -#if (QAS_BITS==SAMPLE_BITS) -        *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride; -        *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride; -#elif (QAS_BITS>SAMPLE_BITS) -        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride; -        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride; -#else -        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride; -        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride; -#endif -      } -    } - -    if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { -      qmfAnaPrototypeFirSlot_NonSymmetric( -                              pWorkBuffer, -                              anaQmf->no_channels, -                              anaQmf->p_filter, -                              anaQmf->p_stride, -                              (FIXP_QAS*)anaQmf->FilterStates -                            ); -    } else { -      qmfAnaPrototypeFirSlot( pWorkBuffer, -                              anaQmf->no_channels, -                              anaQmf->p_filter, -                              anaQmf->p_stride, -                              (FIXP_QAS*)anaQmf->FilterStates -                            ); -    } - -    if (anaQmf->flags & QMF_FLAG_LP) { -      if (anaQmf->flags & QMF_FLAG_CLDFB) -        qmfForwardModulationLP_odd( anaQmf, -                                    pWorkBuffer, -                                    qmfReal ); -      else -        qmfForwardModulationLP_even( anaQmf, -                                     pWorkBuffer, -                                     qmfReal ); - -    } else { -      qmfForwardModulationHQ( anaQmf, -                              pWorkBuffer, -                              qmfReal, -                              qmfImag -                             ); -    } -    /* -      Shift filter states - -      Should be realized with modulo adressing on a DSP instead of a true buffer shift -    */ -    FDKmemmove ((FIXP_QAS*)anaQmf->FilterStates, (FIXP_QAS*)anaQmf->FilterStates+anaQmf->no_channels, offset*sizeof(FIXP_QAS)); -} - - -/*! - * - * \brief Perform complex-valued subband filtering of the time domain - *        data of timeIn and stores the real part of the subband - *        samples in rAnalysis, and the imaginary part in iAnalysis - * The qmf coefficient table is symmetric. The symmetry is expoited by - * shrinking the coefficient table to half the size. The addressing mode - * takes care of the symmetries. - * - * Only the lower bands are obtained (upto anaQmf->lsb). For - * a full bandwidth analysis it is required to set both anaQmf->lsb - * and anaQmf->usb to the amount of QMF bands. - * - * \sa PolyphaseFiltering - */ - -void -qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf,    /*!< Handle of Qmf Analysis Bank */ -                      FIXP_QMF **qmfReal,               /*!< Pointer to real subband slots */ -                      FIXP_QMF **qmfImag,               /*!< Pointer to imag subband slots */ -                      QMF_SCALE_FACTOR *scaleFactor, -                      const INT_PCM *timeIn,            /*!< Time signal */ -                      const int  stride, -                      FIXP_QMF  *pWorkBuffer            /*!< pointer to temporal working buffer */ -                      ) -{ -  int i; -  int no_channels = anaQmf->no_channels; - -  scaleFactor->lb_scale = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK; -  scaleFactor->lb_scale -= anaQmf->filterScale; - -  for (i = 0; i < anaQmf->no_col; i++) -  { -      FIXP_QMF *qmfImagSlot = NULL; - -      if (!(anaQmf->flags & QMF_FLAG_LP)) { -        qmfImagSlot = qmfImag[i]; -      } - -      qmfAnalysisFilteringSlot( anaQmf, qmfReal[i], qmfImagSlot, timeIn , stride, pWorkBuffer ); - -      timeIn += no_channels*stride; - -  } /* no_col loop  i  */ -} - -/*! - * - * \brief Perform low power inverse modulation of the subband - *        samples stored in rSubband (real part) and iSubband (imaginary - *        part) and stores the result in pWorkBuffer. - * - */ -inline -static void -qmfInverseModulationLP_even( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */ -                             const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */ -                             const int   scaleFactorLowBand,  /*!< Scalefactor for Low band */ -                             const int   scaleFactorHighBand, /*!< Scalefactor for High band */ -                             FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/ -                           ) -{ -  int i; -  int L = synQmf->no_channels; -  int M = L>>1; -  int scale; -  FIXP_QMF tmp; -  FIXP_QMF *RESTRICT tReal = pTimeOut; -  FIXP_QMF *RESTRICT tImag = pTimeOut + L; - -  /* Move input to output vector with offset */ -  scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand); -  scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand); -  FDKmemclear(&tReal[0+synQmf->usb], (L-synQmf->usb)*sizeof(FIXP_QMF)); - -  /* Dct type-2 transform */ -  dct_II(tReal, tImag, L, &scale); - -  /* Expand output and replace inplace the output buffers */ -  tImag[0] = tReal[M]; -  tImag[M] = (FIXP_QMF)0; -  tmp = tReal [0]; -  tReal [0] = tReal[M]; -  tReal [M] = tmp; - -  for (i = 1; i < M/2; i++) { -    /* Imag */ -    tmp = tReal[L - i]; -    tImag[M - i] =  tmp; -    tImag[i + M] = -tmp; - -    tmp = tReal[M + i]; -    tImag[i] =  tmp; -    tImag[L - i] = -tmp; - -    /* Real */ -    tReal [M + i] = tReal[i]; -    tReal [L - i] = tReal[M - i]; -    tmp = tReal[i]; -    tReal[i] = tReal [M - i]; -    tReal [M - i] = tmp; - -  } -  /* Remaining odd terms */ -  tmp = tReal[M + M/2]; -  tImag[M/2]     =  tmp; -  tImag[M/2 + M] = -tmp; - -  tReal [M + M/2] = tReal[M/2]; -} - -inline -static void -qmfInverseModulationLP_odd( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */ -                            const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */ -                            const int scaleFactorLowBand,    /*!< Scalefactor for Low band */ -                            const int scaleFactorHighBand,   /*!< Scalefactor for High band */ -                            FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/ -                          ) -{ -  int i; -  int L = synQmf->no_channels; -  int M = L>>1; -  int shift = 0; - -  /* Move input to output vector with offset */ -  scaleValues(pTimeOut+M,              qmfReal,             synQmf->lsb,             scaleFactorLowBand); -  scaleValues(pTimeOut+M+synQmf->lsb,  qmfReal+synQmf->lsb, synQmf->usb-synQmf->lsb, scaleFactorHighBand); -  FDKmemclear(pTimeOut+M+synQmf->usb, (L-synQmf->usb)*sizeof(FIXP_QMF)); - -  dct_IV(pTimeOut+M, L, &shift); -  for (i = 0; i < M; i++) { -    pTimeOut[i]             =  pTimeOut[L - 1 - i]; -    pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i]; -  } -} - - -/*! - * - * \brief Perform complex-valued inverse modulation of the subband - *        samples stored in rSubband (real part) and iSubband (imaginary - *        part) and stores the result in pWorkBuffer. - * - */ -inline -static void -qmfInverseModulationHQ( HANDLE_QMF_FILTER_BANK synQmf,  /*!< Handle of Qmf Synthesis Bank     */ -                        const FIXP_QMF *qmfReal,        /*!< Pointer to qmf real subband slot */ -                        const FIXP_QMF *qmfImag,        /*!< Pointer to qmf imag subband slot */ -                        const int   scaleFactorLowBand, /*!< Scalefactor for Low band         */ -                        const int   scaleFactorHighBand,/*!< Scalefactor for High band        */ -                        FIXP_QMF  *pWorkBuffer          /*!< WorkBuffer (output)              */ -                      ) -{ -  int i; -  int L = synQmf->no_channels; -  int M = L>>1; -  int shift = 0; -  FIXP_QMF *RESTRICT tReal = pWorkBuffer; -  FIXP_QMF *RESTRICT tImag = pWorkBuffer+L; - -  if (synQmf->flags & QMF_FLAG_CLDFB){ -    for (i = 0; i < synQmf->lsb; i++) { -      cplxMult(&tImag[i], &tReal[i], -                scaleValue(qmfImag[i],scaleFactorLowBand), scaleValue(qmfReal[i],scaleFactorLowBand), -                synQmf->t_cos[i], synQmf->t_sin[i]); -    } -    for (; i < synQmf->usb; i++) { -      cplxMult(&tImag[i], &tReal[i], -                scaleValue(qmfImag[i],scaleFactorHighBand), scaleValue(qmfReal[i],scaleFactorHighBand), -                synQmf->t_cos[i], synQmf->t_sin[i]); -    } -  } - -  if ( (synQmf->flags & QMF_FLAG_CLDFB) == 0) { -    scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand); -    scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand); -    scaleValues(&tImag[0],             &qmfImag[0],             synQmf->lsb,             scaleFactorLowBand); -    scaleValues(&tImag[0+synQmf->lsb], &qmfImag[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand); -  } - -  FDKmemclear(&tReal[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF)); -  FDKmemclear(&tImag[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF)); - -  dct_IV(tReal, L, &shift); -  dst_IV(tImag, L, &shift); - -  if (synQmf->flags & QMF_FLAG_CLDFB){ -    for (i = 0; i < M; i++) { -      FIXP_QMF r1, i1, r2, i2; -      r1 = tReal[i]; -      i2 = tImag[L - 1 - i]; -      r2 = tReal[L - i - 1]; -      i1 = tImag[i]; - -      tReal[i] = (r1 - i1)>>1; -      tImag[L - 1 - i] = -(r1 + i1)>>1; -      tReal[L - i - 1] =  (r2 - i2)>>1; -      tImag[i] = -(r2 + i2)>>1; -    } -  } else -  { -    /* The array accesses are negative to compensate the missing minus sign in the low and hi band gain. */ -    /* 26 cycles on ARM926 */ -    for (i = 0; i < M; i++) { -      FIXP_QMF r1, i1, r2, i2; -      r1 = -tReal[i]; -      i2 = -tImag[L - 1 - i]; -      r2 = -tReal[L - i - 1]; -      i1 = -tImag[i]; - -      tReal[i] = (r1 - i1)>>1; -      tImag[L - 1 - i] = -(r1 + i1)>>1; -      tReal[L - i - 1] =  (r2 - i2)>>1; -      tImag[i] = -(r2 + i2)>>1; -    } -  } -} - -void qmfSynthesisFilteringSlot( HANDLE_QMF_FILTER_BANK  synQmf, -                                const FIXP_QMF  *realSlot, -                                const FIXP_QMF  *imagSlot, -                                const int        scaleFactorLowBand, -                                const int        scaleFactorHighBand, -                                INT_PCM         *timeOut, -                                const int        stride, -                                FIXP_QMF        *pWorkBuffer) -{ -    if (!(synQmf->flags & QMF_FLAG_LP)) -      qmfInverseModulationHQ ( synQmf, -                               realSlot, -                               imagSlot, -                               scaleFactorLowBand, -                               scaleFactorHighBand, -                               pWorkBuffer -                             ); -    else -    { -      if (synQmf->flags & QMF_FLAG_CLDFB) { -        qmfInverseModulationLP_odd ( synQmf, -                                 realSlot, -                                 scaleFactorLowBand, -                                 scaleFactorHighBand, -                                 pWorkBuffer -                               ); -      } else { -        qmfInverseModulationLP_even ( synQmf, -                                 realSlot, -                                 scaleFactorLowBand, -                                 scaleFactorHighBand, -                                 pWorkBuffer -                               ); -      } -    } - -    if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) { -        qmfSynPrototypeFirSlot_NonSymmetric ( -                                 synQmf, -                                 pWorkBuffer, -                                 pWorkBuffer+synQmf->no_channels, -                                 timeOut, -                                 stride -                               ); -    } else { -        qmfSynPrototypeFirSlot ( synQmf, -                                 pWorkBuffer, -                                 pWorkBuffer+synQmf->no_channels, -                                 timeOut, -                                 stride -                               ); -    } -} - - -/*! - * - * - * \brief Perform complex-valued subband synthesis of the - *        low band and the high band and store the - *        time domain data in timeOut - * - * First step: Calculate the proper scaling factor of current - * spectral data in qmfReal/qmfImag, old spectral data in the overlap - * range and filter states. - * - * Second step: Perform Frequency-to-Time mapping with inverse - * Modulation slot-wise. - * - * Third step: Perform FIR-filter slot-wise. To save space for filter - * states, the MAC operations are executed directly on the filter states - * instead of accumulating several products in the accumulator. The - * buffer shift at the end of the function should be replaced by a - * modulo operation, which is available on some DSPs. - * - * Last step: Copy the upper part of the spectral data to the overlap buffer. - * - * The qmf coefficient table is symmetric. The symmetry is exploited by - * shrinking the coefficient table to half the size. The addressing mode - * takes care of the symmetries.  If the #define #QMFTABLE_FULL is set, - * coefficient addressing works on the full table size. The code will be - * slightly faster and slightly more compact. - * - * Workbuffer requirement: 2 x sizeof(**QmfBufferReal) * synQmf->no_channels - */ -void -qmfSynthesisFiltering( HANDLE_QMF_FILTER_BANK synQmf,       /*!< Handle of Qmf Synthesis Bank  */ -                       FIXP_QMF  **QmfBufferReal,           /*!< Low and High band, real */ -                       FIXP_QMF  **QmfBufferImag,           /*!< Low and High band, imag */ -                       const QMF_SCALE_FACTOR *scaleFactor, -                       const INT   ov_len,                  /*!< split Slot of overlap and actual slots */ -                       INT_PCM    *timeOut,                 /*!< Pointer to output */ -                       const INT   stride,                  /*!< stride factor of output */ -                       FIXP_QMF   *pWorkBuffer              /*!< pointer to temporal working buffer */ -                      ) -{ -  int i; -  int L = synQmf->no_channels; -  SCHAR scaleFactorHighBand; -  SCHAR scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; - -  /* adapt scaling */ -  scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->hb_scale; -  scaleFactorLowBand_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->ov_lb_scale; -  scaleFactorLowBand_no_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->lb_scale; - -  for (i = 0; i < synQmf->no_col; i++)  /* ----- no_col loop ----- */ -  { -    const FIXP_DBL *QmfBufferImagSlot = NULL; - -    SCHAR scaleFactorLowBand = (i<ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov; - -    if (!(synQmf->flags & QMF_FLAG_LP)) -        QmfBufferImagSlot = QmfBufferImag[i]; - -    qmfSynthesisFilteringSlot(  synQmf, -                                QmfBufferReal[i], -                                QmfBufferImagSlot, -                                scaleFactorLowBand, -                                scaleFactorHighBand, -                                timeOut+(i*L*stride), -                                stride, -                                pWorkBuffer); -  } /* no_col loop  i  */ - -} - - -/*! - * - * \brief Create QMF filter bank instance - * - * \return 0 if successful - * - */ -static int -qmfInitFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,     /*!< Handle to return */ -                   void *pFilterStates,              /*!< Handle to filter states */ -                   int noCols,                       /*!< Number of timeslots per frame */ -                   int lsb,                          /*!< Lower end of QMF frequency range */ -                   int usb,                          /*!< Upper end of QMF frequency range */ -                   int no_channels,                  /*!< Number of channels (bands) */ -                   UINT flags)                       /*!< flags */ -{ -  FDKmemclear(h_Qmf,sizeof(QMF_FILTER_BANK)); - -  if (flags & QMF_FLAG_MPSLDFB) -  { -    return -1; -  } - -  if ( !(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB) ) -  { -    flags |= QMF_FLAG_NONSYMMETRIC; -    h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE; - -    h_Qmf->p_stride = 1; -    switch (no_channels) { -      case 64: -        h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb; -        h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb; -        h_Qmf->p_filter = qmf_cldfb_640; -        h_Qmf->FilterSize = 640; -        break; -      case 32: -        h_Qmf->t_cos = qmf_phaseshift_cos32_cldfb; -        h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb; -        h_Qmf->p_filter = qmf_cldfb_320; -        h_Qmf->FilterSize = 320; -        break; -      default: -        return -1; -    } -  } - -  if ( !(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0) ) -  { -    switch (no_channels) { -      case 64: -        h_Qmf->p_filter = qmf_64; -        h_Qmf->t_cos = qmf_phaseshift_cos64; -        h_Qmf->t_sin = qmf_phaseshift_sin64; -        h_Qmf->p_stride = 1; -        h_Qmf->FilterSize = 640; -        h_Qmf->filterScale = 0; -        break; -      case 32: -        h_Qmf->p_filter = qmf_64; -        if (flags & QMF_FLAG_DOWNSAMPLED) { -          h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32; -          h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32; -        } -        else { -        h_Qmf->t_cos = qmf_phaseshift_cos32; -        h_Qmf->t_sin = qmf_phaseshift_sin32; -        } -        h_Qmf->p_stride = 2; -        h_Qmf->FilterSize = 640; -        h_Qmf->filterScale = 0; -        break; -      default: -        return -1; -    } -  } - -  h_Qmf->flags = flags; - -  h_Qmf->no_channels = no_channels; -  h_Qmf->no_col = noCols; - -  h_Qmf->lsb = lsb; -  h_Qmf->usb = fMin(usb, h_Qmf->no_channels); - -  h_Qmf->FilterStates = (void*)pFilterStates; - -  h_Qmf->outScalefactor = ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + h_Qmf->filterScale; - -  if ( (h_Qmf->p_stride == 2) -    || ((flags & QMF_FLAG_CLDFB) && (no_channels == 32)) ) { -    h_Qmf->outScalefactor -= 1; -  } -  h_Qmf->outGain = (FIXP_DBL)0x80000000; /* default init value will be not applied */ - -  return (0); -} - -/*! - * - * \brief Adjust synthesis qmf filter states - * - * \return void - * - */ -static inline void -qmfAdaptFilterStates (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Filter Bank */ -                      int scaleFactorDiff)               /*!< Scale factor difference to be applied */ -{ -  if (synQmf == NULL || synQmf->FilterStates == NULL) { -    return; -  } -  scaleValues((FIXP_QSS*)synQmf->FilterStates, synQmf->no_channels*(QMF_NO_POLY*2 - 1), scaleFactorDiff); -} - -/*! - * - * \brief Create QMF filter bank instance - * - * Only the lower bands are obtained (upto anaQmf->lsb). For - * a full bandwidth analysis it is required to set both anaQmf->lsb - * and anaQmf->usb to the amount of QMF bands. - * - * \return 0 if succesful - * - */ -int -qmfInitAnalysisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */ -                           FIXP_QAS *pFilterStates,        /*!< Handle to filter states */ -                           int noCols,                     /*!< Number of timeslots per frame */ -                           int lsb,                        /*!< lower end of QMF */ -                           int usb,                        /*!< upper end of QMF */ -                           int no_channels,                /*!< Number of channels (bands) */ -                           int flags)                      /*!< Low Power flag */ -{ -  int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags); -  if ( !(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL) ) { -    FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QAS)); -  } - -  return err; -} - -/*! - * - * \brief Create QMF filter bank instance - * - * Only the lower bands are obtained (upto anaQmf->lsb). For - * a full bandwidth analysis it is required to set both anaQmf->lsb - * and anaQmf->usb to the amount of QMF bands. - * - * \return 0 if succesful - * - */ -int -qmfInitSynthesisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */ -                            FIXP_QSS *pFilterStates,        /*!< Handle to filter states */ -                            int noCols,                     /*!< Number of timeslots per frame */ -                            int lsb,                        /*!< lower end of QMF */ -                            int usb,                        /*!< upper end of QMF */ -                            int no_channels,                /*!< Number of channels (bands) */ -                            int flags)                      /*!< Low Power flag */ -{ -  int oldOutScale = h_Qmf->outScalefactor; -  int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags); -  if ( h_Qmf->FilterStates != NULL ) { -    if ( !(flags & QMF_FLAG_KEEP_STATES) ) { -      FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QSS)); -    } else { -      qmfAdaptFilterStates(h_Qmf, oldOutScale-h_Qmf->outScalefactor); -    } -  } -  return err; -} - - - - -/*! - * - * \brief Change scale factor for output data and adjust qmf filter states - * - * \return void - * - */ -void -qmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */ -                         int outScalefactor                 /*!< New scaling factor for output data */ -                        ) -{ -  if (synQmf == NULL || synQmf->FilterStates == NULL) { -    return; -  } - -  /* Add internal filterbank scale */ -  outScalefactor += ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + synQmf->filterScale; - -  if ( (synQmf->p_stride == 2) -    || ((synQmf->flags & QMF_FLAG_CLDFB) && (synQmf->no_channels == 32)) ) { -    outScalefactor -= 1; -  } - -  /* adjust filter states when scale factor has been changed */ -  if (synQmf->outScalefactor != outScalefactor) -  { -    int diff; - -    if (outScalefactor > (SAMPLE_BITS - 1)) { -      outScalefactor = SAMPLE_BITS - 1; -    } else if (outScalefactor < (1 - SAMPLE_BITS)) { -      outScalefactor = 1 - SAMPLE_BITS; -    } - -    diff = synQmf->outScalefactor - outScalefactor; - -    qmfAdaptFilterStates(synQmf, diff); - -    /* save new scale factor */ -    synQmf->outScalefactor = outScalefactor; -  } -} - -/*! - * - * \brief Change gain for output data - * - * \return void - * - */ -void -qmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */ -                  FIXP_DBL outputGain                /*!< New gain for output data */ -                 ) -{ -  synQmf->outGain = outputGain; -} - | 
