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 /*!
85 \file
86 \brief Envelope calculation
87
88 The envelope adjustor compares the energies present in the transposed
89 highband to the reference energies conveyed with the bitstream.
90 The highband is amplified (sometimes) or attenuated (mostly) to the
91 desired level.
92
93 The spectral shape of the reference energies can be changed several times per
94 frame if necessary. Each set of energy values corresponding to a certain range
95 in time will be called an <em>envelope</em> here.
96 The bitstream supports several frequency scales and two resolutions. Normally,
97 one or more QMF-subbands are grouped to one SBR-band. An envelope contains
98 reference energies for each SBR-band.
99 In addition to the energy envelopes, noise envelopes are transmitted that
100 define the ratio of energy which is generated by adding noise instead of
101 transposing the lowband. The noise envelopes are given in a coarser time
102 and frequency resolution.
103 If a signal contains strong tonal components, synthetic sines can be
104 generated in individual SBR bands.
105
106 An overlap buffer of 6 QMF-timeslots is used to allow a more
107 flexible alignment of the envelopes in time that is not restricted to the
108 core codec's frame borders.
109 Therefore the envelope adjustor has access to the spectral data of the
110 current frame as well as the last 6 QMF-timeslots of the previous frame.
111 However, in average only the data of 1 frame is being processed as
112 the adjustor is called once per frame.
113
114 Depending on the frequency range set in the bitstream, only QMF-subbands between
115 <em>lowSubband</em> and <em>highSubband</em> are adjusted.
116
117 Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a special Mantissa-Exponent format
118 ( see calculateSbrEnvelope() ) are being used. The main entry point for this modules is calculateSbrEnvelope().
119
120 \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref documentationOverview
121 */
122
123
124 #include "env_calc.h"
125
126 #include "sbrdec_freq_sca.h"
127 #include "env_extr.h"
128 #include "transcendent.h"
129 #include "sbr_ram.h"
130 #include "sbr_rom.h"
131
132 #include "genericStds.h" /* need FDKpow() for debug outputs */
133
134 #if defined(__arm__)
135 #include "arm/env_calc_arm.cpp"
136 #endif
137
138 typedef struct
139 {
140 FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
141 FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
142 FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
143 FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
144 FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
145
146 SCHAR nrgRef_e[MAX_FREQ_COEFFS];
147 SCHAR nrgEst_e[MAX_FREQ_COEFFS];
148 SCHAR nrgGain_e[MAX_FREQ_COEFFS];
149 SCHAR noiseLevel_e[MAX_FREQ_COEFFS];
150 SCHAR nrgSine_e[MAX_FREQ_COEFFS];
151 }
152 ENV_CALC_NRGS;
153
154 /*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
155 SCHAR *filtBuffer_e,
156 FIXP_DBL *NrgGain,
157 SCHAR *NrgGain_e,
158 int subbands);
159
160 /*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
161 FIXP_DBL **analysBufferImag,
162 int lowSubband, int highSubband,
163 int start_pos, int next_pos,
164 SCHAR frameExp,
165 FIXP_DBL *nrgEst,
166 SCHAR *nrgEst_e );
167
168 /*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
169 FIXP_DBL **analysBufferImag,
170 int nSfb,
171 UCHAR *freqBandTable,
172 int start_pos, int next_pos,
173 SCHAR input_e,
174 FIXP_DBL *nrg_est,
175 SCHAR *nrg_est_e );
176
177 /*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
178 FIXP_DBL tmpNoise, SCHAR tmpNoise_e,
179 UCHAR sinePresentFlag,
180 UCHAR sineMapped,
181 int noNoiseFlag);
182
183 /*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
184 int lowSubband,
185 int highSubband,
186 FIXP_DBL *sumRef_m,
187 SCHAR *sumRef_e,
188 FIXP_DBL *ptrAvgGain_m,
189 SCHAR *ptrAvgGain_e);
190
191 /*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal,
192 ENV_CALC_NRGS* nrgs,
193 UCHAR *ptrHarmIndex,
194 int lowSubbands,
195 int noSubbands,
196 int scale_change,
197 int noNoiseFlag,
198 int *ptrPhaseIndex,
199 int fCldfb);
200 /*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
201 FIXP_DBL *ptrImag,
202 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
203 ENV_CALC_NRGS* nrgs,
204 int lowSubbands,
205 int noSubbands,
206 int scale_change,
207 FIXP_SGL smooth_ratio,
208 int noNoiseFlag,
209 int filtBufferNoiseShift);
210
211
212 /*!
213 \brief Map sine flags from bitstream to QMF bands
214
215 The bitstream carries only 1 sine flag per band and frame.
216 This function maps every sine flag from the bitstream to a specific QMF subband
217 and to a specific envelope where the sine shall start.
218 The result is stored in the vector sineMapped which contains one entry per
219 QMF subband. The value of an entry specifies the envelope where a sine
220 shall start. A value of #MAX_ENVELOPES indicates that no sine is present
221 in the subband.
222 The missing harmonics flags from the previous frame (harmFlagsPrev) determine
223 if a sine starts at the beginning of the frame or at the transient position.
224 Additionally, the flags in harmFlagsPrev are being updated by this function
225 for the next frame.
226 */
mapSineFlags(UCHAR * freqBandTable,int nSfb,UCHAR * addHarmonics,int * harmFlagsPrev,int tranEnv,SCHAR * sineMapped)227 /*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
228 int nSfb, /*!< Number of bands in the table */
229 UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */
230 int *harmFlagsPrev, /*!< Packed 'addHarmonics' */
231 int tranEnv, /*!< Transient position */
232 SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each QMF band */
233
234 {
235 int i;
236 int lowSubband2 = freqBandTable[0]<<1;
237 int bitcount = 0;
238 int oldflags = *harmFlagsPrev;
239 int newflags = 0;
240
241 /*
242 Format of harmFlagsPrev:
243
244 first word = flags for highest 16 sfb bands in use
245 second word = flags for next lower 16 sfb bands (if present)
246 third word = flags for lowest 16 sfb bands (if present)
247
248 Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
249 The lowest bit of the first word corresponds to the _highest_ sfb band in use.
250 This is ensures that each flag is mapped to the same QMF band even after a
251 change of the crossover-frequency.
252 */
253
254
255 /* Reset the output vector first */
256 FDKmemset(sineMapped, MAX_ENVELOPES,MAX_FREQ_COEFFS); /* MAX_ENVELOPES means 'no sine' */
257
258 freqBandTable += nSfb;
259 addHarmonics += nSfb-1;
260
261 for (i=nSfb; i!=0; i--) {
262 int ui = *freqBandTable--; /* Upper limit of the current scale factor band. */
263 int li = *freqBandTable; /* Lower limit of the current scale factor band. */
264
265 if ( *addHarmonics-- ) { /* There is a sine in this band */
266
267 unsigned int mask = 1 << bitcount;
268 newflags |= mask; /* Set flag */
269
270 /*
271 If there was a sine in the last frame, let it continue from the first envelope on
272 else start at the transient position.
273 */
274 sineMapped[(ui+li-lowSubband2) >> 1] = ( oldflags & mask ) ? 0 : tranEnv;
275 }
276
277 if ((++bitcount == 16) || i==1) {
278 bitcount = 0;
279 *harmFlagsPrev++ = newflags;
280 oldflags = *harmFlagsPrev; /* Fetch 16 of the old flags */
281 newflags = 0;
282 }
283 }
284 }
285
286
287 /*!
288 \brief Reduce gain-adjustment induced aliasing for real valued filterbank.
289 */
290 /*static*/ void
aliasingReduction(FIXP_DBL * degreeAlias,ENV_CALC_NRGS * nrgs,int * useAliasReduction,int noSubbands)291 aliasingReduction(FIXP_DBL* degreeAlias, /*!< estimated aliasing for each QMF channel */
292 ENV_CALC_NRGS* nrgs,
293 int* useAliasReduction, /*!< synthetic sine engergy for each subband, used as flag */
294 int noSubbands) /*!< number of QMF channels to process */
295 {
296 FIXP_DBL* nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
297 SCHAR* nrgGain_e = nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
298 FIXP_DBL* nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
299 SCHAR* nrgEst_e = nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
300 int grouping = 0, index = 0, noGroups, k;
301 int groupVector[MAX_FREQ_COEFFS];
302
303 /* Calculate grouping*/
304 for (k = 0; k < noSubbands-1; k++ ){
305 if ( (degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k] ) {
306 if(grouping==0){
307 groupVector[index++] = k;
308 grouping = 1;
309 }
310 else{
311 if(groupVector[index-1] + 3 == k){
312 groupVector[index++] = k + 1;
313 grouping = 0;
314 }
315 }
316 }
317 else{
318 if(grouping){
319 if(useAliasReduction[k])
320 groupVector[index++] = k + 1;
321 else
322 groupVector[index++] = k;
323 grouping = 0;
324 }
325 }
326 }
327
328 if(grouping){
329 groupVector[index++] = noSubbands;
330 }
331 noGroups = index >> 1;
332
333
334 /*Calculate new gain*/
335 for (int group = 0; group < noGroups; group ++) {
336 FIXP_DBL nrgOrig = FL2FXCONST_DBL(0.0f); /* Original signal energy in current group of bands */
337 SCHAR nrgOrig_e = 0;
338 FIXP_DBL nrgAmp = FL2FXCONST_DBL(0.0f); /* Amplified signal energy in group (using current gains) */
339 SCHAR nrgAmp_e = 0;
340 FIXP_DBL nrgMod = FL2FXCONST_DBL(0.0f); /* Signal energy in group when applying modified gains */
341 SCHAR nrgMod_e = 0;
342 FIXP_DBL groupGain; /* Total energy gain in group */
343 SCHAR groupGain_e;
344 FIXP_DBL compensation; /* Compensation factor for the energy change when applying modified gains */
345 SCHAR compensation_e;
346
347 int startGroup = groupVector[2*group];
348 int stopGroup = groupVector[2*group+1];
349
350 /* Calculate total energy in group before and after amplification with current gains: */
351 for(k = startGroup; k < stopGroup; k++){
352 /* Get original band energy */
353 FIXP_DBL tmp = nrgEst[k];
354 SCHAR tmp_e = nrgEst_e[k];
355
356 FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
357
358 /* Multiply band energy with current gain */
359 tmp = fMult(tmp,nrgGain[k]);
360 tmp_e = tmp_e + nrgGain_e[k];
361
362 FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
363 }
364
365 /* Calculate total energy gain in group */
366 FDK_divide_MantExp(nrgAmp, nrgAmp_e,
367 nrgOrig, nrgOrig_e,
368 &groupGain, &groupGain_e);
369
370 for(k = startGroup; k < stopGroup; k++){
371 FIXP_DBL tmp;
372 SCHAR tmp_e;
373
374 FIXP_DBL alpha = degreeAlias[k];
375 if (k < noSubbands - 1) {
376 if (degreeAlias[k + 1] > alpha)
377 alpha = degreeAlias[k + 1];
378 }
379
380 /* Modify gain depending on the degree of aliasing */
381 FDK_add_MantExp( fMult(alpha,groupGain), groupGain_e,
382 fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,nrgGain[k]), nrgGain_e[k],
383 &nrgGain[k], &nrgGain_e[k] );
384
385 /* Apply modified gain to original energy */
386 tmp = fMult(nrgGain[k],nrgEst[k]);
387 tmp_e = nrgGain_e[k] + nrgEst_e[k];
388
389 /* Accumulate energy with modified gains applied */
390 FDK_add_MantExp( tmp, tmp_e,
391 nrgMod, nrgMod_e,
392 &nrgMod, &nrgMod_e );
393 }
394
395 /* Calculate compensation factor to retain the energy of the amplified signal */
396 FDK_divide_MantExp(nrgAmp, nrgAmp_e,
397 nrgMod, nrgMod_e,
398 &compensation, &compensation_e);
399
400 /* Apply compensation factor to all gains of the group */
401 for(k = startGroup; k < stopGroup; k++){
402 nrgGain[k] = fMult(nrgGain[k],compensation);
403 nrgGain_e[k] = nrgGain_e[k] + compensation_e;
404 }
405 }
406 }
407
408
409 /* Convert headroom bits to exponent */
410 #define SCALE2EXP(s) (15-(s))
411 #define EXP2SCALE(e) (15-(e))
412
413 /*!
414 \brief Apply spectral envelope to subband samples
415
416 This function is called from sbr_dec.cpp in each frame.
417
418 To enhance accuracy and due to the usage of tables for squareroots and
419 inverse, some calculations are performed with the operands being split
420 into mantissa and exponent. The variable names in the source code carry
421 the suffixes <em>_m</em> and <em>_e</em> respectively. The control data
422 in #hFrameData containts envelope data which is represented by this format but
423 stored in single words. (See requantizeEnvelopeData() for details). This data
424 is unpacked within calculateSbrEnvelope() to follow the described suffix convention.
425
426 The actual value (comparable to the corresponding float-variable in the
427 research-implementation) of a mantissa/exponent-pair can be calculated as
428
429 \f$ value = value\_m * 2^{value\_e} \f$
430
431 All energies and noise levels decoded from the bitstream suit for an
432 original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore,
433 the scale factor <em>hb_scale</em> passed into this function will be converted
434 to an 'input exponent' (#input_e), which fits the internal representation.
435
436 Before the actual processing, an exponent #adj_e for resulting adjusted
437 samples is derived from the maximum reference energy.
438
439 Then, for each envelope, the following steps are performed:
440
441 \li Calculate energy in the signal to be adjusted. Depending on the the value of
442 #interpolFreq (interpolation mode), this is either done seperately
443 for each QMF-subband or for each SBR-band.
444 The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas)
445 and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents).
446 \li Calculate gain and noise level for each subband:<br>
447 \f$ gain = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) }
448 \hspace{2cm}
449 noise = \sqrt{ nrgRef \cdot noiseRatio }
450 \f$<br>
451 where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the
452 bitstream and <em>nrgEst</em> is the subband energy before adjustment.
453 The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS]
454 (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels
455 are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS]
456 (exponents).
457 The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS]
458 and #nrgSine_e[#MAX_FREQ_COEFFS].
459 \li Noise limiting: The gain for each subband is limited both absolutely
460 and relatively compared to the total gain over all subbands.
461 \li Boost gain: Calculate and apply boost factor for each limiter band
462 in order to compensate for the energy loss imposed by the limiting.
463 \li Apply gains and add noise: The gains and noise levels are applied
464 to all timeslots of the current envelope. A short FIR-filter (length 4
465 QMF-timeslots) can be used to smooth the sudden change at the envelope borders.
466 Each complex subband sample of the current timeslot is multiplied by the
467 smoothed gain, then random noise with the calculated level is added.
468
469 \note
470 To reduce the stack size, some of the local arrays could be located within
471 the time output buffer. Of the 512 samples temporarily available there,
472 about half the size is already used by #SBR_FRAME_DATA. A pointer to the
473 remaining free memory could be supplied by an additional argument to calculateSbrEnvelope()
474 in sbr_dec:
475
476 \par
477 \code
478 calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
479 &hSbrDec->SbrCalculateEnvelope,
480 hHeaderData,
481 hFrameData,
482 QmfBufferReal,
483 QmfBufferImag,
484 timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1);
485 \endcode
486
487 \par
488 Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays
489 #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
490
491 \par
492 \code
493 fract* nrgRef_m = timeOutPtr;
494 SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
495 fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
496 SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
497 fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
498 \endcode
499
500 <br>
501 */
502 void
calculateSbrEnvelope(QMF_SCALE_FACTOR * sbrScaleFactor,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_FRAME_DATA hFrameData,FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,const int useLP,FIXP_DBL * degreeAlias,const UINT flags,const int frameErrorFlag)503 calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
504 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
505 HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
506 HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
507 FIXP_DBL **analysBufferReal, /*!< Real part of subband samples to be processed */
508 FIXP_DBL **analysBufferImag, /*!< Imag part of subband samples to be processed */
509 const int useLP,
510 FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
511 const UINT flags,
512 const int frameErrorFlag
513 )
514 {
515 int c, i, j, envNoise = 0;
516 UCHAR* borders = hFrameData->frameInfo.borders;
517
518 FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
519 HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
520
521 int lowSubband = hFreq->lowSubband;
522 int highSubband = hFreq->highSubband;
523 int noSubbands = highSubband - lowSubband;
524
525 int noNoiseBands = hFreq->nNfb;
526 int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
527 UCHAR first_start = borders[0] * hHeaderData->timeStep;
528
529 SCHAR sineMapped[MAX_FREQ_COEFFS];
530 SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
531 SCHAR adj_e = 0;
532 SCHAR output_e;
533 SCHAR final_e = 0;
534
535 SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
536
537 int useAliasReduction[64];
538 UCHAR smooth_length = 0;
539
540 FIXP_SGL * pIenv = hFrameData->iEnvelope;
541
542 /*
543 Extract sine flags for all QMF bands
544 */
545 mapSineFlags(hFreq->freqBandTable[1],
546 hFreq->nSfb[1],
547 hFrameData->addHarmonics,
548 h_sbr_cal_env->harmFlagsPrev,
549 hFrameData->frameInfo.tranEnv,
550 sineMapped);
551
552
553 /*
554 Scan for maximum in bufferd noise levels.
555 This is needed in case that we had strong noise in the previous frame
556 which is smoothed into the current frame.
557 The resulting exponent is used as start value for the maximum search
558 in reference energies
559 */
560 if (!useLP)
561 adj_e = h_sbr_cal_env->filtBufferNoise_e - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
562
563 /*
564 Scan for maximum reference energy to be able
565 to select appropriate values for adj_e and final_e.
566 */
567
568 for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
569 INT maxSfbNrg_e = -FRACT_BITS+NRG_EXP_OFFSET; /* start value for maximum search */
570
571 /* Fetch frequency resolution for current envelope: */
572 for (j=hFreq->nSfb[hFrameData->frameInfo.freqRes[i]]; j!=0; j--) {
573 maxSfbNrg_e = fixMax(maxSfbNrg_e,(INT)((LONG)(*pIenv++) & MASK_E));
574 }
575 maxSfbNrg_e -= NRG_EXP_OFFSET;
576
577 /* Energy -> magnitude (sqrt halfens exponent) */
578 maxSfbNrg_e = (maxSfbNrg_e+1) >> 1; /* +1 to go safe (round to next higher int) */
579
580 /* Some safety margin is needed for 2 reasons:
581 - The signal energy is not equally spread over all subband samples in
582 a specific sfb of an envelope (Nrg could be too high by a factor of
583 envWidth * sfbWidth)
584 - Smoothing can smear high gains of the previous envelope into the current
585 */
586 maxSfbNrg_e += 6;
587
588 if (borders[i] < hHeaderData->numberTimeSlots)
589 /* This envelope affects timeslots that belong to the output frame */
590 adj_e = (maxSfbNrg_e > adj_e) ? maxSfbNrg_e : adj_e;
591
592 if (borders[i+1] > hHeaderData->numberTimeSlots)
593 /* This envelope affects timeslots after the output frame */
594 final_e = (maxSfbNrg_e > final_e) ? maxSfbNrg_e : final_e;
595
596 }
597
598 /*
599 Calculate adjustment factors and apply them for every envelope.
600 */
601 pIenv = hFrameData->iEnvelope;
602
603 for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
604
605 int k, noNoiseFlag;
606 SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
607 C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
608
609 /*
610 Helper variables.
611 */
612 UCHAR start_pos = hHeaderData->timeStep * borders[i]; /* Start-position in time (subband sample) for current envelope. */
613 UCHAR stop_pos = hHeaderData->timeStep * borders[i+1]; /* Stop-position in time (subband sample) for current envelope. */
614 UCHAR freq_res = hFrameData->frameInfo.freqRes[i]; /* Frequency resolution for current envelope. */
615
616
617 /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in
618 cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit
619 errors and is tested by some streams from the certification set. */
620 FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
621
622 /* If the start-pos of the current envelope equals the stop pos of the current
623 noise envelope, increase the pointer (i.e. choose the next noise-floor).*/
624 if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise+1]){
625 noiseLevels += noNoiseBands; /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/
626 envNoise++;
627 }
628
629 if(i==hFrameData->frameInfo.tranEnv || i==h_sbr_cal_env->prevTranEnv) /* attack */
630 {
631 noNoiseFlag = 1;
632 if (!useLP)
633 smooth_length = 0; /* No smoothing on attacks! */
634 }
635 else {
636 noNoiseFlag = 0;
637 if (!useLP)
638 smooth_length = (1 - hHeaderData->bs_data.smoothingLength) << 2; /* can become either 0 or 4 */
639 }
640
641
642 /*
643 Energy estimation in transposed highband.
644 */
645 if (hHeaderData->bs_data.interpolFreq)
646 calcNrgPerSubband(analysBufferReal,
647 (useLP) ? NULL : analysBufferImag,
648 lowSubband, highSubband,
649 start_pos, stop_pos,
650 input_e,
651 pNrgs->nrgEst,
652 pNrgs->nrgEst_e);
653 else
654 calcNrgPerSfb(analysBufferReal,
655 (useLP) ? NULL : analysBufferImag,
656 hFreq->nSfb[freq_res],
657 hFreq->freqBandTable[freq_res],
658 start_pos, stop_pos,
659 input_e,
660 pNrgs->nrgEst,
661 pNrgs->nrgEst_e);
662
663 /*
664 Calculate subband gains
665 */
666 {
667 UCHAR * table = hFreq->freqBandTable[freq_res];
668 UCHAR * pUiNoise = &hFreq->freqBandTableNoise[1]; /*! Upper limit of the current noise floor band. */
669
670 FIXP_SGL * pNoiseLevels = noiseLevels;
671
672 FIXP_DBL tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
673 SCHAR tmpNoise_e = (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
674
675 int cc = 0;
676 c = 0;
677 for (j = 0; j < hFreq->nSfb[freq_res]; j++) {
678
679 FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
680 SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
681
682 UCHAR sinePresentFlag = 0;
683 int li = table[j];
684 int ui = table[j+1];
685
686 for (k=li; k<ui; k++) {
687 sinePresentFlag |= (i >= sineMapped[cc]);
688 cc++;
689 }
690
691 for (k=li; k<ui; k++) {
692 if (k >= *pUiNoise) {
693 tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
694 tmpNoise_e = (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
695
696 pUiNoise++;
697 }
698
699 FDK_ASSERT(k >= lowSubband);
700
701 if (useLP)
702 useAliasReduction[k-lowSubband] = !sinePresentFlag;
703
704 pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
705 pNrgs->nrgSine_e[c] = 0;
706
707 calcSubbandGain(refNrg, refNrg_e, pNrgs, c,
708 tmpNoise, tmpNoise_e,
709 sinePresentFlag, i >= sineMapped[c],
710 noNoiseFlag);
711
712 pNrgs->nrgRef[c] = refNrg;
713 pNrgs->nrgRef_e[c] = refNrg_e;
714
715 c++;
716 }
717 pIenv++;
718 }
719 }
720
721 /*
722 Noise limiting
723 */
724
725 for (c = 0; c < hFreq->noLimiterBands; c++) {
726
727 FIXP_DBL sumRef, boostGain, maxGain;
728 FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
729 SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
730
731 calcAvgGain(pNrgs,
732 hFreq->limiterBandTable[c], hFreq->limiterBandTable[c+1],
733 &sumRef, &sumRef_e,
734 &maxGain, &maxGain_e);
735
736 /* Multiply maxGain with limiterGain: */
737 maxGain = fMult(maxGain, FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
738 maxGain_e += FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
739
740 /* Scale mantissa of MaxGain into range between 0.5 and 1: */
741 if (maxGain == FL2FXCONST_DBL(0.0f))
742 maxGain_e = -FRACT_BITS;
743 else {
744 SCHAR charTemp = CountLeadingBits(maxGain);
745 maxGain_e -= charTemp;
746 maxGain <<= (int)charTemp;
747 }
748
749 if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
750 maxGain = FL2FXCONST_DBL(0.5f);
751 maxGain_e = maxGainLimit_e;
752 }
753
754
755 /* Every subband gain is compared to the scaled "average gain"
756 and limited if necessary: */
757 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c+1]; k++) {
758 if ( (pNrgs->nrgGain_e[k] > maxGain_e) || (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k]>maxGain) ) {
759
760 FIXP_DBL noiseAmp;
761 SCHAR noiseAmp_e;
762
763 FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
764 pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k],noiseAmp);
765 pNrgs->noiseLevel_e[k] += noiseAmp_e;
766 pNrgs->nrgGain[k] = maxGain;
767 pNrgs->nrgGain_e[k] = maxGain_e;
768 }
769 }
770
771 /* -- Boost gain
772 Calculate and apply boost factor for each limiter band:
773 1. Check how much energy would be present when using the limited gain
774 2. Calculate boost factor by comparison with reference energy
775 3. Apply boost factor to compensate for the energy loss due to limiting
776 */
777 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
778
779 /* 1.a Add energy of adjusted signal (using preliminary gain) */
780 FIXP_DBL tmp = fMult(pNrgs->nrgGain[k],pNrgs->nrgEst[k]);
781 SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
782 FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
783
784 /* 1.b Add sine energy (if present) */
785 if(pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
786 FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, &accu, &accu_e);
787 }
788 else {
789 /* 1.c Add noise energy (if present) */
790 if(noNoiseFlag == 0) {
791 FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, accu_e, &accu, &accu_e);
792 }
793 }
794 }
795
796 /* 2.a Calculate ratio of wanted energy and accumulated energy */
797 if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
798 boostGain = FL2FXCONST_DBL(0.6279716f);
799 boostGain_e = 2;
800 } else {
801 INT div_e;
802 boostGain = fDivNorm(sumRef, accu, &div_e);
803 boostGain_e = sumRef_e - accu_e + div_e;
804 }
805
806
807 /* 2.b Result too high? --> Limit the boost factor to +4 dB */
808 if((boostGain_e > 3) ||
809 (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
810 (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f)) )
811 {
812 boostGain = FL2FXCONST_DBL(0.6279716f);
813 boostGain_e = 2;
814 }
815 /* 3. Multiply all signal components with the boost factor */
816 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
817 pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k],boostGain);
818 pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
819
820 pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k],boostGain);
821 pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
822
823 pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k],boostGain);
824 pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
825 }
826 }
827 /* End of noise limiting */
828
829 if (useLP)
830 aliasingReduction(degreeAlias+lowSubband,
831 pNrgs,
832 useAliasReduction,
833 noSubbands);
834
835 /* For the timeslots within the range for the output frame,
836 use the same scale for the noise levels.
837 Drawback: If the envelope exceeds the frame border, the noise levels
838 will have to be rescaled later to fit final_e of
839 the gain-values.
840 */
841 noise_e = (start_pos < no_cols) ? adj_e : final_e;
842
843 /*
844 Convert energies to amplitude levels
845 */
846 for (k=0; k<noSubbands; k++) {
847 FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
848 FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], &pNrgs->nrgGain_e[k]);
849 FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], &noise_e);
850 }
851
852
853
854 /*
855 Apply calculated gains and adaptive noise
856 */
857
858 /* assembleHfSignals() */
859 {
860 int scale_change, sc_change;
861 FIXP_SGL smooth_ratio;
862 int filtBufferNoiseShift=0;
863
864 /* Initialize smoothing buffers with the first valid values */
865 if (h_sbr_cal_env->startUp)
866 {
867 if (!useLP) {
868 h_sbr_cal_env->filtBufferNoise_e = noise_e;
869
870 FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR));
871 FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
872 FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL));
873
874 }
875 h_sbr_cal_env->startUp = 0;
876 }
877
878 if (!useLP) {
879
880 equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */
881 h_sbr_cal_env->filtBuffer_e, /* buffered */
882 pNrgs->nrgGain, /* current */
883 pNrgs->nrgGain_e, /* current */
884 noSubbands);
885
886 /* Adapt exponent of buffered noise levels to the current exponent
887 so they can easily be smoothed */
888 if((h_sbr_cal_env->filtBufferNoise_e - noise_e)>=0) {
889 int shift = fixMin(DFRACT_BITS-1,(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
890 for (k=0; k<noSubbands; k++)
891 h_sbr_cal_env->filtBufferNoise[k] <<= shift;
892 }
893 else {
894 int shift = fixMin(DFRACT_BITS-1,-(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
895 for (k=0; k<noSubbands; k++)
896 h_sbr_cal_env->filtBufferNoise[k] >>= shift;
897 }
898
899 h_sbr_cal_env->filtBufferNoise_e = noise_e;
900 }
901
902 /* find best scaling! */
903 scale_change = -(DFRACT_BITS-1);
904 for(k=0;k<noSubbands;k++) {
905 scale_change = fixMax(scale_change,(int)pNrgs->nrgGain_e[k]);
906 }
907 sc_change = (start_pos<no_cols)? adj_e - input_e : final_e - input_e;
908
909 if ((scale_change-sc_change+1)<0)
910 scale_change-=(scale_change-sc_change+1);
911
912 scale_change = (scale_change-sc_change)+1;
913
914 for(k=0;k<noSubbands;k++) {
915 int sc = scale_change-pNrgs->nrgGain_e[k] + (sc_change-1);
916 pNrgs->nrgGain[k] >>= sc;
917 pNrgs->nrgGain_e[k] += sc;
918 }
919
920 if (!useLP) {
921 for(k=0;k<noSubbands;k++) {
922 int sc = scale_change-h_sbr_cal_env->filtBuffer_e[k] + (sc_change-1);
923 h_sbr_cal_env->filtBuffer[k] >>= sc;
924 }
925 }
926
927 for (j = start_pos; j < stop_pos; j++)
928 {
929 /* This timeslot is located within the first part of the processing buffer
930 and will be fed into the QMF-synthesis for the current frame.
931 adj_e - input_e
932 This timeslot will not yet be fed into the QMF so we do not care
933 about the adj_e.
934 sc_change = final_e - input_e
935 */
936 if ( (j==no_cols) && (start_pos<no_cols) )
937 {
938 int shift = (int) (noise_e - final_e);
939 if (!useLP)
940 filtBufferNoiseShift = shift; /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */
941 if (shift>=0) {
942 shift = fixMin(DFRACT_BITS-1,shift);
943 for (k=0; k<noSubbands; k++) {
944 pNrgs->nrgSine[k] <<= shift;
945 pNrgs->noiseLevel[k] <<= shift;
946 /*
947 if (!useLP)
948 h_sbr_cal_env->filtBufferNoise[k] <<= shift;
949 */
950 }
951 }
952 else {
953 shift = fixMin(DFRACT_BITS-1,-shift);
954 for (k=0; k<noSubbands; k++) {
955 pNrgs->nrgSine[k] >>= shift;
956 pNrgs->noiseLevel[k] >>= shift;
957 /*
958 if (!useLP)
959 h_sbr_cal_env->filtBufferNoise[k] >>= shift;
960 */
961 }
962 }
963
964 /* update noise scaling */
965 noise_e = final_e;
966 if (!useLP)
967 h_sbr_cal_env->filtBufferNoise_e = noise_e; /* scaling value unused! */
968
969 /* update gain buffer*/
970 sc_change -= (final_e - input_e);
971
972 if (sc_change<0) {
973 for(k=0;k<noSubbands;k++) {
974 pNrgs->nrgGain[k] >>= -sc_change;
975 pNrgs->nrgGain_e[k] += -sc_change;
976 }
977 if (!useLP) {
978 for(k=0;k<noSubbands;k++) {
979 h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
980 }
981 }
982 } else {
983 scale_change+=sc_change;
984 }
985
986 } // if
987
988 if (!useLP) {
989
990 /* Prevent the smoothing filter from running on constant levels */
991 if (j-start_pos < smooth_length)
992 smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
993
994 else
995 smooth_ratio = FL2FXCONST_SGL(0.0f);
996
997 adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
998 &analysBufferImag[j][lowSubband],
999 h_sbr_cal_env,
1000 pNrgs,
1001 lowSubband,
1002 noSubbands,
1003 scale_change,
1004 smooth_ratio,
1005 noNoiseFlag,
1006 filtBufferNoiseShift);
1007 }
1008 else
1009 {
1010 adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
1011 pNrgs,
1012 &h_sbr_cal_env->harmIndex,
1013 lowSubband,
1014 noSubbands,
1015 scale_change,
1016 noNoiseFlag,
1017 &h_sbr_cal_env->phaseIndex,
1018 (flags & SBRDEC_ELD_GRID));
1019 }
1020 } // for
1021
1022 if (!useLP) {
1023 /* Update time-smoothing-buffers for gains and noise levels
1024 The gains and the noise values of the current envelope are copied into the buffer.
1025 This has to be done at the end of each envelope as the values are required for
1026 a smooth transition to the next envelope. */
1027 FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL));
1028 FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR));
1029 FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
1030 }
1031
1032 }
1033 C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1034 }
1035
1036 /* Rescale output samples */
1037 {
1038 FIXP_DBL maxVal;
1039 int ov_reserve, reserve;
1040
1041 /* Determine headroom in old adjusted samples */
1042 maxVal = maxSubbandSample( analysBufferReal,
1043 (useLP) ? NULL : analysBufferImag,
1044 lowSubband,
1045 highSubband,
1046 0,
1047 first_start);
1048
1049 ov_reserve = fNorm(maxVal);
1050
1051 /* Determine headroom in new adjusted samples */
1052 maxVal = maxSubbandSample( analysBufferReal,
1053 (useLP) ? NULL : analysBufferImag,
1054 lowSubband,
1055 highSubband,
1056 first_start,
1057 no_cols);
1058
1059 reserve = fNorm(maxVal);
1060
1061 /* Determine common output exponent */
1062 if (ov_adj_e - ov_reserve > adj_e - reserve ) /* set output_e to the maximum */
1063 output_e = ov_adj_e - ov_reserve;
1064 else
1065 output_e = adj_e - reserve;
1066
1067 /* Rescale old samples */
1068 rescaleSubbandSamples( analysBufferReal,
1069 (useLP) ? NULL : analysBufferImag,
1070 lowSubband, highSubband,
1071 0, first_start,
1072 ov_adj_e - output_e);
1073
1074 /* Rescale new samples */
1075 rescaleSubbandSamples( analysBufferReal,
1076 (useLP) ? NULL : analysBufferImag,
1077 lowSubband, highSubband,
1078 first_start, no_cols,
1079 adj_e - output_e);
1080 }
1081
1082 /* Update hb_scale */
1083 sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
1084
1085 /* Save the current final exponent for the next frame: */
1086 sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e);
1087
1088
1089 /* We need to remeber to the next frame that the transient
1090 will occur in the first envelope (if tranEnv == nEnvelopes). */
1091 if(hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1092 h_sbr_cal_env->prevTranEnv = 0;
1093 else
1094 h_sbr_cal_env->prevTranEnv = -1;
1095
1096 }
1097
1098
1099 /*!
1100 \brief Create envelope instance
1101
1102 Must be called once for each channel before calculateSbrEnvelope() can be used.
1103
1104 \return errorCode, 0 if successful
1105 */
1106 SBR_ERROR
createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs,HANDLE_SBR_HEADER_DATA hHeaderData,const int chan,const UINT flags)1107 createSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
1108 HANDLE_SBR_HEADER_DATA hHeaderData, /*!< static SBR control data, initialized with defaults */
1109 const int chan, /*!< Channel for which to assign buffers */
1110 const UINT flags)
1111 {
1112 SBR_ERROR err = SBRDEC_OK;
1113 int i;
1114
1115 /* Clear previous missing harmonics flags */
1116 for (i=0; i<(MAX_FREQ_COEFFS+15)>>4; i++) {
1117 hs->harmFlagsPrev[i] = 0;
1118 }
1119 hs->harmIndex = 0;
1120
1121 /*
1122 Setup pointers for time smoothing.
1123 The buffer itself will be initialized later triggered by the startUp-flag.
1124 */
1125 hs->prevTranEnv = -1;
1126
1127
1128 /* initialization */
1129 resetSbrEnvelopeCalc(hs);
1130
1131 if (chan==0) { /* do this only once */
1132 err = resetFreqBandTables(hHeaderData, flags);
1133 }
1134
1135 return err;
1136 }
1137
1138 /*!
1139 \brief Create envelope instance
1140
1141 Must be called once for each channel before calculateSbrEnvelope() can be used.
1142
1143 \return errorCode, 0 if successful
1144 */
1145 int
deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs)1146 deleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs)
1147 {
1148 return 0;
1149 }
1150
1151
1152 /*!
1153 \brief Reset envelope instance
1154
1155 This function must be called for each channel on a change of configuration.
1156 Note that resetFreqBandTables should also be called in this case.
1157
1158 \return errorCode, 0 if successful
1159 */
1160 void
resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv)1161 resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
1162 {
1163 hCalEnv->phaseIndex = 0;
1164
1165 /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */
1166 hCalEnv->filtBufferNoise_e = 0;
1167
1168 hCalEnv->startUp = 1;
1169 }
1170
1171
1172 /*!
1173 \brief Equalize exponents of the buffered gain values and the new ones
1174
1175 After equalization of exponents, the FIR-filter addition for smoothing
1176 can be performed.
1177 This function is called once for each envelope before adjusting.
1178 */
equalizeFiltBufferExp(FIXP_DBL * filtBuffer,SCHAR * filtBuffer_e,FIXP_DBL * nrgGain,SCHAR * nrgGain_e,int subbands)1179 /*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
1180 SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
1181 FIXP_DBL *nrgGain, /*!< gains for current envelope */
1182 SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
1183 int subbands) /*!< Number of QMF subbands */
1184 {
1185 int band;
1186 int diff;
1187
1188 for (band=0; band<subbands; band++){
1189 diff = (int) (nrgGain_e[band] - filtBuffer_e[band]);
1190 if (diff>0) {
1191 filtBuffer[band] >>= diff; /* Compensate for the scale change by shifting the mantissa. */
1192 filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1193 }
1194 else if (diff<0) {
1195 /* The buffered gains seem to be larger, but maybe there
1196 are some unused bits left in the mantissa */
1197
1198 int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band]))-1;
1199
1200 if ((-diff) <= reserve) {
1201 /* There is enough space in the buffered mantissa so
1202 that we can take the new exponent as common.
1203 */
1204 filtBuffer[band] <<= (-diff);
1205 filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1206 }
1207 else {
1208 filtBuffer[band] <<= reserve; /* Shift the mantissa as far as possible: */
1209 filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1210
1211 /* For the remaining difference, change the new gain value */
1212 diff = fixMin(-(reserve + diff),DFRACT_BITS-1);
1213 nrgGain[band] >>= diff;
1214 nrgGain_e[band] += diff;
1215 }
1216 }
1217 }
1218 }
1219
1220 /*!
1221 \brief Shift left the mantissas of all subband samples
1222 in the giventime and frequency range by the specified number of bits.
1223
1224 This function is used to rescale the audio data in the overlap buffer
1225 which has already been envelope adjusted with the last frame.
1226 */
rescaleSubbandSamples(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos,int shift)1227 void rescaleSubbandSamples(FIXP_DBL ** re, /*!< Real part of input and output subband samples */
1228 FIXP_DBL ** im, /*!< Imaginary part of input and output subband samples */
1229 int lowSubband, /*!< Begin of frequency range to process */
1230 int highSubband, /*!< End of frequency range to process */
1231 int start_pos, /*!< Begin of time rage (QMF-timeslot) */
1232 int next_pos, /*!< End of time rage (QMF-timeslot) */
1233 int shift) /*!< number of bits to shift */
1234 {
1235 int width = highSubband-lowSubband;
1236
1237 if ( (width > 0) && (shift!=0) ) {
1238 if (im!=NULL) {
1239 for (int l=start_pos; l<next_pos; l++) {
1240 scaleValues(&re[l][lowSubband], width, shift);
1241 scaleValues(&im[l][lowSubband], width, shift);
1242 }
1243 } else
1244 {
1245 for (int l=start_pos; l<next_pos; l++) {
1246 scaleValues(&re[l][lowSubband], width, shift);
1247 }
1248 }
1249 }
1250 }
1251
1252
1253 /*!
1254 \brief Determine headroom for shifting
1255
1256 Determine by how much the spectrum can be shifted left
1257 for better accuracy in later processing.
1258
1259 \return Number of free bits in the biggest spectral value
1260 */
1261
maxSubbandSample(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos)1262 FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output subband samples */
1263 FIXP_DBL ** im, /*!< Real part of input and output subband samples */
1264 int lowSubband, /*!< Begin of frequency range to process */
1265 int highSubband, /*!< Number of QMF bands to process */
1266 int start_pos, /*!< Begin of time rage (QMF-timeslot) */
1267 int next_pos /*!< End of time rage (QMF-timeslot) */
1268 )
1269 {
1270 FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1271 unsigned int width = highSubband - lowSubband;
1272
1273 FDK_ASSERT(width <= (64));
1274
1275 if ( width > 0 ) {
1276 if (im!=NULL)
1277 {
1278 for (int l=start_pos; l<next_pos; l++)
1279 {
1280 #ifdef FUNCTION_FDK_get_maxval
1281 maxVal = FDK_get_maxval(maxVal, &re[l][lowSubband], &im[l][lowSubband], width);
1282 #else
1283 int k=width;
1284 FIXP_DBL *reTmp = &re[l][lowSubband];
1285 FIXP_DBL *imTmp = &im[l][lowSubband];
1286 do{
1287 FIXP_DBL tmp1 = *(reTmp++);
1288 FIXP_DBL tmp2 = *(imTmp++);
1289 maxVal |= (FIXP_DBL)((LONG)(tmp1)^((LONG)tmp1>>(DFRACT_BITS-1)));
1290 maxVal |= (FIXP_DBL)((LONG)(tmp2)^((LONG)tmp2>>(DFRACT_BITS-1)));
1291 } while(--k!=0);
1292 #endif
1293 }
1294 } else
1295 {
1296 for (int l=start_pos; l<next_pos; l++) {
1297 int k=width;
1298 FIXP_DBL *reTmp = &re[l][lowSubband];
1299 do{
1300 FIXP_DBL tmp = *(reTmp++);
1301 maxVal |= (FIXP_DBL)((LONG)(tmp)^((LONG)tmp>>(DFRACT_BITS-1)));
1302 }while(--k!=0);
1303 }
1304 }
1305 }
1306
1307 return(maxVal);
1308 }
1309
1310 #define SHIFT_BEFORE_SQUARE (3) /* (7/2) */
1311 /*!<
1312 If the accumulator does not provide enough overflow bits or
1313 does not provide a high dynamic range, the below energy calculation
1314 requires an additional shift operation for each sample.
1315 On the other hand, doing the shift allows using a single-precision
1316 multiplication for the square (at least 16bit x 16bit).
1317 For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1318 is required for the energy accumulation.
1319 Theoretically, the sample-squares can sum up to a value of 76,
1320 requiring 7 overflow bits. However since such situations are *very*
1321 rare, accu can be limited to 64.
1322 In case native saturated arithmetic is not available, overflows
1323 can be prevented by replacing the above #define by
1324 #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1325 which will result in slightly reduced accuracy.
1326 */
1327
1328 /*!
1329 \brief Estimates the mean energy of each filter-bank channel for the
1330 duration of the current envelope
1331
1332 This function is used when interpolFreq is true.
1333 */
calcNrgPerSubband(FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,int lowSubband,int highSubband,int start_pos,int next_pos,SCHAR frameExp,FIXP_DBL * nrgEst,SCHAR * nrgEst_e)1334 /*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
1335 FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
1336 int lowSubband, /*!< Begin of the SBR frequency range */
1337 int highSubband, /*!< High end of the SBR frequency range */
1338 int start_pos, /*!< First QMF-slot of current envelope */
1339 int next_pos, /*!< Last QMF-slot of current envelope + 1 */
1340 SCHAR frameExp, /*!< Common exponent for all input samples */
1341 FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
1342 SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */
1343 {
1344 FIXP_SGL invWidth;
1345 SCHAR preShift;
1346 SCHAR shift;
1347 FIXP_DBL sum;
1348 int k,l;
1349
1350 /* Divide by width of envelope later: */
1351 invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
1352 /* The common exponent needs to be doubled because all mantissas are squared: */
1353 frameExp = frameExp << 1;
1354
1355 for (k=lowSubband; k<highSubband; k++) {
1356 FIXP_DBL bufferReal[(((1024)/(32))+(6))];
1357 FIXP_DBL bufferImag[(((1024)/(32))+(6))];
1358 FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1359
1360 if (analysBufferImag!=NULL)
1361 {
1362 for (l=start_pos;l<next_pos;l++)
1363 {
1364 bufferImag[l] = analysBufferImag[l][k];
1365 maxVal |= (FIXP_DBL)((LONG)(bufferImag[l])^((LONG)bufferImag[l]>>(DFRACT_BITS-1)));
1366 bufferReal[l] = analysBufferReal[l][k];
1367 maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
1368 }
1369 }
1370 else
1371 {
1372 for (l=start_pos;l<next_pos;l++)
1373 {
1374 bufferReal[l] = analysBufferReal[l][k];
1375 maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
1376 }
1377 }
1378
1379 if (maxVal!=FL2FXCONST_DBL(0.f)) {
1380
1381
1382 /* If the accu does not provide enough overflow bits, we cannot
1383 shift the samples up to the limit.
1384 Instead, keep up to 3 free bits in each sample, i.e. up to
1385 6 bits after calculation of square.
1386 Please note the comment on saturated arithmetic above!
1387 */
1388 FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1389 preShift = CntLeadingZeros(maxVal)-1;
1390 preShift -= SHIFT_BEFORE_SQUARE;
1391
1392 if (preShift>=0) {
1393 if (analysBufferImag!=NULL) {
1394 for (l=start_pos; l<next_pos; l++) {
1395 FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
1396 FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
1397 accu = fPow2AddDiv2(accu, temp1);
1398 accu = fPow2AddDiv2(accu, temp2);
1399 }
1400 } else
1401 {
1402 for (l=start_pos; l<next_pos; l++) {
1403 FIXP_DBL temp = bufferReal[l] << (int)preShift;
1404 accu = fPow2AddDiv2(accu, temp);
1405 }
1406 }
1407 }
1408 else { /* if negative shift value */
1409 int negpreShift = -preShift;
1410 if (analysBufferImag!=NULL) {
1411 for (l=start_pos; l<next_pos; l++) {
1412 FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
1413 FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
1414 accu = fPow2AddDiv2(accu, temp1);
1415 accu = fPow2AddDiv2(accu, temp2);
1416 }
1417 } else
1418 {
1419 for (l=start_pos; l<next_pos; l++) {
1420 FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
1421 accu = fPow2AddDiv2(accu, temp);
1422 }
1423 }
1424 }
1425 accu <<= 1;
1426
1427 /* Convert double precision to Mantissa/Exponent: */
1428 shift = fNorm(accu);
1429 sum = accu << (int)shift;
1430
1431 /* Divide by width of envelope and apply frame scale: */
1432 *nrgEst++ = fMult(sum, invWidth);
1433 shift += 2 * preShift;
1434 if (analysBufferImag!=NULL)
1435 *nrgEst_e++ = frameExp - shift;
1436 else
1437 *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
1438 } /* maxVal!=0 */
1439 else {
1440
1441 /* Prevent a zero-mantissa-number from being misinterpreted
1442 due to its exponent. */
1443 *nrgEst++ = FL2FXCONST_DBL(0.0f);
1444 *nrgEst_e++ = 0;
1445 }
1446 }
1447 }
1448
1449 /*!
1450 \brief Estimates the mean energy of each Scale factor band for the
1451 duration of the current envelope.
1452
1453 This function is used when interpolFreq is false.
1454 */
calcNrgPerSfb(FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,int nSfb,UCHAR * freqBandTable,int start_pos,int next_pos,SCHAR input_e,FIXP_DBL * nrgEst,SCHAR * nrgEst_e)1455 /*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
1456 FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
1457 int nSfb, /*!< Number of scale factor bands */
1458 UCHAR *freqBandTable, /*!< First Subband for each Sfb */
1459 int start_pos, /*!< First QMF-slot of current envelope */
1460 int next_pos, /*!< Last QMF-slot of current envelope + 1 */
1461 SCHAR input_e, /*!< Common exponent for all input samples */
1462 FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
1463 SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */
1464 {
1465 FIXP_SGL invWidth;
1466 FIXP_DBL temp;
1467 SCHAR preShift;
1468 SCHAR shift, sum_e;
1469 FIXP_DBL sum;
1470
1471 int j,k,l,li,ui;
1472 FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
1473 but overflow bits are required for accumulation */
1474
1475 /* Divide by width of envelope later: */
1476 invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
1477 /* The common exponent needs to be doubled because all mantissas are squared: */
1478 input_e = input_e << 1;
1479
1480 for(j=0; j<nSfb; j++) {
1481 li = freqBandTable[j];
1482 ui = freqBandTable[j+1];
1483
1484 FIXP_DBL maxVal = maxSubbandSample( analysBufferReal,
1485 analysBufferImag,
1486 li,
1487 ui,
1488 start_pos,
1489 next_pos );
1490
1491 if (maxVal!=FL2FXCONST_DBL(0.f)) {
1492
1493 preShift = CntLeadingZeros(maxVal)-1;
1494
1495 /* If the accu does not provide enough overflow bits, we cannot
1496 shift the samples up to the limit.
1497 Instead, keep up to 3 free bits in each sample, i.e. up to
1498 6 bits after calculation of square.
1499 Please note the comment on saturated arithmetic above!
1500 */
1501 preShift -= SHIFT_BEFORE_SQUARE;
1502
1503 sumAll = FL2FXCONST_DBL(0.0f);
1504
1505
1506 for (k=li; k<ui; k++) {
1507
1508 sumLine = FL2FXCONST_DBL(0.0f);
1509
1510 if (analysBufferImag!=NULL) {
1511 if (preShift>=0) {
1512 for (l=start_pos; l<next_pos; l++) {
1513 temp = analysBufferReal[l][k] << (int)preShift;
1514 sumLine += fPow2Div2(temp);
1515 temp = analysBufferImag[l][k] << (int)preShift;
1516 sumLine += fPow2Div2(temp);
1517
1518 }
1519 } else {
1520 for (l=start_pos; l<next_pos; l++) {
1521 temp = analysBufferReal[l][k] >> -(int)preShift;
1522 sumLine += fPow2Div2(temp);
1523 temp = analysBufferImag[l][k] >> -(int)preShift;
1524 sumLine += fPow2Div2(temp);
1525 }
1526 }
1527 } else
1528 {
1529 if (preShift>=0) {
1530 for (l=start_pos; l<next_pos; l++) {
1531 temp = analysBufferReal[l][k] << (int)preShift;
1532 sumLine += fPow2Div2(temp);
1533 }
1534 } else {
1535 for (l=start_pos; l<next_pos; l++) {
1536 temp = analysBufferReal[l][k] >> -(int)preShift;
1537 sumLine += fPow2Div2(temp);
1538 }
1539 }
1540 }
1541
1542 /* The number of QMF-channels per SBR bands may be up to 15.
1543 Shift right to avoid overflows in sum over all channels. */
1544 sumLine = sumLine >> (4-1);
1545 sumAll += sumLine;
1546 }
1547
1548 /* Convert double precision to Mantissa/Exponent: */
1549 shift = fNorm(sumAll);
1550 sum = sumAll << (int)shift;
1551
1552 /* Divide by width of envelope: */
1553 sum = fMult(sum,invWidth);
1554
1555 /* Divide by width of Sfb: */
1556 sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui-li)));
1557
1558 /* Set all Subband energies in the Sfb to the average energy: */
1559 if (analysBufferImag!=NULL)
1560 sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
1561 else
1562 sum_e = input_e + 4 + 1 - shift; /* -4 to compensate right-shift; +1 due to missing imag. part */
1563
1564 sum_e -= 2 * preShift;
1565 } /* maxVal!=0 */
1566 else {
1567
1568 /* Prevent a zero-mantissa-number from being misinterpreted
1569 due to its exponent. */
1570 sum = FL2FXCONST_DBL(0.0f);
1571 sum_e = 0;
1572 }
1573
1574 for (k=li; k<ui; k++)
1575 {
1576 *nrgEst++ = sum;
1577 *nrgEst_e++ = sum_e;
1578 }
1579 }
1580 }
1581
1582
1583 /*!
1584 \brief Calculate gain, noise, and additional sine level for one subband.
1585
1586 The resulting energy gain is given by mantissa and exponent.
1587 */
calcSubbandGain(FIXP_DBL nrgRef,SCHAR nrgRef_e,ENV_CALC_NRGS * nrgs,int i,FIXP_DBL tmpNoise,SCHAR tmpNoise_e,UCHAR sinePresentFlag,UCHAR sineMapped,int noNoiseFlag)1588 /*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
1589 SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
1590 ENV_CALC_NRGS* nrgs,
1591 int i,
1592 FIXP_DBL tmpNoise, /*!< Relative noise level */
1593 SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */
1594 UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
1595 UCHAR sineMapped, /*!< Indicates if sine must be added */
1596 int noNoiseFlag) /*!< Flag to suppress noise addition */
1597 {
1598 FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
1599 SCHAR nrgEst_e = nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
1600 FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
1601 SCHAR *ptrNrgGain_e = &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
1602 FIXP_DBL *ptrNoiseLevel = &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
1603 SCHAR *ptrNoiseLevel_e = &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
1604 FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
1605 SCHAR *ptrNrgSine_e = &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
1606
1607 FIXP_DBL a, b, c;
1608 SCHAR a_e, b_e, c_e;
1609
1610 /*
1611 This addition of 1 prevents divisions by zero in the reference code.
1612 For very small energies in nrgEst, it prevents the gains from becoming
1613 very high which could cause some trouble due to the smoothing.
1614 */
1615 b_e = (int)(nrgEst_e - 1);
1616 if (b_e>=0) {
1617 nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (nrgEst >> 1);
1618 nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
1619
1620 } else {
1621 nrgEst = (nrgEst >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
1622 nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
1623 }
1624
1625 /* A = NrgRef * TmpNoise */
1626 a = fMult(nrgRef,tmpNoise);
1627 a_e = nrgRef_e + tmpNoise_e;
1628
1629 /* B = 1 + TmpNoise */
1630 b_e = (int)(tmpNoise_e - 1);
1631 if (b_e>=0) {
1632 b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (tmpNoise >> 1);
1633 b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
1634 } else {
1635 b = (tmpNoise >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
1636 b_e = 2; /* shift by 1 bit to avoid overflow */
1637 }
1638
1639 /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
1640 FDK_divide_MantExp( a, a_e,
1641 b, b_e,
1642 ptrNoiseLevel, ptrNoiseLevel_e);
1643
1644 if (sinePresentFlag) {
1645
1646 /* C = (1 + TmpNoise) * NrgEst */
1647 c = fMult(b,nrgEst);
1648 c_e = b_e + nrgEst_e;
1649
1650 /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
1651 FDK_divide_MantExp( a, a_e,
1652 c, c_e,
1653 ptrNrgGain, ptrNrgGain_e);
1654
1655 if (sineMapped) {
1656
1657 /* sineLevel = nrgRef/ (1 + TmpNoise) */
1658 FDK_divide_MantExp( nrgRef, nrgRef_e,
1659 b, b_e,
1660 ptrNrgSine, ptrNrgSine_e);
1661 }
1662 }
1663 else {
1664 if (noNoiseFlag) {
1665 /* B = NrgEst */
1666 b = nrgEst;
1667 b_e = nrgEst_e;
1668 }
1669 else {
1670 /* B = NrgEst * (1 + TmpNoise) */
1671 b = fMult(b,nrgEst);
1672 b_e = b_e + nrgEst_e;
1673 }
1674
1675
1676 /* gain = nrgRef / B */
1677 FDK_divide_MantExp( nrgRef, nrgRef_e,
1678 b, b_e,
1679 ptrNrgGain, ptrNrgGain_e);
1680 }
1681 }
1682
1683
1684 /*!
1685 \brief Calculate "average gain" for the specified subband range.
1686
1687 This is rather a gain of the average magnitude than the average
1688 of gains!
1689 The result is used as a relative limit for all gains within the
1690 current "limiter band" (a certain frequency range).
1691 */
calcAvgGain(ENV_CALC_NRGS * nrgs,int lowSubband,int highSubband,FIXP_DBL * ptrSumRef,SCHAR * ptrSumRef_e,FIXP_DBL * ptrAvgGain,SCHAR * ptrAvgGain_e)1692 /*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
1693 int lowSubband, /*!< Begin of the limiter band */
1694 int highSubband, /*!< High end of the limiter band */
1695 FIXP_DBL *ptrSumRef,
1696 SCHAR *ptrSumRef_e,
1697 FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
1698 SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */
1699 {
1700 FIXP_DBL *nrgRef = nrgs->nrgRef; /*!< Reference Energy according to envelope data */
1701 SCHAR *nrgRef_e = nrgs->nrgRef_e; /*!< Reference Energy according to envelope data (exponent) */
1702 FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
1703 SCHAR *nrgEst_e = nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
1704
1705 FIXP_DBL sumRef = 1;
1706 FIXP_DBL sumEst = 1;
1707 SCHAR sumRef_e = -FRACT_BITS;
1708 SCHAR sumEst_e = -FRACT_BITS;
1709 int k;
1710
1711 for (k=lowSubband; k<highSubband; k++){
1712 /* Add nrgRef[k] to sumRef: */
1713 FDK_add_MantExp( sumRef, sumRef_e,
1714 nrgRef[k], nrgRef_e[k],
1715 &sumRef, &sumRef_e );
1716
1717 /* Add nrgEst[k] to sumEst: */
1718 FDK_add_MantExp( sumEst, sumEst_e,
1719 nrgEst[k], nrgEst_e[k],
1720 &sumEst, &sumEst_e );
1721 }
1722
1723 FDK_divide_MantExp(sumRef, sumRef_e,
1724 sumEst, sumEst_e,
1725 ptrAvgGain, ptrAvgGain_e);
1726
1727 *ptrSumRef = sumRef;
1728 *ptrSumRef_e = sumRef_e;
1729 }
1730
1731
1732 /*!
1733 \brief Amplify one timeslot of the signal with the calculated gains
1734 and add the noisefloor.
1735 */
1736
adjustTimeSlotLC(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex,int fCldfb)1737 /*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
1738 ENV_CALC_NRGS* nrgs,
1739 UCHAR *ptrHarmIndex, /*!< Harmonic index */
1740 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
1741 int noSubbands, /*!< Number of QMF subbands */
1742 int scale_change, /*!< Number of bits to shift adjusted samples */
1743 int noNoiseFlag, /*!< Flag to suppress noise addition */
1744 int *ptrPhaseIndex, /*!< Start index to random number array */
1745 int fCldfb) /*!< CLDFB 80 flag */
1746 {
1747 FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
1748 FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
1749 FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
1750
1751 int k;
1752 int index = *ptrPhaseIndex;
1753 UCHAR harmIndex = *ptrHarmIndex;
1754 UCHAR freqInvFlag = (lowSubband & 1);
1755 FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
1756 int tone_count = 0;
1757 int sineSign = 1;
1758
1759 #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f))
1760 #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f))
1761
1762 /*
1763 First pass for k=0 pulled out of the loop:
1764 */
1765
1766 index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
1767
1768 /*
1769 The next multiplication constitutes the actual envelope adjustment
1770 of the signal and should be carried out with full accuracy
1771 (supplying #FRACT_BITS valid bits).
1772 */
1773 signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1774 sineLevel = *pSineLevel++;
1775 sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
1776
1777 if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
1778
1779 else if (!noNoiseFlag)
1780 /* Add noisefloor to the amplified signal */
1781 signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1782
1783 if (fCldfb) {
1784
1785 if (!(harmIndex&0x1)) {
1786 /* harmIndex 0,2 */
1787 signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
1788 *ptrReal++ = signalReal;
1789 }
1790 else {
1791 /* harmIndex 1,3 in combination with freqInvFlag */
1792 int shift = (int) (scale_change+1);
1793 shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
1794
1795 FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift );
1796
1797 FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext);
1798
1799
1800 /* save switch and compare operations and reduce to XOR statement */
1801 if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
1802 *(ptrReal-1) += tmp1;
1803 signalReal -= tmp2;
1804 } else {
1805 *(ptrReal-1) -= tmp1;
1806 signalReal += tmp2;
1807 }
1808 *ptrReal++ = signalReal;
1809 freqInvFlag = !freqInvFlag;
1810 }
1811
1812 } else
1813 {
1814 if (!(harmIndex&0x1)) {
1815 /* harmIndex 0,2 */
1816 signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
1817 *ptrReal++ = signalReal;
1818 }
1819 else {
1820 /* harmIndex 1,3 in combination with freqInvFlag */
1821 int shift = (int) (scale_change+1);
1822 shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
1823
1824 FIXP_DBL tmp1 = (shift>=0) ? ( fMultDiv2(C1, sineLevel) >> shift )
1825 : ( fMultDiv2(C1, sineLevel) << (-shift) );
1826 FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
1827
1828
1829 /* save switch and compare operations and reduce to XOR statement */
1830 if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
1831 *(ptrReal-1) += tmp1;
1832 signalReal -= tmp2;
1833 } else {
1834 *(ptrReal-1) -= tmp1;
1835 signalReal += tmp2;
1836 }
1837 *ptrReal++ = signalReal;
1838 freqInvFlag = !freqInvFlag;
1839 }
1840 }
1841
1842 pNoiseLevel++;
1843
1844 if ( noSubbands > 2 ) {
1845 if (!(harmIndex&0x1)) {
1846 /* harmIndex 0,2 */
1847 if(!harmIndex)
1848 {
1849 sineSign = 0;
1850 }
1851
1852 for (k=noSubbands-2; k!=0; k--) {
1853 FIXP_DBL sinelevel = *pSineLevel++;
1854 index++;
1855 if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == FL2FXCONST_DBL(0.0f)) && !noNoiseFlag)
1856 {
1857 /* Add noisefloor to the amplified signal */
1858 index &= (SBR_NF_NO_RANDOM_VAL - 1);
1859 signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1860 }
1861
1862 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1863 signalReal += fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1864
1865 pNoiseLevel++;
1866 *ptrReal++ = signalReal;
1867 } /* for ... */
1868 }
1869 else {
1870 /* harmIndex 1,3 in combination with freqInvFlag */
1871 if (harmIndex==1) freqInvFlag = !freqInvFlag;
1872
1873 for (k=noSubbands-2; k!=0; k--) {
1874 index++;
1875 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1876 signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1877
1878 if (*pSineLevel++!=FL2FXCONST_DBL(0.0f)) tone_count++;
1879 else if (!noNoiseFlag) {
1880 /* Add noisefloor to the amplified signal */
1881 index &= (SBR_NF_NO_RANDOM_VAL - 1);
1882 signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1883 }
1884
1885 pNoiseLevel++;
1886
1887 if (tone_count <= 16) {
1888 FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
1889 signalReal += (freqInvFlag) ? (-addSine) : (addSine);
1890 }
1891
1892 *ptrReal++ = signalReal;
1893 freqInvFlag = !freqInvFlag;
1894 } /* for ... */
1895 }
1896 }
1897
1898 if (noSubbands > -1) {
1899 index++;
1900 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1901 signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
1902 sineLevelPrev = fMultDiv2(pSineLevel[-1],FL2FX_SGL(0.0163f));
1903 sineLevel = pSineLevel[0];
1904
1905 if (pSineLevel[0]!=FL2FXCONST_DBL(0.0f)) tone_count++;
1906 else if (!noNoiseFlag) {
1907 /* Add noisefloor to the amplified signal */
1908 index &= (SBR_NF_NO_RANDOM_VAL - 1);
1909 signalReal = signalReal + (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1910 }
1911
1912 if (!(harmIndex&0x1)) {
1913 /* harmIndex 0,2 */
1914 *ptrReal = signalReal + ( (sineSign) ? -sineLevel : sineLevel);
1915 }
1916 else {
1917 /* harmIndex 1,3 in combination with freqInvFlag */
1918 if(tone_count <= 16){
1919 if (freqInvFlag) {
1920 *ptrReal++ = signalReal - sineLevelPrev;
1921 if (noSubbands + lowSubband < 63)
1922 *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
1923 }
1924 else {
1925 *ptrReal++ = signalReal + sineLevelPrev;
1926 if (noSubbands + lowSubband < 63)
1927 *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
1928 }
1929 }
1930 else *ptrReal = signalReal;
1931 }
1932 }
1933 *ptrHarmIndex = (harmIndex + 1) & 3;
1934 *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
1935 }
adjustTimeSlotHQ(FIXP_DBL * RESTRICT ptrReal,FIXP_DBL * RESTRICT ptrImag,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,ENV_CALC_NRGS * nrgs,int lowSubband,int noSubbands,int scale_change,FIXP_SGL smooth_ratio,int noNoiseFlag,int filtBufferNoiseShift)1936 void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
1937 FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
1938 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
1939 ENV_CALC_NRGS* nrgs,
1940 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
1941 int noSubbands, /*!< Number of QMF subbands */
1942 int scale_change, /*!< Number of bits to shift adjusted samples */
1943 FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
1944 int noNoiseFlag, /*!< Start index to random number array */
1945 int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
1946 {
1947
1948 FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
1949 FIXP_DBL *RESTRICT noiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
1950 FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
1951
1952 FIXP_DBL *RESTRICT filtBuffer = h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
1953 FIXP_DBL *RESTRICT filtBufferNoise = h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
1954 UCHAR *RESTRICT ptrHarmIndex =&h_sbr_cal_env->harmIndex; /*!< Harmonic index */
1955 int *RESTRICT ptrPhaseIndex =&h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
1956
1957 int k;
1958 FIXP_DBL signalReal, signalImag;
1959 FIXP_DBL noiseReal, noiseImag;
1960 FIXP_DBL smoothedGain, smoothedNoise;
1961 FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
1962 int index = *ptrPhaseIndex;
1963 UCHAR harmIndex = *ptrHarmIndex;
1964 register int freqInvFlag = (lowSubband & 1);
1965 FIXP_DBL sineLevel;
1966 int shift;
1967
1968 *ptrPhaseIndex = (index+noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
1969 *ptrHarmIndex = (harmIndex + 1) & 3;
1970
1971 /*
1972 Possible optimization:
1973 smooth_ratio and harmIndex stay constant during the loop.
1974 It might be faster to include a separate loop in each path.
1975
1976 the check for smooth_ratio is now outside the loop and the workload
1977 of the whole function decreased by about 20 %
1978 */
1979
1980 filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */
1981 if (filtBufferNoiseShift<0)
1982 shift = fixMin(DFRACT_BITS-1,-filtBufferNoiseShift);
1983 else
1984 shift = fixMin(DFRACT_BITS-1, filtBufferNoiseShift);
1985
1986 if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
1987
1988 for (k=0; k<noSubbands; k++) {
1989 /*
1990 Smoothing: The old envelope has been bufferd and a certain ratio
1991 of the old gains and noise levels is used.
1992 */
1993
1994 smoothedGain = fMult(smooth_ratio,filtBuffer[k]) +
1995 fMult(direct_ratio,gain[k]);
1996
1997 if (filtBufferNoiseShift<0) {
1998 smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])>>shift) +
1999 fMult(direct_ratio,noiseLevel[k]);
2000 }
2001 else {
2002 smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])<<shift) +
2003 fMult(direct_ratio,noiseLevel[k]);
2004 }
2005
2006 /*
2007 The next 2 multiplications constitute the actual envelope adjustment
2008 of the signal and should be carried out with full accuracy
2009 (supplying #DFRACT_BITS valid bits).
2010 */
2011 signalReal = fMultDiv2(*ptrReal,smoothedGain)<<((int)scale_change);
2012 signalImag = fMultDiv2(*ptrImag,smoothedGain)<<((int)scale_change);
2013
2014 index++;
2015
2016 if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2017 sineLevel = pSineLevel[k];
2018
2019 switch(harmIndex) {
2020 case 0:
2021 *ptrReal++ = (signalReal + sineLevel);
2022 *ptrImag++ = (signalImag);
2023 break;
2024 case 2:
2025 *ptrReal++ = (signalReal - sineLevel);
2026 *ptrImag++ = (signalImag);
2027 break;
2028 case 1:
2029 *ptrReal++ = (signalReal);
2030 if (freqInvFlag)
2031 *ptrImag++ = (signalImag - sineLevel);
2032 else
2033 *ptrImag++ = (signalImag + sineLevel);
2034 break;
2035 case 3:
2036 *ptrReal++ = signalReal;
2037 if (freqInvFlag)
2038 *ptrImag++ = (signalImag + sineLevel);
2039 else
2040 *ptrImag++ = (signalImag - sineLevel);
2041 break;
2042 }
2043 }
2044 else {
2045 if (noNoiseFlag) {
2046 /* Just the amplified signal is saved */
2047 *ptrReal++ = (signalReal);
2048 *ptrImag++ = (signalImag);
2049 }
2050 else {
2051 /* Add noisefloor to the amplified signal */
2052 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2053 noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)<<4;
2054 noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)<<4;
2055 *ptrReal++ = (signalReal + noiseReal);
2056 *ptrImag++ = (signalImag + noiseImag);
2057 }
2058 }
2059 freqInvFlag ^= 1;
2060 }
2061
2062 }
2063 else
2064 {
2065 for (k=0; k<noSubbands; k++)
2066 {
2067 smoothedGain = gain[k];
2068 signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
2069 signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
2070
2071 index++;
2072
2073 if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f))
2074 {
2075 switch (harmIndex)
2076 {
2077 case 0:
2078 signalReal += sineLevel;
2079 break;
2080 case 1:
2081 if (freqInvFlag)
2082 signalImag -= sineLevel;
2083 else
2084 signalImag += sineLevel;
2085 break;
2086 case 2:
2087 signalReal -= sineLevel;
2088 break;
2089 case 3:
2090 if (freqInvFlag)
2091 signalImag += sineLevel;
2092 else
2093 signalImag -= sineLevel;
2094 break;
2095 }
2096 }
2097 else
2098 {
2099 if (noNoiseFlag == 0)
2100 {
2101 /* Add noisefloor to the amplified signal */
2102 smoothedNoise = noiseLevel[k];
2103 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2104 noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2105 noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2106 signalReal += noiseReal<<4;
2107 signalImag += noiseImag<<4;
2108 }
2109 }
2110 *ptrReal++ = signalReal;
2111 *ptrImag++ = signalImag;
2112
2113 freqInvFlag ^= 1;
2114 }
2115 }
2116 }
2117
2118
2119 /*!
2120 \brief Reset limiter bands.
2121
2122 Build frequency band table for the gain limiter dependent on
2123 the previously generated transposer patch areas.
2124
2125 \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error
2126 */
2127 SBR_ERROR
ResetLimiterBands(UCHAR * limiterBandTable,UCHAR * noLimiterBands,UCHAR * freqBandTable,int noFreqBands,const PATCH_PARAM * patchParam,int noPatches,int limiterBands)2128 ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
2129 UCHAR *noLimiterBands, /*!< Resulting number of limiter band */
2130 UCHAR *freqBandTable, /*!< Table with possible band borders */
2131 int noFreqBands, /*!< Number of bands in freqBandTable */
2132 const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
2133 int noPatches, /*!< Number of transposer patches */
2134 int limiterBands) /*!< Selected 'band density' from bitstream */
2135 {
2136 int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
2137 UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
2138 int patchBorders[MAX_NUM_PATCHES + 1];
2139 int kx, k2;
2140 FIXP_DBL temp;
2141
2142 int lowSubband = freqBandTable[0];
2143 int highSubband = freqBandTable[noFreqBands];
2144
2145 /* 1 limiter band. */
2146 if(limiterBands == 0) {
2147 limiterBandTable[0] = 0;
2148 limiterBandTable[1] = highSubband - lowSubband;
2149 nBands = 1;
2150 } else {
2151 for (i = 0; i < noPatches; i++) {
2152 patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
2153 }
2154 patchBorders[i] = highSubband - lowSubband;
2155
2156 /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
2157 for (k = 0; k <= noFreqBands; k++) {
2158 workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
2159 }
2160 for (k = 1; k < noPatches; k++) {
2161 workLimiterBandTable[noFreqBands + k] = patchBorders[k];
2162 }
2163
2164 tempNoLim = nBands = noFreqBands + noPatches - 1;
2165 shellsort(workLimiterBandTable, tempNoLim + 1);
2166
2167 loLimIndex = 0;
2168 hiLimIndex = 1;
2169
2170
2171 while (hiLimIndex <= tempNoLim) {
2172 k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
2173 kx = workLimiterBandTable[loLimIndex] + lowSubband;
2174
2175 temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */
2176 temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]);
2177
2178 if (temp < FL2FXCONST_DBL (0.49f)>>5) {
2179 if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
2180 workLimiterBandTable[hiLimIndex] = highSubband;
2181 nBands--;
2182 hiLimIndex++;
2183 continue;
2184 }
2185 isPatchBorder[0] = isPatchBorder[1] = 0;
2186 for (k = 0; k <= noPatches; k++) {
2187 if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
2188 isPatchBorder[1] = 1;
2189 break;
2190 }
2191 }
2192 if (!isPatchBorder[1]) {
2193 workLimiterBandTable[hiLimIndex] = highSubband;
2194 nBands--;
2195 hiLimIndex++;
2196 continue;
2197 }
2198 for (k = 0; k <= noPatches; k++) {
2199 if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
2200 isPatchBorder[0] = 1;
2201 break;
2202 }
2203 }
2204 if (!isPatchBorder[0]) {
2205 workLimiterBandTable[loLimIndex] = highSubband;
2206 nBands--;
2207 }
2208 }
2209 loLimIndex = hiLimIndex;
2210 hiLimIndex++;
2211
2212 }
2213 shellsort(workLimiterBandTable, tempNoLim + 1);
2214
2215 /* Test if algorithm exceeded maximum allowed limiterbands */
2216 if( nBands > MAX_NUM_LIMITERS || nBands <= 0) {
2217 return SBRDEC_UNSUPPORTED_CONFIG;
2218 }
2219
2220 /* Copy limiterbands from working buffer into final destination */
2221 for (k = 0; k <= nBands; k++) {
2222 limiterBandTable[k] = workLimiterBandTable[k];
2223 }
2224 }
2225 *noLimiterBands = nBands;
2226
2227 return SBRDEC_OK;
2228 }
2229
2230