1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker
4*e5436536SAndroid Build Coastguard Worker © Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker
7*e5436536SAndroid Build Coastguard Worker 1. INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker
34*e5436536SAndroid Build Coastguard Worker 2. COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker
61*e5436536SAndroid Build Coastguard Worker 3. NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker
71*e5436536SAndroid Build Coastguard Worker 4. DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker
84*e5436536SAndroid Build Coastguard Worker 5. CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker
95*e5436536SAndroid Build Coastguard Worker /******************* Library for basic calculation routines ********************
96*e5436536SAndroid Build Coastguard Worker
97*e5436536SAndroid Build Coastguard Worker Author(s): Matthias Hildenbrand
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description: Module to efficiently handle QMF data for multiple channels and
100*e5436536SAndroid Build Coastguard Worker to share the data between e.g. SBR and MPS
101*e5436536SAndroid Build Coastguard Worker
102*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
103*e5436536SAndroid Build Coastguard Worker
104*e5436536SAndroid Build Coastguard Worker #include "FDK_qmf_domain.h"
105*e5436536SAndroid Build Coastguard Worker
106*e5436536SAndroid Build Coastguard Worker #include "common_fix.h"
107*e5436536SAndroid Build Coastguard Worker
108*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER1_TAG 0
109*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER3_TAG 4
110*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER4_TAG 5
111*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER6_TAG 7
112*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER7_TAG 8
113*e5436536SAndroid Build Coastguard Worker
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1,FIXP_DBL,QMF_WB_SECTION_SIZE,SECT_DATA_L1,WORKBUFFER1_TAG)114*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
115*e5436536SAndroid Build Coastguard Worker SECT_DATA_L1, WORKBUFFER1_TAG)
116*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
117*e5436536SAndroid Build Coastguard Worker SECT_DATA_L2, WORKBUFFER3_TAG)
118*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
119*e5436536SAndroid Build Coastguard Worker SECT_DATA_L2, WORKBUFFER4_TAG)
120*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
121*e5436536SAndroid Build Coastguard Worker SECT_DATA_L2, WORKBUFFER6_TAG)
122*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE,
123*e5436536SAndroid Build Coastguard Worker SECT_DATA_L2, WORKBUFFER7_TAG)
124*e5436536SAndroid Build Coastguard Worker
125*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
126*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
127*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
128*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
129*e5436536SAndroid Build Coastguard Worker
130*e5436536SAndroid Build Coastguard Worker /*! Synthesis states buffer. <br>
131*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
132*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
133*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
134*e5436536SAndroid Build Coastguard Worker
135*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
136*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
137*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal, FIXP_DBL *,
138*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
139*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
140*e5436536SAndroid Build Coastguard Worker
141*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
142*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
143*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag, FIXP_DBL *,
144*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
145*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
146*e5436536SAndroid Build Coastguard Worker
147*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
148*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
149*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
150*e5436536SAndroid Build Coastguard Worker 2 * QMF_DOMAIN_MAX_OV_TIMESLOTS * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
151*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
152*e5436536SAndroid Build Coastguard Worker
153*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
154*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
155*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
156*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
157*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
158*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
159*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
160*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
161*e5436536SAndroid Build Coastguard Worker
162*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
163*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
164*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
165*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
166*e5436536SAndroid Build Coastguard Worker
167*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
168*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
169*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal16, FIXP_DBL *,
170*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
171*e5436536SAndroid Build Coastguard Worker
172*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
173*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
174*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal32, FIXP_DBL *,
175*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
176*e5436536SAndroid Build Coastguard Worker
177*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
178*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
179*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag16, FIXP_DBL *,
180*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
181*e5436536SAndroid Build Coastguard Worker
182*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
183*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
184*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag32, FIXP_DBL *,
185*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
186*e5436536SAndroid Build Coastguard Worker
187*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
188*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
189*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer16, FIXP_DBL,
190*e5436536SAndroid Build Coastguard Worker 2 * QMF_DOMAIN_OV_TIMESLOTS_16 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
191*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
192*e5436536SAndroid Build Coastguard Worker
193*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
194*e5436536SAndroid Build Coastguard Worker Dimension: #((8) + (1)) */
195*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer32, FIXP_DBL,
196*e5436536SAndroid Build Coastguard Worker 2 * QMF_DOMAIN_OV_TIMESLOTS_32 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
197*e5436536SAndroid Build Coastguard Worker ((8) + (1)))
198*e5436536SAndroid Build Coastguard Worker
199*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_FreePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
200*e5436536SAndroid Build Coastguard Worker int err = 0;
201*e5436536SAndroid Build Coastguard Worker int ch;
202*e5436536SAndroid Build Coastguard Worker
203*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < ((8) + (1)); ch++) {
204*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pAnaQmfStates) {
205*e5436536SAndroid Build Coastguard Worker if (qd->globalConf.nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
206*e5436536SAndroid Build Coastguard Worker FreeAnaQmfStates16(&qd->QmfDomainIn[ch].pAnaQmfStates);
207*e5436536SAndroid Build Coastguard Worker } else if (qd->globalConf.nBandsAnalysis ==
208*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
209*e5436536SAndroid Build Coastguard Worker FreeAnaQmfStates24(&qd->QmfDomainIn[ch].pAnaQmfStates);
210*e5436536SAndroid Build Coastguard Worker } else if (qd->globalConf.nBandsAnalysis ==
211*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
212*e5436536SAndroid Build Coastguard Worker FreeAnaQmfStates32(&qd->QmfDomainIn[ch].pAnaQmfStates);
213*e5436536SAndroid Build Coastguard Worker } else {
214*e5436536SAndroid Build Coastguard Worker FreeAnaQmfStates(&qd->QmfDomainIn[ch].pAnaQmfStates);
215*e5436536SAndroid Build Coastguard Worker }
216*e5436536SAndroid Build Coastguard Worker }
217*e5436536SAndroid Build Coastguard Worker
218*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pOverlapBuffer) {
219*e5436536SAndroid Build Coastguard Worker if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
220*e5436536SAndroid Build Coastguard Worker FreeQmfOverlapBuffer16(&qd->QmfDomainIn[ch].pOverlapBuffer);
221*e5436536SAndroid Build Coastguard Worker } else if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
222*e5436536SAndroid Build Coastguard Worker FreeQmfOverlapBuffer32(&qd->QmfDomainIn[ch].pOverlapBuffer);
223*e5436536SAndroid Build Coastguard Worker } else {
224*e5436536SAndroid Build Coastguard Worker FreeQmfOverlapBuffer(&qd->QmfDomainIn[ch].pOverlapBuffer);
225*e5436536SAndroid Build Coastguard Worker }
226*e5436536SAndroid Build Coastguard Worker }
227*e5436536SAndroid Build Coastguard Worker
228*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsReal) {
229*e5436536SAndroid Build Coastguard Worker if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
230*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsReal16(&qd->QmfDomainIn[ch].hQmfSlotsReal);
231*e5436536SAndroid Build Coastguard Worker } else if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
232*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsReal32(&qd->QmfDomainIn[ch].hQmfSlotsReal);
233*e5436536SAndroid Build Coastguard Worker } else {
234*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsReal(&qd->QmfDomainIn[ch].hQmfSlotsReal);
235*e5436536SAndroid Build Coastguard Worker }
236*e5436536SAndroid Build Coastguard Worker }
237*e5436536SAndroid Build Coastguard Worker
238*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsImag) {
239*e5436536SAndroid Build Coastguard Worker if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
240*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsImag16(&qd->QmfDomainIn[ch].hQmfSlotsImag);
241*e5436536SAndroid Build Coastguard Worker }
242*e5436536SAndroid Build Coastguard Worker if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
243*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsImag32(&qd->QmfDomainIn[ch].hQmfSlotsImag);
244*e5436536SAndroid Build Coastguard Worker } else {
245*e5436536SAndroid Build Coastguard Worker FreeQmfSlotsImag(&qd->QmfDomainIn[ch].hQmfSlotsImag);
246*e5436536SAndroid Build Coastguard Worker }
247*e5436536SAndroid Build Coastguard Worker }
248*e5436536SAndroid Build Coastguard Worker }
249*e5436536SAndroid Build Coastguard Worker
250*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < ((8) + (1)); ch++) {
251*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainOut[ch].pSynQmfStates) {
252*e5436536SAndroid Build Coastguard Worker FreeSynQmfStates(&qd->QmfDomainOut[ch].pSynQmfStates);
253*e5436536SAndroid Build Coastguard Worker }
254*e5436536SAndroid Build Coastguard Worker }
255*e5436536SAndroid Build Coastguard Worker
256*e5436536SAndroid Build Coastguard Worker return err;
257*e5436536SAndroid Build Coastguard Worker }
258*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd)259*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
260*e5436536SAndroid Build Coastguard Worker int err = 0;
261*e5436536SAndroid Build Coastguard Worker int ch;
262*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
263*e5436536SAndroid Build Coastguard Worker
264*e5436536SAndroid Build Coastguard Worker if ((gc->nInputChannels > ((8) + (1))) || (gc->nOutputChannels > ((8) + (1))))
265*e5436536SAndroid Build Coastguard Worker return err = 1;
266*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < gc->nInputChannels; ch++) {
267*e5436536SAndroid Build Coastguard Worker int size;
268*e5436536SAndroid Build Coastguard Worker
269*e5436536SAndroid Build Coastguard Worker size = gc->nBandsAnalysis * 10;
270*e5436536SAndroid Build Coastguard Worker if (size > 0) {
271*e5436536SAndroid Build Coastguard Worker if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
272*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
273*e5436536SAndroid Build Coastguard Worker if (NULL ==
274*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch)))
275*e5436536SAndroid Build Coastguard Worker goto bail;
276*e5436536SAndroid Build Coastguard Worker }
277*e5436536SAndroid Build Coastguard Worker } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
278*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
279*e5436536SAndroid Build Coastguard Worker if (NULL ==
280*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch)))
281*e5436536SAndroid Build Coastguard Worker goto bail;
282*e5436536SAndroid Build Coastguard Worker }
283*e5436536SAndroid Build Coastguard Worker } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
284*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
285*e5436536SAndroid Build Coastguard Worker if (NULL ==
286*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch)))
287*e5436536SAndroid Build Coastguard Worker goto bail;
288*e5436536SAndroid Build Coastguard Worker }
289*e5436536SAndroid Build Coastguard Worker } else {
290*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
291*e5436536SAndroid Build Coastguard Worker if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch)))
292*e5436536SAndroid Build Coastguard Worker goto bail;
293*e5436536SAndroid Build Coastguard Worker }
294*e5436536SAndroid Build Coastguard Worker }
295*e5436536SAndroid Build Coastguard Worker } else {
296*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].pAnaQmfStates = NULL;
297*e5436536SAndroid Build Coastguard Worker }
298*e5436536SAndroid Build Coastguard Worker
299*e5436536SAndroid Build Coastguard Worker size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots;
300*e5436536SAndroid Build Coastguard Worker if (size > 0) {
301*e5436536SAndroid Build Coastguard Worker if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
302*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
303*e5436536SAndroid Build Coastguard Worker if (NULL ==
304*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch)))
305*e5436536SAndroid Build Coastguard Worker goto bail;
306*e5436536SAndroid Build Coastguard Worker }
307*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
308*e5436536SAndroid Build Coastguard Worker if (NULL ==
309*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch)))
310*e5436536SAndroid Build Coastguard Worker goto bail;
311*e5436536SAndroid Build Coastguard Worker }
312*e5436536SAndroid Build Coastguard Worker } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
313*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
314*e5436536SAndroid Build Coastguard Worker if (NULL ==
315*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch)))
316*e5436536SAndroid Build Coastguard Worker goto bail;
317*e5436536SAndroid Build Coastguard Worker }
318*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
319*e5436536SAndroid Build Coastguard Worker if (NULL ==
320*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch)))
321*e5436536SAndroid Build Coastguard Worker goto bail;
322*e5436536SAndroid Build Coastguard Worker }
323*e5436536SAndroid Build Coastguard Worker } else {
324*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
325*e5436536SAndroid Build Coastguard Worker if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch)))
326*e5436536SAndroid Build Coastguard Worker goto bail;
327*e5436536SAndroid Build Coastguard Worker }
328*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
329*e5436536SAndroid Build Coastguard Worker if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch)))
330*e5436536SAndroid Build Coastguard Worker goto bail;
331*e5436536SAndroid Build Coastguard Worker }
332*e5436536SAndroid Build Coastguard Worker }
333*e5436536SAndroid Build Coastguard Worker } else {
334*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsReal = NULL;
335*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsImag = NULL;
336*e5436536SAndroid Build Coastguard Worker }
337*e5436536SAndroid Build Coastguard Worker
338*e5436536SAndroid Build Coastguard Worker size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
339*e5436536SAndroid Build Coastguard Worker if (size > 0) {
340*e5436536SAndroid Build Coastguard Worker if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
341*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
342*e5436536SAndroid Build Coastguard Worker if (NULL ==
343*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch)))
344*e5436536SAndroid Build Coastguard Worker goto bail;
345*e5436536SAndroid Build Coastguard Worker }
346*e5436536SAndroid Build Coastguard Worker } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
347*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
348*e5436536SAndroid Build Coastguard Worker if (NULL ==
349*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch)))
350*e5436536SAndroid Build Coastguard Worker goto bail;
351*e5436536SAndroid Build Coastguard Worker }
352*e5436536SAndroid Build Coastguard Worker } else {
353*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
354*e5436536SAndroid Build Coastguard Worker if (NULL ==
355*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch)))
356*e5436536SAndroid Build Coastguard Worker goto bail;
357*e5436536SAndroid Build Coastguard Worker }
358*e5436536SAndroid Build Coastguard Worker }
359*e5436536SAndroid Build Coastguard Worker } else {
360*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].pOverlapBuffer = NULL;
361*e5436536SAndroid Build Coastguard Worker }
362*e5436536SAndroid Build Coastguard Worker }
363*e5436536SAndroid Build Coastguard Worker
364*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < gc->nOutputChannels; ch++) {
365*e5436536SAndroid Build Coastguard Worker int size = gc->nBandsSynthesis * 9;
366*e5436536SAndroid Build Coastguard Worker if (size > 0) {
367*e5436536SAndroid Build Coastguard Worker if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) {
368*e5436536SAndroid Build Coastguard Worker if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch)))
369*e5436536SAndroid Build Coastguard Worker goto bail;
370*e5436536SAndroid Build Coastguard Worker }
371*e5436536SAndroid Build Coastguard Worker } else {
372*e5436536SAndroid Build Coastguard Worker qd->QmfDomainOut[ch].pSynQmfStates = NULL;
373*e5436536SAndroid Build Coastguard Worker }
374*e5436536SAndroid Build Coastguard Worker }
375*e5436536SAndroid Build Coastguard Worker
376*e5436536SAndroid Build Coastguard Worker return err;
377*e5436536SAndroid Build Coastguard Worker
378*e5436536SAndroid Build Coastguard Worker bail:
379*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreePersistentMemory(qd);
380*e5436536SAndroid Build Coastguard Worker return -1;
381*e5436536SAndroid Build Coastguard Worker }
382*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_ClearPersistentMemory(HANDLE_FDK_QMF_DOMAIN hqd)383*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(
384*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN hqd) {
385*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
386*e5436536SAndroid Build Coastguard Worker int ch, size;
387*e5436536SAndroid Build Coastguard Worker if (hqd) {
388*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = &hqd->globalConf;
389*e5436536SAndroid Build Coastguard Worker
390*e5436536SAndroid Build Coastguard Worker size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
391*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < gc->nInputChannels; ch++) {
392*e5436536SAndroid Build Coastguard Worker if (hqd->QmfDomainIn[ch].pOverlapBuffer) {
393*e5436536SAndroid Build Coastguard Worker FDKmemclear(hqd->QmfDomainIn[ch].pOverlapBuffer,
394*e5436536SAndroid Build Coastguard Worker size * sizeof(FIXP_DBL));
395*e5436536SAndroid Build Coastguard Worker }
396*e5436536SAndroid Build Coastguard Worker }
397*e5436536SAndroid Build Coastguard Worker if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
398*e5436536SAndroid Build Coastguard Worker err = QMF_DOMAIN_INIT_ERROR;
399*e5436536SAndroid Build Coastguard Worker }
400*e5436536SAndroid Build Coastguard Worker } else {
401*e5436536SAndroid Build Coastguard Worker err = QMF_DOMAIN_INIT_ERROR;
402*e5436536SAndroid Build Coastguard Worker }
403*e5436536SAndroid Build Coastguard Worker return err;
404*e5436536SAndroid Build Coastguard Worker }
405*e5436536SAndroid Build Coastguard Worker
406*e5436536SAndroid Build Coastguard Worker /*
407*e5436536SAndroid Build Coastguard Worker FDK_getWorkBuffer
408*e5436536SAndroid Build Coastguard Worker
409*e5436536SAndroid Build Coastguard Worker Parameters:
410*e5436536SAndroid Build Coastguard Worker
411*e5436536SAndroid Build Coastguard Worker pWorkBuffer i: array of pointers which point to different workbuffer
412*e5436536SAndroid Build Coastguard Worker sections workBufferOffset i: offset in the workbuffer to the requested
413*e5436536SAndroid Build Coastguard Worker memory memSize i: size of requested memory
414*e5436536SAndroid Build Coastguard Worker
415*e5436536SAndroid Build Coastguard Worker Function:
416*e5436536SAndroid Build Coastguard Worker
417*e5436536SAndroid Build Coastguard Worker The functions returns the address to the requested memory in the workbuffer.
418*e5436536SAndroid Build Coastguard Worker
419*e5436536SAndroid Build Coastguard Worker The overall workbuffer is divided into several sections. There are
420*e5436536SAndroid Build Coastguard Worker QMF_MAX_WB_SECTIONS sections of size QMF_WB_SECTION_SIZE. The function
421*e5436536SAndroid Build Coastguard Worker selects the workbuffer section with the help of the workBufferOffset and than
422*e5436536SAndroid Build Coastguard Worker it verifies whether the requested amount of memory fits into the selected
423*e5436536SAndroid Build Coastguard Worker workbuffer section.
424*e5436536SAndroid Build Coastguard Worker
425*e5436536SAndroid Build Coastguard Worker Returns:
426*e5436536SAndroid Build Coastguard Worker
427*e5436536SAndroid Build Coastguard Worker address to workbuffer
428*e5436536SAndroid Build Coastguard Worker */
FDK_getWorkBuffer(FIXP_DBL ** pWorkBuffer,USHORT workBufferOffset,USHORT workBufferSectSize,USHORT memSize)429*e5436536SAndroid Build Coastguard Worker static FIXP_DBL *FDK_getWorkBuffer(FIXP_DBL **pWorkBuffer,
430*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset,
431*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize, USHORT memSize) {
432*e5436536SAndroid Build Coastguard Worker int idx1;
433*e5436536SAndroid Build Coastguard Worker int idx2;
434*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pwb;
435*e5436536SAndroid Build Coastguard Worker
436*e5436536SAndroid Build Coastguard Worker /* a section must be a multiple of the number of processing bands (currently
437*e5436536SAndroid Build Coastguard Worker * always 64) */
438*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((workBufferSectSize % 64) == 0);
439*e5436536SAndroid Build Coastguard Worker
440*e5436536SAndroid Build Coastguard Worker /* calculate offset within the section */
441*e5436536SAndroid Build Coastguard Worker idx2 = workBufferOffset % workBufferSectSize;
442*e5436536SAndroid Build Coastguard Worker /* calculate section number */
443*e5436536SAndroid Build Coastguard Worker idx1 = (workBufferOffset - idx2) / workBufferSectSize;
444*e5436536SAndroid Build Coastguard Worker /* maximum sectionnumber is QMF_MAX_WB_SECTIONS */
445*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(idx1 < QMF_MAX_WB_SECTIONS);
446*e5436536SAndroid Build Coastguard Worker
447*e5436536SAndroid Build Coastguard Worker /* check, whether workbuffer is available */
448*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(pWorkBuffer[idx1] != NULL);
449*e5436536SAndroid Build Coastguard Worker
450*e5436536SAndroid Build Coastguard Worker /* check, whether buffer fits into selected section */
451*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((idx2 + memSize) <= workBufferSectSize);
452*e5436536SAndroid Build Coastguard Worker
453*e5436536SAndroid Build Coastguard Worker /* get requested address to workbuffer */
454*e5436536SAndroid Build Coastguard Worker pwb = &pWorkBuffer[idx1][idx2];
455*e5436536SAndroid Build Coastguard Worker
456*e5436536SAndroid Build Coastguard Worker return pwb;
457*e5436536SAndroid Build Coastguard Worker }
458*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd,int ch,FIXP_DBL ** pWorkBuffer,USHORT workBufferOffset,USHORT workBufferSectSize,int size)459*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd, int ch,
460*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuffer,
461*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset,
462*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize, int size) {
463*e5436536SAndroid Build Coastguard Worker int err = 0;
464*e5436536SAndroid Build Coastguard Worker int mem_needed;
465*e5436536SAndroid Build Coastguard Worker
466*e5436536SAndroid Build Coastguard Worker mem_needed = qd->QmfDomainIn[ch].workBuf_nBands *
467*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].workBuf_nTimeSlots * CMPLX_MOD;
468*e5436536SAndroid Build Coastguard Worker if (mem_needed > size) {
469*e5436536SAndroid Build Coastguard Worker return (err = 1);
470*e5436536SAndroid Build Coastguard Worker }
471*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].pWorkBuffer = pWorkBuffer;
472*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].workBufferOffset = workBufferOffset;
473*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].workBufferSectSize = workBufferSectSize;
474*e5436536SAndroid Build Coastguard Worker
475*e5436536SAndroid Build Coastguard Worker return err;
476*e5436536SAndroid Build Coastguard Worker }
477*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd)478*e5436536SAndroid Build Coastguard Worker int FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd) {
479*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd != NULL);
480*e5436536SAndroid Build Coastguard Worker return ((qd->QmfDomainIn[0].pAnaQmfStates == NULL) &&
481*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainOut[0].pSynQmfStates == NULL))
482*e5436536SAndroid Build Coastguard Worker ? 0
483*e5436536SAndroid Build Coastguard Worker : 1;
484*e5436536SAndroid Build Coastguard Worker }
485*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd,UINT extra_flags)486*e5436536SAndroid Build Coastguard Worker int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
487*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd != NULL);
488*e5436536SAndroid Build Coastguard Worker int err = 0;
489*e5436536SAndroid Build Coastguard Worker int ch, ts;
490*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
491*e5436536SAndroid Build Coastguard Worker int noCols = gc->nQmfTimeSlots;
492*e5436536SAndroid Build Coastguard Worker int lsb = gc->nBandsAnalysis;
493*e5436536SAndroid Build Coastguard Worker int usb = fMin((INT)gc->nBandsSynthesis, 64);
494*e5436536SAndroid Build Coastguard Worker int nProcBands = gc->nQmfProcBands;
495*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);
496*e5436536SAndroid Build Coastguard Worker
497*e5436536SAndroid Build Coastguard Worker if (extra_flags & QMF_FLAG_MPSLDFB) {
498*e5436536SAndroid Build Coastguard Worker gc->flags &= ~QMF_FLAG_CLDFB;
499*e5436536SAndroid Build Coastguard Worker gc->flags |= QMF_FLAG_MPSLDFB;
500*e5436536SAndroid Build Coastguard Worker }
501*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < gc->nInputChannels; ch++) {
502*e5436536SAndroid Build Coastguard Worker /* distribute memory to slots array */
503*e5436536SAndroid Build Coastguard Worker FIXP_DBL *ptrOv =
504*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
505*e5436536SAndroid Build Coastguard Worker if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
506*e5436536SAndroid Build Coastguard Worker err = 1;
507*e5436536SAndroid Build Coastguard Worker return err;
508*e5436536SAndroid Build Coastguard Worker }
509*e5436536SAndroid Build Coastguard Worker /* This assumes the workbuffer defined for ch0 is the big one being used to
510*e5436536SAndroid Build Coastguard Worker * hold one full frame of QMF data. */
511*e5436536SAndroid Build Coastguard Worker FIXP_DBL **ptr =
512*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
513*e5436536SAndroid Build Coastguard Worker .pWorkBuffer; /* non-persistent workbuffer */
514*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset =
515*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
516*e5436536SAndroid Build Coastguard Worker .workBufferOffset;
517*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize =
518*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
519*e5436536SAndroid Build Coastguard Worker .workBufferSectSize;
520*e5436536SAndroid Build Coastguard Worker
521*e5436536SAndroid Build Coastguard Worker if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
522*e5436536SAndroid Build Coastguard Worker err = 1;
523*e5436536SAndroid Build Coastguard Worker return err;
524*e5436536SAndroid Build Coastguard Worker }
525*e5436536SAndroid Build Coastguard Worker
526*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].pGlobalConf = gc;
527*e5436536SAndroid Build Coastguard Worker for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
528*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
529*e5436536SAndroid Build Coastguard Worker ptrOv += nProcBands;
530*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
531*e5436536SAndroid Build Coastguard Worker ptrOv += nProcBands;
532*e5436536SAndroid Build Coastguard Worker }
533*e5436536SAndroid Build Coastguard Worker for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
534*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
535*e5436536SAndroid Build Coastguard Worker ptr, workBufferOffset, workBufferSectSize, nProcBands);
536*e5436536SAndroid Build Coastguard Worker workBufferOffset += nProcBands;
537*e5436536SAndroid Build Coastguard Worker qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
538*e5436536SAndroid Build Coastguard Worker ptr, workBufferOffset, workBufferSectSize, nProcBands);
539*e5436536SAndroid Build Coastguard Worker workBufferOffset += nProcBands;
540*e5436536SAndroid Build Coastguard Worker }
541*e5436536SAndroid Build Coastguard Worker err |= qmfInitAnalysisFilterBank(
542*e5436536SAndroid Build Coastguard Worker &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
543*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
544*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
545*e5436536SAndroid Build Coastguard Worker gc->nBandsAnalysis, gc->flags | extra_flags);
546*e5436536SAndroid Build Coastguard Worker }
547*e5436536SAndroid Build Coastguard Worker
548*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < gc->nOutputChannels; ch++) {
549*e5436536SAndroid Build Coastguard Worker FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
550*e5436536SAndroid Build Coastguard Worker int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
551*e5436536SAndroid Build Coastguard Worker int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
552*e5436536SAndroid Build Coastguard Worker err |= qmfInitSynthesisFilterBank(
553*e5436536SAndroid Build Coastguard Worker &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
554*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
555*e5436536SAndroid Build Coastguard Worker (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
556*e5436536SAndroid Build Coastguard Worker gc->nBandsSynthesis, gc->flags | extra_flags);
557*e5436536SAndroid Build Coastguard Worker if (outGain_m != (FIXP_DBL)0) {
558*e5436536SAndroid Build Coastguard Worker qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
559*e5436536SAndroid Build Coastguard Worker }
560*e5436536SAndroid Build Coastguard Worker if (outScale) {
561*e5436536SAndroid Build Coastguard Worker qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
562*e5436536SAndroid Build Coastguard Worker }
563*e5436536SAndroid Build Coastguard Worker }
564*e5436536SAndroid Build Coastguard Worker
565*e5436536SAndroid Build Coastguard Worker return err;
566*e5436536SAndroid Build Coastguard Worker }
567*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,int offset)568*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset) {
569*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch != NULL);
570*e5436536SAndroid Build Coastguard Worker int ts;
571*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
572*e5436536SAndroid Build Coastguard Worker int ovSlots = gc->nQmfOvTimeSlots;
573*e5436536SAndroid Build Coastguard Worker int nCols = gc->nQmfTimeSlots;
574*e5436536SAndroid Build Coastguard Worker int nProcBands = gc->nQmfProcBands;
575*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfReal = qd_ch->hQmfSlotsReal;
576*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfImag = qd_ch->hQmfSlotsImag;
577*e5436536SAndroid Build Coastguard Worker QMF_SCALE_FACTOR *pScaling = &qd_ch->scaling;
578*e5436536SAndroid Build Coastguard Worker
579*e5436536SAndroid Build Coastguard Worker /* for high part it would be enough to save only used part of overlap area */
580*e5436536SAndroid Build Coastguard Worker if (qmfImag != NULL) {
581*e5436536SAndroid Build Coastguard Worker for (ts = offset; ts < ovSlots; ts++) {
582*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
583*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * nProcBands);
584*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qmfImag[ts], qmfImag[nCols + ts],
585*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * nProcBands);
586*e5436536SAndroid Build Coastguard Worker }
587*e5436536SAndroid Build Coastguard Worker } else {
588*e5436536SAndroid Build Coastguard Worker for (ts = 0; ts < ovSlots; ts++) {
589*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
590*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * nProcBands);
591*e5436536SAndroid Build Coastguard Worker }
592*e5436536SAndroid Build Coastguard Worker }
593*e5436536SAndroid Build Coastguard Worker pScaling->ov_lb_scale = pScaling->lb_scale;
594*e5436536SAndroid Build Coastguard Worker }
595*e5436536SAndroid Build Coastguard Worker
596*e5436536SAndroid Build Coastguard Worker /* Convert headroom bits to exponent */
597*e5436536SAndroid Build Coastguard Worker #define SCALE2EXP(s) (15 - (s))
598*e5436536SAndroid Build Coastguard Worker #define EXP2SCALE(e) (15 - (e))
599*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,const int ts,const int start_band,const int stop_band,FIXP_DBL * pQmfOutReal,FIXP_DBL * pQmfOutImag,const int exp_out)600*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
601*e5436536SAndroid Build Coastguard Worker const int start_band, const int stop_band,
602*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
603*e5436536SAndroid Build Coastguard Worker const int exp_out) {
604*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch != NULL);
605*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(pQmfOutReal != NULL);
606*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
607*e5436536SAndroid Build Coastguard Worker const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
608*e5436536SAndroid Build Coastguard Worker const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
609*e5436536SAndroid Build Coastguard Worker const int ovSlots = gc->nQmfOvTimeSlots;
610*e5436536SAndroid Build Coastguard Worker const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
611*e5436536SAndroid Build Coastguard Worker : qd_ch->scaling.lb_scale);
612*e5436536SAndroid Build Coastguard Worker const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
613*e5436536SAndroid Build Coastguard Worker const int lsb = qd_ch->fb.lsb;
614*e5436536SAndroid Build Coastguard Worker const int usb = qd_ch->fb.usb;
615*e5436536SAndroid Build Coastguard Worker int b = start_band;
616*e5436536SAndroid Build Coastguard Worker int lb_sf, hb_sf;
617*e5436536SAndroid Build Coastguard Worker
618*e5436536SAndroid Build Coastguard Worker int target_exp =
619*e5436536SAndroid Build Coastguard Worker ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;
620*e5436536SAndroid Build Coastguard Worker
621*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
622*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(start_band >= 0);
623*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(stop_band <= gc->nQmfProcBands);
624*e5436536SAndroid Build Coastguard Worker
625*e5436536SAndroid Build Coastguard Worker if (qd_ch->fb.no_channels == 24) {
626*e5436536SAndroid Build Coastguard Worker target_exp -= 1;
627*e5436536SAndroid Build Coastguard Worker }
628*e5436536SAndroid Build Coastguard Worker
629*e5436536SAndroid Build Coastguard Worker /* Limit scaling factors to maximum negative value to avoid faulty behaviour
630*e5436536SAndroid Build Coastguard Worker due to right-shifts. Corresponding asserts were observed during robustness
631*e5436536SAndroid Build Coastguard Worker testing.
632*e5436536SAndroid Build Coastguard Worker */
633*e5436536SAndroid Build Coastguard Worker lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
634*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(lb_sf < 32);
635*e5436536SAndroid Build Coastguard Worker hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
636*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(hb_sf < 32);
637*e5436536SAndroid Build Coastguard Worker
638*e5436536SAndroid Build Coastguard Worker if (pQmfOutImag == NULL) {
639*e5436536SAndroid Build Coastguard Worker for (; b < fMin(lsb, stop_band); b++) {
640*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
641*e5436536SAndroid Build Coastguard Worker }
642*e5436536SAndroid Build Coastguard Worker for (; b < fMin(usb, stop_band); b++) {
643*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
644*e5436536SAndroid Build Coastguard Worker }
645*e5436536SAndroid Build Coastguard Worker for (; b < stop_band; b++) {
646*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = (FIXP_DBL)0;
647*e5436536SAndroid Build Coastguard Worker }
648*e5436536SAndroid Build Coastguard Worker } else {
649*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(imag != NULL);
650*e5436536SAndroid Build Coastguard Worker for (; b < fMin(lsb, stop_band); b++) {
651*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
652*e5436536SAndroid Build Coastguard Worker pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
653*e5436536SAndroid Build Coastguard Worker }
654*e5436536SAndroid Build Coastguard Worker for (; b < fMin(usb, stop_band); b++) {
655*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
656*e5436536SAndroid Build Coastguard Worker pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
657*e5436536SAndroid Build Coastguard Worker }
658*e5436536SAndroid Build Coastguard Worker for (; b < stop_band; b++) {
659*e5436536SAndroid Build Coastguard Worker pQmfOutReal[b] = (FIXP_DBL)0;
660*e5436536SAndroid Build Coastguard Worker pQmfOutImag[b] = (FIXP_DBL)0;
661*e5436536SAndroid Build Coastguard Worker }
662*e5436536SAndroid Build Coastguard Worker }
663*e5436536SAndroid Build Coastguard Worker }
664*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,const int ts,FIXP_DBL ** ppQmfReal,FIXP_DBL ** ppQmfImag)665*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
666*e5436536SAndroid Build Coastguard Worker const int ts, FIXP_DBL **ppQmfReal,
667*e5436536SAndroid Build Coastguard Worker FIXP_DBL **ppQmfImag) {
668*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch != NULL);
669*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ppQmfReal != NULL);
670*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ppQmfImag != NULL);
671*e5436536SAndroid Build Coastguard Worker const int bands = qd_ch->workBuf_nBands;
672*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
673*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset = qd_ch->workBufferOffset;
674*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize = qd_ch->workBufferSectSize;
675*e5436536SAndroid Build Coastguard Worker
676*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(bands > 0);
677*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ts < qd_ch->workBuf_nTimeSlots);
678*e5436536SAndroid Build Coastguard Worker
679*e5436536SAndroid Build Coastguard Worker *ppQmfReal = FDK_getWorkBuffer(
680*e5436536SAndroid Build Coastguard Worker pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 0) * bands,
681*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands);
682*e5436536SAndroid Build Coastguard Worker *ppQmfImag = FDK_getWorkBuffer(
683*e5436536SAndroid Build Coastguard Worker pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 1) * bands,
684*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands);
685*e5436536SAndroid Build Coastguard Worker }
686*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_WorkBuffer2ProcChannel(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch)687*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_WorkBuffer2ProcChannel(
688*e5436536SAndroid Build Coastguard Worker const HANDLE_FDK_QMF_DOMAIN_IN qd_ch) {
689*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch != NULL);
690*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
691*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
692*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset = qd_ch->workBufferOffset;
693*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize = qd_ch->workBufferSectSize;
694*e5436536SAndroid Build Coastguard Worker
695*e5436536SAndroid Build Coastguard Worker if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
696*e5436536SAndroid Build Coastguard Worker qd_ch->workBuf_nBands) ==
697*e5436536SAndroid Build Coastguard Worker qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {
698*e5436536SAndroid Build Coastguard Worker /* work buffer is part of processing channel => nothing to do */
699*e5436536SAndroid Build Coastguard Worker return;
700*e5436536SAndroid Build Coastguard Worker } else {
701*e5436536SAndroid Build Coastguard Worker /* copy parked new QMF data to processing channel */
702*e5436536SAndroid Build Coastguard Worker const int bands = qd_ch->workBuf_nBands;
703*e5436536SAndroid Build Coastguard Worker const int slots = qd_ch->workBuf_nTimeSlots;
704*e5436536SAndroid Build Coastguard Worker int ts;
705*e5436536SAndroid Build Coastguard Worker for (ts = 0; ts < slots; ts++) {
706*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
707*e5436536SAndroid Build Coastguard Worker FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
708*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands),
709*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands); // parkBuf_to_anaMatrix
710*e5436536SAndroid Build Coastguard Worker workBufferOffset += bands;
711*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
712*e5436536SAndroid Build Coastguard Worker FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
713*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands),
714*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands);
715*e5436536SAndroid Build Coastguard Worker workBufferOffset += bands;
716*e5436536SAndroid Build Coastguard Worker }
717*e5436536SAndroid Build Coastguard Worker }
718*e5436536SAndroid Build Coastguard Worker }
719*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,FIXP_DBL ** ppQmfReal,FIXP_DBL ** ppQmfImag)720*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
721*e5436536SAndroid Build Coastguard Worker FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag) {
722*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch != NULL);
723*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ppQmfReal != NULL);
724*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(ppQmfImag != NULL);
725*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
726*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
727*e5436536SAndroid Build Coastguard Worker USHORT workBufferOffset = qd_ch->workBufferOffset;
728*e5436536SAndroid Build Coastguard Worker USHORT workBufferSectSize = qd_ch->workBufferSectSize;
729*e5436536SAndroid Build Coastguard Worker
730*e5436536SAndroid Build Coastguard Worker if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
731*e5436536SAndroid Build Coastguard Worker qd_ch->workBuf_nBands) ==
732*e5436536SAndroid Build Coastguard Worker qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) { // left channel (anaMatrix)
733*e5436536SAndroid Build Coastguard Worker int ts;
734*e5436536SAndroid Build Coastguard Worker const int bands = gc->nBandsAnalysis;
735*e5436536SAndroid Build Coastguard Worker const int slots = qd_ch->workBuf_nTimeSlots;
736*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(bands <= 64);
737*e5436536SAndroid Build Coastguard Worker for (ts = 0; ts < slots; ts++) {
738*e5436536SAndroid Build Coastguard Worker /* copy current data of processing channel */
739*e5436536SAndroid Build Coastguard Worker FIXP_DBL tmp[64]; // one slot
740*e5436536SAndroid Build Coastguard Worker /* real */
741*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tmp, qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
742*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands); // anaMatrix_to_tmp
743*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
744*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands); // HBE_to_anaMatrix
745*e5436536SAndroid Build Coastguard Worker FDKmemcpy(ppQmfReal[ts], tmp, sizeof(FIXP_DBL) * bands); // tmp_to_HBE
746*e5436536SAndroid Build Coastguard Worker /* imag */
747*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tmp, qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
748*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands);
749*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
750*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands);
751*e5436536SAndroid Build Coastguard Worker FDKmemcpy(ppQmfImag[ts], tmp, sizeof(FIXP_DBL) * bands);
752*e5436536SAndroid Build Coastguard Worker }
753*e5436536SAndroid Build Coastguard Worker } else { // right channel (parkBuf)
754*e5436536SAndroid Build Coastguard Worker const int bands = qd_ch->workBuf_nBands;
755*e5436536SAndroid Build Coastguard Worker const int slots = qd_ch->workBuf_nTimeSlots;
756*e5436536SAndroid Build Coastguard Worker int ts;
757*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(qd_ch->workBuf_nBands == gc->nBandsAnalysis);
758*e5436536SAndroid Build Coastguard Worker for (ts = 0; ts < slots; ts++) {
759*e5436536SAndroid Build Coastguard Worker /* copy HBE QMF data buffer to processing channel */
760*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
761*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands); // HBE_to_anaMatrix
762*e5436536SAndroid Build Coastguard Worker FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
763*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands);
764*e5436536SAndroid Build Coastguard Worker /* copy parked new QMF data to HBE QMF data buffer */
765*e5436536SAndroid Build Coastguard Worker FDKmemcpy(ppQmfReal[ts],
766*e5436536SAndroid Build Coastguard Worker FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
767*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands),
768*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands); // parkBuf_to_HBE
769*e5436536SAndroid Build Coastguard Worker workBufferOffset += bands;
770*e5436536SAndroid Build Coastguard Worker FDKmemcpy(ppQmfImag[ts],
771*e5436536SAndroid Build Coastguard Worker FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
772*e5436536SAndroid Build Coastguard Worker workBufferSectSize, bands),
773*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * bands);
774*e5436536SAndroid Build Coastguard Worker workBufferOffset += bands;
775*e5436536SAndroid Build Coastguard Worker }
776*e5436536SAndroid Build Coastguard Worker }
777*e5436536SAndroid Build Coastguard Worker }
778*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc)779*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
780*e5436536SAndroid Build Coastguard Worker hgc->qmfDomainExplicitConfig = 0;
781*e5436536SAndroid Build Coastguard Worker hgc->flags_requested = 0;
782*e5436536SAndroid Build Coastguard Worker hgc->nInputChannels_requested = 0;
783*e5436536SAndroid Build Coastguard Worker hgc->nOutputChannels_requested = 0;
784*e5436536SAndroid Build Coastguard Worker hgc->parkChannel_requested = 0;
785*e5436536SAndroid Build Coastguard Worker hgc->nBandsAnalysis_requested = 0;
786*e5436536SAndroid Build Coastguard Worker hgc->nBandsSynthesis_requested = 0;
787*e5436536SAndroid Build Coastguard Worker hgc->nQmfTimeSlots_requested = 0;
788*e5436536SAndroid Build Coastguard Worker hgc->nQmfOvTimeSlots_requested = 0;
789*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcBands_requested = 0;
790*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcChannels_requested = 0;
791*e5436536SAndroid Build Coastguard Worker }
792*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc)793*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
794*e5436536SAndroid Build Coastguard Worker hgc->flags = 0;
795*e5436536SAndroid Build Coastguard Worker hgc->nInputChannels = 0;
796*e5436536SAndroid Build Coastguard Worker hgc->nOutputChannels = 0;
797*e5436536SAndroid Build Coastguard Worker hgc->parkChannel = 0;
798*e5436536SAndroid Build Coastguard Worker hgc->nBandsAnalysis = 0;
799*e5436536SAndroid Build Coastguard Worker hgc->nBandsSynthesis = 0;
800*e5436536SAndroid Build Coastguard Worker hgc->nQmfTimeSlots = 0;
801*e5436536SAndroid Build Coastguard Worker hgc->nQmfOvTimeSlots = 0;
802*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcBands = 0;
803*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcChannels = 0;
804*e5436536SAndroid Build Coastguard Worker }
805*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd)806*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd) {
807*e5436536SAndroid Build Coastguard Worker int ch;
808*e5436536SAndroid Build Coastguard Worker
809*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < ((8) + (1)); ch++) {
810*e5436536SAndroid Build Coastguard Worker FDKmemclear(&hqd->QmfDomainIn[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
811*e5436536SAndroid Build Coastguard Worker }
812*e5436536SAndroid Build Coastguard Worker
813*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < ((8) + (1)); ch++) {
814*e5436536SAndroid Build Coastguard Worker FDKmemclear(&hqd->QmfDomainOut[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
815*e5436536SAndroid Build Coastguard Worker }
816*e5436536SAndroid Build Coastguard Worker }
817*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd)818*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
819*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(hqd != NULL);
820*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
821*e5436536SAndroid Build Coastguard Worker int i, size_main, size, size_temp = 0;
822*e5436536SAndroid Build Coastguard Worker
823*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_QMF_DOMAIN_GC hgc = &hqd->globalConf;
824*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuffer = hgc->pWorkBuffer;
825*e5436536SAndroid Build Coastguard Worker
826*e5436536SAndroid Build Coastguard Worker int hasChanged = 0;
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker if ((hgc->nQmfProcChannels_requested > 0) &&
829*e5436536SAndroid Build Coastguard Worker (hgc->nQmfProcBands_requested != 64)) {
830*e5436536SAndroid Build Coastguard Worker return QMF_DOMAIN_INIT_ERROR;
831*e5436536SAndroid Build Coastguard Worker }
832*e5436536SAndroid Build Coastguard Worker if (hgc->nBandsAnalysis_requested > hgc->nQmfProcBands_requested) {
833*e5436536SAndroid Build Coastguard Worker /* In general the output of the qmf analysis is written to QMF memory slots
834*e5436536SAndroid Build Coastguard Worker which size is defined by nQmfProcBands. nBandsSynthesis may be larger
835*e5436536SAndroid Build Coastguard Worker than nQmfProcBands. This is e.g. the case if the QMF based resampler is
836*e5436536SAndroid Build Coastguard Worker used.
837*e5436536SAndroid Build Coastguard Worker */
838*e5436536SAndroid Build Coastguard Worker return QMF_DOMAIN_INIT_ERROR;
839*e5436536SAndroid Build Coastguard Worker }
840*e5436536SAndroid Build Coastguard Worker
841*e5436536SAndroid Build Coastguard Worker /* 1. adjust change of processing channels by comparison of current and
842*e5436536SAndroid Build Coastguard Worker * requested parameters */
843*e5436536SAndroid Build Coastguard Worker if ((hgc->nQmfProcChannels != hgc->nQmfProcChannels_requested) ||
844*e5436536SAndroid Build Coastguard Worker (hgc->nQmfProcBands != hgc->nQmfProcBands_requested) ||
845*e5436536SAndroid Build Coastguard Worker (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested)) {
846*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hgc->nQmfProcChannels_requested; i++) {
847*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[i].workBuf_nBands = hgc->nQmfProcBands_requested;
848*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcBands = hgc->nQmfProcBands_requested;
849*e5436536SAndroid Build Coastguard Worker
850*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[i].workBuf_nTimeSlots = hgc->nQmfTimeSlots_requested;
851*e5436536SAndroid Build Coastguard Worker }
852*e5436536SAndroid Build Coastguard Worker
853*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcChannels =
854*e5436536SAndroid Build Coastguard Worker hgc->nQmfProcChannels_requested; /* keep highest value encountered so
855*e5436536SAndroid Build Coastguard Worker far as allocated */
856*e5436536SAndroid Build Coastguard Worker
857*e5436536SAndroid Build Coastguard Worker hasChanged = 1;
858*e5436536SAndroid Build Coastguard Worker }
859*e5436536SAndroid Build Coastguard Worker
860*e5436536SAndroid Build Coastguard Worker /* 2. reallocate persistent memory if necessary (analysis state-buffers,
861*e5436536SAndroid Build Coastguard Worker * timeslot-pointer-array, overlap-buffers, synthesis state-buffers) */
862*e5436536SAndroid Build Coastguard Worker if ((hgc->nInputChannels != hgc->nInputChannels_requested) ||
863*e5436536SAndroid Build Coastguard Worker (hgc->nBandsAnalysis != hgc->nBandsAnalysis_requested) ||
864*e5436536SAndroid Build Coastguard Worker (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested) ||
865*e5436536SAndroid Build Coastguard Worker (hgc->nQmfOvTimeSlots != hgc->nQmfOvTimeSlots_requested) ||
866*e5436536SAndroid Build Coastguard Worker (hgc->nOutputChannels != hgc->nOutputChannels_requested) ||
867*e5436536SAndroid Build Coastguard Worker (hgc->nBandsSynthesis != hgc->nBandsSynthesis_requested) ||
868*e5436536SAndroid Build Coastguard Worker (hgc->parkChannel != hgc->parkChannel_requested)) {
869*e5436536SAndroid Build Coastguard Worker hgc->nInputChannels = hgc->nInputChannels_requested;
870*e5436536SAndroid Build Coastguard Worker hgc->nBandsAnalysis = hgc->nBandsAnalysis_requested;
871*e5436536SAndroid Build Coastguard Worker hgc->nQmfTimeSlots = hgc->nQmfTimeSlots_requested;
872*e5436536SAndroid Build Coastguard Worker hgc->nQmfOvTimeSlots = hgc->nQmfOvTimeSlots_requested;
873*e5436536SAndroid Build Coastguard Worker hgc->nOutputChannels = hgc->nOutputChannels_requested;
874*e5436536SAndroid Build Coastguard Worker hgc->nBandsSynthesis = hgc->nBandsSynthesis_requested;
875*e5436536SAndroid Build Coastguard Worker hgc->parkChannel = hgc->parkChannel_requested;
876*e5436536SAndroid Build Coastguard Worker
877*e5436536SAndroid Build Coastguard Worker if (FDK_QmfDomain_AllocatePersistentMemory(hqd)) {
878*e5436536SAndroid Build Coastguard Worker err = QMF_DOMAIN_OUT_OF_MEMORY;
879*e5436536SAndroid Build Coastguard Worker goto bail;
880*e5436536SAndroid Build Coastguard Worker }
881*e5436536SAndroid Build Coastguard Worker
882*e5436536SAndroid Build Coastguard Worker /* 3. set request-flag for downsampled SBR */
883*e5436536SAndroid Build Coastguard Worker if ((hgc->nBandsAnalysis == 32) && (hgc->nBandsSynthesis == 32) &&
884*e5436536SAndroid Build Coastguard Worker !(hgc->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
885*e5436536SAndroid Build Coastguard Worker hgc->flags_requested |= QMF_FLAG_DOWNSAMPLED;
886*e5436536SAndroid Build Coastguard Worker }
887*e5436536SAndroid Build Coastguard Worker
888*e5436536SAndroid Build Coastguard Worker hasChanged = 1;
889*e5436536SAndroid Build Coastguard Worker }
890*e5436536SAndroid Build Coastguard Worker
891*e5436536SAndroid Build Coastguard Worker /* 4. initialize tables and buffer for QMF-resampler */
892*e5436536SAndroid Build Coastguard Worker
893*e5436536SAndroid Build Coastguard Worker /* 5. set requested flags */
894*e5436536SAndroid Build Coastguard Worker if (hgc->flags != hgc->flags_requested) {
895*e5436536SAndroid Build Coastguard Worker if ((hgc->flags_requested & QMF_FLAG_MPSLDFB) &&
896*e5436536SAndroid Build Coastguard Worker (hgc->flags_requested & QMF_FLAG_CLDFB)) {
897*e5436536SAndroid Build Coastguard Worker hgc->flags_requested &= ~QMF_FLAG_CLDFB;
898*e5436536SAndroid Build Coastguard Worker }
899*e5436536SAndroid Build Coastguard Worker hgc->flags = hgc->flags_requested;
900*e5436536SAndroid Build Coastguard Worker hasChanged = 1;
901*e5436536SAndroid Build Coastguard Worker }
902*e5436536SAndroid Build Coastguard Worker
903*e5436536SAndroid Build Coastguard Worker if (hasChanged) {
904*e5436536SAndroid Build Coastguard Worker /* 6. recalculate and check size of required workbuffer-space */
905*e5436536SAndroid Build Coastguard Worker
906*e5436536SAndroid Build Coastguard Worker if (hgc->parkChannel && (hqd->globalConf.nQmfProcChannels == 1)) {
907*e5436536SAndroid Build Coastguard Worker /* configure temp QMF buffer for parking right channel MPS212 output,
908*e5436536SAndroid Build Coastguard Worker * (USAC stereoConfigIndex 3 only) */
909*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[1].workBuf_nBands = hqd->globalConf.nBandsAnalysis;
910*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[1].workBuf_nTimeSlots = hqd->globalConf.nQmfTimeSlots;
911*e5436536SAndroid Build Coastguard Worker size_temp = hqd->QmfDomainIn[1].workBuf_nBands *
912*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[1].workBuf_nTimeSlots * CMPLX_MOD;
913*e5436536SAndroid Build Coastguard Worker }
914*e5436536SAndroid Build Coastguard Worker
915*e5436536SAndroid Build Coastguard Worker size_main = hqd->QmfDomainIn[0].workBuf_nBands *
916*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainIn[0].workBuf_nTimeSlots * CMPLX_MOD;
917*e5436536SAndroid Build Coastguard Worker
918*e5436536SAndroid Build Coastguard Worker size = size_main * hgc->nQmfProcChannels + size_temp;
919*e5436536SAndroid Build Coastguard Worker
920*e5436536SAndroid Build Coastguard Worker if (size > (QMF_MAX_WB_SECTIONS * QMF_WB_SECTION_SIZE)) {
921*e5436536SAndroid Build Coastguard Worker err = QMF_DOMAIN_OUT_OF_MEMORY;
922*e5436536SAndroid Build Coastguard Worker goto bail;
923*e5436536SAndroid Build Coastguard Worker }
924*e5436536SAndroid Build Coastguard Worker
925*e5436536SAndroid Build Coastguard Worker /* 7. allocate additional workbuffer if necessary */
926*e5436536SAndroid Build Coastguard Worker if ((size > 0 /* *QMF_WB_SECTION_SIZE */) && (pWorkBuffer[0] == NULL)) {
927*e5436536SAndroid Build Coastguard Worker /* get work buffer of size QMF_WB_SECTION_SIZE */
928*e5436536SAndroid Build Coastguard Worker pWorkBuffer[0] = GetQmfWorkBufferCore6();
929*e5436536SAndroid Build Coastguard Worker }
930*e5436536SAndroid Build Coastguard Worker
931*e5436536SAndroid Build Coastguard Worker if ((size > 1 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[1] == NULL)) {
932*e5436536SAndroid Build Coastguard Worker /* get work buffer of size QMF_WB_SECTION_SIZE */
933*e5436536SAndroid Build Coastguard Worker pWorkBuffer[1] = GetQmfWorkBufferCore1();
934*e5436536SAndroid Build Coastguard Worker }
935*e5436536SAndroid Build Coastguard Worker
936*e5436536SAndroid Build Coastguard Worker if ((size > 2 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[2] == NULL)) {
937*e5436536SAndroid Build Coastguard Worker /* get work buffer of size QMF_WB_SECTION_SIZE */
938*e5436536SAndroid Build Coastguard Worker pWorkBuffer[2] = GetQmfWorkBufferCore3();
939*e5436536SAndroid Build Coastguard Worker }
940*e5436536SAndroid Build Coastguard Worker
941*e5436536SAndroid Build Coastguard Worker if ((size > 3 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[3] == NULL)) {
942*e5436536SAndroid Build Coastguard Worker /* get work buffer of size QMF_WB_SECTION_SIZE */
943*e5436536SAndroid Build Coastguard Worker pWorkBuffer[3] = GetQmfWorkBufferCore4();
944*e5436536SAndroid Build Coastguard Worker }
945*e5436536SAndroid Build Coastguard Worker
946*e5436536SAndroid Build Coastguard Worker if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
947*e5436536SAndroid Build Coastguard Worker /* get work buffer of size QMF_WB_SECTION_SIZE */
948*e5436536SAndroid Build Coastguard Worker pWorkBuffer[4] = GetQmfWorkBufferCore7();
949*e5436536SAndroid Build Coastguard Worker }
950*e5436536SAndroid Build Coastguard Worker
951*e5436536SAndroid Build Coastguard Worker /* 8. distribute workbuffer over processing channels */
952*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hgc->nQmfProcChannels; i++) {
953*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FeedWorkBuffer(hqd, i, pWorkBuffer, size_main * i,
954*e5436536SAndroid Build Coastguard Worker QMF_WB_SECTION_SIZE, size_main);
955*e5436536SAndroid Build Coastguard Worker }
956*e5436536SAndroid Build Coastguard Worker if (hgc->parkChannel) {
957*e5436536SAndroid Build Coastguard Worker for (; i < hgc->nInputChannels; i++) {
958*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FeedWorkBuffer(hqd, 1, pWorkBuffer,
959*e5436536SAndroid Build Coastguard Worker size_main * hgc->nQmfProcChannels,
960*e5436536SAndroid Build Coastguard Worker QMF_WB_SECTION_SIZE, size_temp);
961*e5436536SAndroid Build Coastguard Worker }
962*e5436536SAndroid Build Coastguard Worker }
963*e5436536SAndroid Build Coastguard Worker
964*e5436536SAndroid Build Coastguard Worker /* 9. (re-)init filterbank */
965*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hgc->nOutputChannels; i++) {
966*e5436536SAndroid Build Coastguard Worker if ((hqd->QmfDomainOut[i].fb.lsb == 0) &&
967*e5436536SAndroid Build Coastguard Worker (hqd->QmfDomainOut[i].fb.usb == 0)) {
968*e5436536SAndroid Build Coastguard Worker /* Although lsb and usb are set in the SBR module, they are initialized
969*e5436536SAndroid Build Coastguard Worker * at this point due to the case of using MPS without SBR. */
970*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainOut[i].fb.lsb = hgc->nBandsAnalysis_requested;
971*e5436536SAndroid Build Coastguard Worker hqd->QmfDomainOut[i].fb.usb =
972*e5436536SAndroid Build Coastguard Worker fMin((INT)hgc->nBandsSynthesis_requested, 64);
973*e5436536SAndroid Build Coastguard Worker }
974*e5436536SAndroid Build Coastguard Worker }
975*e5436536SAndroid Build Coastguard Worker if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
976*e5436536SAndroid Build Coastguard Worker err = QMF_DOMAIN_INIT_ERROR;
977*e5436536SAndroid Build Coastguard Worker }
978*e5436536SAndroid Build Coastguard Worker }
979*e5436536SAndroid Build Coastguard Worker
980*e5436536SAndroid Build Coastguard Worker bail:
981*e5436536SAndroid Build Coastguard Worker if (err) {
982*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreeMem(hqd);
983*e5436536SAndroid Build Coastguard Worker }
984*e5436536SAndroid Build Coastguard Worker return err;
985*e5436536SAndroid Build Coastguard Worker }
986*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd)987*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
988*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pWorkBuffer = hqd->globalConf.pWorkBuffer;
989*e5436536SAndroid Build Coastguard Worker
990*e5436536SAndroid Build Coastguard Worker if (pWorkBuffer[0]) FreeQmfWorkBufferCore6(&pWorkBuffer[0]);
991*e5436536SAndroid Build Coastguard Worker if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
992*e5436536SAndroid Build Coastguard Worker if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
993*e5436536SAndroid Build Coastguard Worker if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
994*e5436536SAndroid Build Coastguard Worker if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]);
995*e5436536SAndroid Build Coastguard Worker }
996*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd)997*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
998*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreeWorkBuffer(hqd);
999*e5436536SAndroid Build Coastguard Worker
1000*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreePersistentMemory(hqd);
1001*e5436536SAndroid Build Coastguard Worker
1002*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_ClearFilterBank(hqd);
1003*e5436536SAndroid Build Coastguard Worker
1004*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_ClearConfigured(&hqd->globalConf);
1005*e5436536SAndroid Build Coastguard Worker
1006*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_ClearRequested(&hqd->globalConf);
1007*e5436536SAndroid Build Coastguard Worker }
1008*e5436536SAndroid Build Coastguard Worker
FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd)1009*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd) {
1010*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreeWorkBuffer(hqd);
1011*e5436536SAndroid Build Coastguard Worker
1012*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_FreePersistentMemory(hqd);
1013*e5436536SAndroid Build Coastguard Worker }
1014