Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libSBRenc / src / ton_corr.cpp
1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 © Copyright 1995 - 2013 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
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
307 C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
308 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1);
309 }
310
311 /**************************************************************************/
312 /*!
313 \brief Extracts the parameters required in the decoder to obtain the
314 correct tonal to noise ratio after SBR.
315
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.
322
323 \return none.
324
325 */
326 /**************************************************************************/
327 void
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.*/
339 UINT sbrSyntaxFlags
340 )
341 {
342 INT band;
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;
347
348
349 /* Determine if this is a frame where a transient starts...
350
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.
354 */
355 transientFrame = 0;
356 if(hTonCorr->transientNextFrame){ /* The transient was detected in the previous frame, but is actually */
357 transientFrame = 1;
358 hTonCorr->transientNextFrame = 0;
359
360 if(transientFlag){
361 if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){
362 hTonCorr->transientNextFrame = 1;
363 }
364 }
365 }
366 else{
367 if(transientFlag){
368 if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){
369 transientFrame = 1;
370 hTonCorr->transientNextFrame = 0;
371 }
372 else{
373 hTonCorr->transientNextFrame = 1;
374 }
375 }
376 }
377 transientFrameInvfEst = transientFrame;
378
379
380 /*
381 Estimate the required invese filtereing level.
382 */
383 if (hTonCorr->switchInverseFilt)
384 FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt,
385 hTonCorr->quotaMatrix,
386 hTonCorr->nrgVector,
387 hTonCorr->indexVector,
388 hTonCorr->frameStartIndexInvfEst,
389 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
390 transientFrameInvfEst,
391 infVec);
392
393 /*
394 Detect what tones will be missing.
395 */
396 if (xposType == XPOS_LC ){
397 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector,
398 hTonCorr->quotaMatrix,
399 hTonCorr->signMatrix,
400 hTonCorr->indexVector,
401 frameInfo,
402 transientInfo,
403 missingHarmonicFlag,
404 missingHarmonicsIndex,
405 freqBandTable,
406 nSfb,
407 envelopeCompensation,
408 hTonCorr->nrgVectorFreq);
409 }
410 else{
411 *missingHarmonicFlag = 0;
412 FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR));
413 }
414
415
416
417 /*
418 Noise floor estimation
419 */
420
421 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
422
423 FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate,
424 frameInfo,
425 noiseLevels,
426 hTonCorr->quotaMatrix,
427 hTonCorr->indexVector,
428 *missingHarmonicFlag,
429 hTonCorr->frameStartIndex,
430 hTonCorr->numberOfEstimatesPerFrame,
431 transientFrame,
432 infVecPtr,
433 sbrSyntaxFlags);
434
435
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];
439 }
440 }
441
442 /**************************************************************************/
443 /*!
444 \brief Searches for the closest match in the frequency master table.
445
446
447
448 \return closest entry.
449
450 */
451 /**************************************************************************/
452 static INT
453 findClosestEntry(INT goalSb,
454 UCHAR *v_k_master,
455 INT numMaster,
456 INT direction)
457 {
458 INT index;
459
460 if( goalSb <= v_k_master[0] )
461 return v_k_master[0];
462
463 if( goalSb >= v_k_master[numMaster] )
464 return v_k_master[numMaster];
465
466 if(direction) {
467 index = 0;
468 while( v_k_master[index] < goalSb ) {
469 index++;
470 }
471 } else {
472 index = numMaster;
473 while( v_k_master[index] > goalSb ) {
474 index--;
475 }
476 }
477
478 return v_k_master[index];
479 }
480
481
482 /**************************************************************************/
483 /*!
484 \brief resets the patch
485
486
487
488 \return errorCode, noError if successful.
489
490 */
491 /**************************************************************************/
492 static INT
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. */
500 {
501 INT patch,k,i;
502 INT targetStopBand;
503
504 PATCH_PARAM *patchParam = hTonCorr->patchParam;
505
506 INT sbGuard = hTonCorr->guard;
507 INT sourceStartBand;
508 INT patchDistance;
509 INT numBandsInPatch;
510
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 */
514
515 INT goalSb;
516
517
518 /*
519 * Initialize the patching parameter
520 */
521
522 if (xposctrl == 1) {
523 lsb += xoverOffset;
524 xoverOffset = 0;
525 }
526
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 */
529
530 /* First patch */
531 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
532 targetStopBand = lsb + xoverOffset;
533
534 /* even (odd) numbered channel must be patched to even (odd) numbered channel */
535 patch = 0;
536 while(targetStopBand < usb) {
537
538 /* To many patches */
539 if (patch >= MAX_NUM_PATCHES)
540 return(1); /*Number of patches to high */
541
542 patchParam[patch].guardStartBand = targetStopBand;
543 targetStopBand += sbGuard;
544 patchParam[patch].targetStartBand = targetStopBand;
545
546 numBandsInPatch = goalSb - targetStopBand; /* get the desired range of the patch */
547
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 */
555 }
556
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 */
560
561 if (numBandsInPatch <= 0) {
562 patch--;
563 } else {
564 patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
565 patchParam[patch].targetBandOffs = patchDistance;
566 patchParam[patch].numBandsInPatch = numBandsInPatch;
567 patchParam[patch].sourceStopBand = patchParam[patch].sourceStartBand + numBandsInPatch;
568
569 targetStopBand += patchParam[patch].numBandsInPatch;
570 }
571
572 /* All patches but first */
573 sourceStartBand = hTonCorr->shiftStartSb;
574
575 /* Check if we are close to goalSb */
576 if( fixp_abs(targetStopBand - goalSb) < 3) {
577 goalSb = usb;
578 }
579
580 patch++;
581
582 }
583
584 patch--;
585
586 /* if highest patch contains less than three subband: skip it */
587 if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) {
588 patch--;
589 targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
590 }
591
592 hTonCorr->noOfPatches = patch + 1;
593
594
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;
599
600 for(i = 0; i < hTonCorr->noOfPatches; i++)
601 {
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;
606
607 for(k = 0; k < (targetStart- startGuardBand); k++)
608 hTonCorr->indexVector[startGuardBand+k] = -1;
609
610 for(k = 0; k < numberOfBands; k++)
611 hTonCorr->indexVector[targetStart+k] = sourceStart+k;
612 }
613
614 return (0);
615 }
616
617 /**************************************************************************/
618 /*!
619 \brief Creates an instance of the tonality correction parameter module.
620
621 The module includes modules for inverse filtering level estimation,
622 missing harmonics detection and noise floor level estimation.
623
624 \return errorCode, noError if successful.
625 */
626 /**************************************************************************/
627 INT
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 */
630 {
631 INT i;
632 FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
633 INT* signMatrix = GetRam_Sbr_signMatrix(chan);
634
635 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
636
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);
640 }
641
642 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan);
643
644 return 0;
645 }
646
647
648
649 /**************************************************************************/
650 /*!
651 \brief Initialize an instance of the tonality correction parameter module.
652
653 The module includes modules for inverse filtering level estimation,
654 missing harmonics detection and noise floor level estimation.
655
656 \return errorCode, noError if successful.
657 */
658 /**************************************************************************/
659 INT
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. */
669 {
670 INT nCols = sbrCfg->noQmfSlots;
671 INT fs = sbrCfg->sampleFreq;
672 INT noQmfChannels = sbrCfg->noQmfBands;
673
674 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
675 UCHAR *v_k_master = sbrCfg->v_k_master;
676 INT numMaster = sbrCfg->num_Master;
677
678 UCHAR **freqBandTable = sbrCfg->freqBandTable;
679 INT *nSfb = sbrCfg->nSfb;
680
681 INT i;
682
683 /*
684 Reset the patching and allocate memory for the quota matrix.
685 Assing parameters for the LPC analysis.
686 */
687 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
688 switch (timeSlots) {
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;
696 break;
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;
704 break;
705 }
706 } else
707 switch (timeSlots) {
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;
715 break;
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;
723 break;
724 default:
725 return -1;
726 }
727
728 hTonCorr->bufferLength = nCols;
729 hTonCorr->stepSize = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
730
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;
737
738 hTonCorr->noQmfChannels = noQmfChannels;
739
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);
743 }
744
745 /* Reset the patch.*/
746 hTonCorr->guard = 0;
747 hTonCorr->shiftStartSb = 1;
748
749 if(resetPatch(hTonCorr,
750 xposCtrl,
751 highBandStartSb,
752 v_k_master,
753 numMaster,
754 fs,
755 noQmfChannels))
756 return(1);
757
758 if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
759 ana_max_level,
760 freqBandTable[LO],
761 nSfb[LO],
762 noiseBands,
763 noiseFloorOffset,
764 timeSlots,
765 useSpeechConfig))
766 return(1);
767
768
769 if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt,
770 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
771 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands,
772 useSpeechConfig))
773 return(1);
774
775
776
777 if(FDKsbrEnc_InitSbrMissingHarmonicsDetector(
778 &hTonCorr->sbrMissingHarmonicsDetector,
779 fs,
780 frameSize,
781 nSfb[HI],
782 noQmfChannels,
783 hTonCorr->numberOfEstimates,
784 hTonCorr->move,
785 hTonCorr->numberOfEstimatesPerFrame,
786 sbrCfg->sbrSyntaxFlags))
787 return(1);
788
789
790
791 return (0);
792 }
793
794
795
796 /**************************************************************************/
797 /*!
798 \brief resets tonality correction parameter module.
799
800
801
802 \return errorCode, noError if successful.
803
804 */
805 /**************************************************************************/
806 INT
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. */
816 )
817 {
818
819 /* Reset the patch.*/
820 hTonCorr->guard = 0;
821 hTonCorr->shiftStartSb = 1;
822
823 if(resetPatch(hTonCorr,
824 xposctrl,
825 highBandStartSb,
826 v_k_master,
827 numMaster,
828 fs,
829 noQmfChannels))
830 return(1);
831
832
833
834 /* Reset the noise floor estimate.*/
835 if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
836 freqBandTable[LO],
837 nSfb[LO]))
838 return(1);
839
840 /*
841 Reset the inveerse filtereing detector.
842 */
843 if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt,
844 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
845 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
846 return(1);
847 /* Reset the missing harmonics detector. */
848 if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector,
849 nSfb[HI]))
850 return(1);
851
852 return (0);
853 }
854
855
856
857
858
859 /**************************************************************************/
860 /*!
861 \brief Deletes the tonality correction paramtere module.
862
863
864
865 \return none
866
867 */
868 /**************************************************************************/
869 void
870 FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
871 {
872
873 if (hTonCorr) {
874
875 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
876
877 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
878
879 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector);
880 }
881 }