/src/aac/libSBRenc/src/resampler.cpp
Line  | Count  | Source  | 
1  |  | /* -----------------------------------------------------------------------------  | 
2  |  | Software License for The Fraunhofer FDK AAC Codec Library for Android  | 
3  |  |  | 
4  |  | © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten  | 
5  |  | Forschung e.V. All rights reserved.  | 
6  |  |  | 
7  |  |  1.    INTRODUCTION  | 
8  |  | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software | 
9  |  | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding | 
10  |  | scheme for digital audio. This FDK AAC Codec software is intended to be used on  | 
11  |  | a wide variety of Android devices.  | 
12  |  |  | 
13  |  | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient  | 
14  |  | general perceptual audio codecs. AAC-ELD is considered the best-performing  | 
15  |  | full-bandwidth communications codec by independent studies and is widely  | 
16  |  | deployed. AAC has been standardized by ISO and IEC as part of the MPEG  | 
17  |  | specifications.  | 
18  |  |  | 
19  |  | Patent licenses for necessary patent claims for the FDK AAC Codec (including  | 
20  |  | those of Fraunhofer) may be obtained through Via Licensing  | 
21  |  | (www.vialicensing.com) or through the respective patent owners individually for  | 
22  |  | the purpose of encoding or decoding bit streams in products that are compliant  | 
23  |  | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of  | 
24  |  | Android devices already license these patent claims through Via Licensing or  | 
25  |  | directly from the patent owners, and therefore FDK AAC Codec software may  | 
26  |  | already be covered under those patent licenses when it is used for those  | 
27  |  | licensed purposes only.  | 
28  |  |  | 
29  |  | Commercially-licensed AAC software libraries, including floating-point versions  | 
30  |  | with enhanced sound quality, are also available from Fraunhofer. Users are  | 
31  |  | encouraged to check the Fraunhofer website for additional applications  | 
32  |  | information and documentation.  | 
33  |  |  | 
34  |  | 2.    COPYRIGHT LICENSE  | 
35  |  |  | 
36  |  | Redistribution and use in source and binary forms, with or without modification,  | 
37  |  | are permitted without payment of copyright license fees provided that you  | 
38  |  | satisfy the following conditions:  | 
39  |  |  | 
40  |  | You must retain the complete text of this software license in redistributions of  | 
41  |  | the FDK AAC Codec or your modifications thereto in source code form.  | 
42  |  |  | 
43  |  | You must retain the complete text of this software license in the documentation  | 
44  |  | and/or other materials provided with redistributions of the FDK AAC Codec or  | 
45  |  | your modifications thereto in binary form. You must make available free of  | 
46  |  | charge copies of the complete source code of the FDK AAC Codec and your  | 
47  |  | modifications thereto to recipients of copies in binary form.  | 
48  |  |  | 
49  |  | The name of Fraunhofer may not be used to endorse or promote products derived  | 
50  |  | from this library without prior written permission.  | 
51  |  |  | 
52  |  | You may not charge copyright license fees for anyone to use, copy or distribute  | 
53  |  | the FDK AAC Codec software or your modifications thereto.  | 
54  |  |  | 
55  |  | Your modified versions of the FDK AAC Codec must carry prominent notices stating  | 
56  |  | that you changed the software and the date of any change. For modified versions  | 
57  |  | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"  | 
58  |  | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK  | 
59  |  | AAC Codec Library for Android."  | 
60  |  |  | 
61  |  | 3.    NO PATENT LICENSE  | 
62  |  |  | 
63  |  | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without  | 
64  |  | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.  | 
65  |  | Fraunhofer provides no warranty of patent non-infringement with respect to this  | 
66  |  | software.  | 
67  |  |  | 
68  |  | You may use this FDK AAC Codec software or modifications thereto only for  | 
69  |  | purposes that are authorized by appropriate patent licenses.  | 
70  |  |  | 
71  |  | 4.    DISCLAIMER  | 
72  |  |  | 
73  |  | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright  | 
74  |  | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  | 
75  |  | including but not limited to the implied warranties of merchantability and  | 
76  |  | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR  | 
77  |  | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,  | 
78  |  | or consequential damages, including but not limited to procurement of substitute  | 
79  |  | goods or services; loss of use, data, or profits, or business interruption,  | 
80  |  | however caused and on any theory of liability, whether in contract, strict  | 
81  |  | liability, or tort (including negligence), arising in any way out of the use of  | 
82  |  | this software, even if advised of the possibility of such damage.  | 
83  |  |  | 
84  |  | 5.    CONTACT INFORMATION  | 
85  |  |  | 
86  |  | Fraunhofer Institute for Integrated Circuits IIS  | 
87  |  | Attention: Audio and Multimedia Departments - FDK AAC LL  | 
88  |  | Am Wolfsmantel 33  | 
89  |  | 91058 Erlangen, Germany  | 
90  |  |  | 
91  |  | www.iis.fraunhofer.de/amm  | 
92  |  | amm-info@iis.fraunhofer.de  | 
93  |  | ----------------------------------------------------------------------------- */  | 
94  |  |  | 
95  |  | /**************************** SBR encoder library ******************************  | 
96  |  |  | 
97  |  |    Author(s):  | 
98  |  |  | 
99  |  |    Description:  | 
100  |  |  | 
101  |  | *******************************************************************************/  | 
102  |  |  | 
103  |  | /*!  | 
104  |  |   \file  | 
105  |  |   \brief  FDK resampler tool box:$Revision: 91655 $  | 
106  |  |   \author M. Werner  | 
107  |  | */  | 
108  |  |  | 
109  |  | #include "resampler.h"  | 
110  |  |  | 
111  |  | #include "genericStds.h"  | 
112  |  |  | 
113  |  | /**************************************************************************/  | 
114  |  | /*                   BIQUAD Filter Specifications                         */  | 
115  |  | /**************************************************************************/  | 
116  |  |  | 
117  | 0  | #define B1 0  | 
118  | 0  | #define B2 1  | 
119  | 0  | #define A1 2  | 
120  | 0  | #define A2 3  | 
121  |  |  | 
122  |  | #define BQC(x) FL2FXCONST_SGL(x / 2)  | 
123  |  |  | 
124  |  | struct FILTER_PARAM { | 
125  |  |   const FIXP_SGL *coeffa; /*! SOS matrix One row/section. Scaled using BQC().  | 
126  |  |                              Order of coefficients: B1,B2,A1,A2. B0=A0=1.0 */  | 
127  |  |   FIXP_DBL g;             /*! overall gain */  | 
128  |  |   int Wc;       /*! normalized passband bandwidth at input samplerate * 1000 */  | 
129  |  |   int noCoeffs; /*! number of filter coeffs */  | 
130  |  |   int delay;    /*! delay in samples at input samplerate */  | 
131  |  | };  | 
132  |  |  | 
133  | 0  | #define BIQUAD_COEFSTEP 4  | 
134  |  |  | 
135  |  | /**  | 
136  |  |  *\brief Low Pass  | 
137  |  |  Wc = 0,5, order 30, Stop Band -96dB. Wc criteria is "almost 0dB passband", not  | 
138  |  |  the usual -3db gain point. [b,a]=cheby2(30,96,0.505) [sos,g]=tf2sos(b,a)  | 
139  |  |  bandwidth 0.48  | 
140  |  |  */  | 
141  |  | static const FIXP_SGL sos48[] = { | 
142  |  |     BQC(1.98941075681938),      BQC(0.999999996890811),  | 
143  |  |     BQC(0.863264527201963),     BQC(0.189553799960663),  | 
144  |  |     BQC(1.90733804822445),      BQC(1.00000001736189),  | 
145  |  |     BQC(0.836321575841691),     BQC(0.203505809266564),  | 
146  |  |     BQC(1.75616665495325),      BQC(0.999999946079721),  | 
147  |  |     BQC(0.784699225121588),     BQC(0.230471265506986),  | 
148  |  |     BQC(1.55727745512726),      BQC(1.00000011737815),  | 
149  |  |     BQC(0.712515423588351),     BQC(0.268752723900498),  | 
150  |  |     BQC(1.33407591943643),      BQC(0.999999795953228),  | 
151  |  |     BQC(0.625059117330989),     BQC(0.316194685288965),  | 
152  |  |     BQC(1.10689898412458),      BQC(1.00000035057114),  | 
153  |  |     BQC(0.52803514366398),      BQC(0.370517843224669),  | 
154  |  |     BQC(0.89060371078454),      BQC(0.999999343962822),  | 
155  |  |     BQC(0.426920462165257),     BQC(0.429608200207746),  | 
156  |  |     BQC(0.694438261209433),     BQC(1.0000008629792),  | 
157  |  |     BQC(0.326530699561716),     BQC(0.491714450654174),  | 
158  |  |     BQC(0.523237800935322),     BQC(1.00000101349782),  | 
159  |  |     BQC(0.230829556274851),     BQC(0.555559034843281),  | 
160  |  |     BQC(0.378631165929563),     BQC(0.99998986482665),  | 
161  |  |     BQC(0.142906422036095),     BQC(0.620338874442411),  | 
162  |  |     BQC(0.260786911308437),     BQC(1.00003261460178),  | 
163  |  |     BQC(0.0651008576256505),    BQC(0.685759923926262),  | 
164  |  |     BQC(0.168409429188098),     BQC(0.999933049695828),  | 
165  |  |     BQC(-0.000790067789975562), BQC(0.751905896602325),  | 
166  |  |     BQC(0.100724533818628),     BQC(1.00009472669872),  | 
167  |  |     BQC(-0.0533772830257041),   BQC(0.81930744384525),  | 
168  |  |     BQC(0.0561434357867363),    BQC(0.999911636304276),  | 
169  |  |     BQC(-0.0913550299236405),   BQC(0.88883625875915),  | 
170  |  |     BQC(0.0341680678662057),    BQC(1.00003667508676),  | 
171  |  |     BQC(-0.113405185536697),    BQC(0.961756638268446)};  | 
172  |  |  | 
173  |  | static const FIXP_DBL g48 =  | 
174  |  |     FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;  | 
175  |  |  | 
176  |  | static const struct FILTER_PARAM param_set48 = { | 
177  |  |     sos48, g48, 480, 15, 4 /* LF 2 */  | 
178  |  | };  | 
179  |  |  | 
180  |  | /**  | 
181  |  |  *\brief Low Pass  | 
182  |  |  Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not  | 
183  |  |  the usual -3db gain point. [b,a]=cheby2(24,96,0.5) [sos,g]=tf2sos(b,a)  | 
184  |  |  bandwidth 0.45  | 
185  |  |  */  | 
186  |  | static const FIXP_SGL sos45[] = { | 
187  |  |     BQC(1.982962601444),     BQC(1.00000000007504),    BQC(0.646113303737836),  | 
188  |  |     BQC(0.10851149979981),   BQC(1.85334094281111),    BQC(0.999999999677192),  | 
189  |  |     BQC(0.612073220102006),  BQC(0.130022141698044),   BQC(1.62541051415425),  | 
190  |  |     BQC(1.00000000080398),   BQC(0.547879702855959),   BQC(0.171165825133192),  | 
191  |  |     BQC(1.34554656923247),   BQC(0.9999999980169),     BQC(0.460373914508491),  | 
192  |  |     BQC(0.228677463376354),  BQC(1.05656568503116),    BQC(1.00000000569363),  | 
193  |  |     BQC(0.357891894038287),  BQC(0.298676843912185),   BQC(0.787967587877312),  | 
194  |  |     BQC(0.999999984415017),  BQC(0.248826893211877),   BQC(0.377441803512978),  | 
195  |  |     BQC(0.555480971120497),  BQC(1.00000003583307),    BQC(0.140614263345315),  | 
196  |  |     BQC(0.461979302213679),  BQC(0.364986207070964),   BQC(0.999999932084303),  | 
197  |  |     BQC(0.0392669446074516), BQC(0.55033451180825),    BQC(0.216827267631558),  | 
198  |  |     BQC(1.00000010534682),   BQC(-0.0506232228865103), BQC(0.641691581560946),  | 
199  |  |     BQC(0.108951672277119),  BQC(0.999999871167516),   BQC(-0.125584840183225),  | 
200  |  |     BQC(0.736367748771803),  BQC(0.0387988607229035),  BQC(1.00000011205574),  | 
201  |  |     BQC(-0.182814849097974), BQC(0.835802108714964),   BQC(0.0042866175809225),  | 
202  |  |     BQC(0.999999954830813),  BQC(-0.21965740617151),   BQC(0.942623047782363)};  | 
203  |  |  | 
204  |  | static const FIXP_DBL g45 =  | 
205  |  |     FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000;  | 
206  |  |  | 
207  |  | static const struct FILTER_PARAM param_set45 = { | 
208  |  |     sos45, g45, 450, 12, 4 /* LF 2 */  | 
209  |  | };  | 
210  |  |  | 
211  |  | /*  | 
212  |  |  Created by Octave 2.1.73, Mon Oct 13 17:31:32 2008 CEST  | 
213  |  |  Wc = 0,5, order 16, Stop Band -96dB damping.  | 
214  |  |  [b,a]=cheby2(16,96,0.5)  | 
215  |  |  [sos,g]=tf2sos(b,a)  | 
216  |  |  bandwidth = 0.41  | 
217  |  |  */  | 
218  |  |  | 
219  |  | static const FIXP_SGL sos41[] = { | 
220  |  |     BQC(1.96193625292),      BQC(0.999999999999964),   BQC(0.169266178786789),  | 
221  |  |     BQC(0.0128823300475907), BQC(1.68913437662092),    BQC(1.00000000000053),  | 
222  |  |     BQC(0.124751503206552),  BQC(0.0537472273950989),  BQC(1.27274692366017),  | 
223  |  |     BQC(0.999999999995674),  BQC(0.0433108625178357),  BQC(0.131015753236317),  | 
224  |  |     BQC(0.85214175088395),   BQC(1.00000000001813),    BQC(-0.0625658152550408),  | 
225  |  |     BQC(0.237763778993806),  BQC(0.503841579939009),   BQC(0.999999999953223),  | 
226  |  |     BQC(-0.179176128722865), BQC(0.367475236424474),   BQC(0.249990711986162),  | 
227  |  |     BQC(1.00000000007952),   BQC(-0.294425165824676),  BQC(0.516594857170212),  | 
228  |  |     BQC(0.087971668680286),  BQC(0.999999999915528),   BQC(-0.398956566777928),  | 
229  |  |     BQC(0.686417767801123),  BQC(0.00965373325350294), BQC(1.00000000003744),  | 
230  |  |     BQC(-0.48579173764817),  BQC(0.884931534239068)};  | 
231  |  |  | 
232  |  | static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248);  | 
233  |  |  | 
234  |  | static const struct FILTER_PARAM param_set41 = { | 
235  |  |     sos41, g41, 410, 8, 5 /* LF 3 */  | 
236  |  | };  | 
237  |  |  | 
238  |  | /*  | 
239  |  |  # Created by Octave 2.1.73, Mon Oct 13 17:55:33 2008 CEST  | 
240  |  |  Wc = 0,5, order 12, Stop Band -96dB damping.  | 
241  |  |  [b,a]=cheby2(12,96,0.5);  | 
242  |  |  [sos,g]=tf2sos(b,a)  | 
243  |  | */  | 
244  |  | static const FIXP_SGL sos35[] = { | 
245  |  |     BQC(1.93299325235762),   BQC(0.999999999999985),  BQC(-0.140733187246596),  | 
246  |  |     BQC(0.0124139497836062), BQC(1.4890416764109),    BQC(1.00000000000011),  | 
247  |  |     BQC(-0.198215402588504), BQC(0.0746730616584138), BQC(0.918450161309795),  | 
248  |  |     BQC(0.999999999999619),  BQC(-0.30133912791941),  BQC(0.192276468839529),  | 
249  |  |     BQC(0.454877024246818),  BQC(1.00000000000086),   BQC(-0.432337328809815),  | 
250  |  |     BQC(0.356852933642815),  BQC(0.158017147118507),  BQC(0.999999999998876),  | 
251  |  |     BQC(-0.574817494249777), BQC(0.566380436970833),  BQC(0.0171834649478749),  | 
252  |  |     BQC(1.00000000000055),   BQC(-0.718581178041165), BQC(0.83367484487889)};  | 
253  |  |  | 
254  |  | static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131);  | 
255  |  |  | 
256  |  | static const struct FILTER_PARAM param_set35 = {sos35, g35, 350, 6, 4}; | 
257  |  |  | 
258  |  | /*  | 
259  |  |  # Created by Octave 2.1.73, Mon Oct 13 18:15:38 2008 CEST  | 
260  |  |  Wc = 0,5, order 8, Stop Band -96dB damping.  | 
261  |  |  [b,a]=cheby2(8,96,0.5);  | 
262  |  |  [sos,g]=tf2sos(b,a)  | 
263  |  | */  | 
264  |  | static const FIXP_SGL sos25[] = { | 
265  |  |     BQC(1.85334094301225),   BQC(1.0),  | 
266  |  |     BQC(-0.702127214212663), BQC(0.132452403998767),  | 
267  |  |     BQC(1.056565682167),     BQC(0.999999999999997),  | 
268  |  |     BQC(-0.789503667880785), BQC(0.236328693569128),  | 
269  |  |     BQC(0.364986307455489),  BQC(0.999999999999996),  | 
270  |  |     BQC(-0.955191189843375), BQC(0.442966457936379),  | 
271  |  |     BQC(0.0387985751642125), BQC(1.0),  | 
272  |  |     BQC(-1.19817786088084),  BQC(0.770493895456328)};  | 
273  |  |  | 
274  |  | static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559);  | 
275  |  |  | 
276  |  | static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5}; | 
277  |  |  | 
278  |  | /* Must be sorted in descending order */  | 
279  |  | static const struct FILTER_PARAM *const filter_paramSet[] = { | 
280  |  |     ¶m_set48, ¶m_set45, ¶m_set41, ¶m_set35, ¶m_set25};  | 
281  |  |  | 
282  |  | /**************************************************************************/  | 
283  |  | /*                         Resampler Functions                            */  | 
284  |  | /**************************************************************************/  | 
285  |  |  | 
286  |  | /*!  | 
287  |  |   \brief   Reset downsampler instance and clear delay lines  | 
288  |  |  | 
289  |  |   \return  success of operation  | 
290  |  | */  | 
291  |  |  | 
292  |  | INT FDKaacEnc_InitDownsampler(  | 
293  |  |     DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */  | 
294  |  |     int Wc,                   /*!< normalized cutoff freq * 1000*  */  | 
295  |  |     int ratio)                /*!< downsampler ratio */  | 
296  |  |  | 
297  | 0  | { | 
298  | 0  |   UINT i;  | 
299  | 0  |   const struct FILTER_PARAM *currentSet = NULL;  | 
300  |  | 
  | 
301  | 0  |   FDKmemclear(DownSampler->downFilter.states,  | 
302  | 0  |               sizeof(DownSampler->downFilter.states));  | 
303  | 0  |   DownSampler->downFilter.ptr = 0;  | 
304  |  |  | 
305  |  |   /*  | 
306  |  |     find applicable parameter set  | 
307  |  |   */  | 
308  | 0  |   currentSet = filter_paramSet[0];  | 
309  | 0  |   for (i = 1; i < sizeof(filter_paramSet) / sizeof(struct FILTER_PARAM *);  | 
310  | 0  |        i++) { | 
311  | 0  |     if (filter_paramSet[i]->Wc <= Wc) { | 
312  | 0  |       break;  | 
313  | 0  |     }  | 
314  | 0  |     currentSet = filter_paramSet[i];  | 
315  | 0  |   }  | 
316  |  | 
  | 
317  | 0  |   DownSampler->downFilter.coeffa = currentSet->coeffa;  | 
318  |  | 
  | 
319  | 0  |   DownSampler->downFilter.gain = currentSet->g;  | 
320  | 0  |   FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS * 2);  | 
321  |  |  | 
322  | 0  |   DownSampler->downFilter.noCoeffs = currentSet->noCoeffs;  | 
323  | 0  |   DownSampler->delay = currentSet->delay;  | 
324  | 0  |   DownSampler->downFilter.Wc = currentSet->Wc;  | 
325  |  | 
  | 
