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