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