326  | 0  |   DownSampler->ratio = ratio;  | 
327  | 0  |   DownSampler->pending = ratio - 1;  | 
328  | 0  |   return (1);  | 
329  | 0  | }  | 
330  |  |  | 
331  |  | /*!  | 
332  |  |   \brief   faster simple folding operation  | 
333  |  |            Filter:  | 
334  |  |            H(z) = A(z)/B(z)  | 
335  |  |            with  | 
336  |  |            A(z) = a[0]*z^0 + a[1]*z^1 + a[2]*z^2 ... a[n]*z^n  | 
337  |  |  | 
338  |  |   \return  filtered value  | 
339  |  | */  | 
340  |  |  | 
341  |  | static inline INT_PCM AdvanceFilter(  | 
342  |  |     LP_FILTER *downFilter, /*!< pointer to iir filter instance */  | 
343  |  |     INT_PCM *pInput,       /*!< input of filter                */  | 
344  | 0  |     int downRatio) { | 
345  | 0  |   INT_PCM output;  | 
346  | 0  |   int i, n;  | 
347  |  | 
  | 
348  | 0  | #define BIQUAD_SCALE 12  | 
349  |  | 
  | 
350  | 0  |   FIXP_DBL y = FL2FXCONST_DBL(0.0f);  | 
351  | 0  |   FIXP_DBL input;  | 
352  |  | 
  | 
353  | 0  |   for (n = 0; n < downRatio; n++) { | 
354  | 0  |     FIXP_BQS(*states)[2] = downFilter->states;  | 
355  | 0  |     const FIXP_SGL *coeff = downFilter->coeffa;  | 
356  | 0  |     int s1, s2;  | 
357  |  | 
  | 
358  | 0  |     s1 = downFilter->ptr;  | 
359  | 0  |     s2 = s1 ^ 1;  | 
360  |  | 
  | 
361  | 0  | #if (SAMPLE_BITS == 16)  | 
362  | 0  |     input = ((FIXP_DBL)pInput[n]) << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE);  | 
363  |  | #elif (SAMPLE_BITS == 32)  | 
364  |  |     input = pInput[n] >> BIQUAD_SCALE;  | 
365  |  | #else  | 
366  |  | #error NOT IMPLEMENTED  | 
367  |  | #endif  | 
368  |  | 
  | 
369  | 0  |     FIXP_BQS state1, state2, state1b, state2b;  | 
370  |  | 
  | 
371  | 0  |     state1 = states[0][s1];  | 
372  | 0  |     state2 = states[0][s2];  | 
373  |  |  | 
374  |  |     /* Loop over sections */  | 
375  | 0  |     for (i = 0; i < downFilter->noCoeffs; i++) { | 
376  | 0  |       FIXP_DBL state0;  | 
377  |  |  | 
378  |  |       /* Load merged states (from next section) */  | 
379  | 0  |       state1b = states[i + 1][s1];  | 
380  | 0  |       state2b = states[i + 1][s2];  | 
381  |  | 
  | 
382  | 0  |       state0 = input + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);  | 
383  | 0  |       y = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]);  | 
384  |  |  | 
385  |  |       /* Store new feed forward merge state */  | 
386  | 0  |       states[i + 1][s2] = y << 1;  | 
387  |  |       /* Store new feed backward state */  | 
388  | 0  |       states[i][s2] = input << 1;  | 
389  |  |  | 
390  |  |       /* Feedback output to next section. */  | 
391  | 0  |       input = y;  | 
392  |  |  | 
393  |  |       /* Transfer merged states */  | 
394  | 0  |       state1 = state1b;  | 
395  | 0  |       state2 = state2b;  | 
396  |  |  | 
397  |  |       /* Step to next coef set */  | 
398  | 0  |       coeff += BIQUAD_COEFSTEP;  | 
399  | 0  |     }  | 
400  | 0  |     downFilter->ptr ^= 1;  | 
401  | 0  |   }  | 
402  |  |   /* Apply global gain */  | 
403  | 0  |   y = fMult(y, downFilter->gain);  | 
404  |  |  | 
405  |  |   /* Apply final gain/scaling to output */  | 
406  | 0  | #if (SAMPLE_BITS == 16)  | 
407  | 0  |   output = (INT_PCM)SATURATE_RIGHT_SHIFT(  | 
408  | 0  |       y + (FIXP_DBL)(1 << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE - 1)),  | 
409  | 0  |       DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE, SAMPLE_BITS);  | 
410  |  |   // output = (INT_PCM) SATURATE_RIGHT_SHIFT(y,  | 
411  |  |   // DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE, SAMPLE_BITS);  | 
412  |  | #else  | 
413  |  |   output = SATURATE_LEFT_SHIFT(y, BIQUAD_SCALE, SAMPLE_BITS);  | 
414  |  | #endif  | 
415  |  | 
  | 
