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 54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright 1995 - 2013 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; 10203a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi if (flags & QMF_FLAG_DOWNSAMPLED) { 10213a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32; 10223a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32; 10233a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi } 10243a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi else { 10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->t_cos = qmf_phaseshift_cos32; 10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->t_sin = qmf_phaseshift_sin32; 10273a0a695565d1d360f9a82173469c8ef858bc08a0Jean-Michel Trivi } 10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->p_stride = 2; 10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->FilterSize = 640; 10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->filterScale = 0; 10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->flags = flags; 10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->no_channels = no_channels; 10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->no_col = noCols; 10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->lsb = lsb; 10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->usb = fMin(usb, h_Qmf->no_channels); 10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->FilterStates = (void*)pFilterStates; 10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->outScalefactor = ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + h_Qmf->filterScale; 10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1049381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi if ( (h_Qmf->p_stride == 2) 1050381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi || ((flags & QMF_FLAG_CLDFB) && (no_channels == 32)) ) { 10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->outScalefactor -= 1; 10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_Qmf->outGain = (FIXP_DBL)0x80000000; /* default init value will be not applied */ 10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (0); 10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Adjust synthesis qmf filter states 10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void 10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic inline void 10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfAdaptFilterStates (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Filter Bank */ 10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scaleFactorDiff) /*!< Scale factor difference to be applied */ 10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (synQmf == NULL || synQmf->FilterStates == NULL) { 10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return; 10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues((FIXP_QSS*)synQmf->FilterStates, synQmf->no_channels*(QMF_NO_POLY*2 - 1), scaleFactorDiff); 10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Create QMF filter bank instance 10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Only the lower bands are obtained (upto anaQmf->lsb). For 10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * a full bandwidth analysis it is required to set both anaQmf->lsb 10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * and anaQmf->usb to the amount of QMF bands. 10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return 0 if succesful 10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInitAnalysisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */ 10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_QAS *pFilterStates, /*!< Handle to filter states */ 10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noCols, /*!< Number of timeslots per frame */ 10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lsb, /*!< lower end of QMF */ 10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int usb, /*!< upper end of QMF */ 10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int no_channels, /*!< Number of channels (bands) */ 10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int flags) /*!< Low Power flag */ 10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags); 10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( !(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL) ) { 10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QAS)); 10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return err; 11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Create QMF filter bank instance 11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Only the lower bands are obtained (upto anaQmf->lsb). For 11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * a full bandwidth analysis it is required to set both anaQmf->lsb 11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * and anaQmf->usb to the amount of QMF bands. 11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return 0 if succesful 11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfInitSynthesisFilterBank (HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */ 11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_QSS *pFilterStates, /*!< Handle to filter states */ 11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noCols, /*!< Number of timeslots per frame */ 11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lsb, /*!< lower end of QMF */ 11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int usb, /*!< upper end of QMF */ 11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int no_channels, /*!< Number of channels (bands) */ 11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int flags) /*!< Low Power flag */ 11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int oldOutScale = h_Qmf->outScalefactor; 11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, no_channels, flags); 11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( h_Qmf->FilterStates != NULL ) { 11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( !(flags & QMF_FLAG_KEEP_STATES) ) { 11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemclear(h_Qmf->FilterStates, (2*QMF_NO_POLY-1)*h_Qmf->no_channels*sizeof(FIXP_QSS)); 11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project qmfAdaptFilterStates(h_Qmf, oldOutScale-h_Qmf->outScalefactor); 11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return err; 11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Change scale factor for output data and adjust qmf filter states 11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void 11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ 11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int outScalefactor /*!< New scaling factor for output data */ 11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (synQmf == NULL || synQmf->FilterStates == NULL) { 11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return; 11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add internal filterbank scale */ 11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outScalefactor += ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + synQmf->filterScale; 11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1157381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi if ( (synQmf->p_stride == 2) 1158381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi || ((synQmf->flags & QMF_FLAG_CLDFB) && (synQmf->no_channels == 32)) ) { 11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outScalefactor -= 1; 11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* adjust filter states when scale factor has been changed */ 11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (synQmf->outScalefactor != outScalefactor) 11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int diff; 11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (outScalefactor > (SAMPLE_BITS - 1)) { 11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outScalefactor = SAMPLE_BITS - 1; 11692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else if (outScalefactor < (1 - SAMPLE_BITS)) { 11702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outScalefactor = 1 - SAMPLE_BITS; 11712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project diff = synQmf->outScalefactor - outScalefactor; 11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project qmfAdaptFilterStates(synQmf, diff); 11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* save new scale factor */ 11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project synQmf->outScalefactor = outScalefactor; 11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Change gain for output data 11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return void 11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectqmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ 11912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL outputGain /*!< New gain for output data */ 11922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 11932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project synQmf->outGain = outputGain; 11952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1197