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 decoder library ******************************
96
97 Author(s):
98
99 Description:
100
101 *******************************************************************************/
102
103 /*!
104 \file
105 \brief Envelope calculation
106
107 The envelope adjustor compares the energies present in the transposed
108 highband to the reference energies conveyed with the bitstream.
109 The highband is amplified (sometimes) or attenuated (mostly) to the
110 desired level.
111
112 The spectral shape of the reference energies can be changed several times per
113 frame if necessary. Each set of energy values corresponding to a certain range
114 in time will be called an <em>envelope</em> here.
115 The bitstream supports several frequency scales and two resolutions. Normally,
116 one or more QMF-subbands are grouped to one SBR-band. An envelope contains
117 reference energies for each SBR-band.
118 In addition to the energy envelopes, noise envelopes are transmitted that
119 define the ratio of energy which is generated by adding noise instead of
120 transposing the lowband. The noise envelopes are given in a coarser time
121 and frequency resolution.
122 If a signal contains strong tonal components, synthetic sines can be
123 generated in individual SBR bands.
124
125 An overlap buffer of 6 QMF-timeslots is used to allow a more
126 flexible alignment of the envelopes in time that is not restricted to the
127 core codec's frame borders.
128 Therefore the envelope adjustor has access to the spectral data of the
129 current frame as well as the last 6 QMF-timeslots of the previous frame.
130 However, in average only the data of 1 frame is being processed as
131 the adjustor is called once per frame.
132
133 Depending on the frequency range set in the bitstream, only QMF-subbands
134 between <em>lowSubband</em> and <em>highSubband</em> are adjusted.
135
136 Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a
137 special Mantissa-Exponent format ( see calculateSbrEnvelope() ) are being
138 used. The main entry point for this modules is calculateSbrEnvelope().
139
140 \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref
141 documentationOverview
142 */
143
144 #include "env_calc.h"
145
146 #include "sbrdec_freq_sca.h"
147 #include "env_extr.h"
148 #include "transcendent.h"
149 #include "sbr_ram.h"
150 #include "sbr_rom.h"
151
152 #include "genericStds.h" /* need FDKpow() for debug outputs */
153
154 typedef struct {
155 FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
156 FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
157 FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
158 FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
159 FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
160
161 SCHAR nrgRef_e[MAX_FREQ_COEFFS];
162 SCHAR nrgEst_e[MAX_FREQ_COEFFS];
163 SCHAR nrgGain_e[MAX_FREQ_COEFFS];
164 SCHAR noiseLevel_e[MAX_FREQ_COEFFS];
165 SCHAR nrgSine_e[MAX_FREQ_COEFFS];
166 /* yet another exponent [0]: for ts < no_cols; [1]: for ts >= no_cols */
167 SCHAR exponent[2];
168 } ENV_CALC_NRGS;
169
170 static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e,
171 FIXP_DBL *NrgGain, SCHAR *NrgGain_e,
172 int subbands);
173
174 static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
175 FIXP_DBL **analysBufferImag, int lowSubband,
176 int highSubband, int start_pos, int next_pos,
177 SCHAR frameExp, FIXP_DBL *nrgEst,
178 SCHAR *nrgEst_e);
179
180 static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
181 FIXP_DBL **analysBufferImag, int nSfb,
182 UCHAR *freqBandTable, int start_pos, int next_pos,
183 SCHAR input_e, FIXP_DBL *nrg_est, SCHAR *nrg_est_e);
184
185 static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e,
186 ENV_CALC_NRGS *nrgs, int c, FIXP_DBL tmpNoise,
187 SCHAR tmpNoise_e, UCHAR sinePresentFlag,
188 UCHAR sineMapped, int noNoiseFlag);
189
190 static void calcAvgGain(ENV_CALC_NRGS *nrgs, int lowSubband, int highSubband,
191 FIXP_DBL *sumRef_m, SCHAR *sumRef_e,
192 FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e);
193
194 static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
195 UCHAR *ptrHarmIndex, int lowSubbands,
196 int noSubbands, int scale_change,
197 int noNoiseFlag, int *ptrPhaseIndex,
198 int scale_diff_low);
199
200 static void adjustTimeSlotLC(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
201 UCHAR *ptrHarmIndex, int lowSubbands,
202 int noSubbands, int scale_change, int noNoiseFlag,
203 int *ptrPhaseIndex);
204
205 /**
206 * \brief Variant of adjustTimeSlotHQ() which only regards gain and noise but no
207 * additional harmonics
208 */
209 static void adjustTimeSlotHQ_GainAndNoise(
210 FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
211 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
212 int lowSubbands, int noSubbands, int scale_change, FIXP_SGL smooth_ratio,
213 int noNoiseFlag, int filtBufferNoiseShift);
214 /**
215 * \brief Variant of adjustTimeSlotHQ() which only adds the additional harmonics
216 */
217 static void adjustTimeSlotHQ_AddHarmonics(
218 FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
219 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
220 int lowSubbands, int noSubbands, int scale_change);
221
222 static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
223 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
224 ENV_CALC_NRGS *nrgs, int lowSubbands,
225 int noSubbands, int scale_change,
226 FIXP_SGL smooth_ratio, int noNoiseFlag,
227 int filtBufferNoiseShift);
228
229 /*!
230 \brief Map sine flags from bitstream to QMF bands
231
232 The bitstream carries only 1 sine flag per band (Sfb) and frame.
233 This function maps every sine flag from the bitstream to a specific QMF
234 subband and to a specific envelope where the sine shall start. The result is
235 stored in the vector sineMapped which contains one entry per QMF subband. The
236 value of an entry specifies the envelope where a sine shall start. A value of
237 32 indicates that no sine is present in the subband. The missing harmonics
238 flags from the previous frame (harmFlagsPrev) determine if a sine starts at
239 the beginning of the frame or at the transient position. Additionally, the
240 flags in harmFlagsPrev are being updated by this function for the next frame.
241 */
mapSineFlags(UCHAR * freqBandTable,int nSfb,ULONG * addHarmonics,ULONG * harmFlagsPrev,ULONG * harmFlagsPrevActive,int tranEnv,SCHAR * sineMapped)242 static void mapSineFlags(
243 UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
244 int nSfb, /*!< Number of bands in the table */
245 ULONG *addHarmonics, /*!< Packed addHarmonics of current frame (aligned to
246 the MSB) */
247 ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame (aligned to
248 the LSB) */
249 ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous frame
250 (aligned to the LSB) */
251 int tranEnv, /*!< Transient position */
252 SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each
253 QMF band */
254
255 {
256 int i;
257 int bitcount = 31;
258 ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0};
259 ULONG *curFlags = addHarmonics;
260
261 /*
262 Format of addHarmonics (aligned to MSB):
263
264 Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
265 first word = flags for lowest 32 sfb bands in use
266 second word = flags for higest 32 sfb bands (if present)
267
268 Format of harmFlagsPrev (aligned to LSB):
269
270 Index is absolute (not relative to lsb) so it is correct even if lsb
271 changes first word = flags for lowest 32 qmf bands (0...31) second word =
272 flags for next higher 32 qmf bands (32...63)
273
274 */
275
276 /* Reset the output vector first */
277 FDKmemset(sineMapped, 32,
278 MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */
279 FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG));
280 for (i = 0; i < nSfb; i++) {
281 ULONG maskSfb =
282 1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */
283
284 if (*curFlags & maskSfb) { /* There is a sine in this band */
285 const int lsb = freqBandTable[0]; /* start of sbr range */
286 /* qmf band to which sine should be added */
287 const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1;
288 const int qmfBandDiv32 = qmfBand >> 5;
289 const int maskQmfBand =
290 1 << (qmfBand &
291 31); /* mask to extract harmonic flag from prevFlags */
292
293 /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */
294 harmFlagsQmfBands[qmfBandDiv32] |= maskQmfBand;
295
296 /*
297 If there was a sine in the last frame, let it continue from the first
298 envelope on else start at the transient position. Indexing of sineMapped
299 starts relative to lsb.
300 */
301 sineMapped[qmfBand - lsb] =
302 (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv;
303 if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) {
304 harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand;
305 }
306 }
307
308 if (bitcount-- == 0) {
309 bitcount = 31;
310 curFlags++;
311 }
312 }
313 FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands,
314 sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
315 }
316
317 /*!
318 \brief Restore sineMapped of previous frame
319
320 For PVC it might happen that the PVC framing (always 0) is out of sync with
321 the SBR framing. The adding of additional harmonics is done based on the SBR
322 framing. If the SBR framing is trailing the PVC framing the sine mapping of
323 the previous SBR frame needs to be used for the overlapping time slots.
324 */
mapSineFlagsPvc(UCHAR * freqBandTable,int nSfb,ULONG * harmFlagsPrev,ULONG * harmFlagsPrevActive,SCHAR * sineMapped,int sinusoidalPos,SCHAR * sinusoidalPosPrev,int trailingSbrFrame)325 /*static*/ void mapSineFlagsPvc(
326 UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per
327 band) */
328 int nSfb, /*!< Number of bands in the table */
329 ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame
330 (aligned to the MSB) */
331 ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous
332 frame (aligned to the LSB) */
333 SCHAR *sineMapped, /*!< Resulting vector of sine start positions
334 for each QMF band */
335 int sinusoidalPos, /*!< sinusoidal position */
336 SCHAR *sinusoidalPosPrev, /*!< sinusoidal position of previous
337 frame */
338 int trailingSbrFrame) /*!< indication if the SBR framing is
339 trailing the PVC framing */
340 {
341 /* Reset the output vector first */
342 FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */
343
344 if (trailingSbrFrame) {
345 /* restore sineMapped[] of previous frame */
346 int i;
347 const int lsb = freqBandTable[0];
348 const int usb = freqBandTable[nSfb];
349 for (i = lsb; i < usb; i++) {
350 const int qmfBandDiv32 = i >> 5;
351 const int maskQmfBand =
352 1 << (i & 31); /* mask to extract harmonic flag from prevFlags */
353
354 /* Two cases need to be distinguished ... */
355 if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) {
356 /* the sine mapping already started last PVC frame -> seamlessly
357 * continue */
358 sineMapped[i - lsb] = 0;
359 } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) {
360 /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts
361 * in this frame */
362 sineMapped[i - lsb] =
363 *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots
364 ahead of last frame now */
365 }
366 }
367 }
368 *sinusoidalPosPrev = sinusoidalPos;
369 }
370
371 /*!
372 \brief Reduce gain-adjustment induced aliasing for real valued filterbank.
373 */
aliasingReduction(FIXP_DBL * degreeAlias,ENV_CALC_NRGS * nrgs,UCHAR * useAliasReduction,int noSubbands)374 /*static*/ void aliasingReduction(
375 FIXP_DBL *degreeAlias, /*!< estimated aliasing for each QMF
376 channel */
377 ENV_CALC_NRGS *nrgs,
378 UCHAR *useAliasReduction, /*!< synthetic sine energy for each
379 subband, used as flag */
380 int noSubbands) /*!< number of QMF channels to process */
381 {
382 FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
383 SCHAR *nrgGain_e =
384 nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
385 FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
386 SCHAR *nrgEst_e =
387 nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
388 int grouping = 0, index = 0, noGroups, k;
389 int groupVector[MAX_FREQ_COEFFS];
390
391 /* Calculate grouping*/
392 for (k = 0; k < noSubbands - 1; k++) {
393 if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) {
394 if (grouping == 0) {
395 groupVector[index++] = k;
396 grouping = 1;
397 } else {
398 if (groupVector[index - 1] + 3 == k) {
399 groupVector[index++] = k + 1;
400 grouping = 0;
401 }
402 }
403 } else {
404 if (grouping) {
405 if (useAliasReduction[k])
406 groupVector[index++] = k + 1;
407 else
408 groupVector[index++] = k;
409 grouping = 0;
410 }
411 }
412 }
413
414 if (grouping) {
415 groupVector[index++] = noSubbands;
416 }
417 noGroups = index >> 1;
418
419 /*Calculate new gain*/
420 for (int group = 0; group < noGroups; group++) {
421 FIXP_DBL nrgOrig = FL2FXCONST_DBL(
422 0.0f); /* Original signal energy in current group of bands */
423 SCHAR nrgOrig_e = 0;
424 FIXP_DBL nrgAmp = FL2FXCONST_DBL(
425 0.0f); /* Amplified signal energy in group (using current gains) */
426 SCHAR nrgAmp_e = 0;
427 FIXP_DBL nrgMod = FL2FXCONST_DBL(
428 0.0f); /* Signal energy in group when applying modified gains */
429 SCHAR nrgMod_e = 0;
430 FIXP_DBL groupGain; /* Total energy gain in group */
431 SCHAR groupGain_e;
432 FIXP_DBL compensation; /* Compensation factor for the energy change when
433 applying modified gains */
434 SCHAR compensation_e;
435
436 int startGroup = groupVector[2 * group];
437 int stopGroup = groupVector[2 * group + 1];
438
439 /* Calculate total energy in group before and after amplification with
440 * current gains: */
441 for (k = startGroup; k < stopGroup; k++) {
442 /* Get original band energy */
443 FIXP_DBL tmp = nrgEst[k];
444 SCHAR tmp_e = nrgEst_e[k];
445
446 FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
447
448 /* Multiply band energy with current gain */
449 tmp = fMult(tmp, nrgGain[k]);
450 tmp_e = tmp_e + nrgGain_e[k];
451
452 FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
453 }
454
455 /* Calculate total energy gain in group */
456 FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain,
457 &groupGain_e);
458
459 for (k = startGroup; k < stopGroup; k++) {
460 FIXP_DBL tmp;
461 SCHAR tmp_e;
462
463 FIXP_DBL alpha = degreeAlias[k];
464 if (k < noSubbands - 1) {
465 if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1];
466 }
467
468 /* Modify gain depending on the degree of aliasing */
469 FDK_add_MantExp(
470 fMult(alpha, groupGain), groupGain_e,
471 fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,
472 nrgGain[k]),
473 nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]);
474
475 /* Apply modified gain to original energy */
476 tmp = fMult(nrgGain[k], nrgEst[k]);
477 tmp_e = nrgGain_e[k] + nrgEst_e[k];
478
479 /* Accumulate energy with modified gains applied */
480 FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e);
481 }
482
483 /* Calculate compensation factor to retain the energy of the amplified
484 * signal */
485 FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation,
486 &compensation_e);
487
488 /* Apply compensation factor to all gains of the group */
489 for (k = startGroup; k < stopGroup; k++) {
490 nrgGain[k] = fMult(nrgGain[k], compensation);
491 nrgGain_e[k] = nrgGain_e[k] + compensation_e;
492 }
493 }
494 }
495
496 #define INTER_TES_SF_CHANGE 3
497
498 typedef struct {
499 FIXP_DBL subsample_power_low[(((1024) / (32) * (4) / 2) + (3 * (4)))];
500 FIXP_DBL subsample_power_high[(((1024) / (32) * (4) / 2) + (3 * (4)))];
501 FIXP_DBL gain[(((1024) / (32) * (4) / 2) + (3 * (4)))];
502 SCHAR subsample_power_low_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
503 SCHAR subsample_power_high_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
504 } ITES_TEMP;
505
apply_inter_tes(FIXP_DBL ** qmfReal,FIXP_DBL ** qmfImag,const QMF_SCALE_FACTOR * sbrScaleFactor,const SCHAR exp[2],const int RATE,const int startPos,const int stopPos,const int lowSubband,const int nbSubband,const UCHAR gamma_idx)506 static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
507 const QMF_SCALE_FACTOR *sbrScaleFactor,
508 const SCHAR exp[2], const int RATE,
509 const int startPos, const int stopPos,
510 const int lowSubband, const int nbSubband,
511 const UCHAR gamma_idx) {
512 int highSubband = lowSubband + nbSubband;
513 FIXP_DBL *subsample_power_high, *subsample_power_low;
514 SCHAR *subsample_power_high_sf, *subsample_power_low_sf;
515 FIXP_DBL total_power_high = (FIXP_DBL)0;
516 FIXP_DBL total_power_low = (FIXP_DBL)0;
517 FIXP_DBL *gain;
518 int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
519
520 /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */
521 int gamma_sf =
522 (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */
523
524 int nbSubsample = stopPos - startPos;
525 int i, j;
526
527 C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1);
528 subsample_power_high = pTmp->subsample_power_high;
529 subsample_power_low = pTmp->subsample_power_low;
530 subsample_power_high_sf = pTmp->subsample_power_high_sf;
531 subsample_power_low_sf = pTmp->subsample_power_low_sf;
532 gain = pTmp->gain;
533
534 if (gamma_idx > 0) {
535 int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample);
536 int total_power_low_sf = 1 - DFRACT_BITS;
537 int total_power_high_sf = 1 - DFRACT_BITS;
538
539 for (i = 0; i < nbSubsample; ++i) {
540 FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
541 FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
542 FIXP_DBL maxVal = (FIXP_DBL)0;
543
544 int ts = startPos + i;
545
546 int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale
547 : sbrScaleFactor->lb_scale;
548 low_sf = 15 - low_sf;
549
550 for (j = 0; j < lowSubband; ++j) {
551 bufferImag[j] = qmfImag[startPos + i][j];
552 maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
553 ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
554 bufferReal[j] = qmfReal[startPos + i][j];
555 maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
556 ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
557 }
558
559 subsample_power_low[i] = (FIXP_DBL)0;
560 subsample_power_low_sf[i] = 0;
561
562 if (maxVal != FL2FXCONST_DBL(0.f)) {
563 /* multiply first, then shift for safe summation */
564 int preShift = 1 - CntLeadingZeros(maxVal);
565 int postShift = 32 - fNormz((FIXP_DBL)lowSubband);
566
567 /* reduce preShift because otherwise we risk to square -1.f */
568 if (preShift != 0) preShift++;
569
570 subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1;
571
572 scaleValues(bufferReal, lowSubband, -preShift);
573 scaleValues(bufferImag, lowSubband, -preShift);
574 for (j = 0; j < lowSubband; ++j) {
575 FIXP_DBL addme;
576 addme = fPow2Div2(bufferReal[j]);
577 subsample_power_low[i] += addme >> postShift;
578 addme = fPow2Div2(bufferImag[j]);
579 subsample_power_low[i] += addme >> postShift;
580 }
581 }
582
583 /* now get high */
584
585 maxVal = (FIXP_DBL)0;
586
587 int high_sf = exp[(ts < 16 * RATE) ? 0 : 1];
588
589 for (j = lowSubband; j < highSubband; ++j) {
590 bufferImag[j] = qmfImag[startPos + i][j];
591 maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
592 ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
593 bufferReal[j] = qmfReal[startPos + i][j];
594 maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
595 ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
596 }
597
598 subsample_power_high[i] = (FIXP_DBL)0;
599 subsample_power_high_sf[i] = 0;
600
601 if (maxVal != FL2FXCONST_DBL(0.f)) {
602 int preShift = 1 - CntLeadingZeros(maxVal);
603 /* reduce preShift because otherwise we risk to square -1.f */
604 if (preShift != 0) preShift++;
605
606 int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband));
607 subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1;
608
609 scaleValues(&bufferReal[lowSubband], highSubband - lowSubband,
610 -preShift);
611 scaleValues(&bufferImag[lowSubband], highSubband - lowSubband,
612 -preShift);
613 for (j = lowSubband; j < highSubband; j++) {
614 subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift;
615 subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift;
616 }
617 }
618
619 /* sum all together */
620 FIXP_DBL new_summand = subsample_power_low[i];
621 int new_summand_sf = subsample_power_low_sf[i];
622
623 /* make sure the current sum, and the new summand have the same SF */
624 if (new_summand_sf > total_power_low_sf) {
625 int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf);
626 total_power_low >>= diff;
627 total_power_low_sf = new_summand_sf;
628 } else if (new_summand_sf < total_power_low_sf) {
629 new_summand >>= total_power_low_sf - new_summand_sf;
630 }
631
632 total_power_low += (new_summand >> preShift2);
633
634 new_summand = subsample_power_high[i];
635 new_summand_sf = subsample_power_high_sf[i];
636 if (new_summand_sf > total_power_high_sf) {
637 total_power_high >>=
638 fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf);
639 total_power_high_sf = new_summand_sf;
640 } else if (new_summand_sf < total_power_high_sf) {
641 new_summand >>= total_power_high_sf - new_summand_sf;
642 }
643
644 total_power_high += (new_summand >> preShift2);
645 }
646
647 total_power_low_sf += preShift2;
648 total_power_high_sf += preShift2;
649
650 /* gain[i] = e_LOW[i] */
651 for (i = 0; i < nbSubsample; ++i) {
652 int sf2;
653 FIXP_DBL mult =
654 fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2);
655 int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2;
656
657 if (total_power_low != FIXP_DBL(0)) {
658 gain[i] = fDivNorm(mult, total_power_low, &sf2);
659 gain_sf[i] = mult_sf - total_power_low_sf + sf2;
660 gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
661 if (gain_sf[i] < 0) {
662 gain[i] >>= -gain_sf[i];
663 gain_sf[i] = 0;
664 }
665 } else {
666 if (mult == FIXP_DBL(0)) {
667 gain[i] = FIXP_DBL(0);
668 gain_sf[i] = 0;
669 } else {
670 gain[i] = (FIXP_DBL)MAXVAL_DBL;
671 gain_sf[i] = 0;
672 }
673 }
674 }
675
676 FIXP_DBL total_power_high_after = (FIXP_DBL)0;
677 int total_power_high_after_sf = 1 - DFRACT_BITS;
678
679 /* gain[i] = g_inter[i] */
680 for (i = 0; i < nbSubsample; ++i) {
681 if (gain_sf[i] < 0) {
682 gain[i] >>= -gain_sf[i];
683 gain_sf[i] = 0;
684 }
685
686 /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
687 FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
688 gain_sf[i]; /* to substract this from gain[i] */
689
690 /* gamma is actually always 1 according to the table, so skip the
691 * fMultDiv2 */
692 FIXP_DBL mult = (gain[i] - one) >> 1;
693 int mult_sf = gain_sf[i] + gamma_sf;
694
695 one = FL2FXCONST_DBL(0.5f) >> mult_sf;
696 gain[i] = one + mult;
697 gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
698
699 /* set gain to at least 0.2f */
700 FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */
701 int point_two_sf = -2;
702
703 FIXP_DBL tmp = gain[i];
704 if (point_two_sf < gain_sf[i]) {
705 point_two >>= gain_sf[i] - point_two_sf;
706 } else {
707 tmp >>= point_two_sf - gain_sf[i];
708 }
709
710 /* limit and calculate gain[i]^2 too */
711 FIXP_DBL gain_pow2;
712 int gain_pow2_sf;
713 if (tmp < point_two) {
714 gain[i] = FL2FXCONST_DBL(0.8f);
715 gain_sf[i] = -2;
716 gain_pow2 = FL2FXCONST_DBL(0.64f);
717 gain_pow2_sf = -4;
718 } else {
719 /* this upscaling seems quite important */
720 int r = CountLeadingBits(gain[i]);
721 gain[i] <<= r;
722 gain_sf[i] -= r;
723
724 gain_pow2 = fPow2(gain[i]);
725 gain_pow2_sf = gain_sf[i] << 1;
726 }
727
728 int room;
729 subsample_power_high[i] =
730 fMultNorm(subsample_power_high[i], gain_pow2, &room);
731 subsample_power_high_sf[i] =
732 subsample_power_high_sf[i] + gain_pow2_sf + room;
733
734 int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
735 if (new_summand_sf > total_power_high_after_sf) {
736 total_power_high_after >>=
737 fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
738 total_power_high_after_sf = new_summand_sf;
739 } else if (new_summand_sf < total_power_high_after_sf) {
740 subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf;
741 }
742 total_power_high_after += subsample_power_high[i] >> preShift2;
743 }
744
745 total_power_high_after_sf += preShift2;
746
747 int sf2 = 0;
748 FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
749 int gain_adj_2_sf = 1;
750
751 if ((total_power_high != (FIXP_DBL)0) &&
752 (total_power_high_after != (FIXP_DBL)0)) {
753 gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
754 gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
755 }
756
757 FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
758 int gain_adj_sf = gain_adj_2_sf;
759
760 for (i = 0; i < nbSubsample; ++i) {
761 gain[i] = fMult(gain[i], gain_adj);
762 gain_sf[i] += gain_adj_sf;
763
764 /* limit gain */
765 if (gain_sf[i] > INTER_TES_SF_CHANGE) {
766 gain[i] = (FIXP_DBL)MAXVAL_DBL;
767 gain_sf[i] = INTER_TES_SF_CHANGE;
768 }
769 }
770
771 for (i = 0; i < nbSubsample; ++i) {
772 /* equalize gain[]'s scale factors */
773 gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i];
774
775 for (j = lowSubband; j < highSubband; j++) {
776 qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]);
777 qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]);
778 }
779 }
780 } else { /* gamma_idx == 0 */
781 /* Inter-TES is not active. Still perform the scale change to have a
782 * consistent scaling for all envelopes of this frame. */
783 for (i = 0; i < nbSubsample; ++i) {
784 for (j = lowSubband; j < highSubband; j++) {
785 qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
786 qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
787 }
788 }
789 }
790 C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
791 }
792
793 /*!
794 \brief Apply spectral envelope to subband samples
795
796 This function is called from sbr_dec.cpp in each frame.
797
798 To enhance accuracy and due to the usage of tables for squareroots and
799 inverse, some calculations are performed with the operands being split
800 into mantissa and exponent. The variable names in the source code carry
801 the suffixes <em>_m</em> and <em>_e</em> respectively. The control data
802 in #hFrameData containts envelope data which is represented by this format but
803 stored in single words. (See requantizeEnvelopeData() for details). This data
804 is unpacked within calculateSbrEnvelope() to follow the described suffix
805 convention.
806
807 The actual value (comparable to the corresponding float-variable in the
808 research-implementation) of a mantissa/exponent-pair can be calculated as
809
810 \f$ value = value\_m * 2^{value\_e} \f$
811
812 All energies and noise levels decoded from the bitstream suit for an
813 original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$.
814 Therefore, the scale factor <em>hb_scale</em> passed into this function will
815 be converted to an 'input exponent' (#input_e), which fits the internal
816 representation.
817
818 Before the actual processing, an exponent #adj_e for resulting adjusted
819 samples is derived from the maximum reference energy.
820
821 Then, for each envelope, the following steps are performed:
822
823 \li Calculate energy in the signal to be adjusted. Depending on the the value
824 of #interpolFreq (interpolation mode), this is either done seperately for each
825 QMF-subband or for each SBR-band. The resulting energies are stored in
826 #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgEst_e[#MAX_FREQ_COEFFS]
827 (exponents). \li Calculate gain and noise level for each subband:<br> \f$ gain
828 = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise =
829 \sqrt{ nrgRef \cdot noiseRatio } \f$<br> where <em>noiseRatio</em> and
830 <em>nrgRef</em> are extracted from the bitstream and <em>nrgEst</em> is the
831 subband energy before adjustment. The resulting gains are stored in
832 #nrgGain_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS]
833 (exponents), the noise levels are stored in #noiseLevel_m[#MAX_FREQ_COEFFS]
834 and #noiseLevel_e[#MAX_FREQ_COEFFS] (exponents). The sine levels are stored in
835 #nrgSine_m[#MAX_FREQ_COEFFS] and #nrgSine_e[#MAX_FREQ_COEFFS]. \li Noise
836 limiting: The gain for each subband is limited both absolutely and relatively
837 compared to the total gain over all subbands. \li Boost gain: Calculate and
838 apply boost factor for each limiter band in order to compensate for the energy
839 loss imposed by the limiting. \li Apply gains and add noise: The gains and
840 noise levels are applied to all timeslots of the current envelope. A short
841 FIR-filter (length 4 QMF-timeslots) can be used to smooth the sudden change at
842 the envelope borders. Each complex subband sample of the current timeslot is
843 multiplied by the smoothed gain, then random noise with the calculated level
844 is added.
845
846 \note
847 To reduce the stack size, some of the local arrays could be located within
848 the time output buffer. Of the 512 samples temporarily available there,
849 about half the size is already used by #SBR_FRAME_DATA. A pointer to the
850 remaining free memory could be supplied by an additional argument to
851 calculateSbrEnvelope() in sbr_dec:
852
853 \par
854 \code
855 calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
856 &hSbrDec->SbrCalculateEnvelope,
857 hHeaderData,
858 hFrameData,
859 QmfBufferReal,
860 QmfBufferImag,
861 timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) +
862 1); \endcode
863
864 \par
865 Within calculateSbrEnvelope(), some pointers could be defined instead of the
866 arrays #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
867
868 \par
869 \code
870 fract* nrgRef_m = timeOutPtr;
871 SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
872 fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
873 SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
874 fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
875 \endcode
876
877 <br>
878 */
calculateSbrEnvelope(QMF_SCALE_FACTOR * sbrScaleFactor,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_FRAME_DATA hFrameData,PVC_DYNAMIC_DATA * pPvcDynamicData,FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,const int useLP,FIXP_DBL * degreeAlias,const UINT flags,const int frameErrorFlag)879 void calculateSbrEnvelope(
880 QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
881 HANDLE_SBR_CALCULATE_ENVELOPE
882 h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
883 HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
884 HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
885 PVC_DYNAMIC_DATA *pPvcDynamicData,
886 FIXP_DBL *
887 *analysBufferReal, /*!< Real part of subband samples to be processed */
888 FIXP_DBL *
889 *analysBufferImag, /*!< Imag part of subband samples to be processed */
890 const int useLP,
891 FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
892 const UINT flags, const int frameErrorFlag) {
893 int c, i, i_stop, j, envNoise = 0;
894 UCHAR *borders = hFrameData->frameInfo.borders;
895 UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
896 int pvc_mode = pPvcDynamicData->pvc_mode;
897 int first_start =
898 ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
899 FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
900 HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
901 UCHAR **pFreqBandTable = hFreq->freqBandTable;
902 UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
903
904 int lowSubband = hFreq->lowSubband;
905 int highSubband = hFreq->highSubband;
906 int noSubbands = highSubband - lowSubband;
907
908 /* old high subband before headerchange
909 we asume no headerchange here */
910 int ov_highSubband = hFreq->highSubband;
911
912 int noNoiseBands = hFreq->nNfb;
913 UCHAR *noSubFrameBands = hFreq->nSfb;
914 int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
915
916 SCHAR sineMapped[MAX_FREQ_COEFFS];
917 SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
918 SCHAR adj_e = 0;
919 SCHAR output_e;
920 SCHAR final_e = 0;
921 /* inter-TES is active in one or more envelopes of the current SBR frame */
922 const int iTES_enable = hFrameData->iTESactive;
923 const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
924 SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
925
926 UCHAR smooth_length = 0;
927
928 FIXP_SGL *pIenv = hFrameData->iEnvelope;
929
930 C_ALLOC_SCRATCH_START(useAliasReduction, UCHAR, 64)
931
932 /* if values differ we had a headerchange; if old highband is bigger then new
933 one we need to patch overlap-highband-scaling for this frame (see use of
934 ov_highSubband) as overlap contains higher frequency components which would
935 get lost */
936 if (hFreq->highSubband < hFreq->ov_highSubband) {
937 ov_highSubband = hFreq->ov_highSubband;
938 }
939
940 if (pvc_mode > 0) {
941 if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
942 /* noise envelope of previous frame is trailing into current PVC frame */
943 envNoise = -1;
944 noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
945 noNoiseBands = h_sbr_cal_env->prevNNfb;
946 noSubFrameBands = h_sbr_cal_env->prevNSfb;
947 lowSubband = h_sbr_cal_env->prevLoSubband;
948 highSubband = h_sbr_cal_env->prevHiSubband;
949
950 noSubbands = highSubband - lowSubband;
951 ov_highSubband = highSubband;
952 if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
953 ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
954 }
955
956 pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
957 pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
958 pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
959 }
960
961 mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
962 h_sbr_cal_env->harmFlagsPrev,
963 h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
964 hFrameData->sinusoidal_position,
965 &h_sbr_cal_env->sinusoidal_positionPrev,
966 (borders[0] > bordersPvc[0]) ? 1 : 0);
967 } else {
968 /*
969 Extract sine flags for all QMF bands
970 */
971 mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
972 hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
973 h_sbr_cal_env->harmFlagsPrevActive,
974 hFrameData->frameInfo.tranEnv, sineMapped);
975 }
976
977 /*
978 Scan for maximum in bufferd noise levels.
979 This is needed in case that we had strong noise in the previous frame
980 which is smoothed into the current frame.
981 The resulting exponent is used as start value for the maximum search
982 in reference energies
983 */
984 if (!useLP)
985 adj_e = h_sbr_cal_env->filtBufferNoise_e -
986 getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
987
988 /*
989 Scan for maximum reference energy to be able
990 to select appropriate values for adj_e and final_e.
991 */
992 if (pvc_mode > 0) {
993 INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
994
995 /* Energy -> magnitude (sqrt halfens exponent) */
996 maxSfbNrg_e =
997 (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
998
999 /* Some safety margin is needed for 2 reasons:
1000 - The signal energy is not equally spread over all subband samples in
1001 a specific sfb of an envelope (Nrg could be too high by a factor of
1002 envWidth * sfbWidth)
1003 - Smoothing can smear high gains of the previous envelope into the
1004 current
1005 */
1006 maxSfbNrg_e += 6;
1007
1008 adj_e = maxSfbNrg_e;
1009 // final_e should not exist for PVC fixfix framing
1010 } else {
1011 for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
1012 INT maxSfbNrg_e =
1013 -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
1014
1015 /* Fetch frequency resolution for current envelope: */
1016 for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
1017 maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
1018 }
1019 maxSfbNrg_e -= NRG_EXP_OFFSET;
1020
1021 /* Energy -> magnitude (sqrt halfens exponent) */
1022 maxSfbNrg_e =
1023 (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
1024
1025 /* Some safety margin is needed for 2 reasons:
1026 - The signal energy is not equally spread over all subband samples in
1027 a specific sfb of an envelope (Nrg could be too high by a factor of
1028 envWidth * sfbWidth)
1029 - Smoothing can smear high gains of the previous envelope into the
1030 current
1031 */
1032 maxSfbNrg_e += 6;
1033
1034 if (borders[i] < hHeaderData->numberTimeSlots)
1035 /* This envelope affects timeslots that belong to the output frame */
1036 adj_e = fMax(maxSfbNrg_e, adj_e);
1037
1038 if (borders[i + 1] > hHeaderData->numberTimeSlots)
1039 /* This envelope affects timeslots after the output frame */
1040 final_e = fMax(maxSfbNrg_e, final_e);
1041 }
1042 }
1043 /*
1044 Calculate adjustment factors and apply them for every envelope.
1045 */
1046 pIenv = hFrameData->iEnvelope;
1047
1048 if (pvc_mode > 0) {
1049 /* iterate over SBR time slots starting with bordersPvc[i] */
1050 i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
1051 PVC */
1052 i_stop = PVC_NTIMESLOT;
1053 FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
1054 } else {
1055 /* iterate over SBR envelopes starting with 0 */
1056 i = 0;
1057 i_stop = hFrameData->frameInfo.nEnvelopes;
1058 }
1059 for (; i < i_stop; i++) {
1060 int k, noNoiseFlag;
1061 SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
1062 C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
1063
1064 /*
1065 Helper variables.
1066 */
1067 int start_pos, stop_pos, freq_res;
1068 if (pvc_mode > 0) {
1069 start_pos =
1070 hHeaderData->timeStep *
1071 i; /* Start-position in time (subband sample) for current envelope. */
1072 stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
1073 (subband sample) for
1074 current envelope. */
1075 freq_res =
1076 hFrameData->frameInfo
1077 .freqRes[0]; /* Frequency resolution for current envelope. */
1078 FDK_ASSERT(
1079 freq_res ==
1080 hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
1081 } else {
1082 start_pos = hHeaderData->timeStep *
1083 borders[i]; /* Start-position in time (subband sample) for
1084 current envelope. */
1085 stop_pos = hHeaderData->timeStep *
1086 borders[i + 1]; /* Stop-position in time (subband sample) for
1087 current envelope. */
1088 freq_res =
1089 hFrameData->frameInfo
1090 .freqRes[i]; /* Frequency resolution for current envelope. */
1091 }
1092
1093 /* Always fully initialize the temporary energy table. This prevents
1094 negative energies and extreme gain factors in cases where the number of
1095 limiter bands exceeds the number of subbands. The latter can be caused by
1096 undetected bit errors and is tested by some streams from the
1097 certification set. */
1098 FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
1099
1100 if (pvc_mode > 0) {
1101 /* get predicted energy values from PVC module */
1102 expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
1103 pNrgs->nrgRef_e);
1104
1105 if (i == borders[0]) {
1106 mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
1107 hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
1108 h_sbr_cal_env->harmFlagsPrevActive,
1109 hFrameData->sinusoidal_position, sineMapped);
1110 }
1111
1112 if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1113 if (envNoise >= 0) {
1114 noiseLevels += noNoiseBands; /* The noise floor data is stored in a
1115 row [noiseFloor1 noiseFloor2...].*/
1116 } else {
1117 /* leave trailing noise envelope of past frame */
1118 noNoiseBands = hFreq->nNfb;
1119 noSubFrameBands = hFreq->nSfb;
1120 noiseLevels = hFrameData->sbrNoiseFloorLevel;
1121
1122 lowSubband = hFreq->lowSubband;
1123 highSubband = hFreq->highSubband;
1124
1125 noSubbands = highSubband - lowSubband;
1126 ov_highSubband = highSubband;
1127 if (highSubband < hFreq->ov_highSubband) {
1128 ov_highSubband = hFreq->ov_highSubband;
1129 }
1130
1131 pFreqBandTable[0] = hFreq->freqBandTableLo;
1132 pFreqBandTable[1] = hFreq->freqBandTableHi;
1133 pFreqBandTableNoise = hFreq->freqBandTableNoise;
1134 }
1135 envNoise++;
1136 }
1137 } else {
1138 /* If the start-pos of the current envelope equals the stop pos of the
1139 current noise envelope, increase the pointer (i.e. choose the next
1140 noise-floor).*/
1141 if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1142 noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
1143 [noiseFloor1 noiseFloor2...].*/
1144 envNoise++;
1145 }
1146 }
1147 if (i == hFrameData->frameInfo.tranEnv ||
1148 i == h_sbr_cal_env->prevTranEnv) /* attack */
1149 {
1150 noNoiseFlag = 1;
1151 if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
1152 } else {
1153 noNoiseFlag = 0;
1154 if (!useLP)
1155 smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
1156 << 2; /* can become either 0 or 4 */
1157 }
1158
1159 /*
1160 Energy estimation in transposed highband.
1161 */
1162 if (hHeaderData->bs_data.interpolFreq)
1163 calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1164 lowSubband, highSubband, start_pos, stop_pos, input_e,
1165 pNrgs->nrgEst, pNrgs->nrgEst_e);
1166 else
1167 calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1168 noSubFrameBands[freq_res], pFreqBandTable[freq_res],
1169 start_pos, stop_pos, input_e, pNrgs->nrgEst,
1170 pNrgs->nrgEst_e);
1171
1172 /*
1173 Calculate subband gains
1174 */
1175 {
1176 UCHAR *table = pFreqBandTable[freq_res];
1177 UCHAR *pUiNoise =
1178 &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
1179 band. */
1180
1181 FIXP_SGL *pNoiseLevels = noiseLevels;
1182
1183 FIXP_DBL tmpNoise =
1184 FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1185 SCHAR tmpNoise_e =
1186 (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1187
1188 int cc = 0;
1189 c = 0;
1190 if (pvc_mode > 0) {
1191 for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1192 UCHAR sinePresentFlag = 0;
1193 int li = table[j];
1194 int ui = table[j + 1];
1195
1196 for (k = li; k < ui; k++) {
1197 sinePresentFlag |= (i >= sineMapped[cc]);
1198 cc++;
1199 }
1200
1201 for (k = li; k < ui; k++) {
1202 FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
1203 SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
1204
1205 if (k >= *pUiNoise) {
1206 tmpNoise =
1207 FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1208 tmpNoise_e =
1209 (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1210
1211 pUiNoise++;
1212 }
1213
1214 FDK_ASSERT(k >= lowSubband);
1215
1216 if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1217
1218 pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1219 pNrgs->nrgSine_e[c] = 0;
1220
1221 calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1222 sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1223
1224 c++;
1225 }
1226 }
1227 } else {
1228 for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1229 FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
1230 SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
1231
1232 UCHAR sinePresentFlag = 0;
1233 int li = table[j];
1234 int ui = table[j + 1];
1235
1236 for (k = li; k < ui; k++) {
1237 sinePresentFlag |= (i >= sineMapped[cc]);
1238 cc++;
1239 }
1240
1241 for (k = li; k < ui; k++) {
1242 if (k >= *pUiNoise) {
1243 tmpNoise =
1244 FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1245 tmpNoise_e =
1246 (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1247
1248 pUiNoise++;
1249 }
1250
1251 FDK_ASSERT(k >= lowSubband);
1252
1253 if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1254
1255 pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1256 pNrgs->nrgSine_e[c] = 0;
1257
1258 calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1259 sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1260
1261 pNrgs->nrgRef[c] = refNrg;
1262 pNrgs->nrgRef_e[c] = refNrg_e;
1263
1264 c++;
1265 }
1266 pIenv++;
1267 }
1268 }
1269 }
1270
1271 /*
1272 Noise limiting
1273 */
1274
1275 for (c = 0; c < hFreq->noLimiterBands; c++) {
1276 FIXP_DBL sumRef, boostGain, maxGain;
1277 FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1278 SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
1279 int maxGainLimGainSum_e = 0;
1280
1281 calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
1282 hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
1283 &maxGain_e);
1284
1285 /* Multiply maxGain with limiterGain: */
1286 maxGain = fMult(
1287 maxGain,
1288 FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
1289 /* maxGain_e +=
1290 * FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; */
1291 /* The addition of maxGain_e and FDK_sbrDecoder_sbr_limGains_e[3] might
1292 yield values greater than 127 which doesn't fit into an SCHAR! In these
1293 rare situations limit maxGain_e to 127.
1294 */
1295 maxGainLimGainSum_e =
1296 maxGain_e +
1297 FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
1298 maxGain_e =
1299 (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
1300
1301 /* Scale mantissa of MaxGain into range between 0.5 and 1: */
1302 if (maxGain == FL2FXCONST_DBL(0.0f))
1303 maxGain_e = -FRACT_BITS;
1304 else {
1305 SCHAR charTemp = CountLeadingBits(maxGain);
1306 maxGain_e -= charTemp;
1307 maxGain <<= (int)charTemp;
1308 }
1309
1310 if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
1311 maxGain = FL2FXCONST_DBL(0.5f);
1312 maxGain_e = maxGainLimit_e;
1313 }
1314
1315 /* Every subband gain is compared to the scaled "average gain"
1316 and limited if necessary: */
1317 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1318 k++) {
1319 if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
1320 (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
1321 FIXP_DBL noiseAmp;
1322 SCHAR noiseAmp_e;
1323
1324 FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
1325 pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
1326 pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
1327 pNrgs->noiseLevel_e[k] += noiseAmp_e;
1328 pNrgs->nrgGain[k] = maxGain;
1329 pNrgs->nrgGain_e[k] = maxGain_e;
1330 }
1331 }
1332
1333 /* -- Boost gain
1334 Calculate and apply boost factor for each limiter band:
1335 1. Check how much energy would be present when using the limited gain
1336 2. Calculate boost factor by comparison with reference energy
1337 3. Apply boost factor to compensate for the energy loss due to limiting
1338 */
1339 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1340 k++) {
1341 /* 1.a Add energy of adjusted signal (using preliminary gain) */
1342 FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
1343 SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
1344 FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
1345
1346 /* 1.b Add sine energy (if present) */
1347 if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
1348 FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
1349 &accu, &accu_e);
1350 } else {
1351 /* 1.c Add noise energy (if present) */
1352 if (noNoiseFlag == 0) {
1353 FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
1354 accu_e, &accu, &accu_e);
1355 }
1356 }
1357 }
1358
1359 /* 2.a Calculate ratio of wanted energy and accumulated energy */
1360 if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
1361 boostGain = FL2FXCONST_DBL(0.6279716f);
1362 boostGain_e = 2;
1363 } else {
1364 INT div_e;
1365 boostGain = fDivNorm(sumRef, accu, &div_e);
1366 boostGain_e = sumRef_e - accu_e + div_e;
1367 }
1368
1369 /* 2.b Result too high? --> Limit the boost factor to +4 dB */
1370 if ((boostGain_e > 3) ||
1371 (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
1372 (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
1373 boostGain = FL2FXCONST_DBL(0.6279716f);
1374 boostGain_e = 2;
1375 }
1376 /* 3. Multiply all signal components with the boost factor */
1377 for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1378 k++) {
1379 pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
1380 pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
1381
1382 pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
1383 pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
1384
1385 pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
1386 pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
1387 }
1388 }
1389 /* End of noise limiting */
1390
1391 if (useLP)
1392 aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
1393 noSubbands);
1394
1395 /* For the timeslots within the range for the output frame,
1396 use the same scale for the noise levels.
1397 Drawback: If the envelope exceeds the frame border, the noise levels
1398 will have to be rescaled later to fit final_e of
1399 the gain-values.
1400 */
1401 noise_e = (start_pos < no_cols) ? adj_e : final_e;
1402
1403 /*
1404 Convert energies to amplitude levels
1405 */
1406 for (k = 0; k < noSubbands; k++) {
1407 FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
1408 FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
1409 &pNrgs->nrgGain_e[k]);
1410 FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
1411 &noise_e);
1412 }
1413
1414 /*
1415 Apply calculated gains and adaptive noise
1416 */
1417
1418 /* assembleHfSignals() */
1419 {
1420 int scale_change, sc_change;
1421 FIXP_SGL smooth_ratio;
1422 int filtBufferNoiseShift = 0;
1423
1424 /* Initialize smoothing buffers with the first valid values */
1425 if (h_sbr_cal_env->startUp) {
1426 if (!useLP) {
1427 h_sbr_cal_env->filtBufferNoise_e = noise_e;
1428
1429 FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1430 noSubbands * sizeof(SCHAR));
1431 FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1432 noSubbands * sizeof(FIXP_DBL));
1433 FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1434 noSubbands * sizeof(FIXP_DBL));
1435 }
1436 h_sbr_cal_env->startUp = 0;
1437 }
1438
1439 if (!useLP) {
1440 equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */
1441 h_sbr_cal_env->filtBuffer_e, /* buffered */
1442 pNrgs->nrgGain, /* current */
1443 pNrgs->nrgGain_e, /* current */
1444 noSubbands);
1445
1446 /* Adapt exponent of buffered noise levels to the current exponent
1447 so they can easily be smoothed */
1448 if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
1449 int shift = fixMin(DFRACT_BITS - 1,
1450 (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1451 for (k = 0; k < noSubbands; k++)
1452 h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1453 } else {
1454 int shift =
1455 fixMin(DFRACT_BITS - 1,
1456 -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1457 for (k = 0; k < noSubbands; k++)
1458 h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1459 }
1460
1461 h_sbr_cal_env->filtBufferNoise_e = noise_e;
1462 }
1463
1464 /* find best scaling! */
1465 scale_change = -(DFRACT_BITS - 1);
1466 for (k = 0; k < noSubbands; k++) {
1467 scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
1468 }
1469 sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
1470
1471 if ((scale_change - sc_change + 1) < 0)
1472 scale_change -= (scale_change - sc_change + 1);
1473
1474 scale_change = (scale_change - sc_change) + 1;
1475
1476 for (k = 0; k < noSubbands; k++) {
1477 int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
1478 pNrgs->nrgGain[k] >>= sc;
1479 pNrgs->nrgGain_e[k] += sc;
1480 }
1481
1482 if (!useLP) {
1483 for (k = 0; k < noSubbands; k++) {
1484 int sc =
1485 scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
1486 h_sbr_cal_env->filtBuffer[k] >>= sc;
1487 }
1488 }
1489
1490 for (j = start_pos; j < stop_pos; j++) {
1491 /* This timeslot is located within the first part of the processing
1492 buffer and will be fed into the QMF-synthesis for the current frame.
1493 adj_e - input_e
1494 This timeslot will not yet be fed into the QMF so we do not care
1495 about the adj_e.
1496 sc_change = final_e - input_e
1497 */
1498 if ((j == no_cols) && (start_pos < no_cols)) {
1499 int shift = (int)(noise_e - final_e);
1500 if (!useLP)
1501 filtBufferNoiseShift = shift; /* shifting of
1502 h_sbr_cal_env->filtBufferNoise[k]
1503 will be applied in function
1504 adjustTimeSlotHQ() */
1505 if (shift >= 0) {
1506 shift = fixMin(DFRACT_BITS - 1, shift);
1507 for (k = 0; k < noSubbands; k++) {
1508 pNrgs->nrgSine[k] <<= shift;
1509 pNrgs->noiseLevel[k] <<= shift;
1510 /*
1511 if (!useLP)
1512 h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1513 */
1514 }
1515 } else {
1516 shift = fixMin(DFRACT_BITS - 1, -shift);
1517 for (k = 0; k < noSubbands; k++) {
1518 pNrgs->nrgSine[k] >>= shift;
1519 pNrgs->noiseLevel[k] >>= shift;
1520 /*
1521 if (!useLP)
1522 h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1523 */
1524 }
1525 }
1526
1527 /* update noise scaling */
1528 noise_e = final_e;
1529 if (!useLP)
1530 h_sbr_cal_env->filtBufferNoise_e =
1531 noise_e; /* scaling value unused! */
1532
1533 /* update gain buffer*/
1534 sc_change -= (final_e - input_e);
1535
1536 if (sc_change < 0) {
1537 for (k = 0; k < noSubbands; k++) {
1538 pNrgs->nrgGain[k] >>= -sc_change;
1539 pNrgs->nrgGain_e[k] += -sc_change;
1540 }
1541 if (!useLP) {
1542 for (k = 0; k < noSubbands; k++) {
1543 h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
1544 }
1545 }
1546 } else {
1547 scale_change += sc_change;
1548 }
1549
1550 } /* if */
1551
1552 if (!useLP) {
1553 /* Prevent the smoothing filter from running on constant levels */
1554 if (j - start_pos < smooth_length)
1555 smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
1556 else
1557 smooth_ratio = FL2FXCONST_SGL(0.0f);
1558
1559 if (iTES_enable) {
1560 /* adjustTimeSlotHQ() without adding of additional harmonics */
1561 adjustTimeSlotHQ_GainAndNoise(
1562 &analysBufferReal[j][lowSubband],
1563 &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1564 lowSubband, noSubbands, scale_change, smooth_ratio, noNoiseFlag,
1565 filtBufferNoiseShift);
1566 } else {
1567 adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1568 &analysBufferImag[j][lowSubband], h_sbr_cal_env,
1569 pNrgs, lowSubband, noSubbands, scale_change,
1570 smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
1571 }
1572 } else {
1573 FDK_ASSERT(!iTES_enable); /* not supported */
1574 if (flags & SBRDEC_ELD_GRID) {
1575 /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
1576 adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
1577 &h_sbr_cal_env->harmIndex, lowSubband,
1578 noSubbands, scale_change, noNoiseFlag,
1579 &h_sbr_cal_env->phaseIndex,
1580 EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
1581 } else {
1582 adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
1583 &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1584 scale_change, noNoiseFlag,
1585 &h_sbr_cal_env->phaseIndex);
1586 }
1587 }
1588 /* In case the envelope spans accross the no_cols border both exponents
1589 * are needed. */
1590 /* nrgGain_e[0...(noSubbands-1)] are equalized by
1591 * equalizeFiltBufferExp() */
1592 pNrgs->exponent[(j < no_cols) ? 0 : 1] =
1593 (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
1594 scale_change);
1595 } /* for */
1596
1597 if (iTES_enable) {
1598 apply_inter_tes(
1599 analysBufferReal, /* pABufR, */
1600 analysBufferImag, /* pABufI, */
1601 sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
1602 stop_pos, lowSubband, noSubbands,
1603 hFrameData
1604 ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
1605 );
1606
1607 /* add additional harmonics */
1608 for (j = start_pos; j < stop_pos; j++) {
1609 /* match exponent of additional harmonics to scale change of QMF data
1610 * caused by apply_inter_tes() */
1611 scale_change = 0;
1612
1613 if ((start_pos <= no_cols) && (stop_pos > no_cols)) {
1614 /* Scaling of analysBuffers was potentially changed within this
1615 envelope. The pNrgs->nrgSine_e match the second part of the
1616 envelope. For (j<=no_cols) the exponent of the sine energies has
1617 to be adapted. */
1618 scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
1619 }
1620
1621 adjustTimeSlotHQ_AddHarmonics(
1622 &analysBufferReal[j][lowSubband],
1623 &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1624 lowSubband, noSubbands,
1625 -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
1626 }
1627 }
1628
1629 if (!useLP) {
1630 /* Update time-smoothing-buffers for gains and noise levels
1631 The gains and the noise values of the current envelope are copied
1632 into the buffer. This has to be done at the end of each envelope as
1633 the values are required for a smooth transition to the next envelope.
1634 */
1635 FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1636 noSubbands * sizeof(FIXP_DBL));
1637 FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1638 noSubbands * sizeof(SCHAR));
1639 FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1640 noSubbands * sizeof(FIXP_DBL));
1641 }
1642 }
1643 C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1644 }
1645
1646 /* adapt adj_e to the scale change caused by apply_inter_tes() */
1647 adj_e += iTES_scale_change;
1648
1649 /* Rescale output samples */
1650 {
1651 FIXP_DBL maxVal;
1652 int ov_reserve, reserve;
1653
1654 /* Determine headroom in old adjusted samples */
1655 maxVal =
1656 maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1657 lowSubband, ov_highSubband, 0, first_start);
1658
1659 ov_reserve = fNorm(maxVal);
1660
1661 /* Determine headroom in new adjusted samples */
1662 maxVal =
1663 maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1664 lowSubband, highSubband, first_start, no_cols);
1665
1666 reserve = fNorm(maxVal);
1667
1668 /* Determine common output exponent */
1669 output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
1670
1671 /* Rescale old samples */
1672 rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1673 lowSubband, ov_highSubband, 0, first_start,
1674 ov_adj_e - output_e);
1675
1676 /* Rescale new samples */
1677 rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1678 lowSubband, highSubband, first_start, no_cols,
1679 adj_e - output_e);
1680 }
1681
1682 /* Update hb_scale */
1683 sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
1684
1685 /* Save the current final exponent for the next frame: */
1686 /* adapt final_e to the scale change caused by apply_inter_tes() */
1687 sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e + iTES_scale_change);
1688
1689 /* We need to remember to the next frame that the transient
1690 will occur in the first envelope (if tranEnv == nEnvelopes). */
1691 if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1692 h_sbr_cal_env->prevTranEnv = 0;
1693 else
1694 h_sbr_cal_env->prevTranEnv = -1;
1695
1696 if (pvc_mode > 0) {
1697 /* Not more than just the last noise envelope reaches into the next PVC
1698 frame! This should be true because bs_noise_position is <= 15 */
1699 FDK_ASSERT(hFrameData->frameInfo
1700 .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
1701 PVC_NTIMESLOT);
1702 if (hFrameData->frameInfo
1703 .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
1704 PVC_NTIMESLOT) {
1705 FDK_ASSERT(noiseLevels ==
1706 (hFrameData->sbrNoiseFloorLevel +
1707 (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
1708 h_sbr_cal_env->prevNNfb = noNoiseBands;
1709
1710 h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
1711 h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
1712
1713 h_sbr_cal_env->prevLoSubband = lowSubband;
1714 h_sbr_cal_env->prevHiSubband = highSubband;
1715 h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
1716
1717 FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
1718 noSubFrameBands[0] + 1);
1719 FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
1720 noSubFrameBands[1] + 1);
1721 FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
1722 hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
1723
1724 FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
1725 MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
1726 }
1727 }
1728
1729 C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
1730 }
1731
1732 /*!
1733 \brief Create envelope instance
1734
1735 Must be called once for each channel before calculateSbrEnvelope() can be
1736 used.
1737
1738 \return errorCode, 0 if successful
1739 */
1740 SBR_ERROR
createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs,HANDLE_SBR_HEADER_DATA hHeaderData,const int chan,const UINT flags)1741 createSbrEnvelopeCalc(
1742 HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
1743 HANDLE_SBR_HEADER_DATA
1744 hHeaderData, /*!< static SBR control data, initialized with defaults */
1745 const int chan, /*!< Channel for which to assign buffers */
1746 const UINT flags) {
1747 SBR_ERROR err = SBRDEC_OK;
1748 int i;
1749
1750 /* Clear previous missing harmonics flags */
1751 for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
1752 hs->harmFlagsPrev[i] = 0;
1753 hs->harmFlagsPrevActive[i] = 0;
1754 }
1755 hs->harmIndex = 0;
1756
1757 FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
1758 hs->prevNNfb = 0;
1759 FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
1760 hs->sinusoidal_positionPrev = 0;
1761
1762 /*
1763 Setup pointers for time smoothing.
1764 The buffer itself will be initialized later triggered by the startUp-flag.
1765 */
1766 hs->prevTranEnv = -1;
1767
1768 /* initialization */
1769 resetSbrEnvelopeCalc(hs);
1770
1771 if (chan == 0) { /* do this only once */
1772 err = resetFreqBandTables(hHeaderData, flags);
1773 }
1774
1775 return err;
1776 }
1777
1778 /*!
1779 \brief Create envelope instance
1780
1781 Must be called once for each channel before calculateSbrEnvelope() can be
1782 used.
1783
1784 \return errorCode, 0 if successful
1785 */
deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs)1786 int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs) { return 0; }
1787
1788 /*!
1789 \brief Reset envelope instance
1790
1791 This function must be called for each channel on a change of configuration.
1792 Note that resetFreqBandTables should also be called in this case.
1793
1794 \return errorCode, 0 if successful
1795 */
resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv)1796 void resetSbrEnvelopeCalc(
1797 HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
1798 {
1799 hCalEnv->phaseIndex = 0;
1800
1801 /* Noise exponent needs to be reset because the output exponent for the next
1802 * frame depends on it */
1803 hCalEnv->filtBufferNoise_e = 0;
1804
1805 hCalEnv->startUp = 1;
1806 }
1807
1808 /*!
1809 \brief Equalize exponents of the buffered gain values and the new ones
1810
1811 After equalization of exponents, the FIR-filter addition for smoothing
1812 can be performed.
1813 This function is called once for each envelope before adjusting.
1814 */
equalizeFiltBufferExp(FIXP_DBL * filtBuffer,SCHAR * filtBuffer_e,FIXP_DBL * nrgGain,SCHAR * nrgGain_e,int subbands)1815 static void equalizeFiltBufferExp(
1816 FIXP_DBL *filtBuffer, /*!< bufferd gains */
1817 SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
1818 FIXP_DBL *nrgGain, /*!< gains for current envelope */
1819 SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
1820 int subbands) /*!< Number of QMF subbands */
1821 {
1822 int band;
1823 int diff;
1824
1825 for (band = 0; band < subbands; band++) {
1826 diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
1827 if (diff > 0) {
1828 filtBuffer[band] >>=
1829 diff; /* Compensate for the scale change by shifting the mantissa. */
1830 filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1831 } else if (diff < 0) {
1832 /* The buffered gains seem to be larger, but maybe there
1833 are some unused bits left in the mantissa */
1834
1835 int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
1836
1837 if ((-diff) <= reserve) {
1838 /* There is enough space in the buffered mantissa so
1839 that we can take the new exponent as common.
1840 */
1841 filtBuffer[band] <<= (-diff);
1842 filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1843 } else {
1844 filtBuffer[band] <<=
1845 reserve; /* Shift the mantissa as far as possible: */
1846 filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1847
1848 /* For the remaining difference, change the new gain value */
1849 diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
1850 nrgGain[band] >>= diff;
1851 nrgGain_e[band] += diff;
1852 }
1853 }
1854 }
1855 }
1856
1857 /*!
1858 \brief Shift left the mantissas of all subband samples
1859 in the giventime and frequency range by the specified number of bits.
1860
1861 This function is used to rescale the audio data in the overlap buffer
1862 which has already been envelope adjusted with the last frame.
1863 */
rescaleSubbandSamples(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos,int shift)1864 void rescaleSubbandSamples(
1865 FIXP_DBL **re, /*!< Real part of input and output subband samples */
1866 FIXP_DBL **im, /*!< Imaginary part of input and output subband samples */
1867 int lowSubband, /*!< Begin of frequency range to process */
1868 int highSubband, /*!< End of frequency range to process */
1869 int start_pos, /*!< Begin of time rage (QMF-timeslot) */
1870 int next_pos, /*!< End of time rage (QMF-timeslot) */
1871 int shift) /*!< number of bits to shift */
1872 {
1873 int width = highSubband - lowSubband;
1874
1875 if ((width > 0) && (shift != 0)) {
1876 if (im != NULL) {
1877 for (int l = start_pos; l < next_pos; l++) {
1878 scaleValues(&re[l][lowSubband], width, shift);
1879 scaleValues(&im[l][lowSubband], width, shift);
1880 }
1881 } else {
1882 for (int l = start_pos; l < next_pos; l++) {
1883 scaleValues(&re[l][lowSubband], width, shift);
1884 }
1885 }
1886 }
1887 }
1888
FDK_get_maxval_real(FIXP_DBL maxVal,FIXP_DBL * reTmp,INT width)1889 static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
1890 INT width) {
1891 maxVal = (FIXP_DBL)0;
1892 while (width-- != 0) {
1893 FIXP_DBL tmp = *(reTmp++);
1894 maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
1895 }
1896
1897 return maxVal;
1898 }
1899
1900 /*!
1901 \brief Determine headroom for shifting
1902
1903 Determine by how much the spectrum can be shifted left
1904 for better accuracy in later processing.
1905
1906 \return Number of free bits in the biggest spectral value
1907 */
1908
maxSubbandSample(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos)1909 FIXP_DBL maxSubbandSample(
1910 FIXP_DBL **re, /*!< Real part of input and output subband samples */
1911 FIXP_DBL **im, /*!< Real part of input and output subband samples */
1912 int lowSubband, /*!< Begin of frequency range to process */
1913 int highSubband, /*!< Number of QMF bands to process */
1914 int start_pos, /*!< Begin of time rage (QMF-timeslot) */
1915 int next_pos /*!< End of time rage (QMF-timeslot) */
1916 ) {
1917 FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1918 unsigned int width = highSubband - lowSubband;
1919
1920 FDK_ASSERT(width <= (64));
1921
1922 if (width > 0) {
1923 if (im != NULL) {
1924 for (int l = start_pos; l < next_pos; l++) {
1925 int k = width;
1926 FIXP_DBL *reTmp = &re[l][lowSubband];
1927 FIXP_DBL *imTmp = &im[l][lowSubband];
1928 do {
1929 FIXP_DBL tmp1 = *(reTmp++);
1930 FIXP_DBL tmp2 = *(imTmp++);
1931 maxVal |=
1932 (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
1933 maxVal |=
1934 (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
1935 } while (--k != 0);
1936 }
1937 } else {
1938 for (int l = start_pos; l < next_pos; l++) {
1939 maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
1940 }
1941 }
1942 }
1943
1944 if (maxVal > (FIXP_DBL)0) {
1945 /* For negative input values, maxVal is too small by 1. Add 1 only when
1946 * necessary: if maxVal is a power of 2 */
1947 FIXP_DBL lowerPow2 =
1948 (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
1949 if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
1950 }
1951
1952 return (maxVal);
1953 }
1954
1955 /* #define SHIFT_BEFORE_SQUARE (3) */ /* (7/2) */
1956 /* Avoid assertion failures triggerd by overflows which occured in robustness
1957 tests. Setting the SHIFT_BEFORE_SQUARE to 4 has negligible effect on (USAC)
1958 conformance results. */
1959 #define SHIFT_BEFORE_SQUARE (4) /* ((8 - 0) / 2) */
1960
1961 /*!<
1962 If the accumulator does not provide enough overflow bits or
1963 does not provide a high dynamic range, the below energy calculation
1964 requires an additional shift operation for each sample.
1965 On the other hand, doing the shift allows using a single-precision
1966 multiplication for the square (at least 16bit x 16bit).
1967 For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1968 is required for the energy accumulation.
1969 Theoretically, the sample-squares can sum up to a value of 76,
1970 requiring 7 overflow bits. However since such situations are *very*
1971 rare, accu can be limited to 64.
1972 In case native saturated arithmetic is not available, overflows
1973 can be prevented by replacing the above #define by
1974 #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1975 which will result in slightly reduced accuracy.
1976 */
1977
1978 /*!
1979 \brief Estimates the mean energy of each filter-bank channel for the
1980 duration of the current envelope
1981
1982 This function is used when interpolFreq is true.
1983 */
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)1984 static void calcNrgPerSubband(
1985 FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
1986 FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
1987 int lowSubband, /*!< Begin of the SBR frequency range */
1988 int highSubband, /*!< High end of the SBR frequency range */
1989 int start_pos, /*!< First QMF-slot of current envelope */
1990 int next_pos, /*!< Last QMF-slot of current envelope + 1 */
1991 SCHAR frameExp, /*!< Common exponent for all input samples */
1992 FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
1993 SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */
1994 {
1995 FIXP_SGL invWidth;
1996 SCHAR preShift;
1997 SCHAR shift;
1998 FIXP_DBL sum;
1999 int k;
2000
2001 /* Divide by width of envelope later: */
2002 invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2003 /* The common exponent needs to be doubled because all mantissas are squared:
2004 */
2005 frameExp = frameExp << 1;
2006
2007 for (k = lowSubband; k < highSubband; k++) {
2008 FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2009 FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2010 FIXP_DBL maxVal;
2011
2012 if (analysBufferImag != NULL) {
2013 int l;
2014 maxVal = FL2FX_DBL(0.0f);
2015 for (l = start_pos; l < next_pos; l++) {
2016 bufferImag[l] = analysBufferImag[l][k];
2017 maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
2018 ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
2019 bufferReal[l] = analysBufferReal[l][k];
2020 maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2021 ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2022 }
2023 } else {
2024 int l;
2025 maxVal = FL2FX_DBL(0.0f);
2026 for (l = start_pos; l < next_pos; l++) {
2027 bufferReal[l] = analysBufferReal[l][k];
2028 maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2029 ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2030 }
2031 }
2032
2033 if (maxVal != FL2FXCONST_DBL(0.f)) {
2034 /* If the accu does not provide enough overflow bits, we cannot
2035 shift the samples up to the limit.
2036 Instead, keep up to 3 free bits in each sample, i.e. up to
2037 6 bits after calculation of square.
2038 Please note the comment on saturated arithmetic above!
2039 */
2040 FIXP_DBL accu;
2041 preShift = CntLeadingZeros(maxVal) - 1;
2042 preShift -= SHIFT_BEFORE_SQUARE;
2043
2044 /* Limit preShift to a maximum value to prevent accumulator overflow in
2045 exceptional situations where the signal in the analysis-buffer is very
2046 small (small maxVal).
2047 */
2048 preShift = fMin(preShift, (SCHAR)25);
2049
2050 accu = FL2FXCONST_DBL(0.0f);
2051 if (preShift >= 0) {
2052 int l;
2053 if (analysBufferImag != NULL) {
2054 for (l = start_pos; l < next_pos; l++) {
2055 FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
2056 FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
2057 accu = fPow2AddDiv2(accu, temp1);
2058 accu = fPow2AddDiv2(accu, temp2);
2059 }
2060 } else {
2061 for (l = start_pos; l < next_pos; l++) {
2062 FIXP_DBL temp = bufferReal[l] << (int)preShift;
2063 accu = fPow2AddDiv2(accu, temp);
2064 }
2065 }
2066 } else { /* if negative shift value */
2067 int l;
2068 int negpreShift = -preShift;
2069 if (analysBufferImag != NULL) {
2070 for (l = start_pos; l < next_pos; l++) {
2071 FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
2072 FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
2073 accu = fPow2AddDiv2(accu, temp1);
2074 accu = fPow2AddDiv2(accu, temp2);
2075 }
2076 } else {
2077 for (l = start_pos; l < next_pos; l++) {
2078 FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
2079 accu = fPow2AddDiv2(accu, temp);
2080 }
2081 }
2082 }
2083 accu <<= 1;
2084
2085 /* Convert double precision to Mantissa/Exponent: */
2086 shift = fNorm(accu);
2087 sum = accu << (int)shift;
2088
2089 /* Divide by width of envelope and apply frame scale: */
2090 *nrgEst++ = fMult(sum, invWidth);
2091 shift += 2 * preShift;
2092 if (analysBufferImag != NULL)
2093 *nrgEst_e++ = frameExp - shift;
2094 else
2095 *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
2096 } /* maxVal!=0 */
2097 else {
2098 /* Prevent a zero-mantissa-number from being misinterpreted
2099 due to its exponent. */
2100 *nrgEst++ = FL2FXCONST_DBL(0.0f);
2101 *nrgEst_e++ = 0;
2102 }
2103 }
2104 }
2105
2106 /*!
2107 \brief Estimates the mean energy of each Scale factor band for the
2108 duration of the current envelope.
2109
2110 This function is used when interpolFreq is false.
2111 */
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)2112 static void calcNrgPerSfb(
2113 FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
2114 FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
2115 int nSfb, /*!< Number of scale factor bands */
2116 UCHAR *freqBandTable, /*!< First Subband for each Sfb */
2117 int start_pos, /*!< First QMF-slot of current envelope */
2118 int next_pos, /*!< Last QMF-slot of current envelope + 1 */
2119 SCHAR input_e, /*!< Common exponent for all input samples */
2120 FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
2121 SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */
2122 {
2123 FIXP_SGL invWidth;
2124 FIXP_DBL temp;
2125 SCHAR preShift;
2126 SCHAR shift, sum_e;
2127 FIXP_DBL sum;
2128
2129 int j, k, l, li, ui;
2130 FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
2131 but overflow bits are required for accumulation */
2132
2133 /* Divide by width of envelope later: */
2134 invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2135 /* The common exponent needs to be doubled because all mantissas are squared:
2136 */
2137 input_e = input_e << 1;
2138
2139 for (j = 0; j < nSfb; j++) {
2140 li = freqBandTable[j];
2141 ui = freqBandTable[j + 1];
2142
2143 FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
2144 ui, start_pos, next_pos);
2145
2146 if (maxVal != FL2FXCONST_DBL(0.f)) {
2147 preShift = CntLeadingZeros(maxVal) - 1;
2148
2149 /* If the accu does not provide enough overflow bits, we cannot
2150 shift the samples up to the limit.
2151 Instead, keep up to 3 free bits in each sample, i.e. up to
2152 6 bits after calculation of square.
2153 Please note the comment on saturated arithmetic above!
2154 */
2155 preShift -= SHIFT_BEFORE_SQUARE;
2156
2157 sumAll = FL2FXCONST_DBL(0.0f);
2158
2159 for (k = li; k < ui; k++) {
2160 sumLine = FL2FXCONST_DBL(0.0f);
2161
2162 if (analysBufferImag != NULL) {
2163 if (preShift >= 0) {
2164 for (l = start_pos; l < next_pos; l++) {
2165 temp = analysBufferReal[l][k] << (int)preShift;
2166 sumLine += fPow2Div2(temp);
2167 temp = analysBufferImag[l][k] << (int)preShift;
2168 sumLine += fPow2Div2(temp);
2169 }
2170 } else {
2171 for (l = start_pos; l < next_pos; l++) {
2172 temp = analysBufferReal[l][k] >> -(int)preShift;
2173 sumLine += fPow2Div2(temp);
2174 temp = analysBufferImag[l][k] >> -(int)preShift;
2175 sumLine += fPow2Div2(temp);
2176 }
2177 }
2178 } else {
2179 if (preShift >= 0) {
2180 for (l = start_pos; l < next_pos; l++) {
2181 temp = analysBufferReal[l][k] << (int)preShift;
2182 sumLine += fPow2Div2(temp);
2183 }
2184 } else {
2185 for (l = start_pos; l < next_pos; l++) {
2186 temp = analysBufferReal[l][k] >> -(int)preShift;
2187 sumLine += fPow2Div2(temp);
2188 }
2189 }
2190 }
2191
2192 /* The number of QMF-channels per SBR bands may be up to 15.
2193 Shift right to avoid overflows in sum over all channels. */
2194 sumLine = sumLine >> (4 - 1);
2195 sumAll += sumLine;
2196 }
2197
2198 /* Convert double precision to Mantissa/Exponent: */
2199 shift = fNorm(sumAll);
2200 sum = sumAll << (int)shift;
2201
2202 /* Divide by width of envelope: */
2203 sum = fMult(sum, invWidth);
2204
2205 /* Divide by width of Sfb: */
2206 sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
2207
2208 /* Set all Subband energies in the Sfb to the average energy: */
2209 if (analysBufferImag != NULL)
2210 sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
2211 else
2212 sum_e = input_e + 4 + 1 -
2213 shift; /* -4 to compensate right-shift; +1 due to missing
2214 imag. part */
2215
2216 sum_e -= 2 * preShift;
2217 } /* maxVal!=0 */
2218 else {
2219 /* Prevent a zero-mantissa-number from being misinterpreted
2220 due to its exponent. */
2221 sum = FL2FXCONST_DBL(0.0f);
2222 sum_e = 0;
2223 }
2224
2225 for (k = li; k < ui; k++) {
2226 *nrgEst++ = sum;
2227 *nrgEst_e++ = sum_e;
2228 }
2229 }
2230 }
2231
2232 /*!
2233 \brief Calculate gain, noise, and additional sine level for one subband.
2234
2235 The resulting energy gain is given by mantissa and exponent.
2236 */
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)2237 static void calcSubbandGain(
2238 FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
2239 SCHAR
2240 nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
2241 ENV_CALC_NRGS *nrgs, int i, FIXP_DBL tmpNoise, /*!< Relative noise level */
2242 SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */
2243 UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
2244 UCHAR sineMapped, /*!< Indicates if sine must be added */
2245 int noNoiseFlag) /*!< Flag to suppress noise addition */
2246 {
2247 FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
2248 SCHAR nrgEst_e =
2249 nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
2250 FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
2251 SCHAR *ptrNrgGain_e =
2252 &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
2253 FIXP_DBL *ptrNoiseLevel =
2254 &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
2255 SCHAR *ptrNoiseLevel_e =
2256 &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
2257 FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
2258 SCHAR *ptrNrgSine_e =
2259 &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
2260
2261 FIXP_DBL a, b, c;
2262 SCHAR a_e, b_e, c_e;
2263
2264 /*
2265 This addition of 1 prevents divisions by zero in the reference code.
2266 For very small energies in nrgEst, it prevents the gains from becoming
2267 very high which could cause some trouble due to the smoothing.
2268 */
2269 b_e = (int)(nrgEst_e - 1);
2270 if (b_e >= 0) {
2271 nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2272 (nrgEst >> 1);
2273 nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
2274
2275 } else {
2276 nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2277 (FL2FXCONST_DBL(0.5f) >> 1);
2278 nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
2279 }
2280
2281 /* A = NrgRef * TmpNoise */
2282 a = fMult(nrgRef, tmpNoise);
2283 a_e = nrgRef_e + tmpNoise_e;
2284
2285 /* B = 1 + TmpNoise */
2286 b_e = (int)(tmpNoise_e - 1);
2287 if (b_e >= 0) {
2288 b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2289 (tmpNoise >> 1);
2290 b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
2291 } else {
2292 b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2293 (FL2FXCONST_DBL(0.5f) >> 1);
2294 b_e = 2; /* shift by 1 bit to avoid overflow */
2295 }
2296
2297 /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
2298 FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
2299
2300 if (sinePresentFlag) {
2301 /* C = (1 + TmpNoise) * NrgEst */
2302 c = fMult(b, nrgEst);
2303 c_e = b_e + nrgEst_e;
2304
2305 /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
2306 FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
2307
2308 if (sineMapped) {
2309 /* sineLevel = nrgRef/ (1 + TmpNoise) */
2310 FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
2311 }
2312 } else {
2313 if (noNoiseFlag) {
2314 /* B = NrgEst */
2315 b = nrgEst;
2316 b_e = nrgEst_e;
2317 } else {
2318 /* B = NrgEst * (1 + TmpNoise) */
2319 b = fMult(b, nrgEst);
2320 b_e = b_e + nrgEst_e;
2321 }
2322
2323 /* gain = nrgRef / B */
2324 FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgGain, ptrNrgGain_e);
2325 }
2326 }
2327
2328 /*!
2329 \brief Calculate "average gain" for the specified subband range.
2330
2331 This is rather a gain of the average magnitude than the average
2332 of gains!
2333 The result is used as a relative limit for all gains within the
2334 current "limiter band" (a certain frequency range).
2335 */
calcAvgGain(ENV_CALC_NRGS * nrgs,int lowSubband,int highSubband,FIXP_DBL * ptrSumRef,SCHAR * ptrSumRef_e,FIXP_DBL * ptrAvgGain,SCHAR * ptrAvgGain_e)2336 static void calcAvgGain(
2337 ENV_CALC_NRGS *nrgs, int lowSubband, /*!< Begin of the limiter band */
2338 int highSubband, /*!< High end of the limiter band */
2339 FIXP_DBL *ptrSumRef, SCHAR *ptrSumRef_e,
2340 FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
2341 SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */
2342 {
2343 FIXP_DBL *nrgRef =
2344 nrgs->nrgRef; /*!< Reference Energy according to envelope data */
2345 SCHAR *nrgRef_e =
2346 nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
2347 (exponent) */
2348 FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
2349 SCHAR *nrgEst_e =
2350 nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
2351
2352 FIXP_DBL sumRef = 1;
2353 FIXP_DBL sumEst = 1;
2354 SCHAR sumRef_e = -FRACT_BITS;
2355 SCHAR sumEst_e = -FRACT_BITS;
2356 int k;
2357
2358 for (k = lowSubband; k < highSubband; k++) {
2359 /* Add nrgRef[k] to sumRef: */
2360 FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
2361 &sumRef_e);
2362
2363 /* Add nrgEst[k] to sumEst: */
2364 FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
2365 &sumEst_e);
2366 }
2367
2368 FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
2369 ptrAvgGain_e);
2370
2371 *ptrSumRef = sumRef;
2372 *ptrSumRef_e = sumRef_e;
2373 }
2374
adjustTimeSlot_EldGrid(FIXP_DBL * RESTRICT ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex,int scale_diff_low)2375 static void adjustTimeSlot_EldGrid(
2376 FIXP_DBL *RESTRICT
2377 ptrReal, /*!< Subband samples to be adjusted, real part */
2378 ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2379 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2380 int noSubbands, /*!< Number of QMF subbands */
2381 int scale_change, /*!< Number of bits to shift adjusted samples */
2382 int noNoiseFlag, /*!< Flag to suppress noise addition */
2383 int *ptrPhaseIndex, /*!< Start index to random number array */
2384 int scale_diff_low) /*!< */
2385
2386 {
2387 int k;
2388 FIXP_DBL signalReal, sbNoise;
2389 int tone_count = 0;
2390
2391 FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2392 FIXP_DBL *RESTRICT pNoiseLevel =
2393 nrgs->noiseLevel; /*!< Noise levels of current envelope */
2394 FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2395
2396 int phaseIndex = *ptrPhaseIndex;
2397 UCHAR harmIndex = *ptrHarmIndex;
2398
2399 static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2400
2401 static const FIXP_DBL harmonicPhaseX[4][2] = {
2402 {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
2403 FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
2404 {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
2405 FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
2406 {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
2407 FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
2408 {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
2409 FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
2410
2411 const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
2412 const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
2413
2414 *(ptrReal - 1) = fAddSaturate(
2415 *(ptrReal - 1),
2416 SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
2417 scale_diff_low, DFRACT_BITS));
2418 FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
2419
2420 int idx_k = lowSubband & 1;
2421
2422 for (k = 0; k < noSubbands; k++) {
2423 FIXP_DBL sineLevel_curr = *pSineLevel++;
2424 phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2425
2426 signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
2427 sbNoise = *pNoiseLevel++;
2428 if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2429 signalReal +=
2430 (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)
2431 << 4);
2432 }
2433 signalReal += sineLevel_curr * p_harmonicPhase[0];
2434 signalReal =
2435 fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2436 pSineLevel_prev = sineLevel_curr;
2437 idx_k = !idx_k;
2438 if (k < noSubbands - 1) {
2439 signalReal =
2440 fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
2441 } else /* (k == noSubbands - 1) */
2442 {
2443 if (k + lowSubband + 1 < 63) {
2444 *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2445 }
2446 }
2447 *ptrReal++ = signalReal;
2448
2449 if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
2450 if (++tone_count == 16) {
2451 k++;
2452 break;
2453 }
2454 }
2455 }
2456 /* Run again, if previous loop got breaked with tone_count = 16 */
2457 for (; k < noSubbands; k++) {
2458 FIXP_DBL sineLevel_curr = *pSineLevel++;
2459 phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2460
2461 signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
2462 sbNoise = *pNoiseLevel++;
2463 if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2464 signalReal +=
2465 (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)
2466 << 4);
2467 }
2468 signalReal += sineLevel_curr * p_harmonicPhase[0];
2469 *ptrReal++ = signalReal;
2470 }
2471
2472 *ptrHarmIndex = (harmIndex + 1) & 3;
2473 *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
2474 }
2475
2476 /*!
2477 \brief Amplify one timeslot of the signal with the calculated gains
2478 and add the noisefloor.
2479 */
2480
adjustTimeSlotLC(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex)2481 static void adjustTimeSlotLC(
2482 FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
2483 ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2484 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2485 int noSubbands, /*!< Number of QMF subbands */
2486 int scale_change, /*!< Number of bits to shift adjusted samples */
2487 int noNoiseFlag, /*!< Flag to suppress noise addition */
2488 int *ptrPhaseIndex) /*!< Start index to random number array */
2489 {
2490 FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2491 FIXP_DBL *pNoiseLevel =
2492 nrgs->noiseLevel; /*!< Noise levels of current envelope */
2493 FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2494
2495 int k;
2496 int index = *ptrPhaseIndex;
2497 UCHAR harmIndex = *ptrHarmIndex;
2498 UCHAR freqInvFlag = (lowSubband & 1);
2499 FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
2500 int tone_count = 0;
2501 int sineSign = 1;
2502
2503 #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
2504 #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
2505
2506 /*
2507 First pass for k=0 pulled out of the loop:
2508 */
2509
2510 index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2511
2512 /*
2513 The next multiplication constitutes the actual envelope adjustment
2514 of the signal and should be carried out with full accuracy
2515 (supplying #FRACT_BITS valid bits).
2516 */
2517 signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
2518 sineLevel = *pSineLevel++;
2519 sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
2520
2521 if (sineLevel != FL2FXCONST_DBL(0.0f))
2522 tone_count++;
2523 else if (!noNoiseFlag)
2524 /* Add noisefloor to the amplified signal */
2525 signalReal +=
2526 (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])
2527 << 4);
2528
2529 {
2530 if (!(harmIndex & 0x1)) {
2531 /* harmIndex 0,2 */
2532 signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel;
2533 *ptrReal++ = signalReal;
2534 } else {
2535 /* harmIndex 1,3 in combination with freqInvFlag */
2536 int shift = (int)(scale_change + 1);
2537 shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift)
2538 : fixMax(-(DFRACT_BITS - 1), shift);
2539
2540 FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
2541 : (fMultDiv2(C1, sineLevel) << (-shift));
2542 FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
2543
2544 /* save switch and compare operations and reduce to XOR statement */
2545 if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
2546 *(ptrReal - 1) += tmp1;
2547 signalReal -= tmp2;
2548 } else {
2549 *(ptrReal - 1) -= tmp1;
2550 signalReal += tmp2;
2551 }
2552 *ptrReal++ = signalReal;
2553 freqInvFlag = !freqInvFlag;
2554 }
2555 }
2556
2557 pNoiseLevel++;
2558
2559 if (noSubbands > 2) {
2560 if (!(harmIndex & 0x1)) {
2561 /* harmIndex 0,2 */
2562 if (!harmIndex) {
2563 sineSign = 0;
2564 }
2565
2566 for (k = noSubbands - 2; k != 0; k--) {
2567 FIXP_DBL sinelevel = *pSineLevel++;
2568 index++;
2569 if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
2570 FL2FXCONST_DBL(0.0f)) &&
2571 !noNoiseFlag) {
2572 /* Add noisefloor to the amplified signal */
2573 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2574 signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
2575 pNoiseLevel[0])
2576 << 4);
2577 }
2578
2579 /* The next multiplication constitutes the actual envelope adjustment of
2580 * the signal. */
2581 signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
2582
2583 pNoiseLevel++;
2584 *ptrReal++ = signalReal;
2585 } /* for ... */
2586 } else {
2587 /* harmIndex 1,3 in combination with freqInvFlag */
2588 if (harmIndex == 1) freqInvFlag = !freqInvFlag;
2589
2590 for (k = noSubbands - 2; k != 0; k--) {
2591 index++;
2592 /* The next multiplication constitutes the actual envelope adjustment of
2593 * the signal. */
2594 signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
2595
2596 if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
2597 tone_count++;
2598 else if (!noNoiseFlag) {
2599 /* Add noisefloor to the amplified signal */
2600 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2601 signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
2602 pNoiseLevel[0])
2603 << 4);
2604 }
2605
2606 pNoiseLevel++;
2607
2608 if (tone_count <= 16) {
2609 FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
2610 signalReal += (freqInvFlag) ? (-addSine) : (addSine);
2611 }
2612
2613 *ptrReal++ = signalReal;
2614 freqInvFlag = !freqInvFlag;
2615 } /* for ... */
2616 }
2617 }
2618
2619 if (noSubbands > -1) {
2620 index++;
2621 /* The next multiplication constitutes the actual envelope adjustment of the
2622 * signal. */
2623 signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change);
2624 sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
2625 sineLevel = pSineLevel[0];
2626
2627 if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
2628 tone_count++;
2629 else if (!noNoiseFlag) {
2630 /* Add noisefloor to the amplified signal */
2631 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2632 signalReal =
2633 signalReal +
2634 (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])
2635 << 4);
2636 }
2637
2638 if (!(harmIndex & 0x1)) {
2639 /* harmIndex 0,2 */
2640 *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
2641 } else {
2642 /* harmIndex 1,3 in combination with freqInvFlag */
2643 if (tone_count <= 16) {
2644 if (freqInvFlag) {
2645 *ptrReal++ = signalReal - sineLevelPrev;
2646 if (noSubbands + lowSubband < 63)
2647 *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
2648 } else {
2649 *ptrReal++ = signalReal + sineLevelPrev;
2650 if (noSubbands + lowSubband < 63)
2651 *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
2652 }
2653 } else
2654 *ptrReal = signalReal;
2655 }
2656 }
2657 *ptrHarmIndex = (harmIndex + 1) & 3;
2658 *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2659 }
2660
adjustTimeSlotHQ_GainAndNoise(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)2661 static void adjustTimeSlotHQ_GainAndNoise(
2662 FIXP_DBL *RESTRICT
2663 ptrReal, /*!< Subband samples to be adjusted, real part */
2664 FIXP_DBL *RESTRICT
2665 ptrImag, /*!< Subband samples to be adjusted, imag part */
2666 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2667 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2668 int noSubbands, /*!< Number of QMF subbands */
2669 int scale_change, /*!< Number of bits to shift adjusted samples */
2670 FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
2671 int noNoiseFlag, /*!< Start index to random number array */
2672 int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2673 {
2674 FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2675 FIXP_DBL *RESTRICT noiseLevel =
2676 nrgs->noiseLevel; /*!< Noise levels of current envelope */
2677 FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2678
2679 FIXP_DBL *RESTRICT filtBuffer =
2680 h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2681 FIXP_DBL *RESTRICT filtBufferNoise =
2682 h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2683 int *RESTRICT ptrPhaseIndex =
2684 &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2685
2686 int k;
2687 FIXP_DBL signalReal, signalImag;
2688 FIXP_DBL noiseReal, noiseImag;
2689 FIXP_DBL smoothedGain, smoothedNoise;
2690 FIXP_SGL direct_ratio =
2691 /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2692 int index = *ptrPhaseIndex;
2693 int shift;
2694
2695 *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2696
2697 filtBufferNoiseShift +=
2698 1; /* due to later use of fMultDiv2 instead of fMult */
2699 if (filtBufferNoiseShift < 0) {
2700 shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2701 } else {
2702 shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2703 }
2704
2705 if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2706 for (k = 0; k < noSubbands; k++) {
2707 /*
2708 Smoothing: The old envelope has been bufferd and a certain ratio
2709 of the old gains and noise levels is used.
2710 */
2711 smoothedGain =
2712 fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2713
2714 if (filtBufferNoiseShift < 0) {
2715 smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2716 fMult(direct_ratio, noiseLevel[k]);
2717 } else {
2718 smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
2719 fMult(direct_ratio, noiseLevel[k]);
2720 }
2721
2722 /*
2723 The next 2 multiplications constitute the actual envelope adjustment
2724 of the signal and should be carried out with full accuracy
2725 (supplying #DFRACT_BITS valid bits).
2726 */
2727 signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
2728 signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
2729
2730 index++;
2731
2732 if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
2733 /* Just the amplified signal is saved */
2734 *ptrReal++ = signalReal;
2735 *ptrImag++ = signalImag;
2736 } else {
2737 /* Add noisefloor to the amplified signal */
2738 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2739 noiseReal =
2740 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)
2741 << 4;
2742 noiseImag =
2743 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)
2744 << 4;
2745 *ptrReal++ = (signalReal + noiseReal);
2746 *ptrImag++ = (signalImag + noiseImag);
2747 }
2748 }
2749 } else {
2750 for (k = 0; k < noSubbands; k++) {
2751 smoothedGain = gain[k];
2752 signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
2753 signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
2754
2755 index++;
2756
2757 if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
2758 /* Add noisefloor to the amplified signal */
2759 smoothedNoise = noiseLevel[k];
2760 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2761 noiseReal =
2762 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2763 noiseImag =
2764 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2765
2766 /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
2767 signalReal += noiseReal << 4;
2768 signalImag += noiseImag << 4;
2769 }
2770 *ptrReal++ = signalReal;
2771 *ptrImag++ = signalImag;
2772 }
2773 }
2774 }
2775
adjustTimeSlotHQ_AddHarmonics(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)2776 static void adjustTimeSlotHQ_AddHarmonics(
2777 FIXP_DBL *RESTRICT
2778 ptrReal, /*!< Subband samples to be adjusted, real part */
2779 FIXP_DBL *RESTRICT
2780 ptrImag, /*!< Subband samples to be adjusted, imag part */
2781 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2782 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2783 int noSubbands, /*!< Number of QMF subbands */
2784 int scale_change /*!< Scale mismatch between QMF input and sineLevel
2785 exponent. */
2786 ) {
2787 FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2788 UCHAR *RESTRICT ptrHarmIndex =
2789 &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2790
2791 int k;
2792 FIXP_DBL signalReal, signalImag;
2793 UCHAR harmIndex = *ptrHarmIndex;
2794 int freqInvFlag = (lowSubband & 1);
2795 FIXP_DBL sineLevel;
2796
2797 *ptrHarmIndex = (harmIndex + 1) & 3;
2798
2799 for (k = 0; k < noSubbands; k++) {
2800 sineLevel = pSineLevel[k];
2801 freqInvFlag ^= 1;
2802 if (sineLevel != FL2FXCONST_DBL(0.f)) {
2803 signalReal = ptrReal[k];
2804 signalImag = ptrImag[k];
2805 sineLevel = scaleValue(sineLevel, scale_change);
2806 if (harmIndex & 2) {
2807 /* case 2,3 */
2808 sineLevel = -sineLevel;
2809 }
2810 if (!(harmIndex & 1)) {
2811 /* case 0,2: */
2812 ptrReal[k] = signalReal + sineLevel;
2813 } else {
2814 /* case 1,3 */
2815 if (!freqInvFlag) sineLevel = -sineLevel;
2816 ptrImag[k] = signalImag + sineLevel;
2817 }
2818 }
2819 }
2820 }
2821
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)2822 static void adjustTimeSlotHQ(
2823 FIXP_DBL *RESTRICT
2824 ptrReal, /*!< Subband samples to be adjusted, real part */
2825 FIXP_DBL *RESTRICT
2826 ptrImag, /*!< Subband samples to be adjusted, imag part */
2827 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2828 int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2829 int noSubbands, /*!< Number of QMF subbands */
2830 int scale_change, /*!< Number of bits to shift adjusted samples */
2831 FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
2832 int noNoiseFlag, /*!< Start index to random number array */
2833 int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2834 {
2835 FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2836 FIXP_DBL *RESTRICT noiseLevel =
2837 nrgs->noiseLevel; /*!< Noise levels of current envelope */
2838 FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2839
2840 FIXP_DBL *RESTRICT filtBuffer =
2841 h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2842 FIXP_DBL *RESTRICT filtBufferNoise =
2843 h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2844 UCHAR *RESTRICT ptrHarmIndex =
2845 &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2846 int *RESTRICT ptrPhaseIndex =
2847 &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2848
2849 int k;
2850 FIXP_DBL signalReal, signalImag;
2851 FIXP_DBL noiseReal, noiseImag;
2852 FIXP_DBL smoothedGain, smoothedNoise;
2853 FIXP_SGL direct_ratio =
2854 /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2855 int index = *ptrPhaseIndex;
2856 UCHAR harmIndex = *ptrHarmIndex;
2857 int freqInvFlag = (lowSubband & 1);
2858 FIXP_DBL sineLevel;
2859 int shift;
2860
2861 *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2862 *ptrHarmIndex = (harmIndex + 1) & 3;
2863
2864 /*
2865 Possible optimization:
2866 smooth_ratio and harmIndex stay constant during the loop.
2867 It might be faster to include a separate loop in each path.
2868
2869 the check for smooth_ratio is now outside the loop and the workload
2870 of the whole function decreased by about 20 %
2871 */
2872
2873 filtBufferNoiseShift +=
2874 1; /* due to later use of fMultDiv2 instead of fMult */
2875 if (filtBufferNoiseShift < 0)
2876 shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2877 else
2878 shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2879
2880 if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2881 for (k = 0; k < noSubbands; k++) {
2882 /*
2883 Smoothing: The old envelope has been bufferd and a certain ratio
2884 of the old gains and noise levels is used.
2885 */
2886
2887 smoothedGain =
2888 fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2889
2890 if (filtBufferNoiseShift < 0) {
2891 smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2892 fMult(direct_ratio, noiseLevel[k]);
2893 } else {
2894 smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
2895 fMult(direct_ratio, noiseLevel[k]);
2896 }
2897
2898 /*
2899 The next 2 multiplications constitute the actual envelope adjustment
2900 of the signal and should be carried out with full accuracy
2901 (supplying #DFRACT_BITS valid bits).
2902 */
2903 signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
2904 signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
2905
2906 index++;
2907
2908 if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2909 sineLevel = pSineLevel[k];
2910
2911 switch (harmIndex) {
2912 case 0:
2913 *ptrReal++ = (signalReal + sineLevel);
2914 *ptrImag++ = (signalImag);
2915 break;
2916 case 2:
2917 *ptrReal++ = (signalReal - sineLevel);
2918 *ptrImag++ = (signalImag);
2919 break;
2920 case 1:
2921 *ptrReal++ = (signalReal);
2922 if (freqInvFlag)
2923 *ptrImag++ = (signalImag - sineLevel);
2924 else
2925 *ptrImag++ = (signalImag + sineLevel);
2926 break;
2927 case 3:
2928 *ptrReal++ = signalReal;
2929 if (freqInvFlag)
2930 *ptrImag++ = (signalImag + sineLevel);
2931 else
2932 *ptrImag++ = (signalImag - sineLevel);
2933 break;
2934 }
2935 } else {
2936 if (noNoiseFlag) {
2937 /* Just the amplified signal is saved */
2938 *ptrReal++ = (signalReal);
2939 *ptrImag++ = (signalImag);
2940 } else {
2941 /* Add noisefloor to the amplified signal */
2942 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2943 /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
2944 noiseReal =
2945 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)
2946 << 4;
2947 noiseImag =
2948 fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)
2949 << 4;
2950 *ptrReal++ = (signalReal + noiseReal);
2951 *ptrImag++ = (signalImag + noiseImag);
2952 }
2953 }
2954 freqInvFlag ^= 1;
2955 }
2956
2957 } else {
2958 for (k = 0; k < noSubbands; k++) {
2959 smoothedGain = gain[k];
2960 signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
2961 signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
2962
2963 index++;
2964
2965 if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
2966 switch (harmIndex) {
2967 case 0:
2968 signalReal += sineLevel;
2969 break;
2970 case 1:
2971 if (freqInvFlag)
2972 signalImag -= sineLevel;
2973 else
2974 signalImag += sineLevel;
2975 break;
2976 case 2:
2977 signalReal -= sineLevel;
2978 break;
2979 case 3:
2980 if (freqInvFlag)
2981 signalImag += sineLevel;
2982 else
2983 signalImag -= sineLevel;
2984 break;
2985 }
2986 } else {
2987 if (noNoiseFlag == 0) {
2988 /* Add noisefloor to the amplified signal */
2989 smoothedNoise = noiseLevel[k];
2990 index &= (SBR_NF_NO_RANDOM_VAL - 1);
2991 noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
2992 smoothedNoise);
2993 noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1],
2994 smoothedNoise);
2995
2996 /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
2997 signalReal += noiseReal << 4;
2998 signalImag += noiseImag << 4;
2999 }
3000 }
3001 *ptrReal++ = signalReal;
3002 *ptrImag++ = signalImag;
3003
3004 freqInvFlag ^= 1;
3005 }
3006 }
3007 }
3008
3009 /*!
3010 \brief Reset limiter bands.
3011
3012 Build frequency band table for the gain limiter dependent on
3013 the previously generated transposer patch areas.
3014
3015 \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error
3016 */
3017 SBR_ERROR
ResetLimiterBands(UCHAR * limiterBandTable,UCHAR * noLimiterBands,UCHAR * freqBandTable,int noFreqBands,const PATCH_PARAM * patchParam,int noPatches,int limiterBands,UCHAR sbrPatchingMode,int xOverQmf[MAX_NUM_PATCHES],int b41Sbr)3018 ResetLimiterBands(
3019 UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
3020 UCHAR *noLimiterBands, /*!< Resulting number of limiter band */
3021 UCHAR *freqBandTable, /*!< Table with possible band borders */
3022 int noFreqBands, /*!< Number of bands in freqBandTable */
3023 const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
3024 int noPatches, /*!< Number of transposer patches */
3025 int limiterBands, /*!< Selected 'band density' from bitstream */
3026 UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
3027 int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
3028 UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
3029 int patchBorders[MAX_NUM_PATCHES + 1];
3030 int kx, k2;
3031
3032 int lowSubband = freqBandTable[0];
3033 int highSubband = freqBandTable[noFreqBands];
3034
3035 /* 1 limiter band. */
3036 if (limiterBands == 0) {
3037 limiterBandTable[0] = 0;
3038 limiterBandTable[1] = highSubband - lowSubband;
3039 nBands = 1;
3040 } else {
3041 if (!sbrPatchingMode && xOverQmf != NULL) {
3042 noPatches = 0;
3043
3044 if (b41Sbr == 1) {
3045 for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
3046 if (xOverQmf[i] != 0) noPatches++;
3047 } else {
3048 for (i = 1; i < MAX_STRETCH_HBE; i++)
3049 if (xOverQmf[i] != 0) noPatches++;
3050 }
3051 for (i = 0; i < noPatches; i++) {
3052 patchBorders[i] = xOverQmf[i] - lowSubband;
3053 }
3054 } else {
3055 for (i = 0; i < noPatches; i++) {
3056 patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
3057 }
3058 }
3059 patchBorders[i] = highSubband - lowSubband;
3060
3061 /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
3062 for (k = 0; k <= noFreqBands; k++) {
3063 workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
3064 }
3065 for (k = 1; k < noPatches; k++) {
3066 workLimiterBandTable[noFreqBands + k] = patchBorders[k];
3067 }
3068
3069 tempNoLim = nBands = noFreqBands + noPatches - 1;
3070 shellsort(workLimiterBandTable, tempNoLim + 1);
3071
3072 loLimIndex = 0;
3073 hiLimIndex = 1;
3074
3075 while (hiLimIndex <= tempNoLim) {
3076 FIXP_DBL div_m, oct_m, temp;
3077 INT div_e = 0, oct_e = 0, temp_e = 0;
3078
3079 k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
3080 kx = workLimiterBandTable[loLimIndex] + lowSubband;
3081
3082 div_m = fDivNorm(k2, kx, &div_e);
3083
3084 /* calculate number of octaves */
3085 oct_m = fLog2(div_m, div_e, &oct_e);
3086
3087 /* multiply with limiterbands per octave */
3088 /* values 1, 1.2, 2, 3 -> scale factor of 2 */
3089 temp = fMultNorm(
3090 oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands],
3091 &temp_e);
3092
3093 /* overall scale factor of temp ist addition of scalefactors from log2
3094 calculation, limiter bands scalefactor (2) and limiter bands
3095 multiplication */
3096 temp_e += oct_e + 2;
3097
3098 /* div can be a maximum of 64 (k2 = 64 and kx = 1)
3099 -> oct can be a maximum of 6
3100 -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum
3101 factor of 3)
3102 -> we need a scale factor of 5 for comparisson
3103 */
3104 if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) {
3105 if (workLimiterBandTable[hiLimIndex] ==
3106 workLimiterBandTable[loLimIndex]) {
3107 workLimiterBandTable[hiLimIndex] = highSubband;
3108 nBands--;
3109 hiLimIndex++;
3110 continue;
3111 }
3112 isPatchBorder[0] = isPatchBorder[1] = 0;
3113 for (k = 0; k <= noPatches; k++) {
3114 if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
3115 isPatchBorder[1] = 1;
3116 break;
3117 }
3118 }
3119 if (!isPatchBorder[1]) {
3120 workLimiterBandTable[hiLimIndex] = highSubband;
3121 nBands--;
3122 hiLimIndex++;
3123 continue;
3124 }
3125 for (k = 0; k <= noPatches; k++) {
3126 if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
3127 isPatchBorder[0] = 1;
3128 break;
3129 }
3130 }
3131 if (!isPatchBorder[0]) {
3132 workLimiterBandTable[loLimIndex] = highSubband;
3133 nBands--;
3134 }
3135 }
3136 loLimIndex = hiLimIndex;
3137 hiLimIndex++;
3138 }
3139 shellsort(workLimiterBandTable, tempNoLim + 1);
3140
3141 /* Test if algorithm exceeded maximum allowed limiterbands */
3142 if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
3143 return SBRDEC_UNSUPPORTED_CONFIG;
3144 }
3145
3146 /* Copy limiterbands from working buffer into final destination */
3147 for (k = 0; k <= nBands; k++) {
3148 limiterBandTable[k] = workLimiterBandTable[k];
3149 }
3150 }
3151 *noLimiterBands = nBands;
3152
3153 return SBRDEC_OK;
3154 }
3155