416  | 0  |   return output;  | 
417  | 0  | }  | 
418  |  |  | 
419  |  | /*!  | 
420  |  |   \brief   FDKaacEnc_Downsample numInSamples of type INT_PCM  | 
421  |  |            Returns number of output samples in numOutSamples  | 
422  |  |  | 
423  |  |   \return  success of operation  | 
424  |  | */  | 
425  |  |  | 
426  |  | INT FDKaacEnc_Downsample(  | 
427  |  |     DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */  | 
428  |  |     INT_PCM *inSamples,       /*!< pointer to input samples */  | 
429  |  |     INT numInSamples,         /*!< number  of input samples  */  | 
430  |  |     INT_PCM *outSamples,      /*!< pointer to output samples */  | 
431  |  |     INT *numOutSamples        /*!< pointer tp number of output samples */  | 
432  | 0  | ) { | 
433  | 0  |   INT i;  | 
434  | 0  |   *numOutSamples = 0;  | 
435  |  | 
  | 
436  | 0  |   for (i = 0; i < numInSamples; i += DownSampler->ratio) { | 
437  | 0  |     *outSamples = AdvanceFilter(&(DownSampler->downFilter), &inSamples[i],  | 
438  | 0  |                                 DownSampler->ratio);  | 
439  | 0  |     outSamples++;  | 
440  | 0  |   }  | 
441  | 0  |   *numOutSamples = numInSamples / DownSampler->ratio;  | 
442  |  | 
  | 
443  | 0  |   return 0;  | 
444  | 0  | }  |