/src/aac/libFDK/include/qmf_pcm.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2019 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 | | /******************* Library for basic calculation routines ******************** |
96 | | |
97 | | Author(s): Markus Lohwasser, Josef Hoepfl, Manuel Jander |
98 | | |
99 | | Description: QMF filterbank |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #ifndef QMF_PCM_H |
104 | | #define QMF_PCM_H |
105 | | |
106 | | /* |
107 | | All Synthesis functions dependent on datatype INT_PCM_QMFOUT |
108 | | Should only be included by qmf.cpp, but not compiled separately, please |
109 | | exclude compilation from project, if done otherwise. Is optional included |
110 | | twice to duplicate all functions with two different pre-definitions, as: |
111 | | #define INT_PCM_QMFOUT LONG |
112 | | and ... |
113 | | #define INT_PCM_QMFOUT SHORT |
114 | | needed to run QMF synthesis in both 16bit and 32bit sample output format. |
115 | | */ |
116 | | |
117 | | #define QSSCALE (0) |
118 | 11.3G | #define FX_DBL2FX_QSS(x) (x) |
119 | 1.08G | #define FX_QSS2FX_DBL(x) (x) |
120 | | |
121 | | /*! |
122 | | \brief Perform Synthesis Prototype Filtering on a single slot of input data. |
123 | | |
124 | | The filter takes 2 * qmf->no_channels of input data and |
125 | | generates qmf->no_channels time domain output samples. |
126 | | */ |
127 | | /* static */ |
128 | | #ifndef FUNCTION_qmfSynPrototypeFirSlot |
129 | | void qmfSynPrototypeFirSlot( |
130 | | #else |
131 | | void qmfSynPrototypeFirSlot_fallback( |
132 | | #endif |
133 | | HANDLE_QMF_FILTER_BANK qmf, |
134 | | FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */ |
135 | | FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */ |
136 | | INT_PCM_QMFOUT *RESTRICT timeOut, /*!< Time domain data */ |
137 | 21.5M | int stride) { |
138 | 21.5M | FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates; |
139 | 21.5M | int no_channels = qmf->no_channels; |
140 | 21.5M | const FIXP_PFT *p_Filter = qmf->p_filter; |
141 | 21.5M | int p_stride = qmf->p_stride; |
142 | 21.5M | int j; |
143 | 21.5M | FIXP_QSS *RESTRICT sta = FilterStates; |
144 | 21.5M | const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; |
145 | 21.5M | int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor - |
146 | 21.5M | qmf->outGain_e; |
147 | | |
148 | 21.5M | p_flt = |
149 | 21.5M | p_Filter + p_stride * QMF_NO_POLY; /* 5th of 330 */ |
150 | 21.5M | p_fltm = p_Filter + (qmf->FilterSize / 2) - |
151 | 21.5M | p_stride * QMF_NO_POLY; /* 5 + (320 - 2*5) = 315th of 330 */ |
152 | | |
153 | 21.5M | FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m); |
154 | | |
155 | 21.5M | FIXP_DBL rnd_val = 0; |
156 | | |
157 | 21.5M | if (scale > 0) { |
158 | 0 | if (scale < (DFRACT_BITS - 1)) |
159 | 0 | rnd_val = FIXP_DBL(1 << (scale - 1)); |
160 | 0 | else |
161 | 0 | scale = (DFRACT_BITS - 1); |
162 | 21.5M | } else { |
163 | 21.5M | scale = fMax(scale, -(DFRACT_BITS - 1)); |
164 | 21.5M | } |
165 | | |
166 | 1.10G | for (j = no_channels - 1; j >= 0; j--) { |
167 | 1.08G | FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */ |
168 | 1.08G | FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */ |
169 | 1.08G | { |
170 | 1.08G | INT_PCM_QMFOUT tmp; |
171 | 1.08G | FIXP_DBL Are = fMultAddDiv2(FX_QSS2FX_DBL(sta[0]), p_fltm[0], real); |
172 | | |
173 | | /* This PCM formatting performs: |
174 | | - multiplication with 16-bit gain, if not -1.0f |
175 | | - rounding, if shift right is applied |
176 | | - apply shift left (or right) with saturation to 32 (or 16) bits |
177 | | - store output with --stride in 32 (or 16) bit format |
178 | | */ |
179 | 1.08G | if (gain != (FIXP_SGL)(-32768)) /* -1.0f */ |
180 | 0 | { |
181 | 0 | Are = fMult(Are, gain); |
182 | 0 | } |
183 | 1.08G | if (scale >= 0) { |
184 | 55.4k | FDK_ASSERT( |
185 | 55.4k | Are <= |
186 | 55.4k | (Are + rnd_val)); /* Round-addition must not overflow, might be |
187 | | equal for rnd_val=0 */ |
188 | 55.4k | tmp = (INT_PCM_QMFOUT)( |
189 | 55.4k | SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT)); |
190 | 1.08G | } else { |
191 | 1.08G | tmp = (INT_PCM_QMFOUT)( |
192 | 1.08G | SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT)); |
193 | 1.08G | } |
194 | | |
195 | 1.08G | { timeOut[(j)*stride] = tmp; } |
196 | 1.08G | } |
197 | | |
198 | 1.08G | sta[0] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[1]), p_flt[4], imag)); |
199 | 1.08G | sta[1] = |
200 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[2]), p_fltm[1], real)); |
201 | 1.08G | sta[2] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[3]), p_flt[3], imag)); |
202 | 1.08G | sta[3] = |
203 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[4]), p_fltm[2], real)); |
204 | 1.08G | sta[4] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[5]), p_flt[2], imag)); |
205 | 1.08G | sta[5] = |
206 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[6]), p_fltm[3], real)); |
207 | 1.08G | sta[6] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[7]), p_flt[1], imag)); |
208 | 1.08G | sta[7] = |
209 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[8]), p_fltm[4], real)); |
210 | 1.08G | sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag)); |
211 | 1.08G | p_flt += (p_stride * QMF_NO_POLY); |
212 | 1.08G | p_fltm -= (p_stride * QMF_NO_POLY); |
213 | 1.08G | sta += 9; // = (2*QMF_NO_POLY-1); |
214 | 1.08G | } |
215 | 21.5M | } Unexecuted instantiation: qmfSynPrototypeFirSlot(QMF_FILTER_BANK*, int*, int*, short*, int) qmfSynPrototypeFirSlot(QMF_FILTER_BANK*, int*, int*, int*, int) Line | Count | Source | 137 | 21.5M | int stride) { | 138 | 21.5M | FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates; | 139 | 21.5M | int no_channels = qmf->no_channels; | 140 | 21.5M | const FIXP_PFT *p_Filter = qmf->p_filter; | 141 | 21.5M | int p_stride = qmf->p_stride; | 142 | 21.5M | int j; | 143 | 21.5M | FIXP_QSS *RESTRICT sta = FilterStates; | 144 | 21.5M | const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; | 145 | 21.5M | int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor - | 146 | 21.5M | qmf->outGain_e; | 147 | | | 148 | 21.5M | p_flt = | 149 | 21.5M | p_Filter + p_stride * QMF_NO_POLY; /* 5th of 330 */ | 150 | 21.5M | p_fltm = p_Filter + (qmf->FilterSize / 2) - | 151 | 21.5M | p_stride * QMF_NO_POLY; /* 5 + (320 - 2*5) = 315th of 330 */ | 152 | | | 153 | 21.5M | FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m); | 154 | | | 155 | 21.5M | FIXP_DBL rnd_val = 0; | 156 | | | 157 | 21.5M | if (scale > 0) { | 158 | 0 | if (scale < (DFRACT_BITS - 1)) | 159 | 0 | rnd_val = FIXP_DBL(1 << (scale - 1)); | 160 | 0 | else | 161 | 0 | scale = (DFRACT_BITS - 1); | 162 | 21.5M | } else { | 163 | 21.5M | scale = fMax(scale, -(DFRACT_BITS - 1)); | 164 | 21.5M | } | 165 | | | 166 | 1.10G | for (j = no_channels - 1; j >= 0; j--) { | 167 | 1.08G | FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */ | 168 | 1.08G | FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */ | 169 | 1.08G | { | 170 | 1.08G | INT_PCM_QMFOUT tmp; | 171 | 1.08G | FIXP_DBL Are = fMultAddDiv2(FX_QSS2FX_DBL(sta[0]), p_fltm[0], real); | 172 | | | 173 | | /* This PCM formatting performs: | 174 | | - multiplication with 16-bit gain, if not -1.0f | 175 | | - rounding, if shift right is applied | 176 | | - apply shift left (or right) with saturation to 32 (or 16) bits | 177 | | - store output with --stride in 32 (or 16) bit format | 178 | | */ | 179 | 1.08G | if (gain != (FIXP_SGL)(-32768)) /* -1.0f */ | 180 | 0 | { | 181 | 0 | Are = fMult(Are, gain); | 182 | 0 | } | 183 | 1.08G | if (scale >= 0) { | 184 | 55.4k | FDK_ASSERT( | 185 | 55.4k | Are <= | 186 | 55.4k | (Are + rnd_val)); /* Round-addition must not overflow, might be | 187 | | equal for rnd_val=0 */ | 188 | 55.4k | tmp = (INT_PCM_QMFOUT)( | 189 | 55.4k | SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT)); | 190 | 1.08G | } else { | 191 | 1.08G | tmp = (INT_PCM_QMFOUT)( | 192 | 1.08G | SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT)); | 193 | 1.08G | } | 194 | | | 195 | 1.08G | { timeOut[(j)*stride] = tmp; } | 196 | 1.08G | } | 197 | | | 198 | 1.08G | sta[0] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[1]), p_flt[4], imag)); | 199 | 1.08G | sta[1] = | 200 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[2]), p_fltm[1], real)); | 201 | 1.08G | sta[2] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[3]), p_flt[3], imag)); | 202 | 1.08G | sta[3] = | 203 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[4]), p_fltm[2], real)); | 204 | 1.08G | sta[4] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[5]), p_flt[2], imag)); | 205 | 1.08G | sta[5] = | 206 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[6]), p_fltm[3], real)); | 207 | 1.08G | sta[6] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[7]), p_flt[1], imag)); | 208 | 1.08G | sta[7] = | 209 | 1.08G | FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[8]), p_fltm[4], real)); | 210 | 1.08G | sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag)); | 211 | 1.08G | p_flt += (p_stride * QMF_NO_POLY); | 212 | 1.08G | p_fltm -= (p_stride * QMF_NO_POLY); | 213 | 1.08G | sta += 9; // = (2*QMF_NO_POLY-1); | 214 | 1.08G | } | 215 | 21.5M | } |
|
216 | | |
217 | | #ifndef FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric |
218 | | /*! |
219 | | \brief Perform Synthesis Prototype Filtering on a single slot of input data. |
220 | | |
221 | | The filter takes 2 * qmf->no_channels of input data and |
222 | | generates qmf->no_channels time domain output samples. |
223 | | */ |
224 | | static void qmfSynPrototypeFirSlot_NonSymmetric( |
225 | | HANDLE_QMF_FILTER_BANK qmf, |
226 | | FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */ |
227 | | FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */ |
228 | | INT_PCM_QMFOUT *RESTRICT timeOut, /*!< Time domain data */ |
229 | 3.24M | int stride) { |
230 | 3.24M | FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates; |
231 | 3.24M | int no_channels = qmf->no_channels; |
232 | 3.24M | const FIXP_PFT *p_Filter = qmf->p_filter; |
233 | 3.24M | int p_stride = qmf->p_stride; |
234 | 3.24M | int j; |
235 | 3.24M | FIXP_QSS *RESTRICT sta = FilterStates; |
236 | 3.24M | const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; |
237 | 3.24M | int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor - |
238 | 3.24M | qmf->outGain_e; |
239 | | |
240 | 3.24M | p_flt = p_Filter; /*!< Pointer to first half of filter coefficients */ |
241 | 3.24M | p_fltm = |
242 | 3.24M | &p_flt[qmf->FilterSize / 2]; /* at index 320, overall 640 coefficients */ |
243 | | |
244 | 3.24M | FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m); |
245 | | |
246 | 3.24M | FIXP_DBL rnd_val = (FIXP_DBL)0; |
247 | | |
248 | 3.24M | if (scale > 0) { |
249 | 0 | if (scale < (DFRACT_BITS - 1)) |
250 | 0 | rnd_val = FIXP_DBL(1 << (scale - 1)); |
251 | 0 | else |
252 | 0 | scale = (DFRACT_BITS - 1); |
253 | 3.24M | } else { |
254 | 3.24M | scale = fMax(scale, -(DFRACT_BITS - 1)); |
255 | 3.24M | } |
256 | | |
257 | 161M | for (j = no_channels - 1; j >= 0; j--) { |
258 | 158M | FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */ |
259 | 158M | FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */ |
260 | 158M | { |
261 | 158M | INT_PCM_QMFOUT tmp; |
262 | 158M | FIXP_DBL Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[4], real)); |
263 | | |
264 | | /* This PCM formatting performs: |
265 | | - multiplication with 16-bit gain, if not -1.0f |
266 | | - rounding, if shift right is applied |
267 | | - apply shift left (or right) with saturation to 32 (or 16) bits |
268 | | - store output with --stride in 32 (or 16) bit format |
269 | | */ |
270 | 158M | if (gain != (FIXP_SGL)(-32768)) /* -1.0f */ |
271 | 0 | { |
272 | 0 | Are = fMult(Are, gain); |
273 | 0 | } |
274 | 158M | if (scale > 0) { |
275 | 0 | FDK_ASSERT(Are < |
276 | 0 | (Are + rnd_val)); /* Round-addition must not overflow */ |
277 | 0 | tmp = (INT_PCM_QMFOUT)( |
278 | 0 | SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT)); |
279 | 158M | } else { |
280 | 158M | tmp = (INT_PCM_QMFOUT)( |
281 | 158M | SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT)); |
282 | 158M | } |
283 | 158M | timeOut[j * stride] = tmp; |
284 | 158M | } |
285 | | |
286 | 158M | sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2(p_flt[4], imag)); |
287 | 158M | sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[3], real)); |
288 | 158M | sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2(p_flt[3], imag)); |
289 | | |
290 | 158M | sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[2], real)); |
291 | 158M | sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2(p_flt[2], imag)); |
292 | 158M | sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[1], real)); |
293 | 158M | sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2(p_flt[1], imag)); |
294 | | |
295 | 158M | sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[0], real)); |
296 | 158M | sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag)); |
297 | | |
298 | 158M | p_flt += (p_stride * QMF_NO_POLY); |
299 | 158M | p_fltm += (p_stride * QMF_NO_POLY); |
300 | 158M | sta += 9; // = (2*QMF_NO_POLY-1); |
301 | 158M | } |
302 | 3.24M | } Unexecuted instantiation: qmf.cpp:qmfSynPrototypeFirSlot_NonSymmetric(QMF_FILTER_BANK*, int*, int*, short*, int) qmf.cpp:qmfSynPrototypeFirSlot_NonSymmetric(QMF_FILTER_BANK*, int*, int*, int*, int) Line | Count | Source | 229 | 3.24M | int stride) { | 230 | 3.24M | FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates; | 231 | 3.24M | int no_channels = qmf->no_channels; | 232 | 3.24M | const FIXP_PFT *p_Filter = qmf->p_filter; | 233 | 3.24M | int p_stride = qmf->p_stride; | 234 | 3.24M | int j; | 235 | 3.24M | FIXP_QSS *RESTRICT sta = FilterStates; | 236 | 3.24M | const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm; | 237 | 3.24M | int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor - | 238 | 3.24M | qmf->outGain_e; | 239 | | | 240 | 3.24M | p_flt = p_Filter; /*!< Pointer to first half of filter coefficients */ | 241 | 3.24M | p_fltm = | 242 | 3.24M | &p_flt[qmf->FilterSize / 2]; /* at index 320, overall 640 coefficients */ | 243 | | | 244 | 3.24M | FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m); | 245 | | | 246 | 3.24M | FIXP_DBL rnd_val = (FIXP_DBL)0; | 247 | | | 248 | 3.24M | if (scale > 0) { | 249 | 0 | if (scale < (DFRACT_BITS - 1)) | 250 | 0 | rnd_val = FIXP_DBL(1 << (scale - 1)); | 251 | 0 | else | 252 | 0 | scale = (DFRACT_BITS - 1); | 253 | 3.24M | } else { | 254 | 3.24M | scale = fMax(scale, -(DFRACT_BITS - 1)); | 255 | 3.24M | } | 256 | | | 257 | 161M | for (j = no_channels - 1; j >= 0; j--) { | 258 | 158M | FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */ | 259 | 158M | FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */ | 260 | 158M | { | 261 | 158M | INT_PCM_QMFOUT tmp; | 262 | 158M | FIXP_DBL Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[4], real)); | 263 | | | 264 | | /* This PCM formatting performs: | 265 | | - multiplication with 16-bit gain, if not -1.0f | 266 | | - rounding, if shift right is applied | 267 | | - apply shift left (or right) with saturation to 32 (or 16) bits | 268 | | - store output with --stride in 32 (or 16) bit format | 269 | | */ | 270 | 158M | if (gain != (FIXP_SGL)(-32768)) /* -1.0f */ | 271 | 0 | { | 272 | 0 | Are = fMult(Are, gain); | 273 | 0 | } | 274 | 158M | if (scale > 0) { | 275 | 0 | FDK_ASSERT(Are < | 276 | 0 | (Are + rnd_val)); /* Round-addition must not overflow */ | 277 | 0 | tmp = (INT_PCM_QMFOUT)( | 278 | 0 | SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT)); | 279 | 158M | } else { | 280 | 158M | tmp = (INT_PCM_QMFOUT)( | 281 | 158M | SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT)); | 282 | 158M | } | 283 | 158M | timeOut[j * stride] = tmp; | 284 | 158M | } | 285 | | | 286 | 158M | sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2(p_flt[4], imag)); | 287 | 158M | sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[3], real)); | 288 | 158M | sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2(p_flt[3], imag)); | 289 | | | 290 | 158M | sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[2], real)); | 291 | 158M | sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2(p_flt[2], imag)); | 292 | 158M | sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[1], real)); | 293 | 158M | sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2(p_flt[1], imag)); | 294 | | | 295 | 158M | sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[0], real)); | 296 | 158M | sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag)); | 297 | | | 298 | 158M | p_flt += (p_stride * QMF_NO_POLY); | 299 | 158M | p_fltm += (p_stride * QMF_NO_POLY); | 300 | 158M | sta += 9; // = (2*QMF_NO_POLY-1); | 301 | 158M | } | 302 | 3.24M | } |
|
303 | | #endif /* FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric */ |
304 | | |
305 | | void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf, |
306 | | const FIXP_DBL *realSlot, |
307 | | const FIXP_DBL *imagSlot, |
308 | | const int scaleFactorLowBand, |
309 | | const int scaleFactorHighBand, |
310 | | INT_PCM_QMFOUT *timeOut, const int stride, |
311 | 24.7M | FIXP_DBL *pWorkBuffer) { |
312 | 24.7M | if (!(synQmf->flags & QMF_FLAG_LP)) |
313 | 15.5M | qmfInverseModulationHQ(synQmf, realSlot, imagSlot, scaleFactorLowBand, |
314 | 15.5M | scaleFactorHighBand, pWorkBuffer); |
315 | 9.23M | else { |
316 | 9.23M | if (synQmf->flags & QMF_FLAG_CLDFB) { |
317 | 2.22M | qmfInverseModulationLP_odd(synQmf, realSlot, scaleFactorLowBand, |
318 | 2.22M | scaleFactorHighBand, pWorkBuffer); |
319 | 7.01M | } else { |
320 | 7.01M | qmfInverseModulationLP_even(synQmf, realSlot, scaleFactorLowBand, |
321 | 7.01M | scaleFactorHighBand, pWorkBuffer); |
322 | 7.01M | } |
323 | 9.23M | } |
324 | | |
325 | 24.7M | if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) { |
326 | 3.24M | qmfSynPrototypeFirSlot_NonSymmetric(synQmf, pWorkBuffer, |
327 | 3.24M | pWorkBuffer + synQmf->no_channels, |
328 | 3.24M | timeOut, stride); |
329 | 21.5M | } else { |
330 | 21.5M | qmfSynPrototypeFirSlot(synQmf, pWorkBuffer, |
331 | 21.5M | pWorkBuffer + synQmf->no_channels, timeOut, stride); |
332 | 21.5M | } |
333 | 24.7M | } Unexecuted instantiation: qmfSynthesisFilteringSlot(QMF_FILTER_BANK*, int const*, int const*, int, int, short*, int, int*) qmfSynthesisFilteringSlot(QMF_FILTER_BANK*, int const*, int const*, int, int, int*, int, int*) Line | Count | Source | 311 | 24.7M | FIXP_DBL *pWorkBuffer) { | 312 | 24.7M | if (!(synQmf->flags & QMF_FLAG_LP)) | 313 | 15.5M | qmfInverseModulationHQ(synQmf, realSlot, imagSlot, scaleFactorLowBand, | 314 | 15.5M | scaleFactorHighBand, pWorkBuffer); | 315 | 9.23M | else { | 316 | 9.23M | if (synQmf->flags & QMF_FLAG_CLDFB) { | 317 | 2.22M | qmfInverseModulationLP_odd(synQmf, realSlot, scaleFactorLowBand, | 318 | 2.22M | scaleFactorHighBand, pWorkBuffer); | 319 | 7.01M | } else { | 320 | 7.01M | qmfInverseModulationLP_even(synQmf, realSlot, scaleFactorLowBand, | 321 | 7.01M | scaleFactorHighBand, pWorkBuffer); | 322 | 7.01M | } | 323 | 9.23M | } | 324 | | | 325 | 24.7M | if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) { | 326 | 3.24M | qmfSynPrototypeFirSlot_NonSymmetric(synQmf, pWorkBuffer, | 327 | 3.24M | pWorkBuffer + synQmf->no_channels, | 328 | 3.24M | timeOut, stride); | 329 | 21.5M | } else { | 330 | 21.5M | qmfSynPrototypeFirSlot(synQmf, pWorkBuffer, | 331 | 21.5M | pWorkBuffer + synQmf->no_channels, timeOut, stride); | 332 | 21.5M | } | 333 | 24.7M | } |
|
334 | | |
335 | | /*! |
336 | | * |
337 | | * \brief Perform complex-valued subband synthesis of the |
338 | | * low band and the high band and store the |
339 | | * time domain data in timeOut |
340 | | * |
341 | | * First step: Calculate the proper scaling factor of current |
342 | | * spectral data in qmfReal/qmfImag, old spectral data in the overlap |
343 | | * range and filter states. |
344 | | * |
345 | | * Second step: Perform Frequency-to-Time mapping with inverse |
346 | | * Modulation slot-wise. |
347 | | * |
348 | | * Third step: Perform FIR-filter slot-wise. To save space for filter |
349 | | * states, the MAC operations are executed directly on the filter states |
350 | | * instead of accumulating several products in the accumulator. The |
351 | | * buffer shift at the end of the function should be replaced by a |
352 | | * modulo operation, which is available on some DSPs. |
353 | | * |
354 | | * Last step: Copy the upper part of the spectral data to the overlap buffer. |
355 | | * |
356 | | * The qmf coefficient table is symmetric. The symmetry is exploited by |
357 | | * shrinking the coefficient table to half the size. The addressing mode |
358 | | * takes care of the symmetries. If the #define #QMFTABLE_FULL is set, |
359 | | * coefficient addressing works on the full table size. The code will be |
360 | | * slightly faster and slightly more compact. |
361 | | * |
362 | | * Workbuffer requirement: 2 x sizeof(**QmfBufferReal) * synQmf->no_channels |
363 | | * The workbuffer must be aligned |
364 | | */ |
365 | | void qmfSynthesisFiltering( |
366 | | HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ |
367 | | FIXP_DBL **QmfBufferReal, /*!< Low and High band, real */ |
368 | | FIXP_DBL **QmfBufferImag, /*!< Low and High band, imag */ |
369 | | const QMF_SCALE_FACTOR *scaleFactor, |
370 | | const INT ov_len, /*!< split Slot of overlap and actual slots */ |
371 | | INT_PCM_QMFOUT *timeOut, /*!< Pointer to output */ |
372 | | const INT stride, /*!< stride factor of output */ |
373 | | FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ |
374 | 371k | ) { |
375 | 371k | int i; |
376 | 371k | int L = synQmf->no_channels; |
377 | 371k | int scaleFactorHighBand; |
378 | 371k | int scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; |
379 | | |
380 | 371k | FDK_ASSERT(synQmf->no_channels >= synQmf->lsb); |
381 | 371k | FDK_ASSERT(synQmf->no_channels >= synQmf->usb); |
382 | | |
383 | | /* adapt scaling */ |
384 | 371k | scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - |
385 | 371k | scaleFactor->hb_scale - synQmf->filterScale; |
386 | 371k | scaleFactorLowBand_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - |
387 | 371k | scaleFactor->ov_lb_scale - synQmf->filterScale; |
388 | 371k | scaleFactorLowBand_no_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - |
389 | 371k | scaleFactor->lb_scale - synQmf->filterScale; |
390 | | |
391 | 11.4M | for (i = 0; i < synQmf->no_col; i++) /* ----- no_col loop ----- */ |
392 | 11.0M | { |
393 | 11.0M | const FIXP_DBL *QmfBufferImagSlot = NULL; |
394 | | |
395 | 11.0M | int scaleFactorLowBand = |
396 | 11.0M | (i < ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov; |
397 | | |
398 | 11.0M | if (!(synQmf->flags & QMF_FLAG_LP)) QmfBufferImagSlot = QmfBufferImag[i]; |
399 | | |
400 | 11.0M | qmfSynthesisFilteringSlot(synQmf, QmfBufferReal[i], QmfBufferImagSlot, |
401 | 11.0M | scaleFactorLowBand, scaleFactorHighBand, |
402 | 11.0M | timeOut + (i * L * stride), stride, pWorkBuffer); |
403 | 11.0M | } /* no_col loop i */ |
404 | 371k | } Unexecuted instantiation: qmfSynthesisFiltering(QMF_FILTER_BANK*, int**, int**, QMF_SCALE_FACTOR const*, int, short*, int, int*) qmfSynthesisFiltering(QMF_FILTER_BANK*, int**, int**, QMF_SCALE_FACTOR const*, int, int*, int, int*) Line | Count | Source | 374 | 371k | ) { | 375 | 371k | int i; | 376 | 371k | int L = synQmf->no_channels; | 377 | 371k | int scaleFactorHighBand; | 378 | 371k | int scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; | 379 | | | 380 | 371k | FDK_ASSERT(synQmf->no_channels >= synQmf->lsb); | 381 | 371k | FDK_ASSERT(synQmf->no_channels >= synQmf->usb); | 382 | | | 383 | | /* adapt scaling */ | 384 | 371k | scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - | 385 | 371k | scaleFactor->hb_scale - synQmf->filterScale; | 386 | 371k | scaleFactorLowBand_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - | 387 | 371k | scaleFactor->ov_lb_scale - synQmf->filterScale; | 388 | 371k | scaleFactorLowBand_no_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - | 389 | 371k | scaleFactor->lb_scale - synQmf->filterScale; | 390 | | | 391 | 11.4M | for (i = 0; i < synQmf->no_col; i++) /* ----- no_col loop ----- */ | 392 | 11.0M | { | 393 | 11.0M | const FIXP_DBL *QmfBufferImagSlot = NULL; | 394 | | | 395 | 11.0M | int scaleFactorLowBand = | 396 | 11.0M | (i < ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov; | 397 | | | 398 | 11.0M | if (!(synQmf->flags & QMF_FLAG_LP)) QmfBufferImagSlot = QmfBufferImag[i]; | 399 | | | 400 | 11.0M | qmfSynthesisFilteringSlot(synQmf, QmfBufferReal[i], QmfBufferImagSlot, | 401 | 11.0M | scaleFactorLowBand, scaleFactorHighBand, | 402 | 11.0M | timeOut + (i * L * stride), stride, pWorkBuffer); | 403 | 11.0M | } /* no_col loop i */ | 404 | 371k | } |
|
405 | | |
406 | | /*! |
407 | | * |
408 | | * \brief Create QMF filter bank instance |
409 | | * |
410 | | * |
411 | | * \return 0 if successful |
412 | | * |
413 | | */ |
414 | | int qmfInitAnalysisFilterBank( |
415 | | HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */ |
416 | | FIXP_QAS *pFilterStates, /*!< Handle to filter states */ |
417 | | int noCols, /*!< Number of timeslots per frame */ |
418 | | int lsb, /*!< lower end of QMF */ |
419 | | int usb, /*!< upper end of QMF */ |
420 | | int no_channels, /*!< Number of channels (bands) */ |
421 | | int flags) /*!< Low Power flag */ |
422 | 138k | { |
423 | 138k | int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, |
424 | 138k | no_channels, flags, 0); |
425 | 138k | if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) { |
426 | 94.2k | FDKmemclear(h_Qmf->FilterStates, |
427 | 94.2k | (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS)); |
428 | 94.2k | } |
429 | | |
430 | 138k | FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb); |
431 | | |
432 | 138k | return err; |
433 | 138k | } Unexecuted instantiation: qmfInitAnalysisFilterBank(QMF_FILTER_BANK*, short*, int, int, int, int, int) qmfInitAnalysisFilterBank(QMF_FILTER_BANK*, int*, int, int, int, int, int) Line | Count | Source | 422 | 138k | { | 423 | 138k | int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, | 424 | 138k | no_channels, flags, 0); | 425 | 138k | if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) { | 426 | 94.2k | FDKmemclear(h_Qmf->FilterStates, | 427 | 94.2k | (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS)); | 428 | 94.2k | } | 429 | | | 430 | 138k | FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb); | 431 | | | 432 | 138k | return err; | 433 | 138k | } |
|
434 | | |
435 | | #ifndef FUNCTION_qmfAnaPrototypeFirSlot |
436 | | /*! |
437 | | \brief Perform Analysis Prototype Filtering on a single slot of input data. |
438 | | */ |
439 | | static void qmfAnaPrototypeFirSlot( |
440 | | FIXP_DBL *analysisBuffer, |
441 | | INT no_channels, /*!< Number channels of analysis filter */ |
442 | | const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */ |
443 | 15.2M | FIXP_QAS *RESTRICT pFilterStates) { |
444 | 15.2M | INT k; |
445 | | |
446 | 15.2M | FIXP_DBL accu; |
447 | 15.2M | const FIXP_PFT *RESTRICT p_flt = p_filter; |
448 | 15.2M | FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1; |
449 | 15.2M | FIXP_DBL *RESTRICT pData_1 = analysisBuffer; |
450 | | |
451 | 15.2M | FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates; |
452 | 15.2M | FIXP_QAS *RESTRICT sta_1 = |
453 | 15.2M | (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1; |
454 | 15.2M | INT pfltStep = QMF_NO_POLY * (p_stride); |
455 | 15.2M | INT staStep1 = no_channels << 1; |
456 | 15.2M | INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */ |
457 | | |
458 | | /* FIR filters 127..64 0..63 */ |
459 | 396M | for (k = 0; k < no_channels; k++) { |
460 | 381M | accu = fMultDiv2(p_flt[0], *sta_1); |
461 | 381M | sta_1 -= staStep1; |
462 | 381M | accu += fMultDiv2(p_flt[1], *sta_1); |
463 | 381M | sta_1 -= staStep1; |
464 | 381M | accu += fMultDiv2(p_flt[2], *sta_1); |
465 | 381M | sta_1 -= staStep1; |
466 | 381M | accu += fMultDiv2(p_flt[3], *sta_1); |
467 | 381M | sta_1 -= staStep1; |
468 | 381M | accu += fMultDiv2(p_flt[4], *sta_1); |
469 | 381M | *pData_1++ = (accu << 1); |
470 | 381M | sta_1 += staStep2; |
471 | | |
472 | 381M | p_flt += pfltStep; |
473 | 381M | accu = fMultDiv2(p_flt[0], *sta_0); |
474 | 381M | sta_0 += staStep1; |
475 | 381M | accu += fMultDiv2(p_flt[1], *sta_0); |
476 | 381M | sta_0 += staStep1; |
477 | 381M | accu += fMultDiv2(p_flt[2], *sta_0); |
478 | 381M | sta_0 += staStep1; |
479 | 381M | accu += fMultDiv2(p_flt[3], *sta_0); |
480 | 381M | sta_0 += staStep1; |
481 | 381M | accu += fMultDiv2(p_flt[4], *sta_0); |
482 | 381M | *pData_0-- = (accu << 1); |
483 | 381M | sta_0 -= staStep2; |
484 | 381M | } |
485 | 15.2M | } Unexecuted instantiation: qmf.cpp:qmfAnaPrototypeFirSlot(int*, int, short const*, int, short*) qmf.cpp:qmfAnaPrototypeFirSlot(int*, int, short const*, int, int*) Line | Count | Source | 443 | 15.2M | FIXP_QAS *RESTRICT pFilterStates) { | 444 | 15.2M | INT k; | 445 | | | 446 | 15.2M | FIXP_DBL accu; | 447 | 15.2M | const FIXP_PFT *RESTRICT p_flt = p_filter; | 448 | 15.2M | FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1; | 449 | 15.2M | FIXP_DBL *RESTRICT pData_1 = analysisBuffer; | 450 | | | 451 | 15.2M | FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates; | 452 | 15.2M | FIXP_QAS *RESTRICT sta_1 = | 453 | 15.2M | (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1; | 454 | 15.2M | INT pfltStep = QMF_NO_POLY * (p_stride); | 455 | 15.2M | INT staStep1 = no_channels << 1; | 456 | 15.2M | INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */ | 457 | | | 458 | | /* FIR filters 127..64 0..63 */ | 459 | 396M | for (k = 0; k < no_channels; k++) { | 460 | 381M | accu = fMultDiv2(p_flt[0], *sta_1); | 461 | 381M | sta_1 -= staStep1; | 462 | 381M | accu += fMultDiv2(p_flt[1], *sta_1); | 463 | 381M | sta_1 -= staStep1; | 464 | 381M | accu += fMultDiv2(p_flt[2], *sta_1); | 465 | 381M | sta_1 -= staStep1; | 466 | 381M | accu += fMultDiv2(p_flt[3], *sta_1); | 467 | 381M | sta_1 -= staStep1; | 468 | 381M | accu += fMultDiv2(p_flt[4], *sta_1); | 469 | 381M | *pData_1++ = (accu << 1); | 470 | 381M | sta_1 += staStep2; | 471 | | | 472 | 381M | p_flt += pfltStep; | 473 | 381M | accu = fMultDiv2(p_flt[0], *sta_0); | 474 | 381M | sta_0 += staStep1; | 475 | 381M | accu += fMultDiv2(p_flt[1], *sta_0); | 476 | 381M | sta_0 += staStep1; | 477 | 381M | accu += fMultDiv2(p_flt[2], *sta_0); | 478 | 381M | sta_0 += staStep1; | 479 | 381M | accu += fMultDiv2(p_flt[3], *sta_0); | 480 | 381M | sta_0 += staStep1; | 481 | 381M | accu += fMultDiv2(p_flt[4], *sta_0); | 482 | 381M | *pData_0-- = (accu << 1); | 483 | 381M | sta_0 -= staStep2; | 484 | 381M | } | 485 | 15.2M | } |
|
486 | | #endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */ |
487 | | |
488 | | #ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric |
489 | | /*! |
490 | | \brief Perform Analysis Prototype Filtering on a single slot of input data. |
491 | | */ |
492 | | static void qmfAnaPrototypeFirSlot_NonSymmetric( |
493 | | FIXP_DBL *analysisBuffer, |
494 | | int no_channels, /*!< Number channels of analysis filter */ |
495 | | const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */ |
496 | 2.75M | FIXP_QAS *RESTRICT pFilterStates) { |
497 | 2.75M | const FIXP_PFT *RESTRICT p_flt = p_filter; |
498 | 2.75M | int p, k; |
499 | | |
500 | 176M | for (k = 0; k < 2 * no_channels; k++) { |
501 | 174M | FIXP_DBL accu = (FIXP_DBL)0; |
502 | | |
503 | 174M | p_flt += QMF_NO_POLY * (p_stride - 1); |
504 | | |
505 | | /* |
506 | | Perform FIR-Filter |
507 | | */ |
508 | 1.04G | for (p = 0; p < QMF_NO_POLY; p++) { |
509 | 870M | accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]); |
510 | 870M | } |
511 | 174M | analysisBuffer[2 * no_channels - 1 - k] = (accu << 1); |
512 | 174M | pFilterStates++; |
513 | 174M | } |
514 | 2.75M | } Unexecuted instantiation: qmf.cpp:qmfAnaPrototypeFirSlot_NonSymmetric(int*, int, short const*, int, short*) qmf.cpp:qmfAnaPrototypeFirSlot_NonSymmetric(int*, int, short const*, int, int*) Line | Count | Source | 496 | 2.75M | FIXP_QAS *RESTRICT pFilterStates) { | 497 | 2.75M | const FIXP_PFT *RESTRICT p_flt = p_filter; | 498 | 2.75M | int p, k; | 499 | | | 500 | 176M | for (k = 0; k < 2 * no_channels; k++) { | 501 | 174M | FIXP_DBL accu = (FIXP_DBL)0; | 502 | | | 503 | 174M | p_flt += QMF_NO_POLY * (p_stride - 1); | 504 | | | 505 | | /* | 506 | | Perform FIR-Filter | 507 | | */ | 508 | 1.04G | for (p = 0; p < QMF_NO_POLY; p++) { | 509 | 870M | accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]); | 510 | 870M | } | 511 | 174M | analysisBuffer[2 * no_channels - 1 - k] = (accu << 1); | 512 | 174M | pFilterStates++; | 513 | 174M | } | 514 | 2.75M | } |
|
515 | | #endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */ |
516 | | |
517 | | /* |
518 | | * \brief Perform one QMF slot analysis of the time domain data of timeIn |
519 | | * with specified stride and stores the real part of the subband |
520 | | * samples in rSubband, and the imaginary part in iSubband |
521 | | * |
522 | | * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case |
523 | | * of implicit resampling (USAC with reduced 3/4 core frame length). |
524 | | */ |
525 | | void qmfAnalysisFilteringSlot( |
526 | | HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ |
527 | | FIXP_DBL *qmfReal, /*!< Low and High band, real */ |
528 | | FIXP_DBL *qmfImag, /*!< Low and High band, imag */ |
529 | | const INT_PCM_QMFIN *RESTRICT timeIn, /*!< Pointer to input */ |
530 | | const int stride, /*!< stride factor of input */ |
531 | | FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ |
532 | 17.9M | ) { |
533 | 17.9M | int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1); |
534 | | /* |
535 | | Feed time signal into oldest anaQmf->no_channels states |
536 | | */ |
537 | 17.9M | { |
538 | 17.9M | FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset; |
539 | | |
540 | | /* Feed and scale actual time in slot */ |
541 | 252M | for (int i = anaQmf->no_channels >> 1; i != 0; i--) { |
542 | | /* Place INT_PCM value left aligned in scaledTimeIn */ |
543 | 234M | *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; |
544 | 234M | timeIn += stride; |
545 | 234M | *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; |
546 | 234M | timeIn += stride; |
547 | 234M | } |
548 | 17.9M | } |
549 | | |
550 | 17.9M | if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { |
551 | 2.75M | qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels, |
552 | 2.75M | anaQmf->p_filter, anaQmf->p_stride, |
553 | 2.75M | (FIXP_QAS *)anaQmf->FilterStates); |
554 | 15.2M | } else { |
555 | 15.2M | qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter, |
556 | 15.2M | anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates); |
557 | 15.2M | } |
558 | | |
559 | 17.9M | if (anaQmf->flags & QMF_FLAG_LP) { |
560 | 3.62M | if (anaQmf->flags & QMF_FLAG_CLDFB) |
561 | 2.22M | qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal); |
562 | 1.40M | else |
563 | 1.40M | qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal); |
564 | | |
565 | 14.3M | } else { |
566 | 14.3M | qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag); |
567 | 14.3M | } |
568 | | /* |
569 | | Shift filter states |
570 | | |
571 | | Should be realized with modulo addressing on a DSP instead of a true buffer |
572 | | shift |
573 | | */ |
574 | 17.9M | FDKmemmove(anaQmf->FilterStates, |
575 | 17.9M | (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels, |
576 | 17.9M | offset * sizeof(FIXP_QAS)); |
577 | 17.9M | } Unexecuted instantiation: qmfAnalysisFilteringSlot(QMF_FILTER_BANK*, int*, int*, short const*, int, int*) qmfAnalysisFilteringSlot(QMF_FILTER_BANK*, int*, int*, int const*, int, int*) Line | Count | Source | 532 | 17.9M | ) { | 533 | 17.9M | int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1); | 534 | | /* | 535 | | Feed time signal into oldest anaQmf->no_channels states | 536 | | */ | 537 | 17.9M | { | 538 | 17.9M | FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset; | 539 | | | 540 | | /* Feed and scale actual time in slot */ | 541 | 252M | for (int i = anaQmf->no_channels >> 1; i != 0; i--) { | 542 | | /* Place INT_PCM value left aligned in scaledTimeIn */ | 543 | 234M | *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; | 544 | 234M | timeIn += stride; | 545 | 234M | *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; | 546 | 234M | timeIn += stride; | 547 | 234M | } | 548 | 17.9M | } | 549 | | | 550 | 17.9M | if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { | 551 | 2.75M | qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels, | 552 | 2.75M | anaQmf->p_filter, anaQmf->p_stride, | 553 | 2.75M | (FIXP_QAS *)anaQmf->FilterStates); | 554 | 15.2M | } else { | 555 | 15.2M | qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter, | 556 | 15.2M | anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates); | 557 | 15.2M | } | 558 | | | 559 | 17.9M | if (anaQmf->flags & QMF_FLAG_LP) { | 560 | 3.62M | if (anaQmf->flags & QMF_FLAG_CLDFB) | 561 | 2.22M | qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal); | 562 | 1.40M | else | 563 | 1.40M | qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal); | 564 | | | 565 | 14.3M | } else { | 566 | 14.3M | qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag); | 567 | 14.3M | } | 568 | | /* | 569 | | Shift filter states | 570 | | | 571 | | Should be realized with modulo addressing on a DSP instead of a true buffer | 572 | | shift | 573 | | */ | 574 | 17.9M | FDKmemmove(anaQmf->FilterStates, | 575 | 17.9M | (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels, | 576 | 17.9M | offset * sizeof(FIXP_QAS)); | 577 | 17.9M | } |
|
578 | | |
579 | | /*! |
580 | | * |
581 | | * \brief Perform complex-valued subband filtering of the time domain |
582 | | * data of timeIn and stores the real part of the subband |
583 | | * samples in rAnalysis, and the imaginary part in iAnalysis |
584 | | * The qmf coefficient table is symmetric. The symmetry is expoited by |
585 | | * shrinking the coefficient table to half the size. The addressing mode |
586 | | * takes care of the symmetries. |
587 | | * |
588 | | * |
589 | | * \sa PolyphaseFiltering |
590 | | */ |
591 | | void qmfAnalysisFiltering( |
592 | | HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ |
593 | | FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ |
594 | | FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ |
595 | | QMF_SCALE_FACTOR *scaleFactor, |
596 | | const INT_PCM_QMFIN *timeIn, /*!< Time signal */ |
597 | | const int timeIn_e, const int stride, |
598 | | FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ |
599 | 440k | ) { |
600 | 440k | int i; |
601 | 440k | int no_channels = anaQmf->no_channels; |
602 | | |
603 | 440k | scaleFactor->lb_scale = |
604 | 440k | -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e; |
605 | 440k | scaleFactor->lb_scale -= anaQmf->filterScale; |
606 | | |
607 | 12.5M | for (i = 0; i < anaQmf->no_col; i++) { |
608 | 12.1M | FIXP_DBL *qmfImagSlot = NULL; |
609 | | |
610 | 12.1M | if (!(anaQmf->flags & QMF_FLAG_LP)) { |
611 | 8.50M | qmfImagSlot = qmfImag[i]; |
612 | 8.50M | } |
613 | | |
614 | 12.1M | qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride, |
615 | 12.1M | pWorkBuffer); |
616 | | |
617 | 12.1M | timeIn += no_channels * stride; |
618 | | |
619 | 12.1M | } /* no_col loop i */ |
620 | 440k | } Unexecuted instantiation: qmfAnalysisFiltering(QMF_FILTER_BANK*, int**, int**, QMF_SCALE_FACTOR*, short const*, int, int, int*) qmfAnalysisFiltering(QMF_FILTER_BANK*, int**, int**, QMF_SCALE_FACTOR*, int const*, int, int, int*) Line | Count | Source | 599 | 440k | ) { | 600 | 440k | int i; | 601 | 440k | int no_channels = anaQmf->no_channels; | 602 | | | 603 | 440k | scaleFactor->lb_scale = | 604 | 440k | -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e; | 605 | 440k | scaleFactor->lb_scale -= anaQmf->filterScale; | 606 | | | 607 | 12.5M | for (i = 0; i < anaQmf->no_col; i++) { | 608 | 12.1M | FIXP_DBL *qmfImagSlot = NULL; | 609 | | | 610 | 12.1M | if (!(anaQmf->flags & QMF_FLAG_LP)) { | 611 | 8.50M | qmfImagSlot = qmfImag[i]; | 612 | 8.50M | } | 613 | | | 614 | 12.1M | qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride, | 615 | 12.1M | pWorkBuffer); | 616 | | | 617 | 12.1M | timeIn += no_channels * stride; | 618 | | | 619 | 12.1M | } /* no_col loop i */ | 620 | 440k | } |
|
621 | | #endif /* QMF_PCM_H */ |