1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6 All rights reserved.
7
8 1. INTRODUCTION
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.
12
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.
17
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.
24
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.
28
29 2. COPYRIGHT LICENSE
30
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:
33
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.
36
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.
41
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44
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.
47
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."
52
53 3. NO PATENT LICENSE
54
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.
58
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61
62 4. DISCLAIMER
63
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.
72
73 5. CONTACT INFORMATION
74
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83
84 #include "ton_corr.h"
85
86 #include "sbr_ram.h"
87 #include "sbr_misc.h"
88 #include "genericStds.h"
89 #include "autocorr2nd.h"
90
91
92
93 /***************************************************************************
94
95 Send autoCorrSecondOrder to mlfile
96
97 ****************************************************************************/
98
99 /**************************************************************************/
100 /*!
101 \brief Calculates the tonal to noise ration for different frequency bands
102 and time segments.
103
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).
108
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
112
113 \return none.
114
115 */
116 /**************************************************************************/
117
118 void
FDKsbrEnc_CalculateTonalityQuotas(HANDLE_SBR_TON_CORR_EST hTonCorr,FIXP_DBL ** RESTRICT sourceBufferReal,FIXP_DBL ** RESTRICT sourceBufferImag,INT usb,INT qmfScale)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 */
124 )
125 {
126 INT i, k, r, r2, timeIndex, autoCorrScaling;
127
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;
140
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 */
143
144 FIXP_DBL *realBuf;
145 FIXP_DBL *imagBuf;
146
147 FIXP_DBL alphar[2],alphai[2],fac;
148
149 C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1);
150 C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
151
152 realBuf = realBufRef;
153 imagBuf = realBuf + BAND_V_SIZE*NUM_V_COMBINE;
154
155
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)) );
158
159 /*
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));
165 }
166
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));
170
171 /*
172 * Calculate the quotas for the current time steps.
173 **************************************************/
174
175 for (r = 0; r < usb; r++)
176 {
177 int blockLength;
178
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;
185 } else {
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++) {
189 int v;
190 FIXP_DBL *ptr;
191 ptr = realBuf+i;
192 for (v=0; v<NUM_V_COMBINE; v++)
193 {
194 ptr[0] = sourceBufferReal[i][r+v];
195 ptr[0+BAND_V_SIZE*NUM_V_COMBINE] = sourceBufferImag[i][r+v];
196 ptr -= BAND_V_SIZE;
197 }
198 }
199 }
200
201 blockLength = pBlockLength[0];
202
203 while(k <= buffLen - blockLength)
204 {
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);
207
208 scaleValues(&realBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling);
209 scaleValues(&imagBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling);
210
211 autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */
212 autoCorrScaling += autoCorr2nd_cplx ( ac, realBuf+k, imagBuf+k, blockLength );
213
214
215 if(ac->det == FL2FXCONST_DBL(0.0f)){
216 alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f);
217
218 alphar[0] = (ac->r01r)>>2;
219 alphai[0] = (ac->r01i)>>2;
220
221 fac = fMultDiv2(ac->r00r, ac->r11r)>>1;
222 }
223 else{
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);
226
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);
229
230 fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r))>>(ac->det_scale+1);
231 }
232
233 if(fac == FL2FXCONST_DBL(0.0f)){
234 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
235 signMatrix[timeIndex][r] = 0;
236 }
237 else {
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;
242 INT sign;
243
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));
245 num = fixp_abs(num);
246
247 denom = (fac>>1) + (fMultDiv2(fac,RELAXATION_FRACT)>>RELAXATION_SHIFT) - num;
248 denom = fixp_abs(denom);
249
250 num = fMult(num,RELAXATION_FRACT);
251
252 numShift = CountLeadingBits(num) - 2;
253 num = scaleValue(num, numShift);
254
255 denomShift = CountLeadingBits(denom);
256 denom = (FIXP_DBL)denom << denomShift;
257
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;
265 }
266 else {
267 quotaMatrix[timeIndex][r] = schur_div(num,denom,16) >> commonShift;
268 }
269 }
270 else {
271 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
272 }
273
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) ) ) ) {
277 sign = 1;
278 }
279 else {
280 sign = -1;
281 }
282 }
283 else {
284 sign = 1;
285 }
286
287 if(sign < 0) {
288 r2 = r; /* (INT) pow(-1, band); */
289 }
290 else {
291 r2 = r + 1; /* (INT) pow(-1, band+1); */
292 }
293 signMatrix[timeIndex][r] = 1 - 2*(r2 & 0x1);
294 }
295
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)));
299
300 blockLength = pBlockLength[1];
301 k += stepSize;
302 timeIndex++;
303 }
304 }
305
306 FDK_ASSERT(noEstPerFrame == 2);
307
308
309 C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
310 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1);
311 }
312
313 /**************************************************************************/
314 /*!
315 \brief Extracts the parameters required in the decoder to obtain the
316 correct tonal to noise ratio after SBR.
317
318 Estimates the tonal to noise ratio of the original signal (using LPC).
319 Predicts the tonal to noise ration of the SBR signal (in the decoder) by
320 patching the tonal to noise ratio values similar to the patching of the
321 lowband in the decoder. Given the tonal to noise ratio of the original
322 and the SBR signal, it estimates the required amount of inverse filtering,
323 additional noise as well as any additional sines.
324
325 \return none.
326
327 */
328 /**************************************************************************/
329 void
FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,INVF_MODE * infVec,FIXP_DBL * noiseLevels,INT * missingHarmonicFlag,UCHAR * missingHarmonicsIndex,UCHAR * envelopeCompensation,const SBR_FRAME_INFO * frameInfo,UCHAR * transientInfo,UCHAR * freqBandTable,INT nSfb,XPOS_MODE xposType,UINT sbrSyntaxFlags)330 FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,/*!< Handle to SBR_TON_CORR struct. */
331 INVF_MODE* infVec, /*!< Vector where the inverse filtering levels will be stored. */
332 FIXP_DBL * noiseLevels, /*!< Vector where the noise levels will be stored. */
333 INT* missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/
334 UCHAR * missingHarmonicsIndex, /*!< Vector indicating where sines are missing. */
335 UCHAR * envelopeCompensation, /*!< Vector to store compensation values for the energies in. */
336 const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/
337 UCHAR* transientInfo, /*!< Transient info.*/
338 UCHAR* freqBandTable, /*!< Frequency band tables for high-res.*/
339 INT nSfb, /*!< Number of scalefactor bands for high-res. */
340 XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/
341 UINT sbrSyntaxFlags
342 )
343 {
344 INT band;
345 INT transientFlag = transientInfo[1] ; /*!< Flag indicating if a transient is present in the current frame. */
346 INT transientPos = transientInfo[0]; /*!< Position of the transient.*/
347 INT transientFrame, transientFrameInvfEst;
348 INVF_MODE* infVecPtr;
349
350
351 /* Determine if this is a frame where a transient starts...
352
353 The detection of noise-floor, missing harmonics and invf_est, is not in sync for the
354 non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the
355 present frame as well as in the next.
356 */
357 transientFrame = 0;
358 if(hTonCorr->transientNextFrame){ /* The transient was detected in the previous frame, but is actually */
359 transientFrame = 1;
360 hTonCorr->transientNextFrame = 0;
361
362 if(transientFlag){
363 if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){
364 hTonCorr->transientNextFrame = 1;
365 }
366 }
367 }
368 else{
369 if(transientFlag){
370 if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){
371 transientFrame = 1;
372 hTonCorr->transientNextFrame = 0;
373 }
374 else{
375 hTonCorr->transientNextFrame = 1;
376 }
377 }
378 }
379 transientFrameInvfEst = transientFrame;
380
381
382 /*
383 Estimate the required invese filtereing level.
384 */
385 if (hTonCorr->switchInverseFilt)
386 FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt,
387 hTonCorr->quotaMatrix,
388 hTonCorr->nrgVector,
389 hTonCorr->indexVector,
390 hTonCorr->frameStartIndexInvfEst,
391 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
392 transientFrameInvfEst,
393 infVec);
394
395 /*
396 Detect what tones will be missing.
397 */
398 if (xposType == XPOS_LC ){
399 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector,
400 hTonCorr->quotaMatrix,
401 hTonCorr->signMatrix,
402 hTonCorr->indexVector,
403 frameInfo,
404 transientInfo,
405 missingHarmonicFlag,
406 missingHarmonicsIndex,
407 freqBandTable,
408 nSfb,
409 envelopeCompensation,
410 hTonCorr->nrgVectorFreq);
411 }
412 else{
413 *missingHarmonicFlag = 0;
414 FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR));
415 }
416
417
418
419 /*
420 Noise floor estimation
421 */
422
423 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
424
425 FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate,
426 frameInfo,
427 noiseLevels,
428 hTonCorr->quotaMatrix,
429 hTonCorr->indexVector,
430 *missingHarmonicFlag,
431 hTonCorr->frameStartIndex,
432 hTonCorr->numberOfEstimatesPerFrame,
433 transientFrame,
434 infVecPtr,
435 sbrSyntaxFlags);
436
437
438 /* Store the invfVec data for the next frame...*/
439 for(band = 0 ; band < hTonCorr->sbrInvFilt.noDetectorBands; band++){
440 hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
441 }
442 }
443
444 /**************************************************************************/
445 /*!
446 \brief Searches for the closest match in the frequency master table.
447
448
449
450 \return closest entry.
451
452 */
453 /**************************************************************************/
454 static INT
findClosestEntry(INT goalSb,UCHAR * v_k_master,INT numMaster,INT direction)455 findClosestEntry(INT goalSb,
456 UCHAR *v_k_master,
457 INT numMaster,
458 INT direction)
459 {
460 INT index;
461
462 if( goalSb <= v_k_master[0] )
463 return v_k_master[0];
464
465 if( goalSb >= v_k_master[numMaster] )
466 return v_k_master[numMaster];
467
468 if(direction) {
469 index = 0;
470 while( v_k_master[index] < goalSb ) {
471 index++;
472 }
473 } else {
474 index = numMaster;
475 while( v_k_master[index] > goalSb ) {
476 index--;
477 }
478 }
479
480 return v_k_master[index];
481 }
482
483
484 /**************************************************************************/
485 /*!
486 \brief resets the patch
487
488
489
490 \return errorCode, noError if successful.
491
492 */
493 /**************************************************************************/
494 static INT
resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr,INT xposctrl,INT highBandStartSb,UCHAR * v_k_master,INT numMaster,INT fs,INT noChannels)495 resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
496 INT xposctrl, /*!< Different patch modes. */
497 INT highBandStartSb, /*!< Start band of the SBR range. */
498 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/
499 INT numMaster, /*!< Number of elements in the master table. */
500 INT fs, /*!< Sampling frequency. */
501 INT noChannels) /*!< Number of QMF-channels. */
502 {
503 INT patch,k,i;
504 INT targetStopBand;
505
506 PATCH_PARAM *patchParam = hTonCorr->patchParam;
507
508 INT sbGuard = hTonCorr->guard;
509 INT sourceStartBand;
510 INT patchDistance;
511 INT numBandsInPatch;
512
513 INT lsb = v_k_master[0]; /* Lowest subband related to the synthesis filterbank */
514 INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis filterbank */
515 INT xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
516
517 INT goalSb;
518
519
520 /*
521 * Initialize the patching parameter
522 */
523
524 if (xposctrl == 1) {
525 lsb += xoverOffset;
526 xoverOffset = 0;
527 }
528
529 goalSb = (INT)( (2 * noChannels * 16000 + (fs>>1)) / fs ); /* 16 kHz band */
530 goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 1); /* Adapt region to master-table */
531
532 /* First patch */
533 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
534 targetStopBand = lsb + xoverOffset;
535
536 /* even (odd) numbered channel must be patched to even (odd) numbered channel */
537 patch = 0;
538 while(targetStopBand < usb) {
539
540 /* To many patches */
541 if (patch >= MAX_NUM_PATCHES)
542 return(1); /*Number of patches to high */
543
544 patchParam[patch].guardStartBand = targetStopBand;
545 targetStopBand += sbGuard;
546 patchParam[patch].targetStartBand = targetStopBand;
547
548 numBandsInPatch = goalSb - targetStopBand; /* get the desired range of the patch */
549
550 if ( numBandsInPatch >= lsb - sourceStartBand ) {
551 /* desired number bands are not available -> patch whole source range */
552 patchDistance = targetStopBand - sourceStartBand; /* get the targetOffset */
553 patchDistance = patchDistance & ~1; /* rounding off odd numbers and make all even */
554 numBandsInPatch = lsb - (targetStopBand - patchDistance);
555 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) -
556 targetStopBand; /* Adapt region to master-table */
557 }
558
559 /* desired number bands are available -> get the minimal even patching distance */
560 patchDistance = numBandsInPatch + targetStopBand - lsb; /* get minimal distance */
561 patchDistance = (patchDistance + 1) & ~1; /* rounding up odd numbers and make all even */
562
563 if (numBandsInPatch <= 0) {
564 patch--;
565 } else {
566 patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
567 patchParam[patch].targetBandOffs = patchDistance;
568 patchParam[patch].numBandsInPatch = numBandsInPatch;
569 patchParam[patch].sourceStopBand = patchParam[patch].sourceStartBand + numBandsInPatch;
570
571 targetStopBand += patchParam[patch].numBandsInPatch;
572 }
573
574 /* All patches but first */
575 sourceStartBand = hTonCorr->shiftStartSb;
576
577 /* Check if we are close to goalSb */
578 if( fixp_abs(targetStopBand - goalSb) < 3) {
579 goalSb = usb;
580 }
581
582 patch++;
583
584 }
585
586 patch--;
587
588 /* if highest patch contains less than three subband: skip it */
589 if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) {
590 patch--;
591 targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
592 }
593
594 hTonCorr->noOfPatches = patch + 1;
595
596
597 /* Assign the index-vector, so we know where to look for the high-band.
598 -1 represents a guard-band. */
599 for(k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
600 hTonCorr->indexVector[k] = k;
601
602 for(i = 0; i < hTonCorr->noOfPatches; i++)
603 {
604 INT sourceStart = hTonCorr->patchParam[i].sourceStartBand;
605 INT targetStart = hTonCorr->patchParam[i].targetStartBand;
606 INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch;
607 INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
608
609 for(k = 0; k < (targetStart- startGuardBand); k++)
610 hTonCorr->indexVector[startGuardBand+k] = -1;
611
612 for(k = 0; k < numberOfBands; k++)
613 hTonCorr->indexVector[targetStart+k] = sourceStart+k;
614 }
615
616 return (0);
617 }
618
619 /**************************************************************************/
620 /*!
621 \brief Creates an instance of the tonality correction parameter module.
622
623 The module includes modules for inverse filtering level estimation,
624 missing harmonics detection and noise floor level estimation.
625
626 \return errorCode, noError if successful.
627 */
628 /**************************************************************************/
629 INT
FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,INT chan)630 FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
631 INT chan) /*!< Channel index, needed for mem allocation */
632 {
633 INT i;
634 FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
635 INT* signMatrix = GetRam_Sbr_signMatrix(chan);
636
637 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
638
639 for (i=0; i<MAX_NO_OF_ESTIMATES; i++) {
640 hTonCorr->quotaMatrix[i] = quotaMatrix + (i*QMF_CHANNELS);
641 hTonCorr->signMatrix[i] = signMatrix + (i*QMF_CHANNELS);
642 }
643
644 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan);
645
646 return 0;
647 }
648
649
650
651 /**************************************************************************/
652 /*!
653 \brief Initialize an instance of the tonality correction parameter module.
654
655 The module includes modules for inverse filtering level estimation,
656 missing harmonics detection and noise floor level estimation.
657
658 \return errorCode, noError if successful.
659 */
660 /**************************************************************************/
661 INT
FDKsbrEnc_InitTonCorrParamExtr(INT frameSize,HANDLE_SBR_TON_CORR_EST hTonCorr,HANDLE_SBR_CONFIG_DATA sbrCfg,INT timeSlots,INT xposCtrl,INT ana_max_level,INT noiseBands,INT noiseFloorOffset,UINT useSpeechConfig)662 FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current SBR frame size. */
663 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
664 HANDLE_SBR_CONFIG_DATA sbrCfg, /*!< Pointer to SBR configuration parameters. */
665 INT timeSlots, /*!< Number of time-slots per frame */
666 INT xposCtrl, /*!< Different patch modes. */
667 INT ana_max_level, /*!< Maximum level of the adaptive noise. */
668 INT noiseBands, /*!< Number of noise bands per octave. */
669 INT noiseFloorOffset, /*!< Noise floor offset. */
670 UINT useSpeechConfig) /*!< Speech or music tuning. */
671 {
672 INT nCols = sbrCfg->noQmfSlots;
673 INT fs = sbrCfg->sampleFreq;
674 INT noQmfChannels = sbrCfg->noQmfBands;
675
676 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
677 UCHAR *v_k_master = sbrCfg->v_k_master;
678 INT numMaster = sbrCfg->num_Master;
679
680 UCHAR **freqBandTable = sbrCfg->freqBandTable;
681 INT *nSfb = sbrCfg->nSfb;
682
683 INT i;
684
685 /*
686 Reset the patching and allocate memory for the quota matrix.
687 Assing parameters for the LPC analysis.
688 */
689 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
690 switch (timeSlots) {
691 case NUMBER_TIME_SLOTS_1920:
692 hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
693 hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
694 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
695 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7;
696 hTonCorr->frameStartIndexInvfEst = 0;
697 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
698 break;
699 case NUMBER_TIME_SLOTS_2048:
700 hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
701 hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
702 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
703 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8;
704 hTonCorr->frameStartIndexInvfEst = 0;
705 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
706 break;
707 }
708 } else
709 switch (timeSlots) {
710 case NUMBER_TIME_SLOTS_2048:
711 hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */
712 hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */
713 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
714 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
715 hTonCorr->frameStartIndexInvfEst = 0;
716 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
717 break;
718 case NUMBER_TIME_SLOTS_1920:
719 hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */
720 hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */
721 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
722 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
723 hTonCorr->frameStartIndexInvfEst = 0;
724 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
725 break;
726 default:
727 return -1;
728 }
729
730 hTonCorr->bufferLength = nCols;
731 hTonCorr->stepSize = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
732
733 hTonCorr->nextSample = LPC_ORDER; /* firstSample */
734 hTonCorr->move = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates to move when buffering.*/
735 hTonCorr->startIndexMatrix = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest estimations in the tonality Matrix.*/
736 hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */
737 hTonCorr->prevTransientFlag = 0;
738 hTonCorr->transientNextFrame = 0;
739
740 hTonCorr->noQmfChannels = noQmfChannels;
741
742 for (i=0; i<hTonCorr->numberOfEstimates; i++) {
743 FDKmemclear (hTonCorr->quotaMatrix[i] , sizeof(FIXP_DBL)*noQmfChannels);
744 FDKmemclear (hTonCorr->signMatrix[i] , sizeof(INT)*noQmfChannels);
745 }
746
747 /* Reset the patch.*/
748 hTonCorr->guard = 0;
749 hTonCorr->shiftStartSb = 1;
750
751 if(resetPatch(hTonCorr,
752 xposCtrl,
753 highBandStartSb,
754 v_k_master,
755 numMaster,
756 fs,
757 noQmfChannels))
758 return(1);
759
760 if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
761 ana_max_level,
762 freqBandTable[LO],
763 nSfb[LO],
764 noiseBands,
765 noiseFloorOffset,
766 timeSlots,
767 useSpeechConfig))
768 return(1);
769
770
771 if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt,
772 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
773 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands,
774 useSpeechConfig))
775 return(1);
776
777
778
779 if(FDKsbrEnc_InitSbrMissingHarmonicsDetector(
780 &hTonCorr->sbrMissingHarmonicsDetector,
781 fs,
782 frameSize,
783 nSfb[HI],
784 noQmfChannels,
785 hTonCorr->numberOfEstimates,
786 hTonCorr->move,
787 hTonCorr->numberOfEstimatesPerFrame,
788 sbrCfg->sbrSyntaxFlags))
789 return(1);
790
791
792
793 return (0);
794 }
795
796
797
798 /**************************************************************************/
799 /*!
800 \brief resets tonality correction parameter module.
801
802
803
804 \return errorCode, noError if successful.
805
806 */
807 /**************************************************************************/
808 INT
FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,INT xposctrl,INT highBandStartSb,UCHAR * v_k_master,INT numMaster,INT fs,UCHAR ** freqBandTable,INT * nSfb,INT noQmfChannels)809 FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
810 INT xposctrl, /*!< Different patch modes. */
811 INT highBandStartSb, /*!< Start band of the SBR range. */
812 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/
813 INT numMaster, /*!< Number of elements in the master table. */
814 INT fs, /*!< Sampling frequency (of the SBR part). */
815 UCHAR ** freqBandTable, /*!< Frequency band table for low-res and high-res. */
816 INT* nSfb, /*!< Number of frequency bands (hig-res and low-res). */
817 INT noQmfChannels /*!< Number of QMF channels. */
818 )
819 {
820
821 /* Reset the patch.*/
822 hTonCorr->guard = 0;
823 hTonCorr->shiftStartSb = 1;
824
825 if(resetPatch(hTonCorr,
826 xposctrl,
827 highBandStartSb,
828 v_k_master,
829 numMaster,
830 fs,
831 noQmfChannels))
832 return(1);
833
834
835
836 /* Reset the noise floor estimate.*/
837 if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
838 freqBandTable[LO],
839 nSfb[LO]))
840 return(1);
841
842 /*
843 Reset the inveerse filtereing detector.
844 */
845 if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt,
846 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
847 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
848 return(1);
849 /* Reset the missing harmonics detector. */
850 if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector,
851 nSfb[HI]))
852 return(1);
853
854 return (0);
855 }
856
857
858
859
860
861 /**************************************************************************/
862 /*!
863 \brief Deletes the tonality correction paramtere module.
864
865
866
867 \return none
868
869 */
870 /**************************************************************************/
871 void
FDKsbrEnc_DeleteTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr)872 FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
873 {
874
875 if (hTonCorr) {
876
877 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
878
879 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
880
881 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector);
882 }
883 }
884