• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CLpc_SynthesisLattice(FIXP_DBL * signal,const int signal_size,const int signal_e,const int signal_e_out,const int inc,const FIXP_SGL * coeff,const int order,FIXP_DBL * state)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                            const int order, FIXP_DBL *state) {
120   int i, j;
121   FIXP_DBL *pSignal;
122   int shift;
123 
124   FDK_ASSERT(order <= LPC_MAX_ORDER);
125   FDK_ASSERT(order > 0);
126 
127   if (inc == -1)
128     pSignal = &signal[signal_size - 1];
129   else
130     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   shift = -order_ld[order - 1];
144 
145   for (i = signal_size; i != 0; i--) {
146     FIXP_DBL *pState = state + order - 1;
147     const FIXP_SGL *pCoeff = coeff + order - 1;
148     FIXP_DBL tmp;
149 
150     tmp = scaleValue(*pSignal, shift + signal_e) -
151           fMultDiv2(*pCoeff--, *pState--);
152     for (j = order - 1; j != 0; j--) {
153       tmp = fMultSubDiv2(tmp, pCoeff[0], pState[0]);
154       pState[1] = pState[0] + (fMultDiv2(*pCoeff--, tmp) << 2);
155       pState--;
156     }
157 
158     *pSignal = scaleValueSaturate(tmp, -shift - signal_e_out);
159 
160     /* exponent of state[] is -1 */
161     pState[1] = tmp << 1;
162     pSignal += inc;
163   }
164 }
165 #endif
166 
167 #ifndef FUNCTION_CLpc_SynthesisLattice_DBL
CLpc_SynthesisLattice(FIXP_DBL * signal,const int signal_size,const int signal_e,const int signal_e_out,const int inc,const FIXP_DBL * coeff,const int order,FIXP_DBL * state)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                            const int order, FIXP_DBL *state) {
172   int i, j;
173   FIXP_DBL *pSignal;
174 
175   FDK_ASSERT(order <= LPC_MAX_ORDER);
176   FDK_ASSERT(order > 0);
177 
178   if (inc == -1)
179     pSignal = &signal[signal_size - 1];
180   else
181     pSignal = &signal[0];
182 
183   FDK_ASSERT(signal_size > 0);
184   for (i = signal_size; i != 0; i--) {
185     FIXP_DBL *pState = state + order - 1;
186     const FIXP_DBL *pCoeff = coeff + order - 1;
187     FIXP_DBL tmp, accu;
188 
189     accu =
190         fMultSubDiv2(scaleValue(*pSignal, signal_e - 1), *pCoeff--, *pState--);
191     tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
192 
193     for (j = order - 1; j != 0; j--) {
194       accu = fMultSubDiv2(tmp >> 1, pCoeff[0], pState[0]);
195       tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
196 
197       accu = fMultAddDiv2(pState[0] >> 1, *pCoeff--, tmp);
198       pState[1] = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
199 
200       pState--;
201     }
202 
203     *pSignal = scaleValue(tmp, -signal_e_out);
204 
205     /* exponent of state[] is 0 */
206     pState[1] = tmp;
207     pSignal += inc;
208   }
209 }
210 
211 #endif
212 
213 /* LPC_SYNTHESIS_IIR version */
CLpc_Synthesis(FIXP_DBL * signal,const int signal_size,const int signal_e,const int inc,const FIXP_LPC_TNS * lpcCoeff_m,const int lpcCoeff_e,const int order,FIXP_DBL * state,int * pStateIndex)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                     int *pStateIndex) {
218   int i, j;
219   FIXP_DBL *pSignal;
220   int stateIndex = *pStateIndex;
221 
222   FIXP_LPC_TNS coeff[2 * LPC_MAX_ORDER];
223   FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS));
224   FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS));
225 
226   FDK_ASSERT(order <= LPC_MAX_ORDER);
227   FDK_ASSERT(stateIndex < order);
228 
229   if (inc == -1)
230     pSignal = &signal[signal_size - 1];
231   else
232     pSignal = &signal[0];
233 
234   /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */
235 
236   for (i = 0; i < signal_size; i++) {
237     FIXP_DBL x;
238     const FIXP_LPC_TNS *pCoeff = coeff + order - stateIndex;
239 
240     x = scaleValue(*pSignal, -(lpcCoeff_e + 1));
241     for (j = 0; j < order; j++) {
242       x -= fMultDiv2(state[j], pCoeff[j]);
243     }
244     x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS);
245 
246     /* Update states */
247     stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1);
248     state[stateIndex] = x;
249 
250     *pSignal = scaleValue(x, signal_e);
251     pSignal += inc;
252   }
253 
254   *pStateIndex = stateIndex;
255 }
256 /* default version */
CLpc_Synthesis(FIXP_DBL * signal,const int signal_size,const int signal_e,const int inc,const FIXP_LPC * lpcCoeff_m,const int lpcCoeff_e,const int order,FIXP_DBL * state,int * pStateIndex)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                     int *pStateIndex) {
261   int i, j;
262   FIXP_DBL *pSignal;
263   int stateIndex = *pStateIndex;
264 
265   FIXP_LPC coeff[2 * LPC_MAX_ORDER];
266   FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC));
267   FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC));
268 
269   FDK_ASSERT(order <= LPC_MAX_ORDER);
270   FDK_ASSERT(stateIndex < order);
271 
272   if (inc == -1)
273     pSignal = &signal[signal_size - 1];
274   else
275     pSignal = &signal[0];
276 
277   /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */
278 
279   for (i = 0; i < signal_size; i++) {
280     FIXP_DBL x;
281     const FIXP_LPC *pCoeff = coeff + order - stateIndex;
282 
283     x = scaleValue(*pSignal, -(lpcCoeff_e + 1));
284     for (j = 0; j < order; j++) {
285       x -= fMultDiv2(state[j], pCoeff[j]);
286     }
287     x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS);
288 
289     /* Update states */
290     stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1);
291     state[stateIndex] = x;
292 
293     *pSignal = scaleValue(x, signal_e);
294     pSignal += inc;
295   }
296 
297   *pStateIndex = stateIndex;
298 }
299 
300 /* FIR */
CLpc_Analysis(FIXP_DBL * RESTRICT signal,const int signal_size,const FIXP_LPC lpcCoeff_m[],const int lpcCoeff_e,const int order,FIXP_DBL * RESTRICT filtState,int * filtStateIndex)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                    int *filtStateIndex) {
305   int stateIndex;
306   INT i, j, shift = lpcCoeff_e + 1; /* +1, because fMultDiv2 */
307   FIXP_DBL tmp;
308 
309   if (order <= 0) {
310     return;
311   }
312   if (filtStateIndex != NULL) {
313     stateIndex = *filtStateIndex;
314   } else {
315     stateIndex = 0;
316   }
317 
318   /* keep filter coefficients twice and save memory copy operation in
319      modulo state buffer */
320   FIXP_LPC coeff[2 * LPC_MAX_ORDER];
321   FIXP_LPC *pCoeff;
322   FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC));
323   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   FDK_ASSERT(shift >= 0);
333 
334   for (j = 0; j < signal_size; j++) {
335     pCoeff = &coeff[(order - stateIndex)];
336 
337     tmp = signal[j] >> shift;
338     for (i = 0; i < order; i++) {
339       tmp = fMultAddDiv2(tmp, pCoeff[i], filtState[i]);
340     }
341 
342     stateIndex =
343         ((stateIndex - 1) < 0) ? (stateIndex - 1 + order) : (stateIndex - 1);
344     filtState[stateIndex] = signal[j];
345 
346     signal[j] = tmp << shift;
347   }
348 
349   if (filtStateIndex != NULL) {
350     *filtStateIndex = stateIndex;
351   }
352 }
353 
354 /* For the LPC_SYNTHESIS_IIR version */
CLpc_ParcorToLpc(const FIXP_LPC_TNS reflCoeff[],FIXP_LPC_TNS LpcCoeff[],INT numOfCoeff,FIXP_DBL workBuffer[])355 INT CLpc_ParcorToLpc(const FIXP_LPC_TNS reflCoeff[], FIXP_LPC_TNS LpcCoeff[],
356                      INT numOfCoeff, FIXP_DBL workBuffer[]) {
357   INT i, j;
358   INT shiftval,
359       par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */
360   FIXP_DBL maxVal = (FIXP_DBL)0;
361 
362   workBuffer[0] = FX_LPC_TNS2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal;
363   for (i = 1; i < numOfCoeff; i++) {
364     for (j = 0; j < i / 2; j++) {
365       FIXP_DBL tmp1, tmp2;
366 
367       tmp1 = workBuffer[j];
368       tmp2 = workBuffer[i - 1 - j];
369       workBuffer[j] += fMult(reflCoeff[i], tmp2);
370       workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1);
371     }
372     if (i & 1) {
373       workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]);
374     }
375 
376     workBuffer[i] = FX_LPC_TNS2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal;
377   }
378 
379   /* calculate exponent */
380   for (i = 0; i < numOfCoeff; i++) {
381     maxVal = fMax(maxVal, fAbs(workBuffer[i]));
382   }
383 
384   shiftval = fMin(fNorm(maxVal), par2LpcShiftVal);
385 
386   for (i = 0; i < numOfCoeff; i++) {
387     LpcCoeff[i] = FX_DBL2FX_LPC_TNS(workBuffer[i] << shiftval);
388   }
389 
390   return (par2LpcShiftVal - shiftval);
391 }
392 /* Default version */
CLpc_ParcorToLpc(const FIXP_LPC reflCoeff[],FIXP_LPC LpcCoeff[],INT numOfCoeff,FIXP_DBL workBuffer[])393 INT CLpc_ParcorToLpc(const FIXP_LPC reflCoeff[], FIXP_LPC LpcCoeff[],
394                      INT numOfCoeff, FIXP_DBL workBuffer[]) {
395   INT i, j;
396   INT shiftval,
397       par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */
398   FIXP_DBL maxVal = (FIXP_DBL)0;
399 
400   workBuffer[0] = FX_LPC2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal;
401   for (i = 1; i < numOfCoeff; i++) {
402     for (j = 0; j < i / 2; j++) {
403       FIXP_DBL tmp1, tmp2;
404 
405       tmp1 = workBuffer[j];
406       tmp2 = workBuffer[i - 1 - j];
407       workBuffer[j] += fMult(reflCoeff[i], tmp2);
408       workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1);
409     }
410     if (i & 1) {
411       workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]);
412     }
413 
414     workBuffer[i] = FX_LPC2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal;
415   }
416 
417   /* calculate exponent */
418   for (i = 0; i < numOfCoeff; i++) {
419     maxVal = fMax(maxVal, fAbs(workBuffer[i]));
420   }
421 
422   shiftval = fMin(fNorm(maxVal), par2LpcShiftVal);
423 
424   for (i = 0; i < numOfCoeff; i++) {
425     LpcCoeff[i] = FX_DBL2FX_LPC(workBuffer[i] << shiftval);
426   }
427 
428   return (par2LpcShiftVal - shiftval);
429 }
430 
CLpc_AutoToParcor(FIXP_DBL acorr[],const int acorr_e,FIXP_LPC reflCoeff[],const int numOfCoeff,FIXP_DBL * pPredictionGain_m,INT * pPredictionGain_e)431 void CLpc_AutoToParcor(FIXP_DBL acorr[], const int acorr_e,
432                        FIXP_LPC reflCoeff[], const int numOfCoeff,
433                        FIXP_DBL *pPredictionGain_m, INT *pPredictionGain_e) {
434   INT i, j, scale = 0;
435   FIXP_DBL parcorWorkBuffer[LPC_MAX_ORDER];
436 
437   FIXP_DBL *workBuffer = parcorWorkBuffer;
438   FIXP_DBL autoCorr_0 = acorr[0];
439 
440   FDKmemclear(reflCoeff, numOfCoeff * sizeof(FIXP_LPC));
441 
442   if (autoCorr_0 == FL2FXCONST_DBL(0.0)) {
443     if (pPredictionGain_m != NULL) {
444       *pPredictionGain_m = FL2FXCONST_DBL(0.5f);
445       *pPredictionGain_e = 1;
446     }
447     return;
448   }
449 
450   FDKmemcpy(workBuffer, acorr + 1, numOfCoeff * sizeof(FIXP_DBL));
451   for (i = 0; i < numOfCoeff; i++) {
452     LONG sign = ((LONG)workBuffer[0] >> (DFRACT_BITS - 1));
453     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     if (acorr[0] < tmp) break;
459 
460     /* tmp = div(num, denum, 16) */
461     tmp = (FIXP_DBL)((LONG)schur_div(tmp, acorr[0], FRACT_BITS) ^ (~sign));
462 
463     reflCoeff[i] = FX_DBL2FX_LPC(tmp);
464 
465     for (j = numOfCoeff - i - 1; j >= 0; j--) {
466       FIXP_DBL accu1 = fMult(tmp, acorr[j]);
467       FIXP_DBL accu2 = fMult(tmp, workBuffer[j]);
468       workBuffer[j] += accu1;
469       acorr[j] += accu2;
470     }
471     /* Check preconditions for division function: denum (=acorr[0]) > 0 */
472     if (acorr[0] == (FIXP_DBL)0) break;
473 
474     workBuffer++;
475   }
476 
477   if (pPredictionGain_m != NULL) {
478     if (acorr[0] > (FIXP_DBL)0) {
479       /* prediction gain = signal power / error (residual) power */
480       *pPredictionGain_m = fDivNormSigned(autoCorr_0, acorr[0], &scale);
481       *pPredictionGain_e = scale;
482     } else {
483       *pPredictionGain_m = (FIXP_DBL)0;
484       *pPredictionGain_e = 0;
485     }
486   }
487 }
488