2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
88 #include "genericStds.h"
89 #include "autocorr2nd.h"
93 /***************************************************************************
95 Send autoCorrSecondOrder to mlfile
97 ****************************************************************************/
99 /**************************************************************************/
101 \brief Calculates the tonal to noise ration for different frequency bands
104 The ratio between the predicted energy (tonal energy A) and the total
105 energy (A + B) is calculated. This is converted to the ratio between
106 the predicted energy (tonal energy A) and the non-predictable energy
107 (noise energy B). Hence the quota-matrix contains A/B = q/(1-q).
109 The samples in nrgVector are scaled by 1.0/16.0
110 The samples in pNrgVectorFreq are scaled by 1.0/2.0
111 The samples in quotaMatrix are scaled by RELAXATION
116 /**************************************************************************/
119 FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr
, /*!< Handle to SBR_TON_CORR struct. */
120 FIXP_DBL
**RESTRICT sourceBufferReal
, /*!< The real part of the QMF-matrix. */
121 FIXP_DBL
**RESTRICT sourceBufferImag
, /*!< The imaginary part of the QMF-matrix. */
122 INT usb
, /*!< upper side band, highest + 1 QMF band in the SBR range. */
123 INT qmfScale
/*!< sclefactor of QMF subsamples */
126 INT i
, k
, r
, r2
, timeIndex
, autoCorrScaling
;
128 INT startIndexMatrix
= hTonCorr
->startIndexMatrix
;
129 INT totNoEst
= hTonCorr
->numberOfEstimates
;
130 INT noEstPerFrame
= hTonCorr
->numberOfEstimatesPerFrame
;
131 INT move
= hTonCorr
->move
;
132 INT noQmfChannels
= hTonCorr
->noQmfChannels
; /* Numer of Bands */
133 INT buffLen
= hTonCorr
->bufferLength
; /* Numer of Slots */
134 INT stepSize
= hTonCorr
->stepSize
;
135 INT
*pBlockLength
= hTonCorr
->lpcLength
;
136 INT
** RESTRICT signMatrix
= hTonCorr
->signMatrix
;
137 FIXP_DBL
* RESTRICT nrgVector
= hTonCorr
->nrgVector
;
138 FIXP_DBL
** RESTRICT quotaMatrix
= hTonCorr
->quotaMatrix
;
139 FIXP_DBL
* RESTRICT pNrgVectorFreq
= hTonCorr
->nrgVectorFreq
;
141 #define BAND_V_SIZE QMF_MAX_TIME_SLOTS
142 #define NUM_V_COMBINE 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */
147 FIXP_DBL alphar
[2],alphai
[2],fac
;
149 C_ALLOC_SCRATCH_START(ac
, ACORR_COEFS
, 1);
150 C_ALLOC_SCRATCH_START(realBufRef
, FIXP_DBL
, 2*BAND_V_SIZE
*NUM_V_COMBINE
);
152 realBuf
= realBufRef
;
153 imagBuf
= realBuf
+ BAND_V_SIZE
*NUM_V_COMBINE
;
156 FDK_ASSERT(buffLen
<= BAND_V_SIZE
);
157 FDK_ASSERT(sizeof(FIXP_DBL
)*NUM_V_COMBINE
*BAND_V_SIZE
*2 < (1024*sizeof(FIXP_DBL
)-sizeof(ACORR_COEFS
)) );
160 * Buffering of the quotaMatrix and the quotaMatrixTransp.
161 *********************************************************/
162 for(i
= 0 ; i
< move
; i
++){
163 FDKmemcpy(quotaMatrix
[i
],quotaMatrix
[i
+ noEstPerFrame
],noQmfChannels
* sizeof(FIXP_DBL
));
164 FDKmemcpy(signMatrix
[i
],signMatrix
[i
+ noEstPerFrame
],noQmfChannels
* sizeof(INT
));
167 FDKmemmove(nrgVector
,nrgVector
+noEstPerFrame
,move
*sizeof(FIXP_DBL
));
168 FDKmemclear(nrgVector
+startIndexMatrix
,(totNoEst
-startIndexMatrix
)*sizeof(FIXP_DBL
));
169 FDKmemclear(pNrgVectorFreq
,noQmfChannels
* sizeof(FIXP_DBL
));
172 * Calculate the quotas for the current time steps.
173 **************************************************/
175 for (r
= 0; r
< usb
; r
++)
179 k
= hTonCorr
->nextSample
; /* startSample */
180 timeIndex
= startIndexMatrix
;
181 /* Copy as many as possible Band accross all Slots at once */
182 if (realBuf
!= realBufRef
) {
183 realBuf
-= BAND_V_SIZE
;
184 imagBuf
-= BAND_V_SIZE
;
186 realBuf
+= BAND_V_SIZE
*(NUM_V_COMBINE
-1);
187 imagBuf
+= BAND_V_SIZE
*(NUM_V_COMBINE
-1);
188 for (i
= 0; i
< buffLen
; i
++) {
192 for (v
=0; v
<NUM_V_COMBINE
; v
++)
194 ptr
[0] = sourceBufferReal
[i
][r
+v
];
195 ptr
[0+BAND_V_SIZE
*NUM_V_COMBINE
] = sourceBufferImag
[i
][r
+v
];
201 blockLength
= pBlockLength
[0];
203 while(k
<= buffLen
- blockLength
)
205 autoCorrScaling
= fixMin(getScalefactor(&realBuf
[k
-LPC_ORDER
], LPC_ORDER
+blockLength
), getScalefactor(&imagBuf
[k
-LPC_ORDER
], LPC_ORDER
+blockLength
));
206 autoCorrScaling
= fixMax(0, autoCorrScaling
-1);
208 scaleValues(&realBuf
[k
-LPC_ORDER
], LPC_ORDER
+blockLength
, autoCorrScaling
);
209 scaleValues(&imagBuf
[k
-LPC_ORDER
], LPC_ORDER
+blockLength
, autoCorrScaling
);
211 autoCorrScaling
<<= 1; /* consider qmf buffer scaling twice */
212 autoCorrScaling
+= autoCorr2nd_cplx ( ac
, realBuf
+k
, imagBuf
+k
, blockLength
);
215 if(ac
->det
== FL2FXCONST_DBL(0.0f
)){
216 alphar
[1] = alphai
[1] = FL2FXCONST_DBL(0.0f
);
218 alphar
[0] = (ac
->r01r
)>>2;
219 alphai
[0] = (ac
->r01i
)>>2;
221 fac
= fMultDiv2(ac
->r00r
, ac
->r11r
)>>1;
224 alphar
[1] = (fMultDiv2(ac
->r01r
, ac
->r12r
)>>1) - (fMultDiv2(ac
->r01i
, ac
->r12i
)>>1) - (fMultDiv2(ac
->r02r
, ac
->r11r
)>>1);
225 alphai
[1] = (fMultDiv2(ac
->r01i
, ac
->r12r
)>>1) + (fMultDiv2(ac
->r01r
, ac
->r12i
)>>1) - (fMultDiv2(ac
->r02i
, ac
->r11r
)>>1);
227 alphar
[0] = (fMultDiv2(ac
->r01r
, ac
->det
)>>(ac
->det_scale
+1)) + fMult(alphar
[1], ac
->r12r
) + fMult(alphai
[1], ac
->r12i
);
228 alphai
[0] = (fMultDiv2(ac
->r01i
, ac
->det
)>>(ac
->det_scale
+1)) + fMult(alphai
[1], ac
->r12r
) - fMult(alphar
[1], ac
->r12i
);
230 fac
= fMultDiv2(ac
->r00r
, fMult(ac
->det
, ac
->r11r
))>>(ac
->det_scale
+1);
233 if(fac
== FL2FXCONST_DBL(0.0f
)){
234 quotaMatrix
[timeIndex
][r
] = FL2FXCONST_DBL(0.0f
);
235 signMatrix
[timeIndex
][r
] = 0;
238 /* quotaMatrix is scaled with the factor RELAXATION
239 parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 * 2^RELAXATION_SHIFT) */
240 FIXP_DBL tmp
,num
,denom
;
241 INT numShift
,denomShift
,commonShift
;
244 num
= fMultDiv2(alphar
[0], ac
->r01r
) + fMultDiv2(alphai
[0], ac
->r01i
) - fMultDiv2(alphar
[1], fMult(ac
->r02r
, ac
->r11r
)) - fMultDiv2(alphai
[1], fMult(ac
->r02i
, ac
->r11r
));
247 denom
= (fac
>>1) + (fMultDiv2(fac
,RELAXATION_FRACT
)>>RELAXATION_SHIFT
) - num
;
248 denom
= fixp_abs(denom
);
250 num
= fMult(num
,RELAXATION_FRACT
);
252 numShift
= CountLeadingBits(num
) - 2;
253 num
= scaleValue(num
, numShift
);
255 denomShift
= CountLeadingBits(denom
);
256 denom
= (FIXP_DBL
)denom
<< denomShift
;
258 if ((num
> FL2FXCONST_DBL(0.0f
)) && (denom
!= FL2FXCONST_DBL(0.0f
))) {
259 commonShift
= fixMin(numShift
- denomShift
+ RELAXATION_SHIFT
, DFRACT_BITS
-1);
260 if (commonShift
< 0) {
261 commonShift
= -commonShift
;
262 tmp
= schur_div(num
,denom
,16);
263 commonShift
= fixMin(commonShift
,CountLeadingBits(tmp
));
264 quotaMatrix
[timeIndex
][r
] = tmp
<< commonShift
;
267 quotaMatrix
[timeIndex
][r
] = schur_div(num
,denom
,16) >> commonShift
;
271 quotaMatrix
[timeIndex
][r
] = FL2FXCONST_DBL(0.0f
);
274 if (ac
->r11r
!= FL2FXCONST_DBL(0.0f
)) {
275 if ( ( (ac
->r01r
>= FL2FXCONST_DBL(0.0f
) ) && ( ac
->r11r
>= FL2FXCONST_DBL(0.0f
) ) )
276 ||( (ac
->r01r
< FL2FXCONST_DBL(0.0f
) ) && ( ac
->r11r
< FL2FXCONST_DBL(0.0f
) ) ) ) {
288 r2
= r
; /* (INT) pow(-1, band); */
291 r2
= r
+ 1; /* (INT) pow(-1, band+1); */
293 signMatrix
[timeIndex
][r
] = 1 - 2*(r2
& 0x1);
296 nrgVector
[timeIndex
] += ((ac
->r00r
) >> fixMin(DFRACT_BITS
-1,(2*qmfScale
+autoCorrScaling
+ SCALE_NRGVEC
)));
297 /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced division by shifting with one */
298 pNrgVectorFreq
[r
] = pNrgVectorFreq
[r
] + ((ac
->r00r
) >> fixMin(DFRACT_BITS
-1,(2*qmfScale
+autoCorrScaling
+ SCALE_NRGVEC
)));
300 blockLength
= pBlockLength
[1];
307 C_ALLOC_SCRATCH_END(realBuf
, FIXP_DBL
, 2*BAND_V_SIZE
*NUM_V_COMBINE
);
308 C_ALLOC_SCRATCH_END(ac
, ACORR_COEFS
, 1);
311 /**************************************************************************/
313 \brief Extracts the parameters required in the decoder to obtain the
314 correct tonal to noise ratio after SBR.
316 Estimates the tonal to noise ratio of the original signal (using LPC).
317 Predicts the tonal to noise ration of the SBR signal (in the decoder) by
318 patching the tonal to noise ratio values similar to the patching of the
319 lowband in the decoder. Given the tonal to noise ratio of the original
320 and the SBR signal, it estimates the required amount of inverse filtering,
321 additional noise as well as any additional sines.
326 /**************************************************************************/
328 FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr
,/*!< Handle to SBR_TON_CORR struct. */
329 INVF_MODE
* infVec
, /*!< Vector where the inverse filtering levels will be stored. */
330 FIXP_DBL
* noiseLevels
, /*!< Vector where the noise levels will be stored. */
331 INT
* missingHarmonicFlag
, /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/
332 UCHAR
* missingHarmonicsIndex
, /*!< Vector indicating where sines are missing. */
333 UCHAR
* envelopeCompensation
, /*!< Vector to store compensation values for the energies in. */
334 const SBR_FRAME_INFO
*frameInfo
, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/
335 UCHAR
* transientInfo
, /*!< Transient info.*/
336 UCHAR
* freqBandTable
, /*!< Frequency band tables for high-res.*/
337 INT nSfb
, /*!< Number of scalefactor bands for high-res. */
338 XPOS_MODE xposType
, /*!< Type of transposer used in the decoder.*/
343 INT transientFlag
= transientInfo
[1] ; /*!< Flag indicating if a transient is present in the current frame. */
344 INT transientPos
= transientInfo
[0]; /*!< Position of the transient.*/
345 INT transientFrame
, transientFrameInvfEst
;
346 INVF_MODE
* infVecPtr
;
349 /* Determine if this is a frame where a transient starts...
351 The detection of noise-floor, missing harmonics and invf_est, is not in sync for the
352 non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the
353 present frame as well as in the next.
356 if(hTonCorr
->transientNextFrame
){ /* The transient was detected in the previous frame, but is actually */
358 hTonCorr
->transientNextFrame
= 0;
361 if(transientPos
+ hTonCorr
->transientPosOffset
>= frameInfo
->borders
[frameInfo
->nEnvelopes
]){
362 hTonCorr
->transientNextFrame
= 1;
368 if(transientPos
+ hTonCorr
->transientPosOffset
< frameInfo
->borders
[frameInfo
->nEnvelopes
]){
370 hTonCorr
->transientNextFrame
= 0;
373 hTonCorr
->transientNextFrame
= 1;
377 transientFrameInvfEst
= transientFrame
;
381 Estimate the required invese filtereing level.
383 if (hTonCorr
->switchInverseFilt
)
384 FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr
->sbrInvFilt
,
385 hTonCorr
->quotaMatrix
,
387 hTonCorr
->indexVector
,
388 hTonCorr
->frameStartIndexInvfEst
,
389 hTonCorr
->numberOfEstimatesPerFrame
+ hTonCorr
->frameStartIndexInvfEst
,
390 transientFrameInvfEst
,
394 Detect what tones will be missing.
396 if (xposType
== XPOS_LC
){
397 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr
->sbrMissingHarmonicsDetector
,
398 hTonCorr
->quotaMatrix
,
399 hTonCorr
->signMatrix
,
400 hTonCorr
->indexVector
,
404 missingHarmonicsIndex
,
407 envelopeCompensation
,
408 hTonCorr
->nrgVectorFreq
);
411 *missingHarmonicFlag
= 0;
412 FDKmemclear(missingHarmonicsIndex
,nSfb
*sizeof(UCHAR
));
418 Noise floor estimation
421 infVecPtr
= hTonCorr
->sbrInvFilt
.prevInvfMode
;
423 FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr
->sbrNoiseFloorEstimate
,
426 hTonCorr
->quotaMatrix
,
427 hTonCorr
->indexVector
,
428 *missingHarmonicFlag
,
429 hTonCorr
->frameStartIndex
,
430 hTonCorr
->numberOfEstimatesPerFrame
,
436 /* Store the invfVec data for the next frame...*/
437 for(band
= 0 ; band
< hTonCorr
->sbrInvFilt
.noDetectorBands
; band
++){
438 hTonCorr
->sbrInvFilt
.prevInvfMode
[band
] = infVec
[band
];
442 /**************************************************************************/
444 \brief Searches for the closest match in the frequency master table.
448 \return closest entry.
451 /**************************************************************************/
453 findClosestEntry(INT goalSb
,
460 if( goalSb
<= v_k_master
[0] )
461 return v_k_master
[0];
463 if( goalSb
>= v_k_master
[numMaster
] )
464 return v_k_master
[numMaster
];
468 while( v_k_master
[index
] < goalSb
) {
473 while( v_k_master
[index
] > goalSb
) {
478 return v_k_master
[index
];
482 /**************************************************************************/
484 \brief resets the patch
488 \return errorCode, noError if successful.
491 /**************************************************************************/
493 resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr
, /*!< Handle to SBR_TON_CORR struct. */
494 INT xposctrl
, /*!< Different patch modes. */
495 INT highBandStartSb
, /*!< Start band of the SBR range. */
496 UCHAR
*v_k_master
, /*!< Master frequency table from which all other table are derived.*/
497 INT numMaster
, /*!< Number of elements in the master table. */
498 INT fs
, /*!< Sampling frequency. */
499 INT noChannels
) /*!< Number of QMF-channels. */
504 PATCH_PARAM
*patchParam
= hTonCorr
->patchParam
;
506 INT sbGuard
= hTonCorr
->guard
;
511 INT lsb
= v_k_master
[0]; /* Lowest subband related to the synthesis filterbank */
512 INT usb
= v_k_master
[numMaster
]; /* Stop subband related to the synthesis filterbank */
513 INT xoverOffset
= highBandStartSb
- v_k_master
[0]; /* Calculate distance in subbands between k0 and kx */
519 * Initialize the patching parameter
527 goalSb
= (INT
)( (2 * noChannels
* 16000 + (fs
>>1)) / fs
); /* 16 kHz band */
528 goalSb
= findClosestEntry(goalSb
, v_k_master
, numMaster
, 1); /* Adapt region to master-table */
531 sourceStartBand
= hTonCorr
->shiftStartSb
+ xoverOffset
;
532 targetStopBand
= lsb
+ xoverOffset
;
534 /* even (odd) numbered channel must be patched to even (odd) numbered channel */
536 while(targetStopBand
< usb
) {
538 /* To many patches */
539 if (patch
>= MAX_NUM_PATCHES
)
540 return(1); /*Number of patches to high */
542 patchParam
[patch
].guardStartBand
= targetStopBand
;
543 targetStopBand
+= sbGuard
;
544 patchParam
[patch
].targetStartBand
= targetStopBand
;
546 numBandsInPatch
= goalSb
- targetStopBand
; /* get the desired range of the patch */
548 if ( numBandsInPatch
>= lsb
- sourceStartBand
) {
549 /* desired number bands are not available -> patch whole source range */
550 patchDistance
= targetStopBand
- sourceStartBand
; /* get the targetOffset */
551 patchDistance
= patchDistance
& ~1; /* rounding off odd numbers and make all even */
552 numBandsInPatch
= lsb
- (targetStopBand
- patchDistance
);
553 numBandsInPatch
= findClosestEntry(targetStopBand
+ numBandsInPatch
, v_k_master
, numMaster
, 0) -
554 targetStopBand
; /* Adapt region to master-table */
557 /* desired number bands are available -> get the minimal even patching distance */
558 patchDistance
= numBandsInPatch
+ targetStopBand
- lsb
; /* get minimal distance */
559 patchDistance
= (patchDistance
+ 1) & ~1; /* rounding up odd numbers and make all even */
561 if (numBandsInPatch
<= 0) {
564 patchParam
[patch
].sourceStartBand
= targetStopBand
- patchDistance
;
565 patchParam
[patch
].targetBandOffs
= patchDistance
;
566 patchParam
[patch
].numBandsInPatch
= numBandsInPatch
;
567 patchParam
[patch
].sourceStopBand
= patchParam
[patch
].sourceStartBand
+ numBandsInPatch
;
569 targetStopBand
+= patchParam
[patch
].numBandsInPatch
;
572 /* All patches but first */
573 sourceStartBand
= hTonCorr
->shiftStartSb
;
575 /* Check if we are close to goalSb */
576 if( fixp_abs(targetStopBand
- goalSb
) < 3) {
586 /* if highest patch contains less than three subband: skip it */
587 if ( patchParam
[patch
].numBandsInPatch
< 3 && patch
> 0 ) {
589 targetStopBand
= patchParam
[patch
].targetStartBand
+ patchParam
[patch
].numBandsInPatch
;
592 hTonCorr
->noOfPatches
= patch
+ 1;
595 /* Assign the index-vector, so we know where to look for the high-band.
596 -1 represents a guard-band. */
597 for(k
= 0; k
< hTonCorr
->patchParam
[0].guardStartBand
; k
++)
598 hTonCorr
->indexVector
[k
] = k
;
600 for(i
= 0; i
< hTonCorr
->noOfPatches
; i
++)
602 INT sourceStart
= hTonCorr
->patchParam
[i
].sourceStartBand
;
603 INT targetStart
= hTonCorr
->patchParam
[i
].targetStartBand
;
604 INT numberOfBands
= hTonCorr
->patchParam
[i
].numBandsInPatch
;
605 INT startGuardBand
= hTonCorr
->patchParam
[i
].guardStartBand
;
607 for(k
= 0; k
< (targetStart
- startGuardBand
); k
++)
608 hTonCorr
->indexVector
[startGuardBand
+k
] = -1;
610 for(k
= 0; k
< numberOfBands
; k
++)
611 hTonCorr
->indexVector
[targetStart
+k
] = sourceStart
+k
;
617 /**************************************************************************/
619 \brief Creates an instance of the tonality correction parameter module.
621 The module includes modules for inverse filtering level estimation,
622 missing harmonics detection and noise floor level estimation.
624 \return errorCode, noError if successful.
626 /**************************************************************************/
628 FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr
, /*!< Pointer to handle to SBR_TON_CORR struct. */
629 INT chan
) /*!< Channel index, needed for mem allocation */
632 FIXP_DBL
* quotaMatrix
= GetRam_Sbr_quotaMatrix(chan
);
633 INT
* signMatrix
= GetRam_Sbr_signMatrix(chan
);
635 FDKmemclear(hTonCorr
, sizeof(SBR_TON_CORR_EST
));
637 for (i
=0; i
<MAX_NO_OF_ESTIMATES
; i
++) {
638 hTonCorr
->quotaMatrix
[i
] = quotaMatrix
+ (i
*QMF_CHANNELS
);
639 hTonCorr
->signMatrix
[i
] = signMatrix
+ (i
*QMF_CHANNELS
);
642 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr
->sbrMissingHarmonicsDetector
, chan
);
649 /**************************************************************************/
651 \brief Initialize an instance of the tonality correction parameter module.
653 The module includes modules for inverse filtering level estimation,
654 missing harmonics detection and noise floor level estimation.
656 \return errorCode, noError if successful.
658 /**************************************************************************/
660 FDKsbrEnc_InitTonCorrParamExtr (INT frameSize
, /*!< Current SBR frame size. */
661 HANDLE_SBR_TON_CORR_EST hTonCorr
, /*!< Pointer to handle to SBR_TON_CORR struct. */
662 HANDLE_SBR_CONFIG_DATA sbrCfg
, /*!< Pointer to SBR configuration parameters. */
663 INT timeSlots
, /*!< Number of time-slots per frame */
664 INT xposCtrl
, /*!< Different patch modes. */
665 INT ana_max_level
, /*!< Maximum level of the adaptive noise. */
666 INT noiseBands
, /*!< Number of noise bands per octave. */
667 INT noiseFloorOffset
, /*!< Noise floor offset. */
668 UINT useSpeechConfig
) /*!< Speech or music tuning. */
670 INT nCols
= sbrCfg
->noQmfSlots
;
671 INT fs
= sbrCfg
->sampleFreq
;
672 INT noQmfChannels
= sbrCfg
->noQmfBands
;
674 INT highBandStartSb
= sbrCfg
->freqBandTable
[LOW_RES
][0];
675 UCHAR
*v_k_master
= sbrCfg
->v_k_master
;
676 INT numMaster
= sbrCfg
->num_Master
;
678 UCHAR
**freqBandTable
= sbrCfg
->freqBandTable
;
679 INT
*nSfb
= sbrCfg
->nSfb
;
684 Reset the patching and allocate memory for the quota matrix.
685 Assing parameters for the LPC analysis.
687 if (sbrCfg
->sbrSyntaxFlags
& SBR_SYNTAX_LOW_DELAY
) {
689 case NUMBER_TIME_SLOTS_1920
:
690 hTonCorr
->lpcLength
[0] = 8 - LPC_ORDER
;
691 hTonCorr
->lpcLength
[1] = 7 - LPC_ORDER
;
692 hTonCorr
->numberOfEstimates
= NO_OF_ESTIMATES_LD
;
693 hTonCorr
->numberOfEstimatesPerFrame
= sbrCfg
->noQmfSlots
/ 7;
694 hTonCorr
->frameStartIndexInvfEst
= 0;
695 hTonCorr
->transientPosOffset
= FRAME_MIDDLE_SLOT_512LD
;
697 case NUMBER_TIME_SLOTS_2048
:
698 hTonCorr
->lpcLength
[0] = 8 - LPC_ORDER
;
699 hTonCorr
->lpcLength
[1] = 8 - LPC_ORDER
;
700 hTonCorr
->numberOfEstimates
= NO_OF_ESTIMATES_LD
;
701 hTonCorr
->numberOfEstimatesPerFrame
= sbrCfg
->noQmfSlots
/ 8;
702 hTonCorr
->frameStartIndexInvfEst
= 0;
703 hTonCorr
->transientPosOffset
= FRAME_MIDDLE_SLOT_512LD
;
708 case NUMBER_TIME_SLOTS_2048
:
709 hTonCorr
->lpcLength
[0] = 16 - LPC_ORDER
; /* blockLength[0] */
710 hTonCorr
->lpcLength
[1] = 16 - LPC_ORDER
; /* blockLength[0] */
711 hTonCorr
->numberOfEstimates
= NO_OF_ESTIMATES_LC
;
712 hTonCorr
->numberOfEstimatesPerFrame
= sbrCfg
->noQmfSlots
/ 16;
713 hTonCorr
->frameStartIndexInvfEst
= 0;
714 hTonCorr
->transientPosOffset
= FRAME_MIDDLE_SLOT_2048
;
716 case NUMBER_TIME_SLOTS_1920
:
717 hTonCorr
->lpcLength
[0] = 15 - LPC_ORDER
; /* blockLength[0] */
718 hTonCorr
->lpcLength
[1] = 15 - LPC_ORDER
; /* blockLength[0] */
719 hTonCorr
->numberOfEstimates
= NO_OF_ESTIMATES_LC
;
720 hTonCorr
->numberOfEstimatesPerFrame
= sbrCfg
->noQmfSlots
/ 15;
721 hTonCorr
->frameStartIndexInvfEst
= 0;
722 hTonCorr
->transientPosOffset
= FRAME_MIDDLE_SLOT_1920
;
728 hTonCorr
->bufferLength
= nCols
;
729 hTonCorr
->stepSize
= hTonCorr
->lpcLength
[0] + LPC_ORDER
; /* stepSize[0] implicitly 0. */
731 hTonCorr
->nextSample
= LPC_ORDER
; /* firstSample */
732 hTonCorr
->move
= hTonCorr
->numberOfEstimates
- hTonCorr
->numberOfEstimatesPerFrame
; /* Number of estimates to move when buffering.*/
733 hTonCorr
->startIndexMatrix
= hTonCorr
->numberOfEstimates
- hTonCorr
->numberOfEstimatesPerFrame
; /* Where to store the latest estimations in the tonality Matrix.*/
734 hTonCorr
->frameStartIndex
= 0; /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */
735 hTonCorr
->prevTransientFlag
= 0;
736 hTonCorr
->transientNextFrame
= 0;
738 hTonCorr
->noQmfChannels
= noQmfChannels
;
740 for (i
=0; i
<hTonCorr
->numberOfEstimates
; i
++) {
741 FDKmemclear (hTonCorr
->quotaMatrix
[i
] , sizeof(FIXP_DBL
)*noQmfChannels
);
742 FDKmemclear (hTonCorr
->signMatrix
[i
] , sizeof(INT
)*noQmfChannels
);
745 /* Reset the patch.*/
747 hTonCorr
->shiftStartSb
= 1;
749 if(resetPatch(hTonCorr
,
758 if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr
->sbrNoiseFloorEstimate
,
769 if(FDKsbrEnc_initInvFiltDetector(&hTonCorr
->sbrInvFilt
,
770 hTonCorr
->sbrNoiseFloorEstimate
.freqBandTableQmf
,
771 hTonCorr
->sbrNoiseFloorEstimate
.noNoiseBands
,
777 if(FDKsbrEnc_InitSbrMissingHarmonicsDetector(
778 &hTonCorr
->sbrMissingHarmonicsDetector
,
783 hTonCorr
->numberOfEstimates
,
785 hTonCorr
->numberOfEstimatesPerFrame
,
786 sbrCfg
->sbrSyntaxFlags
))
796 /**************************************************************************/
798 \brief resets tonality correction parameter module.
802 \return errorCode, noError if successful.
805 /**************************************************************************/
807 FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr
, /*!< Handle to SBR_TON_CORR struct. */
808 INT xposctrl
, /*!< Different patch modes. */
809 INT highBandStartSb
, /*!< Start band of the SBR range. */
810 UCHAR
*v_k_master
, /*!< Master frequency table from which all other table are derived.*/
811 INT numMaster
, /*!< Number of elements in the master table. */
812 INT fs
, /*!< Sampling frequency (of the SBR part). */
813 UCHAR
** freqBandTable
, /*!< Frequency band table for low-res and high-res. */
814 INT
* nSfb
, /*!< Number of frequency bands (hig-res and low-res). */
815 INT noQmfChannels
/*!< Number of QMF channels. */
819 /* Reset the patch.*/
821 hTonCorr
->shiftStartSb
= 1;
823 if(resetPatch(hTonCorr
,
834 /* Reset the noise floor estimate.*/
835 if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr
->sbrNoiseFloorEstimate
,
841 Reset the inveerse filtereing detector.
843 if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr
->sbrInvFilt
,
844 hTonCorr
->sbrNoiseFloorEstimate
.freqBandTableQmf
,
845 hTonCorr
->sbrNoiseFloorEstimate
.noNoiseBands
))
847 /* Reset the missing harmonics detector. */
848 if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr
->sbrMissingHarmonicsDetector
,
859 /**************************************************************************/
861 \brief Deletes the tonality correction paramtere module.
868 /**************************************************************************/
870 FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr
) /*!< Handle to SBR_TON_CORR struct. */
875 FreeRam_Sbr_quotaMatrix(hTonCorr
->quotaMatrix
);
877 FreeRam_Sbr_signMatrix(hTonCorr
->signMatrix
);
879 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr
->sbrMissingHarmonicsDetector
);