/src/fdk-aac/libFDK/src/FDK_lpc.cpp
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 - 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 | | /******************* Library for basic calculation routines ******************** |
96 | | |
97 | | Author(s): Manuel Jander |
98 | | |
99 | | Description: LPC related functions |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "FDK_lpc.h" |
104 | | |
105 | | /* Internal scaling of LPC synthesis to avoid overflow of filte states. |
106 | | This depends on the LPC order, because the LPC order defines the amount |
107 | | of MAC operations. */ |
108 | | static SCHAR order_ld[LPC_MAX_ORDER] = { |
109 | | /* Assume that Synthesis filter output does not clip and filter |
110 | | accu does change no more than 1.0 for each iteration. |
111 | | ceil(0.5*log((1:24))/log(2)) */ |
112 | | 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}; |
113 | | |
114 | | /* IIRLattice */ |
115 | | #ifndef FUNCTION_CLpc_SynthesisLattice_SGL |
116 | | void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size, |
117 | | const int signal_e, const int signal_e_out, |
118 | | const int inc, const FIXP_SGL *coeff, |
119 | 0 | const int order, FIXP_DBL *state) { |
120 | 0 | int i, j; |
121 | 0 | FIXP_DBL *pSignal; |
122 | 0 | int shift; |
123 | |
|
124 | 0 | FDK_ASSERT(order <= LPC_MAX_ORDER); |
125 | 0 | FDK_ASSERT(order > 0); |
126 | | |
127 | 0 | if (inc == -1) |
128 | 0 | pSignal = &signal[signal_size - 1]; |
129 | 0 | else |
130 | 0 | pSignal = &signal[0]; |
131 | | |
132 | | /* |
133 | | tmp = x(k) - K(M)*g(M); |
134 | | for m=M-1:-1:1 |
135 | | tmp = tmp - K(m) * g(m); |
136 | | g(m+1) = g(m) + K(m) * tmp; |
137 | | endfor |
138 | | g(1) = tmp; |
139 | | |
140 | | y(k) = tmp; |
141 | | */ |
142 | |
|
143 | 0 | shift = -order_ld[order - 1]; |
144 | |
|
145 | 0 | for (i = signal_size; i != 0; i--) { |
146 | 0 | FIXP_DBL *pState = state + order - 1; |
147 | 0 | const FIXP_SGL *pCoeff = coeff + order - 1; |
148 | 0 | FIXP_DBL tmp; |
149 | |
|
150 | 0 | tmp = scaleValue(*pSignal, shift + signal_e) - |
151 | 0 | fMultDiv2(*pCoeff--, *pState--); |
152 | 0 | for (j = order - 1; j != 0; j--) { |
153 | 0 | tmp = fMultSubDiv2(tmp, pCoeff[0], pState[0]); |
154 | 0 | pState[1] = pState[0] + (fMultDiv2(*pCoeff--, tmp) << 2); |
155 | 0 | pState--; |
156 | 0 | } |
157 | |
|
158 | 0 | *pSignal = scaleValueSaturate(tmp, -shift - signal_e_out); |
159 | | |
160 | | /* exponent of state[] is -1 */ |
161 | 0 | pState[1] = tmp << 1; |
162 | 0 | pSignal += inc; |
163 | 0 | } |
164 | 0 | } |
165 | | #endif |
166 | | |
167 | | #ifndef FUNCTION_CLpc_SynthesisLattice_DBL |
168 | | void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size, |
169 | | const int signal_e, const int signal_e_out, |
170 | | const int inc, const FIXP_DBL *coeff, |
171 | 0 | const int order, FIXP_DBL *state) { |
172 | 0 | int i, j; |
173 | 0 | FIXP_DBL *pSignal; |
174 | |
|
175 | 0 | FDK_ASSERT(order <= LPC_MAX_ORDER); |
176 | 0 | FDK_ASSERT(order > 0); |
177 | | |
178 | 0 | if (inc == -1) |
179 | 0 | pSignal = &signal[signal_size - 1]; |
180 | 0 | else |
181 | 0 | pSignal = &signal[0]; |
182 | |
|
183 | 0 | FDK_ASSERT(signal_size > 0); |
184 | 0 | for (i = signal_size; i != 0; i--) { |
185 | 0 | FIXP_DBL *pState = state + order - 1; |
186 | 0 | const FIXP_DBL *pCoeff = coeff + order - 1; |
187 | 0 | FIXP_DBL tmp, accu; |
188 | |
|
189 | 0 | accu = |
190 | 0 | fMultSubDiv2(scaleValue(*pSignal, signal_e - 1), *pCoeff--, *pState--); |
191 | 0 | tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); |
192 | |
|
193 | 0 | for (j = order - 1; j != 0; j--) { |
194 | 0 | accu = fMultSubDiv2(tmp >> 1, pCoeff[0], pState[0]); |
195 | 0 | tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); |
196 | |
|
197 | 0 | accu = fMultAddDiv2(pState[0] >> 1, *pCoeff--, tmp); |
198 | 0 | pState[1] = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); |
199 | |
|
200 | 0 | pState--; |
201 | 0 | } |
202 | |
|
203 | 0 | *pSignal = scaleValue(tmp, -signal_e_out); |
204 | | |
205 | | /* exponent of state[] is 0 */ |
206 | 0 | pState[1] = tmp; |
207 | 0 | pSignal += inc; |
208 | 0 | } |
209 | 0 | } |
210 | | |
211 | | #endif |
212 | | |
213 | | /* LPC_SYNTHESIS_IIR version */ |
214 | | void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e, |
215 | | const int inc, const FIXP_LPC_TNS *lpcCoeff_m, |
216 | | const int lpcCoeff_e, const int order, FIXP_DBL *state, |
217 | 0 | int *pStateIndex) { |
218 | 0 | int i, j; |
219 | 0 | FIXP_DBL *pSignal; |
220 | 0 | int stateIndex = *pStateIndex; |
221 | |
|
222 | 0 | FIXP_LPC_TNS coeff[2 * LPC_MAX_ORDER]; |
223 | 0 | FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS)); |
224 | 0 | FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS)); |
225 | |
|
226 | 0 | FDK_ASSERT(order <= LPC_MAX_ORDER); |
227 | 0 | FDK_ASSERT(stateIndex < order); |
228 | | |
229 | 0 | if (inc == -1) |
230 | 0 | pSignal = &signal[signal_size - 1]; |
231 | 0 | else |
232 | 0 | pSignal = &signal[0]; |
233 | | |
234 | | /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */ |
235 | |
|
236 | 0 | for (i = 0; i < signal_size; i++) { |
237 | 0 | FIXP_DBL x; |
238 | 0 | const FIXP_LPC_TNS *pCoeff = coeff + order - stateIndex; |
239 | |
|
240 | 0 | x = scaleValue(*pSignal, -(lpcCoeff_e + 1)); |
241 | 0 | for (j = 0; j < order; j++) { |
242 | 0 | x -= fMultDiv2(state[j], pCoeff[j]); |
243 | 0 | } |
244 | 0 | x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS); |
245 | | |
246 | | /* Update states */ |
247 | 0 | stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1); |
248 | 0 | state[stateIndex] = x; |
249 | |
|
250 | 0 | *pSignal = scaleValue(x, signal_e); |
251 | 0 | pSignal += inc; |
252 | 0 | } |
253 | |
|
254 | 0 | *pStateIndex = stateIndex; |
255 | 0 | } |
256 | | /* default version */ |
257 | | void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e, |
258 | | const int inc, const FIXP_LPC *lpcCoeff_m, |
259 | | const int lpcCoeff_e, const int order, FIXP_DBL *state, |
260 | 0 | int *pStateIndex) { |
261 | 0 | int i, j; |
262 | 0 | FIXP_DBL *pSignal; |
263 | 0 | int stateIndex = *pStateIndex; |
264 | |
|
265 | 0 | FIXP_LPC coeff[2 * LPC_MAX_ORDER]; |
266 | 0 | FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC)); |
267 | 0 | FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC)); |
268 | |
|
269 | 0 | FDK_ASSERT(order <= LPC_MAX_ORDER); |
270 | 0 | FDK_ASSERT(stateIndex < order); |
271 | | |
272 | 0 | if (inc == -1) |
273 | 0 | pSignal = &signal[signal_size - 1]; |
274 | 0 | else |
275 | 0 | pSignal = &signal[0]; |
276 | | |
277 | | /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */ |
278 | |
|
279 | 0 | for (i = 0; i < signal_size; i++) { |
280 | 0 | FIXP_DBL x; |
281 | 0 | const FIXP_LPC *pCoeff = coeff + order - stateIndex; |
282 | |
|
283 | 0 | x = scaleValue(*pSignal, -(lpcCoeff_e + 1)); |
284 | 0 | for (j = 0; j < order; j++) { |
285 | 0 | x -= fMultDiv2(state[j], pCoeff[j]); |
286 | 0 | } |
287 | 0 | x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS); |
288 | | |
289 | | /* Update states */ |
290 | 0 | stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1); |
291 | 0 | state[stateIndex] = x; |
292 | |
|
293 | 0 | *pSignal = scaleValue(x, signal_e); |
294 | 0 | pSignal += inc; |
295 | 0 | } |
296 | |
|
297 | 0 | *pStateIndex = stateIndex; |
298 | 0 | } |
299 | | |
300 | | /* FIR */ |
301 | | void CLpc_Analysis(FIXP_DBL *RESTRICT signal, const int signal_size, |
302 | | const FIXP_LPC lpcCoeff_m[], const int lpcCoeff_e, |
303 | | const int order, FIXP_DBL *RESTRICT filtState, |
304 | 0 | int *filtStateIndex) { |
305 | 0 | int stateIndex; |
306 | 0 | INT i, j, shift = lpcCoeff_e + 1; /* +1, because fMultDiv2 */ |
307 | 0 | FIXP_DBL tmp; |
308 | |
|
309 | 0 | if (order <= 0) { |
310 | 0 | return; |
311 | 0 | } |
312 | 0 | if (filtStateIndex != NULL) { |
313 | 0 | stateIndex = *filtStateIndex; |
314 | 0 | } else { |
315 | 0 | stateIndex = 0; |
316 | 0 | } |
317 | | |
318 | | /* keep filter coefficients twice and save memory copy operation in |
319 | | modulo state buffer */ |
320 | 0 | FIXP_LPC coeff[2 * LPC_MAX_ORDER]; |
321 | 0 | FIXP_LPC *pCoeff; |
322 | 0 | FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC)); |
323 | 0 | FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC)); |
324 | | |
325 | | /* |
326 | | # Analysis filter, obtain residual. |
327 | | for k = 0:BL-1 |
328 | | err(i-BL+k) = a * inputSignal(i-BL+k:-1:i-BL-M+k); |
329 | | endfor |
330 | | */ |
331 | |
|
332 | 0 | FDK_ASSERT(shift >= 0); |
333 | | |
334 | 0 | for (j = 0; j < signal_size; j++) { |
335 | 0 | pCoeff = &coeff[(order - stateIndex)]; |
336 | |
|
337 | 0 | tmp = signal[j] >> shift; |
338 | 0 | for (i = 0; i < order; i++) { |
339 | 0 | tmp = fMultAddDiv2(tmp, pCoeff[i], filtState[i]); |
340 | 0 | } |
341 | |
|
342 | 0 | stateIndex = |
343 | 0 | ((stateIndex - 1) < 0) ? (stateIndex - 1 + order) : (stateIndex - 1); |
344 | 0 | filtState[stateIndex] = signal[j]; |
345 | |
|
346 | 0 | signal[j] = tmp << shift; |
347 | 0 | } |
348 | |
|
349 | 0 | if (filtStateIndex != NULL) { |
350 | 0 | *filtStateIndex = stateIndex; |
351 | 0 | } |
352 | 0 | } |
353 | | |
354 | | /* For the LPC_SYNTHESIS_IIR version */ |
355 | | INT CLpc_ParcorToLpc(const FIXP_LPC_TNS reflCoeff[], FIXP_LPC_TNS LpcCoeff[], |
356 | 0 | INT numOfCoeff, FIXP_DBL workBuffer[]) { |
357 | 0 | INT i, j; |
358 | 0 | INT shiftval, |
359 | 0 | par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ |
360 | 0 | FIXP_DBL maxVal = (FIXP_DBL)0; |
361 | |
|
362 | 0 | workBuffer[0] = FX_LPC_TNS2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal; |
363 | 0 | for (i = 1; i < numOfCoeff; i++) { |
364 | 0 | for (j = 0; j < i / 2; j++) { |
365 | 0 | FIXP_DBL tmp1, tmp2; |
366 | |
|
367 | 0 | tmp1 = workBuffer[j]; |
368 | 0 | tmp2 = workBuffer[i - 1 - j]; |
369 | 0 | workBuffer[j] += fMult(reflCoeff[i], tmp2); |
370 | 0 | workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1); |
371 | 0 | } |
372 | 0 | if (i & 1) { |
373 | 0 | workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]); |
374 | 0 | } |
375 | |
|
376 | 0 | workBuffer[i] = FX_LPC_TNS2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal; |
377 | 0 | } |
378 | | |
379 | | /* calculate exponent */ |
380 | 0 | for (i = 0; i < numOfCoeff; i++) { |
381 | 0 | maxVal = fMax(maxVal, fAbs(workBuffer[i])); |
382 | 0 | } |
383 | |
|
384 | 0 | shiftval = fMin(fNorm(maxVal), par2LpcShiftVal); |
385 | |
|
386 | 0 | for (i = 0; i < numOfCoeff; i++) { |
387 | 0 | LpcCoeff[i] = FX_DBL2FX_LPC_TNS(workBuffer[i] << shiftval); |
388 | 0 | } |
389 | |
|
390 | 0 | return (par2LpcShiftVal - shiftval); |
391 | 0 | } |
392 | | /* Default version */ |
393 | | INT CLpc_ParcorToLpc(const FIXP_LPC reflCoeff[], FIXP_LPC LpcCoeff[], |
394 | 0 | INT numOfCoeff, FIXP_DBL workBuffer[]) { |
395 | 0 | INT i, j; |
396 | 0 | INT shiftval, |
397 | 0 | par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ |
398 | 0 | FIXP_DBL maxVal = (FIXP_DBL)0; |
399 | |
|
400 | 0 | workBuffer[0] = FX_LPC2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal; |
401 | 0 | for (i = 1; i < numOfCoeff; i++) { |
402 | 0 | for (j = 0; j < i / 2; j++) { |
403 | 0 | FIXP_DBL tmp1, tmp2; |
404 | |
|
405 | 0 | tmp1 = workBuffer[j]; |
406 | 0 | tmp2 = workBuffer[i - 1 - j]; |
407 | 0 | workBuffer[j] += fMult(reflCoeff[i], tmp2); |
408 | 0 | workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1); |
409 | 0 | } |
410 | 0 | if (i & 1) { |
411 | 0 | workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]); |
412 | 0 | } |
413 | |
|
414 | 0 | workBuffer[i] = FX_LPC2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal; |
415 | 0 | } |
416 | | |
417 | | /* calculate exponent */ |
418 | 0 | for (i = 0; i < numOfCoeff; i++) { |
419 | 0 | maxVal = fMax(maxVal, fAbs(workBuffer[i])); |
420 | 0 | } |
421 | |
|
422 | 0 | shiftval = fMin(fNorm(maxVal), par2LpcShiftVal); |
423 | |
|
424 | 0 | for (i = 0; i < numOfCoeff; i++) { |
425 | 0 | LpcCoeff[i] = FX_DBL2FX_LPC(workBuffer[i] << shiftval); |
426 | 0 | } |
427 | |
|
428 | 0 | return (par2LpcShiftVal - shiftval); |
429 | 0 | } |
430 | | |
431 | | void CLpc_AutoToParcor(FIXP_DBL acorr[], const int acorr_e, |
432 | | FIXP_LPC reflCoeff[], const int numOfCoeff, |
433 | 0 | FIXP_DBL *pPredictionGain_m, INT *pPredictionGain_e) { |
434 | 0 | INT i, j, scale = 0; |
435 | 0 | FIXP_DBL parcorWorkBuffer[LPC_MAX_ORDER]; |
436 | |
|
437 | 0 | FIXP_DBL *workBuffer = parcorWorkBuffer; |
438 | 0 | FIXP_DBL autoCorr_0 = acorr[0]; |
439 | |
|
440 | 0 | FDKmemclear(reflCoeff, numOfCoeff * sizeof(FIXP_LPC)); |
441 | |
|
442 | 0 | if (autoCorr_0 == FL2FXCONST_DBL(0.0)) { |
443 | 0 | if (pPredictionGain_m != NULL) { |
444 | 0 | *pPredictionGain_m = FL2FXCONST_DBL(0.5f); |
445 | 0 | *pPredictionGain_e = 1; |
446 | 0 | } |
447 | 0 | return; |
448 | 0 | } |
449 | | |
450 | 0 | FDKmemcpy(workBuffer, acorr + 1, numOfCoeff * sizeof(FIXP_DBL)); |
451 | 0 | for (i = 0; i < numOfCoeff; i++) { |
452 | 0 | LONG sign = ((LONG)workBuffer[0] >> (DFRACT_BITS - 1)); |
453 | 0 | FIXP_DBL tmp = (FIXP_DBL)((LONG)workBuffer[0] ^ sign); |
454 | | |
455 | | /* Check preconditions for division function: num<=denum */ |
456 | | /* For 1st iteration acorr[0] cannot be 0, it is checked before loop */ |
457 | | /* Due to exor operation with "sign", num(=tmp) is greater/equal 0 */ |
458 | 0 | if (acorr[0] < tmp) break; |
459 | | |
460 | | /* tmp = div(num, denum, 16) */ |
461 | 0 | tmp = (FIXP_DBL)((LONG)schur_div(tmp, acorr[0], FRACT_BITS) ^ (~sign)); |
462 | |
|
463 | 0 | reflCoeff[i] = FX_DBL2FX_LPC(tmp); |
464 | |
|
465 | 0 | for (j = numOfCoeff - i - 1; j >= 0; j--) { |
466 | 0 | FIXP_DBL accu1 = fMult(tmp, acorr[j]); |
467 | 0 | FIXP_DBL accu2 = fMult(tmp, workBuffer[j]); |
468 | 0 | workBuffer[j] += accu1; |
469 | 0 | acorr[j] += accu2; |
470 | 0 | } |
471 | | /* Check preconditions for division function: denum (=acorr[0]) > 0 */ |
472 | 0 | if (acorr[0] == (FIXP_DBL)0) break; |
473 | | |
474 | 0 | workBuffer++; |
475 | 0 | } |
476 | |
|
477 | 0 | if (pPredictionGain_m != NULL) { |
478 | 0 | if (acorr[0] > (FIXP_DBL)0) { |
479 | | /* prediction gain = signal power / error (residual) power */ |
480 | 0 | *pPredictionGain_m = fDivNormSigned(autoCorr_0, acorr[0], &scale); |
481 | 0 | *pPredictionGain_e = scale; |
482 | 0 | } else { |
483 | 0 | *pPredictionGain_m = (FIXP_DBL)0; |
484 | 0 | *pPredictionGain_e = 0; |
485 | 0 | } |
486 | 0 | } |
487 | 0 | } |