qmf.cpp revision 381d69840ad3af2259f0b7ef49236f9ee9c76b76
12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* -----------------------------------------------------------------------------------------------------------
32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android
42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
52228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project� Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  All rights reserved.
72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1.    INTRODUCTION
92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices.
122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications.
172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with
212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only.
242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation.
282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2.    COPYRIGHT LICENSE
302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without
322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions:
332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or
352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form.
362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials
382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your
402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form.
412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without
432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission.
442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto.
472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term
502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3.    NO PATENT LICENSE
542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software.
582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses.
612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4.    DISCLAIMER
632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits,
692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict
702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if
712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage.
722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5.    CONTACT INFORMATION
742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS
762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL
772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33
782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany
792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm
812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de
822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */
832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/********************************  Fraunhofer IIS  ***************************
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Author(s):   Markus Lohwasser, Josef Hoepfl, Manuel Jander
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Description: QMF filterbank
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project******************************************************************************/
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \file
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief  Complex qmf analysis/synthesis,
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This module contains the qmf filterbank for analysis [ cplxAnalysisQmfFiltering() ] and
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  synthesis [ cplxSynthesisQmfFiltering() ]. It is a polyphase implementation of a complex
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  exponential modulated filter bank. The analysis part usually runs at half the sample rate
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  than the synthesis part. (So called "dual-rate" mode.)
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The coefficients of the prototype filter are specified in #sbr_qmf_64_640 (in sbr_rom.cpp).
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Thus only a 64 channel version (32 on the analysis side) with a 640 tap prototype filter
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  are used.
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \anchor PolyphaseFiltering <h2>About polyphase filtering</h2>
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The polyphase implementation of a filterbank requires filtering at the input and output.
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This is implemented as part of cplxAnalysisQmfFiltering() and cplxSynthesisQmfFiltering().
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The implementation requires the filter coefficients in a specific structure as described in
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #sbr_qmf_64_640_qmf (in sbr_rom.cpp).
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This module comprises the computationally most expensive functions of the SBR decoder. The accuracy of
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  computations is also important and has a direct impact on the overall sound quality. Therefore a special
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  test program is available which can be used to only test the filterbank: main_audio.cpp
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  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.
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  An interesting note: The function getScalefactor() can constitute a significant amount of computational complexity - very much depending on the
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  bitrate. Since it is a rather small function, effective assembler optimization might be possible.
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "qmf.h"
1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "fixpoint_math.h"
1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "dct.h"
1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef QMFSYN_STATES_16BIT
1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define QSSCALE (7)
1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define FX_DBL2FX_QSS(x) ((FIXP_QSS) ((x)>>(DFRACT_BITS-QSS_BITS-QSSCALE) ))
1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define FX_QSS2FX_DBL(x) ((FIXP_DBL)((LONG)x)<<(DFRACT_BITS-QSS_BITS-QSSCALE))
1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define QSSCALE (0)
1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define FX_DBL2FX_QSS(x) (x)
1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define FX_QSS2FX_DBL(x) (x)
1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if defined(__arm__)
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "arm/qmf_arm.cpp"
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Algorithmic scaling in sbrForwardModulation()
1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The scaling in sbrForwardModulation() is caused by:
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li 1 R_SHIFT in sbrForwardModulation()
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li 5/6 R_SHIFT in dct3() if using 32/64 Bands
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li 1 ommited gain of 2.0 in qmfForwardModulation()
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK 7
1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Algorithmic scaling in cplxSynthesisQmfFiltering()
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The scaling in cplxSynthesisQmfFiltering() is caused by:
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li  5/6 R_SHIFT in dct2() if using 32/64 Bands
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li  1 ommited gain of 2.0 in qmfInverseModulation()
1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li -6 division by 64 in synthesis filterbank
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *   \li x bits external influence
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK 1
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Perform Synthesis Prototype Filtering on a single slot of input data.
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The filter takes 2 * qmf->no_channels of input data and
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  generates qmf->no_channels time domain output samples.
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_qmfSynPrototypeFirSlot
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfSynPrototypeFirSlot(
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfSynPrototypeFirSlot_fallback(
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             HANDLE_QMF_FILTER_BANK qmf,
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             int       stride
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            )
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates;
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int       no_channels = qmf->no_channels;
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_PFT *p_Filter = qmf->p_filter;
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int p_stride = qmf->p_stride;
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int j;
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QSS *RESTRICT sta = FilterStates;
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor);
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  p_flt  = p_Filter+p_stride*QMF_NO_POLY;          /*                     5-ter von 330 */
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  p_fltm = p_Filter+(qmf->FilterSize/2)-p_stride*QMF_NO_POLY;  /* 5 + (320 - 2*5) = 315-ter von 330 */
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0);
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (j = no_channels-1; j >= 0; j--) {  /* ---- l�uft ueber alle Linien eines Slots ---- */
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF real  =  realSlot[j];  // ~~"~~
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT_PCM tmp;
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_DBL Are = FX_QSS2FX_DBL(sta[0]) + fMultDiv2( p_fltm[0] , real);
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (qmf->outGain!=(FIXP_DBL)0x80000000) {
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        Are = fMult(Are,qmf->outGain);
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #if SAMPLE_BITS > 16
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #else
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #endif
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (Are < (FIXP_QMF)0) {
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        tmp = -tmp;
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      timeOut[ (j)*stride ] = tmp;
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag ));
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real ));
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag ));
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real ));
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag ));
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real ));
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag ));
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real ));
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag ));
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_flt  += (p_stride*QMF_NO_POLY);
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_fltm -= (p_stride*QMF_NO_POLY);
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta    += 9; // = (2*QMF_NO_POLY-1);
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Perform Synthesis Prototype Filtering on a single slot of input data.
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The filter takes 2 * qmf->no_channels of input data and
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  generates qmf->no_channels time domain output samples.
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfSynPrototypeFirSlot_NonSymmetric(
2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             HANDLE_QMF_FILTER_BANK qmf,
2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */
2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */
2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */
2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             int       stride
2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            )
2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QSS* FilterStates = (FIXP_QSS*)qmf->FilterStates;
2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int       no_channels = qmf->no_channels;
2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_PFT *p_Filter = qmf->p_filter;
2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int p_stride = qmf->p_stride;
2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int j;
2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QSS *RESTRICT sta = FilterStates;
2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor);
2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  p_flt  = p_Filter;                           /*!< Pointer to first half of filter coefficients */
2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  p_fltm = &p_flt[qmf->FilterSize/2];  /* at index 320, overall 640 coefficients */
2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0);
2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (j = no_channels-1; j >= 0; j--) {  /* ---- l�uft ueber alle Linien eines Slots ---- */
2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF imag  =  imagSlot[j];  // no_channels-1 .. 0
2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF real  =  realSlot[j];  // ~~"~~
2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT_PCM tmp;
2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_QMF Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[4] , real ));
2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #if SAMPLE_BITS > 16
2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tmp = (INT_PCM)(SATURATE_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #else
2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tmp = (INT_PCM)(SATURATE_RIGHT_SHIFT(fAbs(Are), scale, SAMPLE_BITS));
2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #endif
2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (Are < (FIXP_QMF)0) {
2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        tmp = -tmp;
2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      timeOut[j*stride] = tmp;
2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2( p_flt [4] , imag ));
2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[3] , real ));
2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2( p_flt [3] , imag ));
2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[2] , real ));
2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2( p_flt [2] , imag ));
2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[1] , real ));
2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2( p_flt [1] , imag ));
2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2( p_fltm[0] , real ));
2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta[8] =          FX_DBL2FX_QSS(fMultDiv2( p_flt [0] , imag ));
2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_flt  += (p_stride*QMF_NO_POLY);
2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_fltm += (p_stride*QMF_NO_POLY);
2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta    += 9; // = (2*QMF_NO_POLY-1);
3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric */
3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_qmfAnaPrototypeFirSlot
3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Perform Analysis Prototype Filtering on a single slot of input data.
3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfAnaPrototypeFirSlot( FIXP_QMF *analysisBuffer,
3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             int       no_channels,             /*!< Number channels of analysis filter */
3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             const FIXP_PFT *p_filter,
3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             int       p_stride,                /*!< Stide of analysis filter    */
3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QAS *RESTRICT pFilterStates
3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            )
3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int k;
3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL accu;
3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    const FIXP_PFT *RESTRICT p_flt = p_filter;
3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF *RESTRICT pData_0 = analysisBuffer + 2*no_channels - 1;
3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF *RESTRICT pData_1 = analysisBuffer;
3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QAS *RESTRICT sta_1 = (FIXP_QAS *)pFilterStates + (2*QMF_NO_POLY*no_channels) - 1;
3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int pfltStep = QMF_NO_POLY * (p_stride);
3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int staStep1 = no_channels<<1;
3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int staStep2 = (no_channels<<3) - 1; /* Rewind one less */
3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* FIR filter 0 */
3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1;
3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1;
3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1;
3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1;
3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu +=  fMultDiv2( p_flt[4], *sta_1);
3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *pData_1++ = FX_DBL2FX_QMF(accu<<1);
3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta_1 += staStep2;
3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_flt += pfltStep;
3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* FIR filters 1..63 127..65 */
3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (k=0; k<no_channels-1; k++)
3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1;
3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1;
3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1;
3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1;
3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu += fMultDiv2( p_flt[4], *sta_0);
3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      *pData_0-- = FX_DBL2FX_QMF(accu<<1);
3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      sta_0 -= staStep2;
3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu =   fMultDiv2( p_flt[0], *sta_1);  sta_1 -= staStep1;
3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu +=  fMultDiv2( p_flt[1], *sta_1);  sta_1 -= staStep1;
3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu +=  fMultDiv2( p_flt[2], *sta_1);  sta_1 -= staStep1;
3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu +=  fMultDiv2( p_flt[3], *sta_1);  sta_1 -= staStep1;
3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu +=  fMultDiv2( p_flt[4], *sta_1);
3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      *pData_1++ = FX_DBL2FX_QMF(accu<<1);
3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      sta_1 += staStep2;
3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      p_flt += pfltStep;
3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* FIR filter 64 */
3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu =  fMultDiv2( p_flt[0], *sta_0);  sta_0 += staStep1;
3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu += fMultDiv2( p_flt[1], *sta_0);  sta_0 += staStep1;
3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu += fMultDiv2( p_flt[2], *sta_0);  sta_0 += staStep1;
3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu += fMultDiv2( p_flt[3], *sta_0);  sta_0 += staStep1;
3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu += fMultDiv2( p_flt[4], *sta_0);
3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *pData_0-- = FX_DBL2FX_QMF(accu<<1);
3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sta_0 -= staStep2;
3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Perform Analysis Prototype Filtering on a single slot of input data.
3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfAnaPrototypeFirSlot_NonSymmetric(
3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        FIXP_QMF *analysisBuffer,
3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        int       no_channels,             /*!< Number channels of analysis filter */
3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        const FIXP_PFT *p_filter,
3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        int       p_stride,                /*!< Stide of analysis filter    */
3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        FIXP_QAS *RESTRICT pFilterStates
3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       )
3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_PFT *RESTRICT p_flt = p_filter;
3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int  p, k;
3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (k = 0; k < 2*no_channels; k++)
3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL accu = (FIXP_DBL)0;
3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p_flt += QMF_NO_POLY * (p_stride - 1);
3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Perform FIR-Filter
3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (p = 0; p < QMF_NO_POLY; p++) {
4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      accu +=  fMultDiv2(*p_flt++, pFilterStates[2*no_channels * p]);
4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    analysisBuffer[2*no_channels - 1 - k] = FX_DBL2FX_QMF(accu<<1);
4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pFilterStates++;
4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform real-valued forward modulation of the time domain
4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        data of timeIn and stores the real part of the subband
4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples in rSubband
4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfForwardModulationLP_even( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */
4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *timeIn,              /*!< Time Signal */
4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *rSubband )           /*!< Real Output */
4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = anaQmf->no_channels;
4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int M = L>>1;
4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int scale;
4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF accu;
4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_QMF *timeInTmp1 = (FIXP_QMF *) &timeIn[3 * M];
4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const FIXP_QMF *timeInTmp2 = timeInTmp1;
4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF *rSubbandTmp = rSubband;
4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  rSubband[0] = timeIn[3 * M] >> 1;
4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = M-1; i != 0; i--) {
4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1);
4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *++rSubbandTmp = accu;
4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  timeInTmp1 = &timeIn[2 * M];
4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  timeInTmp2 = &timeIn[0];
4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  rSubbandTmp = &rSubband[M];
4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = L-M; i != 0; i--) {
4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1);
4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *rSubbandTmp++ = accu;
4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_III(rSubband, timeIn, L, &scale);
4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if !defined(FUNCTION_qmfForwardModulationLP_odd)
4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfForwardModulationLP_odd( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */
4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            const FIXP_QMF *timeIn,        /*!< Time Signal */
4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            FIXP_QMF *rSubband )           /*!< Real Output */
4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = anaQmf->no_channels;
4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int M = L>>1;
4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int shift = (anaQmf->no_channels>>6) + 1;
4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < M; i++) {
4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    rSubband[M + i]     = (timeIn[L - 1 - i]>>1) - (timeIn[i]>>shift);
4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    rSubband[M - 1 - i] = (timeIn[L + i]>>1)     + (timeIn[2 * L - 1 - i]>>shift);
4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_IV(rSubband, L, &shift);
4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !defined(FUNCTION_qmfForwardModulationLP_odd) */
4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform complex-valued forward modulation of the time domain
4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        data of timeIn and stores the real part of the subband
4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples in rSubband, and the imaginary part in iSubband
4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        Only the lower bands are obtained (upto anaQmf->lsb). For
4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        a full bandwidth analysis it is required to set both anaQmf->lsb
4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        and anaQmf->usb to the amount of QMF bands.
4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfForwardModulationHQ( HANDLE_QMF_FILTER_BANK anaQmf,     /*!< Handle of Qmf Analysis Bank  */
4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        const FIXP_QMF *RESTRICT timeIn,   /*!< Time Signal */
4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        FIXP_QMF *RESTRICT rSubband,       /*!< Real Output */
4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        FIXP_QMF *RESTRICT iSubband        /*!< Imaginary Output */
4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       )
4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = anaQmf->no_channels;
4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L2 = L<<1;
4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int shift = 0;
4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < L; i+=2) {
4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_QMF x0, x1, y0, y1;
4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x0 = timeIn[i] >> 1;
4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x1 = timeIn[i+1] >> 1;
5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    y0 = timeIn[L2 - 1 - i] >> 1;
5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    y1 = timeIn[L2 - 2 - i] >> 1;
5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    rSubband[i] = x0 - y0;
5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    rSubband[i+1] = x1 - y1;
5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    iSubband[i] = x0 + y0;
5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    iSubband[i+1] = x1 + y1;
5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_IV(rSubband, L, &shift);
5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dst_IV(iSubband, L, &shift);
5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      const FIXP_QTW *RESTRICT sbr_t_cos;
5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      const FIXP_QTW *RESTRICT sbr_t_sin;
5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      sbr_t_cos = anaQmf->t_cos;
5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      sbr_t_sin = anaQmf->t_sin;
5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (i = 0; i < anaQmf->lsb; i++) {
5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i], sbr_t_cos[i], sbr_t_sin[i]);
5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*
5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform one QMF slot analysis of the time domain data of timeIn
5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        with specified stride and stores the real part of the subband
5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples in rSubband, and the imaginary part in iSubband
5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        Only the lower bands are obtained (upto anaQmf->lsb). For
5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        a full bandwidth analysis it is required to set both anaQmf->lsb
5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        and anaQmf->usb to the amount of QMF bands.
5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf,  /*!< Handle of Qmf Synthesis Bank  */
5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          FIXP_QMF      *qmfReal,         /*!< Low and High band, real */
5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          FIXP_QMF      *qmfImag,         /*!< Low and High band, imag */
5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          const int      stride,          /*!< stride factor of input */
5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          FIXP_QMF      *pWorkBuffer      /*!< pointer to temporal working buffer */
5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         )
5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int i;
5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int offset = anaQmf->no_channels*(QMF_NO_POLY*2-1);
5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Feed time signal into oldest anaQmf->no_channels states
5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_QAS *RESTRICT FilterStatesAnaTmp = ((FIXP_QAS*)anaQmf->FilterStates)+offset;
5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Feed and scale actual time in slot */
5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for(i=anaQmf->no_channels>>1; i!=0; i--) {
5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Place INT_PCM value left aligned in scaledTimeIn */
5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if (QAS_BITS==SAMPLE_BITS)
5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride;
5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; timeIn += stride;
5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#elif (QAS_BITS>SAMPLE_BITS)
5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride;
5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)<<(QAS_BITS-SAMPLE_BITS)); timeIn += stride;
5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride;
5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn)>>(SAMPLE_BITS-QAS_BITS)); timeIn += stride;
5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfAnaPrototypeFirSlot_NonSymmetric(
5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              pWorkBuffer,
5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->no_channels,
5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->p_filter,
5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->p_stride,
5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              (FIXP_QAS*)anaQmf->FilterStates
5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            );
5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfAnaPrototypeFirSlot( pWorkBuffer,
5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->no_channels,
5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->p_filter,
5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              anaQmf->p_stride,
5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              (FIXP_QAS*)anaQmf->FilterStates
5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            );
5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (anaQmf->flags & QMF_FLAG_LP) {
5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (anaQmf->flags & QMF_FLAG_CLDFB)
5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfForwardModulationLP_odd( anaQmf,
5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    pWorkBuffer,
5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    qmfReal );
5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      else
5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfForwardModulationLP_even( anaQmf,
5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                     pWorkBuffer,
5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                     qmfReal );
5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfForwardModulationHQ( anaQmf,
5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              pWorkBuffer,
5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              qmfReal,
5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              qmfImag
6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             );
6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Shift filter states
6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Should be realized with modulo adressing on a DSP instead of a true buffer shift
6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDKmemmove ((FIXP_QAS*)anaQmf->FilterStates, (FIXP_QAS*)anaQmf->FilterStates+anaQmf->no_channels, offset*sizeof(FIXP_QAS));
6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform complex-valued subband filtering of the time domain
6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        data of timeIn and stores the real part of the subband
6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples in rAnalysis, and the imaginary part in iAnalysis
6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The qmf coefficient table is symmetric. The symmetry is expoited by
6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * shrinking the coefficient table to half the size. The addressing mode
6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * takes care of the symmetries.
6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Only the lower bands are obtained (upto anaQmf->lsb). For
6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * a full bandwidth analysis it is required to set both anaQmf->lsb
6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * and anaQmf->usb to the amount of QMF bands.
6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \sa PolyphaseFiltering
6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf,    /*!< Handle of Qmf Analysis Bank */
6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      FIXP_QMF **qmfReal,               /*!< Pointer to real subband slots */
6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      FIXP_QMF **qmfImag,               /*!< Pointer to imag subband slots */
6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      QMF_SCALE_FACTOR *scaleFactor,
6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const INT_PCM *timeIn,            /*!< Time signal */
6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const int  stride,
6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      FIXP_QMF  *pWorkBuffer            /*!< pointer to temporal working buffer */
6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      )
6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int no_channels = anaQmf->no_channels;
6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleFactor->lb_scale = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK;
6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleFactor->lb_scale -= anaQmf->filterScale;
6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < anaQmf->no_col; i++)
6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_QMF *qmfImagSlot = NULL;
6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (!(anaQmf->flags & QMF_FLAG_LP)) {
6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfImagSlot = qmfImag[i];
6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfAnalysisFilteringSlot( anaQmf, qmfReal[i], qmfImagSlot, timeIn , stride, pWorkBuffer );
6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      timeIn += no_channels*stride;
6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } /* no_col loop  i  */
6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform low power inverse modulation of the subband
6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples stored in rSubband (real part) and iSubband (imaginary
6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        part) and stores the result in pWorkBuffer.
6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectinline
6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInverseModulationLP_even( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */
6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */
6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             const int   scaleFactorLowBand,  /*!< Scalefactor for Low band */
6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             const int   scaleFactorHighBand, /*!< Scalefactor for High band */
6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/
6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           )
6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = synQmf->no_channels;
6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int M = L>>1;
6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int scale;
6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF tmp;
6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF *RESTRICT tReal = pTimeOut;
6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF *RESTRICT tImag = pTimeOut + L;
6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Move input to output vector with offset */
6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand);
6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(&tReal[0+synQmf->usb], (L-synQmf->usb)*sizeof(FIXP_QMF));
6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Dct type-2 transform */
6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_II(tReal, tImag, L, &scale);
6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Expand output and replace inplace the output buffers */
6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tImag[0] = tReal[M];
6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tImag[M] = (FIXP_QMF)0;
6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tmp = tReal [0];
6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tReal [0] = tReal[M];
6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tReal [M] = tmp;
6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 1; i < M/2; i++) {
6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Imag */
6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tmp = tReal[L - i];
7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tImag[M - i] =  tmp;
7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tImag[i + M] = -tmp;
7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tmp = tReal[M + i];
7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tImag[i] =  tmp;
7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tImag[L - i] = -tmp;
7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Real */
7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tReal [M + i] = tReal[i];
7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tReal [L - i] = tReal[M - i];
7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tmp = tReal[i];
7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tReal[i] = tReal [M - i];
7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tReal [M - i] = tmp;
7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Remaining odd terms */
7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tmp = tReal[M + M/2];
7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tImag[M/2]     =  tmp;
7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tImag[M/2 + M] = -tmp;
7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tReal [M + M/2] = tReal[M/2];
7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectinline
7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInverseModulationLP_odd( HANDLE_QMF_FILTER_BANK synQmf,   /*!< Handle of Qmf Synthesis Bank  */
7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            const FIXP_QMF *qmfReal,         /*!< Pointer to qmf real subband slot (input) */
7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            const int scaleFactorLowBand,    /*!< Scalefactor for Low band */
7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            const int scaleFactorHighBand,   /*!< Scalefactor for High band */
7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            FIXP_QMF *pTimeOut               /*!< Pointer to qmf subband slot (output)*/
7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          )
7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = synQmf->no_channels;
7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int M = L>>1;
7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int shift = 0;
7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Move input to output vector with offset */
7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleValues(pTimeOut+M,              qmfReal,             synQmf->lsb,             scaleFactorLowBand);
7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleValues(pTimeOut+M+synQmf->lsb,  qmfReal+synQmf->lsb, synQmf->usb-synQmf->lsb, scaleFactorHighBand);
7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(pTimeOut+M+synQmf->usb, (L-synQmf->usb)*sizeof(FIXP_QMF));
7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_IV(pTimeOut+M, L, &shift);
7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < M; i++) {
7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pTimeOut[i]             =  pTimeOut[L - 1 - i];
7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i];
7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform complex-valued inverse modulation of the subband
7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        samples stored in rSubband (real part) and iSubband (imaginary
7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        part) and stores the result in pWorkBuffer.
7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectinline
7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInverseModulationHQ( HANDLE_QMF_FILTER_BANK synQmf,  /*!< Handle of Qmf Synthesis Bank     */
7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        const FIXP_QMF *qmfReal,        /*!< Pointer to qmf real subband slot */
7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        const FIXP_QMF *qmfImag,        /*!< Pointer to qmf imag subband slot */
7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        const int   scaleFactorLowBand, /*!< Scalefactor for Low band         */
7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        const int   scaleFactorHighBand,/*!< Scalefactor for High band        */
7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        FIXP_QMF  *pWorkBuffer          /*!< WorkBuffer (output)              */
7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      )
7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = synQmf->no_channels;
7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int M = L>>1;
7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int shift = 0;
7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF *RESTRICT tReal = pWorkBuffer;
7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_QMF *RESTRICT tImag = pWorkBuffer+L;
7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (synQmf->flags & QMF_FLAG_CLDFB){
7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < synQmf->lsb; i++) {
7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      cplxMult(&tImag[i], &tReal[i],
7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                scaleValue(qmfImag[i],scaleFactorLowBand), scaleValue(qmfReal[i],scaleFactorLowBand),
7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                synQmf->t_cos[i], synQmf->t_sin[i]);
7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (; i < synQmf->usb; i++) {
7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      cplxMult(&tImag[i], &tReal[i],
7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                scaleValue(qmfImag[i],scaleFactorHighBand), scaleValue(qmfReal[i],scaleFactorHighBand),
7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                synQmf->t_cos[i], synQmf->t_sin[i]);
7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( (synQmf->flags & QMF_FLAG_CLDFB) == 0) {
7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    scaleValues(&tReal[0],             &qmfReal[0],             synQmf->lsb,             scaleFactorLowBand);
7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    scaleValues(&tReal[0+synQmf->lsb], &qmfReal[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    scaleValues(&tImag[0],             &qmfImag[0],             synQmf->lsb,             scaleFactorLowBand);
7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    scaleValues(&tImag[0+synQmf->lsb], &qmfImag[0+synQmf->lsb], synQmf->usb-synQmf->lsb, scaleFactorHighBand);
7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(&tReal[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF));
7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(&tImag[synQmf->usb], (synQmf->no_channels-synQmf->usb)*sizeof(FIXP_QMF));
7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dct_IV(tReal, L, &shift);
7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  dst_IV(tImag, L, &shift);
7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (synQmf->flags & QMF_FLAG_CLDFB){
8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < M; i++) {
8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_QMF r1, i1, r2, i2;
8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      r1 = tReal[i];
8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      i2 = tImag[L - 1 - i];
8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      r2 = tReal[L - i - 1];
8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      i1 = tImag[i];
8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tReal[i] = (r1 - i1)>>1;
8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tImag[L - 1 - i] = -(r1 + i1)>>1;
8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tReal[L - i - 1] =  (r2 - i2)>>1;
8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tImag[i] = -(r2 + i2)>>1;
8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else
8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* The array accesses are negative to compensate the missing minus sign in the low and hi band gain. */
8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* 26 cycles on ARM926 */
8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < M; i++) {
8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_QMF r1, i1, r2, i2;
8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      r1 = -tReal[i];
8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      i2 = -tImag[L - 1 - i];
8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      r2 = -tReal[L - i - 1];
8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      i1 = -tImag[i];
8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tReal[i] = (r1 - i1)>>1;
8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tImag[L - 1 - i] = -(r1 + i1)>>1;
8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tReal[L - i - 1] =  (r2 - i2)>>1;
8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      tImag[i] = -(r2 + i2)>>1;
8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid qmfSynthesisFilteringSlot( HANDLE_QMF_FILTER_BANK  synQmf,
8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                const FIXP_QMF  *realSlot,
8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                const FIXP_QMF  *imagSlot,
8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                const int        scaleFactorLowBand,
8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                const int        scaleFactorHighBand,
8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                INT_PCM         *timeOut,
8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                const int        stride,
8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                FIXP_QMF        *pWorkBuffer)
8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (!(synQmf->flags & QMF_FLAG_LP))
8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfInverseModulationHQ ( synQmf,
8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               realSlot,
8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               imagSlot,
8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               scaleFactorLowBand,
8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               scaleFactorHighBand,
8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               pWorkBuffer
8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             );
8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (synQmf->flags & QMF_FLAG_CLDFB) {
8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfInverseModulationLP_odd ( synQmf,
8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 realSlot,
8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 scaleFactorLowBand,
8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 scaleFactorHighBand,
8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer
8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               );
8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      } else {
8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfInverseModulationLP_even ( synQmf,
8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 realSlot,
8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 scaleFactorLowBand,
8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 scaleFactorHighBand,
8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer
8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               );
8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) {
8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfSynPrototypeFirSlot_NonSymmetric (
8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 synQmf,
8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer,
8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer+synQmf->no_channels,
8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 timeOut,
8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 stride
8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               );
8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        qmfSynPrototypeFirSlot ( synQmf,
8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer,
8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 pWorkBuffer+synQmf->no_channels,
8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 timeOut,
8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                 stride
8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               );
8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Perform complex-valued subband synthesis of the
8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        low band and the high band and store the
8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        time domain data in timeOut
8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * First step: Calculate the proper scaling factor of current
8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * spectral data in qmfReal/qmfImag, old spectral data in the overlap
8962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * range and filter states.
8972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Second step: Perform Frequency-to-Time mapping with inverse
8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Modulation slot-wise.
9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Third step: Perform FIR-filter slot-wise. To save space for filter
9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * states, the MAC operations are executed directly on the filter states
9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * instead of accumulating several products in the accumulator. The
9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * buffer shift at the end of the function should be replaced by a
9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * modulo operation, which is available on some DSPs.
9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Last step: Copy the upper part of the spectral data to the overlap buffer.
9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The qmf coefficient table is symmetric. The symmetry is exploited by
9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * shrinking the coefficient table to half the size. The addressing mode
9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * takes care of the symmetries.  If the #define #QMFTABLE_FULL is set,
9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * coefficient addressing works on the full table size. The code will be
9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * slightly faster and slightly more compact.
9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Workbuffer requirement: 2 x sizeof(**QmfBufferReal) * synQmf->no_channels
9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfSynthesisFiltering( HANDLE_QMF_FILTER_BANK synQmf,       /*!< Handle of Qmf Synthesis Bank  */
9192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       FIXP_QMF  **QmfBufferReal,           /*!< Low and High band, real */
9202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       FIXP_QMF  **QmfBufferImag,           /*!< Low and High band, imag */
9212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       const QMF_SCALE_FACTOR *scaleFactor,
9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       const INT   ov_len,                  /*!< split Slot of overlap and actual slots */
9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       INT_PCM    *timeOut,                 /*!< Pointer to output */
9242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       const INT   stride,                  /*!< stride factor of output */
9252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       FIXP_QMF   *pWorkBuffer              /*!< pointer to temporal working buffer */
9262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      )
9272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
9282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
9292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int L = synQmf->no_channels;
9302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  SCHAR scaleFactorHighBand;
9312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  SCHAR scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;
9322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* adapt scaling */
9342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->hb_scale;
9352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleFactorLowBand_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->ov_lb_scale;
9362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleFactorLowBand_no_ov = - ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - scaleFactor->lb_scale;
9372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < synQmf->no_col; i++)  /* ----- no_col loop ----- */
9392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    const FIXP_DBL *QmfBufferImagSlot = NULL;
9412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    SCHAR scaleFactorLowBand = (i<ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov;
9432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (!(synQmf->flags & QMF_FLAG_LP))
9452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        QmfBufferImagSlot = QmfBufferImag[i];
9462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    qmfSynthesisFilteringSlot(  synQmf,
9482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                QmfBufferReal[i],
9492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                QmfBufferImagSlot,
9502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                scaleFactorLowBand,
9512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                scaleFactorHighBand,
9522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                timeOut+(i*L*stride),
9532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                stride,
9542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pWorkBuffer);
9552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } /* no_col loop  i  */
9562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
9582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
9612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Create QMF filter bank instance
9632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return 0 if successful
9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int
9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInitFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,     /*!< Handle to return */
9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   void *pFilterStates,              /*!< Handle to filter states */
9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   int noCols,                       /*!< Number of timeslots per frame */
9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   int lsb,                          /*!< Lower end of QMF frequency range */
9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   int usb,                          /*!< Upper end of QMF frequency range */
9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   int no_channels,                  /*!< Number of channels (bands) */
9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   UINT flags)                       /*!< flags */
9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(h_Qmf,sizeof(QMF_FILTER_BANK));
9772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (flags & QMF_FLAG_MPSLDFB)
9792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return -1;
9812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( !(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB) )
9842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    flags |= QMF_FLAG_NONSYMMETRIC;
9862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE;
9872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_Qmf->p_stride = 1;
9892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    switch (no_channels) {
9902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case 64:
9912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb;
9922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb;
9932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_filter = qmf_cldfb_640;
9942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->FilterSize = 640;
9952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
9962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case 32:
9972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_cos = qmf_phaseshift_cos32_cldfb;
9982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb;
9992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_filter = qmf_cldfb_320;
10002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->FilterSize = 320;
10012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
10022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      default:
10032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return -1;
10042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( !(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0) )
10082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
10092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    switch (no_channels) {
10102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case 64:
10112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_filter = qmf_64;
10122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_cos = qmf_phaseshift_cos64;
10132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_sin = qmf_phaseshift_sin64;
10142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_stride = 1;
10152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->FilterSize = 640;
10162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->filterScale = 0;
10172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
10182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case 32:
10192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_filter = qmf_64;
10202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_cos = qmf_phaseshift_cos32;
10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->t_sin = qmf_phaseshift_sin32;
10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->p_stride = 2;
10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->FilterSize = 640;
10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_Qmf->filterScale = 0;
10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      default:
10272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return -1;
10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->flags = flags;
10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->no_channels = no_channels;
10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->no_col = noCols;
10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->lsb = lsb;
10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->usb = fMin(usb, h_Qmf->no_channels);
10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->FilterStates = (void*)pFilterStates;
10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->outScalefactor = ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + h_Qmf->filterScale;
10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1043381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi  if ( (h_Qmf->p_stride == 2)
1044381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi    || ((flags & QMF_FLAG_CLDFB) && (no_channels == 32)) ) {
10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_Qmf->outScalefactor -= 1;
10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_Qmf->outGain = (FIXP_DBL)0x80000000; /* default init value will be not applied */
10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (0);
10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Adjust synthesis qmf filter states
10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void
10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic inline void
10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfAdaptFilterStates (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Filter Bank */
10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      int scaleFactorDiff)               /*!< Scale factor difference to be applied */
10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (synQmf == NULL || synQmf->FilterStates == NULL) {
10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return;
10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  scaleValues((FIXP_QSS*)synQmf->FilterStates, synQmf->no_channels*(QMF_NO_POLY*2 - 1), scaleFactorDiff);
10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Create QMF filter bank instance
10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Only the lower bands are obtained (upto anaQmf->lsb). For
10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * a full bandwidth analysis it is required to set both anaQmf->lsb
10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * and anaQmf->usb to the amount of QMF bands.
10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return 0 if succesful
10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint
10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInitAnalysisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */
10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           FIXP_QAS *pFilterStates,        /*!< Handle to filter states */
10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           int noCols,                     /*!< Number of timeslots per frame */
10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           int lsb,                        /*!< lower end of QMF */
10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           int usb,                        /*!< upper end of QMF */
10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           int no_channels,                /*!< Number of channels (bands) */
10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           int flags)                      /*!< Low Power flag */
10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags);
10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( !(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL) ) {
10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QAS));
10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return err;
10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Create QMF filter bank instance
11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Only the lower bands are obtained (upto anaQmf->lsb). For
11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * a full bandwidth analysis it is required to set both anaQmf->lsb
11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * and anaQmf->usb to the amount of QMF bands.
11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return 0 if succesful
11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint
11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInitSynthesisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf,   /*!< Returns handle */
11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            FIXP_QSS *pFilterStates,        /*!< Handle to filter states */
11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            int noCols,                     /*!< Number of timeslots per frame */
11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            int lsb,                        /*!< lower end of QMF */
11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            int usb,                        /*!< upper end of QMF */
11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            int no_channels,                /*!< Number of channels (bands) */
11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            int flags)                      /*!< Low Power flag */
11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int oldOutScale = h_Qmf->outScalefactor;
11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags);
11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( h_Qmf->FilterStates != NULL ) {
11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( !(flags & QMF_FLAG_KEEP_STATES) ) {
11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QSS));
11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      qmfAdaptFilterStates(h_Qmf, oldOutScale-h_Qmf->outScalefactor);
11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return err;
11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Change scale factor for output data and adjust qmf filter states
11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void
11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */
11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         int outScalefactor                 /*!< New scaling factor for output data */
11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        )
11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (synQmf == NULL || synQmf->FilterStates == NULL) {
11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return;
11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Add internal filterbank scale */
11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  outScalefactor += ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + synQmf->filterScale;
11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1151381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi  if ( (synQmf->p_stride == 2)
1152381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi    || ((synQmf->flags & QMF_FLAG_CLDFB) && (synQmf->no_channels == 32)) ) {
11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    outScalefactor -= 1;
11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* adjust filter states when scale factor has been changed */
11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (synQmf->outScalefactor != outScalefactor)
11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int diff;
11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (outScalefactor > (SAMPLE_BITS - 1)) {
11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      outScalefactor = SAMPLE_BITS - 1;
11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else if (outScalefactor < (1 - SAMPLE_BITS)) {
11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      outScalefactor = 1 - SAMPLE_BITS;
11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    diff = synQmf->outScalefactor - outScalefactor;
11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    qmfAdaptFilterStates(synQmf, diff);
11702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* save new scale factor */
11722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    synQmf->outScalefactor = outScalefactor;
11732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Change gain for output data
11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void
11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *
11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf,     /*!< Handle of Qmf Synthesis Bank */
11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  FIXP_DBL outputGain                /*!< New gain for output data */
11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 )
11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  synQmf->outGain = outputGain;
11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1191