1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /**************************** SBR encoder library ******************************
96
97 Author(s):
98
99 Description:
100
101 *******************************************************************************/
102
103 #include "ton_corr.h"
104
105 #include "sbrenc_ram.h"
106 #include "sbr_misc.h"
107 #include "genericStds.h"
108 #include "autocorr2nd.h"
109
110 #define BAND_V_SIZE 32
111 #define NUM_V_COMBINE \
112 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */
113
114 /**************************************************************************/
115 /*!
116 \brief Calculates the tonal to noise ration for different frequency bands
117 and time segments.
118
119 The ratio between the predicted energy (tonal energy A) and the total
120 energy (A + B) is calculated. This is converted to the ratio between
121 the predicted energy (tonal energy A) and the non-predictable energy
122 (noise energy B). Hence the quota-matrix contains A/B = q/(1-q).
123
124 The samples in nrgVector are scaled by 1.0/16.0
125 The samples in pNrgVectorFreq are scaled by 1.0/2.0
126 The samples in quotaMatrix are scaled by RELAXATION
127
128 \return none.
129
130 */
131 /**************************************************************************/
132
FDKsbrEnc_CalculateTonalityQuotas(HANDLE_SBR_TON_CORR_EST hTonCorr,FIXP_DBL ** RESTRICT sourceBufferReal,FIXP_DBL ** RESTRICT sourceBufferImag,INT usb,INT qmfScale)133 void FDKsbrEnc_CalculateTonalityQuotas(
134 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
135 FIXP_DBL **RESTRICT
136 sourceBufferReal, /*!< The real part of the QMF-matrix. */
137 FIXP_DBL **RESTRICT
138 sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */
139 INT usb, /*!< upper side band, highest + 1 QMF band in the SBR range. */
140 INT qmfScale /*!< sclefactor of QMF subsamples */
141 ) {
142 INT i, k, r, r2, timeIndex, autoCorrScaling;
143
144 INT startIndexMatrix = hTonCorr->startIndexMatrix;
145 INT totNoEst = hTonCorr->numberOfEstimates;
146 INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame;
147 INT move = hTonCorr->move;
148 INT noQmfChannels = hTonCorr->noQmfChannels; /* Number of Bands */
149 INT buffLen = hTonCorr->bufferLength; /* Number of Slots */
150 INT stepSize = hTonCorr->stepSize;
151 INT *pBlockLength = hTonCorr->lpcLength;
152 INT **RESTRICT signMatrix = hTonCorr->signMatrix;
153 FIXP_DBL *RESTRICT nrgVector = hTonCorr->nrgVector;
154 FIXP_DBL **RESTRICT quotaMatrix = hTonCorr->quotaMatrix;
155 FIXP_DBL *RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq;
156
157 FIXP_DBL *realBuf;
158 FIXP_DBL *imagBuf;
159
160 FIXP_DBL alphar[2], alphai[2], fac;
161
162 C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1)
163 C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
164 realBuf = realBufRef;
165 imagBuf = realBuf + BAND_V_SIZE * NUM_V_COMBINE;
166
167 FDK_ASSERT(buffLen <= BAND_V_SIZE);
168 FDK_ASSERT(sizeof(FIXP_DBL) * NUM_V_COMBINE * BAND_V_SIZE * 2 <
169 (1024 * sizeof(FIXP_DBL) - sizeof(ACORR_COEFS)));
170
171 /*
172 * Buffering of the quotaMatrix and the quotaMatrixTransp.
173 *********************************************************/
174 for (i = 0; i < move; i++) {
175 FDKmemcpy(quotaMatrix[i], quotaMatrix[i + noEstPerFrame],
176 noQmfChannels * sizeof(FIXP_DBL));
177 FDKmemcpy(signMatrix[i], signMatrix[i + noEstPerFrame],
178 noQmfChannels * sizeof(INT));
179 }
180
181 FDKmemmove(nrgVector, nrgVector + noEstPerFrame, move * sizeof(FIXP_DBL));
182 FDKmemclear(nrgVector + startIndexMatrix,
183 (totNoEst - startIndexMatrix) * sizeof(FIXP_DBL));
184 FDKmemclear(pNrgVectorFreq, noQmfChannels * sizeof(FIXP_DBL));
185
186 /*
187 * Calculate the quotas for the current time steps.
188 **************************************************/
189
190 for (r = 0; r < usb; r++) {
191 int blockLength;
192
193 k = hTonCorr->nextSample; /* startSample */
194 timeIndex = startIndexMatrix;
195 /* Copy as many as possible Band across all Slots at once */
196 if (realBuf != realBufRef) {
197 realBuf -= BAND_V_SIZE;
198 imagBuf -= BAND_V_SIZE;
199 } else {
200 realBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
201 imagBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
202
203 for (i = 0; i < buffLen; i++) {
204 int v;
205 FIXP_DBL *ptr;
206 ptr = realBuf + i;
207 for (v = 0; v < NUM_V_COMBINE; v++) {
208 ptr[0] = sourceBufferReal[i][r + v];
209 ptr[0 + BAND_V_SIZE * NUM_V_COMBINE] = sourceBufferImag[i][r + v];
210 ptr -= BAND_V_SIZE;
211 }
212 }
213 }
214
215 blockLength = pBlockLength[0];
216
217 while (k <= buffLen - blockLength) {
218 autoCorrScaling = fixMin(
219 getScalefactor(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength),
220 getScalefactor(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength));
221 autoCorrScaling = fixMax(0, autoCorrScaling - 1);
222
223 scaleValues(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
224 autoCorrScaling);
225 scaleValues(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
226 autoCorrScaling);
227
228 autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */
229 autoCorrScaling +=
230 autoCorr2nd_cplx(ac, realBuf + k, imagBuf + k, blockLength);
231
232 if (ac->det == FL2FXCONST_DBL(0.0f)) {
233 alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f);
234
235 alphar[0] = (ac->r01r) >> 2;
236 alphai[0] = (ac->r01i) >> 2;
237
238 fac = fMultDiv2(ac->r00r, ac->r11r) >> 1;
239 } else {
240 alphar[1] = (fMultDiv2(ac->r01r, ac->r12r) >> 1) -
241 (fMultDiv2(ac->r01i, ac->r12i) >> 1) -
242 (fMultDiv2(ac->r02r, ac->r11r) >> 1);
243 alphai[1] = (fMultDiv2(ac->r01i, ac->r12r) >> 1) +
244 (fMultDiv2(ac->r01r, ac->r12i) >> 1) -
245 (fMultDiv2(ac->r02i, ac->r11r) >> 1);
246
247 alphar[0] = (fMultDiv2(ac->r01r, ac->det) >> (ac->det_scale + 1)) +
248 fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i);
249 alphai[0] = (fMultDiv2(ac->r01i, ac->det) >> (ac->det_scale + 1)) +
250 fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i);
251
252 fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r)) >>
253 (ac->det_scale + 1);
254 }
255
256 if (fac == FL2FXCONST_DBL(0.0f)) {
257 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
258 signMatrix[timeIndex][r] = 0;
259 } else {
260 /* quotaMatrix is scaled with the factor RELAXATION
261 parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 *
262 2^RELAXATION_SHIFT) */
263 FIXP_DBL tmp, num, denom;
264 INT numShift, denomShift, commonShift;
265 INT sign;
266
267 num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) -
268 fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) -
269 fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r));
270 num = fixp_abs(num);
271
272 denom = (fac >> 1) +
273 (fMultDiv2(fac, RELAXATION_FRACT) >> RELAXATION_SHIFT) - num;
274 denom = fixp_abs(denom);
275
276 num = fMult(num, RELAXATION_FRACT);
277
278 numShift = CountLeadingBits(num) - 2;
279 num = scaleValue(num, numShift);
280
281 denomShift = CountLeadingBits(denom);
282 denom = (FIXP_DBL)denom << denomShift;
283
284 if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) {
285 commonShift =
286 fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS - 1);
287 if (commonShift < 0) {
288 commonShift = -commonShift;
289 tmp = schur_div(num, denom, 16);
290 commonShift = fixMin(commonShift, CountLeadingBits(tmp));
291 quotaMatrix[timeIndex][r] = tmp << commonShift;
292 } else {
293 quotaMatrix[timeIndex][r] =
294 schur_div(num, denom, 16) >> commonShift;
295 }
296 } else {
297 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
298 }
299
300 if (ac->r11r != FL2FXCONST_DBL(0.0f)) {
301 if (((ac->r01r >= FL2FXCONST_DBL(0.0f)) &&
302 (ac->r11r >= FL2FXCONST_DBL(0.0f))) ||
303 ((ac->r01r < FL2FXCONST_DBL(0.0f)) &&
304 (ac->r11r < FL2FXCONST_DBL(0.0f)))) {
305 sign = 1;
306 } else {
307 sign = -1;
308 }
309 } else {
310 sign = 1;
311 }
312
313 if (sign < 0) {
314 r2 = r; /* (INT) pow(-1, band); */
315 } else {
316 r2 = r + 1; /* (INT) pow(-1, band+1); */
317 }
318 signMatrix[timeIndex][r] = 1 - 2 * (r2 & 0x1);
319 }
320
321 nrgVector[timeIndex] +=
322 ((ac->r00r) >>
323 fixMin(DFRACT_BITS - 1,
324 (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
325 /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced
326 * division by shifting with one */
327 pNrgVectorFreq[r] =
328 pNrgVectorFreq[r] +
329 ((ac->r00r) >>
330 fixMin(DFRACT_BITS - 1,
331 (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
332
333 blockLength = pBlockLength[1];
334 k += stepSize;
335 timeIndex++;
336 }
337 }
338
339 C_ALLOC_SCRATCH_END(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
340 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1)
341 }
342
343 /**************************************************************************/
344 /*!
345 \brief Extracts the parameters required in the decoder to obtain the
346 correct tonal to noise ratio after SBR.
347
348 Estimates the tonal to noise ratio of the original signal (using LPC).
349 Predicts the tonal to noise ration of the SBR signal (in the decoder) by
350 patching the tonal to noise ratio values similar to the patching of the
351 lowband in the decoder. Given the tonal to noise ratio of the original
352 and the SBR signal, it estimates the required amount of inverse filtering,
353 additional noise as well as any additional sines.
354
355 \return none.
356
357 */
358 /**************************************************************************/
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)359 void FDKsbrEnc_TonCorrParamExtr(
360 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
361 INVF_MODE *infVec, /*!< Vector where the inverse filtering levels will be
362 stored. */
363 FIXP_DBL *noiseLevels, /*!< Vector where the noise levels will be stored. */
364 INT *missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any
365 strong sines are missing.*/
366 UCHAR *missingHarmonicsIndex, /*!< Vector indicating where sines are
367 missing. */
368 UCHAR *envelopeCompensation, /*!< Vector to store compensation values for
369 the energies in. */
370 const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time
371 and frequency grid of the current
372 frame.*/
373 UCHAR *transientInfo, /*!< Transient info.*/
374 UCHAR *freqBandTable, /*!< Frequency band tables for high-res.*/
375 INT nSfb, /*!< Number of scalefactor bands for high-res. */
376 XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/
377 UINT sbrSyntaxFlags) {
378 INT band;
379 INT transientFlag = transientInfo[1]; /*!< Flag indicating if a transient is
380 present in the current frame. */
381 INT transientPos = transientInfo[0]; /*!< Position of the transient.*/
382 INT transientFrame, transientFrameInvfEst;
383 INVF_MODE *infVecPtr;
384
385 /* Determine if this is a frame where a transient starts...
386
387 The detection of noise-floor, missing harmonics and invf_est, is not in sync
388 for the non-buf-opt decoder such as AAC. Hence we need to keep track on the
389 transient in the present frame as well as in the next.
390 */
391 transientFrame = 0;
392 if (hTonCorr->transientNextFrame) { /* The transient was detected in the
393 previous frame, but is actually */
394 transientFrame = 1;
395 hTonCorr->transientNextFrame = 0;
396
397 if (transientFlag) {
398 if (transientPos + hTonCorr->transientPosOffset >=
399 frameInfo->borders[frameInfo->nEnvelopes]) {
400 hTonCorr->transientNextFrame = 1;
401 }
402 }
403 } else {
404 if (transientFlag) {
405 if (transientPos + hTonCorr->transientPosOffset <
406 frameInfo->borders[frameInfo->nEnvelopes]) {
407 transientFrame = 1;
408 hTonCorr->transientNextFrame = 0;
409 } else {
410 hTonCorr->transientNextFrame = 1;
411 }
412 }
413 }
414 transientFrameInvfEst = transientFrame;
415
416 /*
417 Estimate the required invese filtereing level.
418 */
419 if (hTonCorr->switchInverseFilt)
420 FDKsbrEnc_qmfInverseFilteringDetector(
421 &hTonCorr->sbrInvFilt, hTonCorr->quotaMatrix, hTonCorr->nrgVector,
422 hTonCorr->indexVector, hTonCorr->frameStartIndexInvfEst,
423 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
424 transientFrameInvfEst, infVec);
425
426 /*
427 Detect what tones will be missing.
428 */
429 if (xposType == XPOS_LC) {
430 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
431 &hTonCorr->sbrMissingHarmonicsDetector, hTonCorr->quotaMatrix,
432 hTonCorr->signMatrix, hTonCorr->indexVector, frameInfo, transientInfo,
433 missingHarmonicFlag, missingHarmonicsIndex, freqBandTable, nSfb,
434 envelopeCompensation, hTonCorr->nrgVectorFreq);
435 } else {
436 *missingHarmonicFlag = 0;
437 FDKmemclear(missingHarmonicsIndex, nSfb * sizeof(UCHAR));
438 }
439
440 /*
441 Noise floor estimation
442 */
443
444 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
445
446 FDKsbrEnc_sbrNoiseFloorEstimateQmf(
447 &hTonCorr->sbrNoiseFloorEstimate, frameInfo, noiseLevels,
448 hTonCorr->quotaMatrix, hTonCorr->indexVector, *missingHarmonicFlag,
449 hTonCorr->frameStartIndex, hTonCorr->numberOfEstimatesPerFrame,
450 transientFrame, infVecPtr, sbrSyntaxFlags);
451
452 /* Store the invfVec data for the next frame...*/
453 for (band = 0; band < hTonCorr->sbrInvFilt.noDetectorBands; band++) {
454 hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
455 }
456 }
457
458 /**************************************************************************/
459 /*!
460 \brief Searches for the closest match in the frequency master table.
461
462
463
464 \return closest entry.
465
466 */
467 /**************************************************************************/
findClosestEntry(INT goalSb,UCHAR * v_k_master,INT numMaster,INT direction)468 static INT findClosestEntry(INT goalSb, UCHAR *v_k_master, INT numMaster,
469 INT direction) {
470 INT index;
471
472 if (goalSb <= v_k_master[0]) return v_k_master[0];
473
474 if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
475
476 if (direction) {
477 index = 0;
478 while (v_k_master[index] < goalSb) {
479 index++;
480 }
481 } else {
482 index = numMaster;
483 while (v_k_master[index] > goalSb) {
484 index--;
485 }
486 }
487
488 return v_k_master[index];
489 }
490
491 /**************************************************************************/
492 /*!
493 \brief resets the patch
494
495
496
497 \return errorCode, noError if successful.
498
499 */
500 /**************************************************************************/
resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr,INT xposctrl,INT highBandStartSb,UCHAR * v_k_master,INT numMaster,INT fs,INT noChannels)501 static INT resetPatch(
502 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
503 INT xposctrl, /*!< Different patch modes. */
504 INT highBandStartSb, /*!< Start band of the SBR range. */
505 UCHAR *v_k_master, /*!< Master frequency table from which all other table
506 are derived.*/
507 INT numMaster, /*!< Number of elements in the master table. */
508 INT fs, /*!< Sampling frequency. */
509 INT noChannels) /*!< Number of QMF-channels. */
510 {
511 INT patch, k, i;
512 INT targetStopBand;
513
514 PATCH_PARAM *patchParam = hTonCorr->patchParam;
515
516 INT sbGuard = hTonCorr->guard;
517 INT sourceStartBand;
518 INT patchDistance;
519 INT numBandsInPatch;
520
521 INT lsb =
522 v_k_master[0]; /* Lowest subband related to the synthesis filterbank */
523 INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis
524 filterbank */
525 INT xoverOffset =
526 highBandStartSb -
527 v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
528
529 INT goalSb;
530
531 /*
532 * Initialize the patching parameter
533 */
534
535 if (xposctrl == 1) {
536 lsb += xoverOffset;
537 xoverOffset = 0;
538 }
539
540 goalSb = (INT)((2 * noChannels * 16000 + (fs >> 1)) / fs); /* 16 kHz band */
541 goalSb = findClosestEntry(goalSb, v_k_master, numMaster,
542 1); /* Adapt region to master-table */
543
544 /* First patch */
545 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
546 targetStopBand = lsb + xoverOffset;
547
548 /* even (odd) numbered channel must be patched to even (odd) numbered channel
549 */
550 patch = 0;
551 while (targetStopBand < usb) {
552 /* To many patches */
553 if (patch >= MAX_NUM_PATCHES) return (1); /*Number of patches to high */
554
555 patchParam[patch].guardStartBand = targetStopBand;
556 targetStopBand += sbGuard;
557 patchParam[patch].targetStartBand = targetStopBand;
558
559 numBandsInPatch =
560 goalSb - targetStopBand; /* get the desired range of the patch */
561
562 if (numBandsInPatch >= lsb - sourceStartBand) {
563 /* desired number bands are not available -> patch whole source range */
564 patchDistance =
565 targetStopBand - sourceStartBand; /* get the targetOffset */
566 patchDistance =
567 patchDistance & ~1; /* rounding off odd numbers and make all even */
568 numBandsInPatch = lsb - (targetStopBand - patchDistance);
569 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
570 v_k_master, numMaster, 0) -
571 targetStopBand; /* Adapt region to master-table */
572 }
573
574 /* desired number bands are available -> get the minimal even patching
575 * distance */
576 patchDistance =
577 numBandsInPatch + targetStopBand - lsb; /* get minimal distance */
578 patchDistance = (patchDistance + 1) &
579 ~1; /* rounding up odd numbers and make all even */
580
581 if (numBandsInPatch <= 0) {
582 patch--;
583 } else {
584 patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
585 patchParam[patch].targetBandOffs = patchDistance;
586 patchParam[patch].numBandsInPatch = numBandsInPatch;
587 patchParam[patch].sourceStopBand =
588 patchParam[patch].sourceStartBand + numBandsInPatch;
589
590 targetStopBand += patchParam[patch].numBandsInPatch;
591 }
592
593 /* All patches but first */
594 sourceStartBand = hTonCorr->shiftStartSb;
595
596 /* Check if we are close to goalSb */
597 if (fixp_abs(targetStopBand - goalSb) < 3) {
598 goalSb = usb;
599 }
600
601 patch++;
602 }
603
604 patch--;
605
606 /* if highest patch contains less than three subband: skip it */
607 if (patchParam[patch].numBandsInPatch < 3 && patch > 0) {
608 patch--;
609 }
610
611 hTonCorr->noOfPatches = patch + 1;
612
613 /* Assign the index-vector, so we know where to look for the high-band.
614 -1 represents a guard-band. */
615 for (k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
616 hTonCorr->indexVector[k] = k;
617
618 for (i = 0; i < hTonCorr->noOfPatches; i++) {
619 INT sourceStart = hTonCorr->patchParam[i].sourceStartBand;
620 INT targetStart = hTonCorr->patchParam[i].targetStartBand;
621 INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch;
622 INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
623
624 for (k = 0; k < (targetStart - startGuardBand); k++)
625 hTonCorr->indexVector[startGuardBand + k] = -1;
626
627 for (k = 0; k < numberOfBands; k++)
628 hTonCorr->indexVector[targetStart + k] = sourceStart + k;
629 }
630
631 return (0);
632 }
633
634 /**************************************************************************/
635 /*!
636 \brief Creates an instance of the tonality correction parameter module.
637
638 The module includes modules for inverse filtering level estimation,
639 missing harmonics detection and noise floor level estimation.
640
641 \return errorCode, noError if successful.
642 */
643 /**************************************************************************/
FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,INT chan)644 INT FDKsbrEnc_CreateTonCorrParamExtr(
645 HANDLE_SBR_TON_CORR_EST
646 hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
647 INT chan) /*!< Channel index, needed for mem allocation */
648 {
649 INT i;
650 FIXP_DBL *quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
651 INT *signMatrix = GetRam_Sbr_signMatrix(chan);
652
653 if ((NULL == quotaMatrix) || (NULL == signMatrix)) {
654 goto bail;
655 }
656
657 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
658
659 for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) {
660 hTonCorr->quotaMatrix[i] = quotaMatrix + (i * 64);
661 hTonCorr->signMatrix[i] = signMatrix + (i * 64);
662 }
663
664 if (0 != FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
665 &hTonCorr->sbrMissingHarmonicsDetector, chan)) {
666 goto bail;
667 }
668
669 return 0;
670
671 bail:
672 hTonCorr->quotaMatrix[0] = quotaMatrix;
673 hTonCorr->signMatrix[0] = signMatrix;
674
675 FDKsbrEnc_DeleteTonCorrParamExtr(hTonCorr);
676
677 return -1;
678 }
679
680 /**************************************************************************/
681 /*!
682 \brief Initialize an instance of the tonality correction parameter module.
683
684 The module includes modules for inverse filtering level estimation,
685 missing harmonics detection and noise floor level estimation.
686
687 \return errorCode, noError if successful.
688 */
689 /**************************************************************************/
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)690 INT FDKsbrEnc_InitTonCorrParamExtr(
691 INT frameSize, /*!< Current SBR frame size. */
692 HANDLE_SBR_TON_CORR_EST
693 hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
694 HANDLE_SBR_CONFIG_DATA
695 sbrCfg, /*!< Pointer to SBR configuration parameters. */
696 INT timeSlots, /*!< Number of time-slots per frame */
697 INT xposCtrl, /*!< Different patch modes. */
698 INT ana_max_level, /*!< Maximum level of the adaptive noise. */
699 INT noiseBands, /*!< Number of noise bands per octave. */
700 INT noiseFloorOffset, /*!< Noise floor offset. */
701 UINT useSpeechConfig) /*!< Speech or music tuning. */
702 {
703 INT nCols = sbrCfg->noQmfSlots;
704 INT fs = sbrCfg->sampleFreq;
705 INT noQmfChannels = sbrCfg->noQmfBands;
706
707 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
708 UCHAR *v_k_master = sbrCfg->v_k_master;
709 INT numMaster = sbrCfg->num_Master;
710
711 UCHAR **freqBandTable = sbrCfg->freqBandTable;
712 INT *nSfb = sbrCfg->nSfb;
713
714 INT i;
715
716 /*
717 Reset the patching and allocate memory for the quota matrix.
718 Assuming parameters for the LPC analysis.
719 */
720 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
721 switch (timeSlots) {
722 case NUMBER_TIME_SLOTS_1920:
723 hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
724 hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
725 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
726 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
727 hTonCorr->frameStartIndexInvfEst = 0;
728 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
729 break;
730 case NUMBER_TIME_SLOTS_2048:
731 hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
732 hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
733 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
734 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
735 hTonCorr->frameStartIndexInvfEst = 0;
736 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
737 break;
738 }
739 } else
740 switch (timeSlots) {
741 case NUMBER_TIME_SLOTS_2048:
742 hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */
743 hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */
744 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
745 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
746 hTonCorr->frameStartIndexInvfEst = 0;
747 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
748 break;
749 case NUMBER_TIME_SLOTS_1920:
750 hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */
751 hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */
752 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
753 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
754 hTonCorr->frameStartIndexInvfEst = 0;
755 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
756 break;
757 default:
758 return -1;
759 }
760
761 hTonCorr->bufferLength = nCols;
762 hTonCorr->stepSize =
763 hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
764
765 hTonCorr->nextSample = LPC_ORDER; /* firstSample */
766 hTonCorr->move = hTonCorr->numberOfEstimates -
767 hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates
768 to move when
769 buffering.*/
770 if (hTonCorr->move < 0) {
771 return -1;
772 }
773 hTonCorr->startIndexMatrix =
774 hTonCorr->numberOfEstimates -
775 hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest
776 estimations in the tonality
777 Matrix.*/
778 hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current
779 frame (to be sent to the decoder) starts. */
780 hTonCorr->prevTransientFlag = 0;
781 hTonCorr->transientNextFrame = 0;
782
783 hTonCorr->noQmfChannels = noQmfChannels;
784
785 for (i = 0; i < hTonCorr->numberOfEstimates; i++) {
786 FDKmemclear(hTonCorr->quotaMatrix[i], sizeof(FIXP_DBL) * noQmfChannels);
787 FDKmemclear(hTonCorr->signMatrix[i], sizeof(INT) * noQmfChannels);
788 }
789
790 /* Reset the patch.*/
791 hTonCorr->guard = 0;
792 hTonCorr->shiftStartSb = 1;
793
794 if (resetPatch(hTonCorr, xposCtrl, highBandStartSb, v_k_master, numMaster, fs,
795 noQmfChannels))
796 return (1);
797
798 if (FDKsbrEnc_InitSbrNoiseFloorEstimate(
799 &hTonCorr->sbrNoiseFloorEstimate, ana_max_level, freqBandTable[LO],
800 nSfb[LO], noiseBands, noiseFloorOffset, timeSlots, useSpeechConfig))
801 return (1);
802
803 if (FDKsbrEnc_initInvFiltDetector(
804 &hTonCorr->sbrInvFilt,
805 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
806 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, useSpeechConfig))
807 return (1);
808
809 if (FDKsbrEnc_InitSbrMissingHarmonicsDetector(
810 &hTonCorr->sbrMissingHarmonicsDetector, fs, frameSize, nSfb[HI],
811 noQmfChannels, hTonCorr->numberOfEstimates, hTonCorr->move,
812 hTonCorr->numberOfEstimatesPerFrame, sbrCfg->sbrSyntaxFlags))
813 return (1);
814
815 return (0);
816 }
817
818 /**************************************************************************/
819 /*!
820 \brief resets tonality correction parameter module.
821
822
823
824 \return errorCode, noError if successful.
825
826 */
827 /**************************************************************************/
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)828 INT FDKsbrEnc_ResetTonCorrParamExtr(
829 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
830 INT xposctrl, /*!< Different patch modes. */
831 INT highBandStartSb, /*!< Start band of the SBR range. */
832 UCHAR *v_k_master, /*!< Master frequency table from which all other table
833 are derived.*/
834 INT numMaster, /*!< Number of elements in the master table. */
835 INT fs, /*!< Sampling frequency (of the SBR part). */
836 UCHAR *
837 *freqBandTable, /*!< Frequency band table for low-res and high-res. */
838 INT *nSfb, /*!< Number of frequency bands (hig-res and low-res). */
839 INT noQmfChannels /*!< Number of QMF channels. */
840 ) {
841 /* Reset the patch.*/
842 hTonCorr->guard = 0;
843 hTonCorr->shiftStartSb = 1;
844
845 if (resetPatch(hTonCorr, xposctrl, highBandStartSb, v_k_master, numMaster, fs,
846 noQmfChannels))
847 return (1);
848
849 /* Reset the noise floor estimate.*/
850 if (FDKsbrEnc_resetSbrNoiseFloorEstimate(&hTonCorr->sbrNoiseFloorEstimate,
851 freqBandTable[LO], nSfb[LO]))
852 return (1);
853
854 /*
855 Reset the inveerse filtereing detector.
856 */
857 if (FDKsbrEnc_resetInvFiltDetector(
858 &hTonCorr->sbrInvFilt,
859 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
860 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
861 return (1);
862 /* Reset the missing harmonics detector. */
863 if (FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
864 &hTonCorr->sbrMissingHarmonicsDetector, nSfb[HI]))
865 return (1);
866
867 return (0);
868 }
869
870 /**************************************************************************/
871 /*!
872 \brief Deletes the tonality correction paramtere module.
873
874
875
876 \return none
877
878 */
879 /**************************************************************************/
FDKsbrEnc_DeleteTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr)880 void FDKsbrEnc_DeleteTonCorrParamExtr(
881 HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
882 {
883 if (hTonCorr) {
884 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
885
886 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
887
888 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
889 &hTonCorr->sbrMissingHarmonicsDetector);
890 }
891 }
892