2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
86 \brief Envelope calculation
88 The envelope adjustor compares the energies present in the transposed
89 highband to the reference energies conveyed with the bitstream.
90 The highband is amplified (sometimes) or attenuated (mostly) to the
93 The spectral shape of the reference energies can be changed several times per
94 frame if necessary. Each set of energy values corresponding to a certain range
95 in time will be called an <em>envelope</em> here.
96 The bitstream supports several frequency scales and two resolutions. Normally,
97 one or more QMF-subbands are grouped to one SBR-band. An envelope contains
98 reference energies for each SBR-band.
99 In addition to the energy envelopes, noise envelopes are transmitted that
100 define the ratio of energy which is generated by adding noise instead of
101 transposing the lowband. The noise envelopes are given in a coarser time
102 and frequency resolution.
103 If a signal contains strong tonal components, synthetic sines can be
104 generated in individual SBR bands.
106 An overlap buffer of 6 QMF-timeslots is used to allow a more
107 flexible alignment of the envelopes in time that is not restricted to the
108 core codec's frame borders.
109 Therefore the envelope adjustor has access to the spectral data of the
110 current frame as well as the last 6 QMF-timeslots of the previous frame.
111 However, in average only the data of 1 frame is being processed as
112 the adjustor is called once per frame.
114 Depending on the frequency range set in the bitstream, only QMF-subbands between
115 <em>lowSubband</em> and <em>highSubband</em> are adjusted.
117 Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a special Mantissa-Exponent format
118 ( see calculateSbrEnvelope() ) are being used. The main entry point for this modules is calculateSbrEnvelope().
120 \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref documentationOverview
124 #include "env_calc.h"
126 #include "sbrdec_freq_sca.h"
127 #include "env_extr.h"
128 #include "transcendent.h"
132 #include "genericStds.h" /* need FDKpow() for debug outputs */
135 #include "arm/env_calc_arm.cpp"
140 FIXP_DBL nrgRef
[MAX_FREQ_COEFFS
];
141 FIXP_DBL nrgEst
[MAX_FREQ_COEFFS
];
142 FIXP_DBL nrgGain
[MAX_FREQ_COEFFS
];
143 FIXP_DBL noiseLevel
[MAX_FREQ_COEFFS
];
144 FIXP_DBL nrgSine
[MAX_FREQ_COEFFS
];
146 SCHAR nrgRef_e
[MAX_FREQ_COEFFS
];
147 SCHAR nrgEst_e
[MAX_FREQ_COEFFS
];
148 SCHAR nrgGain_e
[MAX_FREQ_COEFFS
];
149 SCHAR noiseLevel_e
[MAX_FREQ_COEFFS
];
150 SCHAR nrgSine_e
[MAX_FREQ_COEFFS
];
154 /*static*/ void equalizeFiltBufferExp(FIXP_DBL
*filtBuffer
,
160 /*static*/ void calcNrgPerSubband(FIXP_DBL
**analysBufferReal
,
161 FIXP_DBL
**analysBufferImag
,
162 int lowSubband
, int highSubband
,
163 int start_pos
, int next_pos
,
168 /*static*/ void calcNrgPerSfb(FIXP_DBL
**analysBufferReal
,
169 FIXP_DBL
**analysBufferImag
,
171 UCHAR
*freqBandTable
,
172 int start_pos
, int next_pos
,
177 /*static*/ void calcSubbandGain(FIXP_DBL nrgRef
, SCHAR nrgRef_e
, ENV_CALC_NRGS
* nrgs
, int c
,
178 FIXP_DBL tmpNoise
, SCHAR tmpNoise_e
,
179 UCHAR sinePresentFlag
,
183 /*static*/ void calcAvgGain(ENV_CALC_NRGS
* nrgs
,
188 FIXP_DBL
*ptrAvgGain_m
,
189 SCHAR
*ptrAvgGain_e
);
191 /*static*/ void adjustTimeSlotLC(FIXP_DBL
*ptrReal
,
200 /*static*/ void adjustTimeSlotHQ(FIXP_DBL
*ptrReal
,
202 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env
,
207 FIXP_SGL smooth_ratio
,
209 int filtBufferNoiseShift
);
213 \brief Map sine flags from bitstream to QMF bands
215 The bitstream carries only 1 sine flag per band and frame.
216 This function maps every sine flag from the bitstream to a specific QMF subband
217 and to a specific envelope where the sine shall start.
218 The result is stored in the vector sineMapped which contains one entry per
219 QMF subband. The value of an entry specifies the envelope where a sine
220 shall start. A value of #MAX_ENVELOPES indicates that no sine is present
222 The missing harmonics flags from the previous frame (harmFlagsPrev) determine
223 if a sine starts at the beginning of the frame or at the transient position.
224 Additionally, the flags in harmFlagsPrev are being updated by this function
227 /*static*/ void mapSineFlags(UCHAR
*freqBandTable
, /*!< Band borders (there's only 1 flag per band) */
228 int nSfb
, /*!< Number of bands in the table */
229 UCHAR
*addHarmonics
, /*!< vector with 1 flag per sfb */
230 int *harmFlagsPrev
, /*!< Packed 'addHarmonics' */
231 int tranEnv
, /*!< Transient position */
232 SCHAR
*sineMapped
) /*!< Resulting vector of sine start positions for each QMF band */
236 int lowSubband2
= freqBandTable
[0]<<1;
238 int oldflags
= *harmFlagsPrev
;
242 Format of harmFlagsPrev:
244 first word = flags for highest 16 sfb bands in use
245 second word = flags for next lower 16 sfb bands (if present)
246 third word = flags for lowest 16 sfb bands (if present)
248 Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
249 The lowest bit of the first word corresponds to the _highest_ sfb band in use.
250 This is ensures that each flag is mapped to the same QMF band even after a
251 change of the crossover-frequency.
255 /* Reset the output vector first */
256 FDKmemset(sineMapped
, MAX_ENVELOPES
,MAX_FREQ_COEFFS
); /* MAX_ENVELOPES means 'no sine' */
258 freqBandTable
+= nSfb
;
259 addHarmonics
+= nSfb
-1;
261 for (i
=nSfb
; i
!=0; i
--) {
262 int ui
= *freqBandTable
--; /* Upper limit of the current scale factor band. */
263 int li
= *freqBandTable
; /* Lower limit of the current scale factor band. */
265 if ( *addHarmonics
-- ) { /* There is a sine in this band */
267 unsigned int mask
= 1 << bitcount
;
268 newflags
|= mask
; /* Set flag */
271 If there was a sine in the last frame, let it continue from the first envelope on
272 else start at the transient position.
274 sineMapped
[(ui
+li
-lowSubband2
) >> 1] = ( oldflags
& mask
) ? 0 : tranEnv
;
277 if ((++bitcount
== 16) || i
==1) {
279 *harmFlagsPrev
++ = newflags
;
280 oldflags
= *harmFlagsPrev
; /* Fetch 16 of the old flags */
288 \brief Reduce gain-adjustment induced aliasing for real valued filterbank.
291 aliasingReduction(FIXP_DBL
* degreeAlias
, /*!< estimated aliasing for each QMF channel */
293 int* useAliasReduction
, /*!< synthetic sine engergy for each subband, used as flag */
294 int noSubbands
) /*!< number of QMF channels to process */
296 FIXP_DBL
* nrgGain
= nrgs
->nrgGain
; /*!< subband gains to be modified */
297 SCHAR
* nrgGain_e
= nrgs
->nrgGain_e
; /*!< subband gains to be modified (exponents) */
298 FIXP_DBL
* nrgEst
= nrgs
->nrgEst
; /*!< subband energy before amplification */
299 SCHAR
* nrgEst_e
= nrgs
->nrgEst_e
; /*!< subband energy before amplification (exponents) */
300 int grouping
= 0, index
= 0, noGroups
, k
;
301 int groupVector
[MAX_FREQ_COEFFS
];
303 /* Calculate grouping*/
304 for (k
= 0; k
< noSubbands
-1; k
++ ){
305 if ( (degreeAlias
[k
+ 1] != FL2FXCONST_DBL(0.0f
)) && useAliasReduction
[k
] ) {
307 groupVector
[index
++] = k
;
311 if(groupVector
[index
-1] + 3 == k
){
312 groupVector
[index
++] = k
+ 1;
319 if(useAliasReduction
[k
])
320 groupVector
[index
++] = k
+ 1;
322 groupVector
[index
++] = k
;
329 groupVector
[index
++] = noSubbands
;
331 noGroups
= index
>> 1;
334 /*Calculate new gain*/
335 for (int group
= 0; group
< noGroups
; group
++) {
336 FIXP_DBL nrgOrig
= FL2FXCONST_DBL(0.0f
); /* Original signal energy in current group of bands */
338 FIXP_DBL nrgAmp
= FL2FXCONST_DBL(0.0f
); /* Amplified signal energy in group (using current gains) */
340 FIXP_DBL nrgMod
= FL2FXCONST_DBL(0.0f
); /* Signal energy in group when applying modified gains */
342 FIXP_DBL groupGain
; /* Total energy gain in group */
344 FIXP_DBL compensation
; /* Compensation factor for the energy change when applying modified gains */
345 SCHAR compensation_e
;
347 int startGroup
= groupVector
[2*group
];
348 int stopGroup
= groupVector
[2*group
+1];
350 /* Calculate total energy in group before and after amplification with current gains: */
351 for(k
= startGroup
; k
< stopGroup
; k
++){
352 /* Get original band energy */
353 FIXP_DBL tmp
= nrgEst
[k
];
354 SCHAR tmp_e
= nrgEst_e
[k
];
356 FDK_add_MantExp(tmp
, tmp_e
, nrgOrig
, nrgOrig_e
, &nrgOrig
, &nrgOrig_e
);
358 /* Multiply band energy with current gain */
359 tmp
= fMult(tmp
,nrgGain
[k
]);
360 tmp_e
= tmp_e
+ nrgGain_e
[k
];
362 FDK_add_MantExp(tmp
, tmp_e
, nrgAmp
, nrgAmp_e
, &nrgAmp
, &nrgAmp_e
);
365 /* Calculate total energy gain in group */
366 FDK_divide_MantExp(nrgAmp
, nrgAmp_e
,
368 &groupGain
, &groupGain_e
);
370 for(k
= startGroup
; k
< stopGroup
; k
++){
374 FIXP_DBL alpha
= degreeAlias
[k
];
375 if (k
< noSubbands
- 1) {
376 if (degreeAlias
[k
+ 1] > alpha
)
377 alpha
= degreeAlias
[k
+ 1];
380 /* Modify gain depending on the degree of aliasing */
381 FDK_add_MantExp( fMult(alpha
,groupGain
), groupGain_e
,
382 fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL
)MAXVAL_DBL
- alpha
,nrgGain
[k
]), nrgGain_e
[k
],
383 &nrgGain
[k
], &nrgGain_e
[k
] );
385 /* Apply modified gain to original energy */
386 tmp
= fMult(nrgGain
[k
],nrgEst
[k
]);
387 tmp_e
= nrgGain_e
[k
] + nrgEst_e
[k
];
389 /* Accumulate energy with modified gains applied */
390 FDK_add_MantExp( tmp
, tmp_e
,
392 &nrgMod
, &nrgMod_e
);
395 /* Calculate compensation factor to retain the energy of the amplified signal */
396 FDK_divide_MantExp(nrgAmp
, nrgAmp_e
,
398 &compensation
, &compensation_e
);
400 /* Apply compensation factor to all gains of the group */
401 for(k
= startGroup
; k
< stopGroup
; k
++){
402 nrgGain
[k
] = fMult(nrgGain
[k
],compensation
);
403 nrgGain_e
[k
] = nrgGain_e
[k
] + compensation_e
;
409 /* Convert headroom bits to exponent */
410 #define SCALE2EXP(s) (15-(s))
411 #define EXP2SCALE(e) (15-(e))
414 \brief Apply spectral envelope to subband samples
416 This function is called from sbr_dec.cpp in each frame.
418 To enhance accuracy and due to the usage of tables for squareroots and
419 inverse, some calculations are performed with the operands being split
420 into mantissa and exponent. The variable names in the source code carry
421 the suffixes <em>_m</em> and <em>_e</em> respectively. The control data
422 in #hFrameData containts envelope data which is represented by this format but
423 stored in single words. (See requantizeEnvelopeData() for details). This data
424 is unpacked within calculateSbrEnvelope() to follow the described suffix convention.
426 The actual value (comparable to the corresponding float-variable in the
427 research-implementation) of a mantissa/exponent-pair can be calculated as
429 \f$ value = value\_m * 2^{value\_e} \f$
431 All energies and noise levels decoded from the bitstream suit for an
432 original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore,
433 the scale factor <em>hb_scale</em> passed into this function will be converted
434 to an 'input exponent' (#input_e), which fits the internal representation.
436 Before the actual processing, an exponent #adj_e for resulting adjusted
437 samples is derived from the maximum reference energy.
439 Then, for each envelope, the following steps are performed:
441 \li Calculate energy in the signal to be adjusted. Depending on the the value of
442 #interpolFreq (interpolation mode), this is either done seperately
443 for each QMF-subband or for each SBR-band.
444 The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas)
445 and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents).
446 \li Calculate gain and noise level for each subband:<br>
447 \f$ gain = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) }
449 noise = \sqrt{ nrgRef \cdot noiseRatio }
451 where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the
452 bitstream and <em>nrgEst</em> is the subband energy before adjustment.
453 The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS]
454 (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels
455 are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS]
457 The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS]
458 and #nrgSine_e[#MAX_FREQ_COEFFS].
459 \li Noise limiting: The gain for each subband is limited both absolutely
460 and relatively compared to the total gain over all subbands.
461 \li Boost gain: Calculate and apply boost factor for each limiter band
462 in order to compensate for the energy loss imposed by the limiting.
463 \li Apply gains and add noise: The gains and noise levels are applied
464 to all timeslots of the current envelope. A short FIR-filter (length 4
465 QMF-timeslots) can be used to smooth the sudden change at the envelope borders.
466 Each complex subband sample of the current timeslot is multiplied by the
467 smoothed gain, then random noise with the calculated level is added.
470 To reduce the stack size, some of the local arrays could be located within
471 the time output buffer. Of the 512 samples temporarily available there,
472 about half the size is already used by #SBR_FRAME_DATA. A pointer to the
473 remaining free memory could be supplied by an additional argument to calculateSbrEnvelope()
478 calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
479 &hSbrDec->SbrCalculateEnvelope,
484 timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1);
488 Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays
489 #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
493 fract* nrgRef_m = timeOutPtr;
494 SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
495 fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
496 SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
497 fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
503 calculateSbrEnvelope (QMF_SCALE_FACTOR
*sbrScaleFactor
, /*!< Scaling factors */
504 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env
, /*!< Handle to struct filled by the create-function */
505 HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
506 HANDLE_SBR_FRAME_DATA hFrameData
, /*!< Control data of current frame */
507 FIXP_DBL
**analysBufferReal
, /*!< Real part of subband samples to be processed */
508 FIXP_DBL
**analysBufferImag
, /*!< Imag part of subband samples to be processed */
510 FIXP_DBL
*degreeAlias
, /*!< Estimated aliasing for each QMF channel */
512 const int frameErrorFlag
515 int c
, i
, j
, envNoise
= 0;
516 UCHAR
* borders
= hFrameData
->frameInfo
.borders
;
518 FIXP_SGL
*noiseLevels
= hFrameData
->sbrNoiseFloorLevel
;
519 HANDLE_FREQ_BAND_DATA hFreq
= &hHeaderData
->freqBandData
;
521 int lowSubband
= hFreq
->lowSubband
;
522 int highSubband
= hFreq
->highSubband
;
523 int noSubbands
= highSubband
- lowSubband
;
525 int noNoiseBands
= hFreq
->nNfb
;
526 int no_cols
= hHeaderData
->numberTimeSlots
* hHeaderData
->timeStep
;
527 UCHAR first_start
= borders
[0] * hHeaderData
->timeStep
;
529 SCHAR sineMapped
[MAX_FREQ_COEFFS
];
530 SCHAR ov_adj_e
= SCALE2EXP(sbrScaleFactor
->ov_hb_scale
);
535 SCHAR maxGainLimit_e
= (frameErrorFlag
) ? MAX_GAIN_CONCEAL_EXP
: MAX_GAIN_EXP
;
537 int useAliasReduction
[64];
538 UCHAR smooth_length
= 0;
540 FIXP_SGL
* pIenv
= hFrameData
->iEnvelope
;
543 Extract sine flags for all QMF bands
545 mapSineFlags(hFreq
->freqBandTable
[1],
547 hFrameData
->addHarmonics
,
548 h_sbr_cal_env
->harmFlagsPrev
,
549 hFrameData
->frameInfo
.tranEnv
,
554 Scan for maximum in bufferd noise levels.
555 This is needed in case that we had strong noise in the previous frame
556 which is smoothed into the current frame.
557 The resulting exponent is used as start value for the maximum search
558 in reference energies
561 adj_e
= h_sbr_cal_env
->filtBufferNoise_e
- getScalefactor(h_sbr_cal_env
->filtBufferNoise
, noSubbands
);
564 Scan for maximum reference energy to be able
565 to select appropriate values for adj_e and final_e.
568 for (i
= 0; i
< hFrameData
->frameInfo
.nEnvelopes
; i
++) {
569 INT maxSfbNrg_e
= -FRACT_BITS
+NRG_EXP_OFFSET
; /* start value for maximum search */
571 /* Fetch frequency resolution for current envelope: */
572 for (j
=hFreq
->nSfb
[hFrameData
->frameInfo
.freqRes
[i
]]; j
!=0; j
--) {
573 maxSfbNrg_e
= fixMax(maxSfbNrg_e
,(INT
)((LONG
)(*pIenv
++) & MASK_E
));
575 maxSfbNrg_e
-= NRG_EXP_OFFSET
;
577 /* Energy -> magnitude (sqrt halfens exponent) */
578 maxSfbNrg_e
= (maxSfbNrg_e
+1) >> 1; /* +1 to go safe (round to next higher int) */
580 /* Some safety margin is needed for 2 reasons:
581 - The signal energy is not equally spread over all subband samples in
582 a specific sfb of an envelope (Nrg could be too high by a factor of
584 - Smoothing can smear high gains of the previous envelope into the current
588 if (borders
[i
] < hHeaderData
->numberTimeSlots
)
589 /* This envelope affects timeslots that belong to the output frame */
590 adj_e
= (maxSfbNrg_e
> adj_e
) ? maxSfbNrg_e
: adj_e
;
592 if (borders
[i
+1] > hHeaderData
->numberTimeSlots
)
593 /* This envelope affects timeslots after the output frame */
594 final_e
= (maxSfbNrg_e
> final_e
) ? maxSfbNrg_e
: final_e
;
599 Calculate adjustment factors and apply them for every envelope.
601 pIenv
= hFrameData
->iEnvelope
;
603 for (i
= 0; i
< hFrameData
->frameInfo
.nEnvelopes
; i
++) {
606 SCHAR noise_e
, input_e
= SCALE2EXP(sbrScaleFactor
->hb_scale
);
607 C_ALLOC_SCRATCH_START(pNrgs
, ENV_CALC_NRGS
, 1);
612 UCHAR start_pos
= hHeaderData
->timeStep
* borders
[i
]; /* Start-position in time (subband sample) for current envelope. */
613 UCHAR stop_pos
= hHeaderData
->timeStep
* borders
[i
+1]; /* Stop-position in time (subband sample) for current envelope. */
614 UCHAR freq_res
= hFrameData
->frameInfo
.freqRes
[i
]; /* Frequency resolution for current envelope. */
617 /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in
618 cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit
619 errors and is tested by some streams from the certification set. */
620 FDKmemclear(pNrgs
, sizeof(ENV_CALC_NRGS
));
622 /* If the start-pos of the current envelope equals the stop pos of the current
623 noise envelope, increase the pointer (i.e. choose the next noise-floor).*/
624 if (borders
[i
] == hFrameData
->frameInfo
.bordersNoise
[envNoise
+1]){
625 noiseLevels
+= noNoiseBands
; /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/
629 if(i
==hFrameData
->frameInfo
.tranEnv
|| i
==h_sbr_cal_env
->prevTranEnv
) /* attack */
633 smooth_length
= 0; /* No smoothing on attacks! */
638 smooth_length
= (1 - hHeaderData
->bs_data
.smoothingLength
) << 2; /* can become either 0 or 4 */
643 Energy estimation in transposed highband.
645 if (hHeaderData
->bs_data
.interpolFreq
)
646 calcNrgPerSubband(analysBufferReal
,
647 (useLP
) ? NULL
: analysBufferImag
,
648 lowSubband
, highSubband
,
654 calcNrgPerSfb(analysBufferReal
,
655 (useLP
) ? NULL
: analysBufferImag
,
656 hFreq
->nSfb
[freq_res
],
657 hFreq
->freqBandTable
[freq_res
],
664 Calculate subband gains
667 UCHAR
* table
= hFreq
->freqBandTable
[freq_res
];
668 UCHAR
* pUiNoise
= &hFreq
->freqBandTableNoise
[1]; /*! Upper limit of the current noise floor band. */
670 FIXP_SGL
* pNoiseLevels
= noiseLevels
;
672 FIXP_DBL tmpNoise
= FX_SGL2FX_DBL((FIXP_SGL
)((LONG
)(*pNoiseLevels
) & MASK_M
));
673 SCHAR tmpNoise_e
= (UCHAR
)((LONG
)(*pNoiseLevels
++) & MASK_E
) - NOISE_EXP_OFFSET
;
677 for (j
= 0; j
< hFreq
->nSfb
[freq_res
]; j
++) {
679 FIXP_DBL refNrg
= FX_SGL2FX_DBL((FIXP_SGL
)((LONG
)(*pIenv
) & MASK_M
));
680 SCHAR refNrg_e
= (SCHAR
)((LONG
)(*pIenv
) & MASK_E
) - NRG_EXP_OFFSET
;
682 UCHAR sinePresentFlag
= 0;
686 for (k
=li
; k
<ui
; k
++) {
687 sinePresentFlag
|= (i
>= sineMapped
[cc
]);
691 for (k
=li
; k
<ui
; k
++) {
692 if (k
>= *pUiNoise
) {
693 tmpNoise
= FX_SGL2FX_DBL((FIXP_SGL
)((LONG
)(*pNoiseLevels
) & MASK_M
));
694 tmpNoise_e
= (SCHAR
)((LONG
)(*pNoiseLevels
++) & MASK_E
) - NOISE_EXP_OFFSET
;
699 FDK_ASSERT(k
>= lowSubband
);
702 useAliasReduction
[k
-lowSubband
] = !sinePresentFlag
;
704 pNrgs
->nrgSine
[c
] = FL2FXCONST_DBL(0.0f
);
705 pNrgs
->nrgSine_e
[c
] = 0;
707 calcSubbandGain(refNrg
, refNrg_e
, pNrgs
, c
,
708 tmpNoise
, tmpNoise_e
,
709 sinePresentFlag
, i
>= sineMapped
[c
],
712 pNrgs
->nrgRef
[c
] = refNrg
;
713 pNrgs
->nrgRef_e
[c
] = refNrg_e
;
725 for (c
= 0; c
< hFreq
->noLimiterBands
; c
++) {
727 FIXP_DBL sumRef
, boostGain
, maxGain
;
728 FIXP_DBL accu
= FL2FXCONST_DBL(0.0f
);
729 SCHAR sumRef_e
, boostGain_e
, maxGain_e
, accu_e
= 0;
732 hFreq
->limiterBandTable
[c
], hFreq
->limiterBandTable
[c
+1],
734 &maxGain
, &maxGain_e
);
736 /* Multiply maxGain with limiterGain: */
737 maxGain
= fMult(maxGain
, FDK_sbrDecoder_sbr_limGains_m
[hHeaderData
->bs_data
.limiterGains
]);
738 maxGain_e
+= FDK_sbrDecoder_sbr_limGains_e
[hHeaderData
->bs_data
.limiterGains
];
740 /* Scale mantissa of MaxGain into range between 0.5 and 1: */
741 if (maxGain
== FL2FXCONST_DBL(0.0f
))
742 maxGain_e
= -FRACT_BITS
;
744 SCHAR charTemp
= CountLeadingBits(maxGain
);
745 maxGain_e
-= charTemp
;
746 maxGain
<<= (int)charTemp
;
749 if (maxGain_e
>= maxGainLimit_e
) { /* upper limit (e.g. 96 dB) */
750 maxGain
= FL2FXCONST_DBL(0.5f
);
751 maxGain_e
= maxGainLimit_e
;
755 /* Every subband gain is compared to the scaled "average gain"
756 and limited if necessary: */
757 for (k
= hFreq
->limiterBandTable
[c
]; k
< hFreq
->limiterBandTable
[c
+1]; k
++) {
758 if ( (pNrgs
->nrgGain_e
[k
] > maxGain_e
) || (pNrgs
->nrgGain_e
[k
] == maxGain_e
&& pNrgs
->nrgGain
[k
]>maxGain
) ) {
763 FDK_divide_MantExp(maxGain
, maxGain_e
, pNrgs
->nrgGain
[k
], pNrgs
->nrgGain_e
[k
], &noiseAmp
, &noiseAmp_e
);
764 pNrgs
->noiseLevel
[k
] = fMult(pNrgs
->noiseLevel
[k
],noiseAmp
);
765 pNrgs
->noiseLevel_e
[k
] += noiseAmp_e
;
766 pNrgs
->nrgGain
[k
] = maxGain
;
767 pNrgs
->nrgGain_e
[k
] = maxGain_e
;
772 Calculate and apply boost factor for each limiter band:
773 1. Check how much energy would be present when using the limited gain
774 2. Calculate boost factor by comparison with reference energy
775 3. Apply boost factor to compensate for the energy loss due to limiting
777 for (k
= hFreq
->limiterBandTable
[c
]; k
< hFreq
->limiterBandTable
[c
+ 1]; k
++) {
779 /* 1.a Add energy of adjusted signal (using preliminary gain) */
780 FIXP_DBL tmp
= fMult(pNrgs
->nrgGain
[k
],pNrgs
->nrgEst
[k
]);
781 SCHAR tmp_e
= pNrgs
->nrgGain_e
[k
] + pNrgs
->nrgEst_e
[k
];
782 FDK_add_MantExp(tmp
, tmp_e
, accu
, accu_e
, &accu
, &accu_e
);
784 /* 1.b Add sine energy (if present) */
785 if(pNrgs
->nrgSine
[k
] != FL2FXCONST_DBL(0.0f
)) {
786 FDK_add_MantExp(pNrgs
->nrgSine
[k
], pNrgs
->nrgSine_e
[k
], accu
, accu_e
, &accu
, &accu_e
);
789 /* 1.c Add noise energy (if present) */
790 if(noNoiseFlag
== 0) {
791 FDK_add_MantExp(pNrgs
->noiseLevel
[k
], pNrgs
->noiseLevel_e
[k
], accu
, accu_e
, &accu
, &accu_e
);
796 /* 2.a Calculate ratio of wanted energy and accumulated energy */
797 if (accu
== (FIXP_DBL
)0) { /* If divisor is 0, limit quotient to +4 dB */
798 boostGain
= FL2FXCONST_DBL(0.6279716f
);
802 boostGain
= fDivNorm(sumRef
, accu
, &div_e
);
803 boostGain_e
= sumRef_e
- accu_e
+ div_e
;
807 /* 2.b Result too high? --> Limit the boost factor to +4 dB */
808 if((boostGain_e
> 3) ||
809 (boostGain_e
== 2 && boostGain
> FL2FXCONST_DBL(0.6279716f
)) ||
810 (boostGain_e
== 3 && boostGain
> FL2FXCONST_DBL(0.3139858f
)) )
812 boostGain
= FL2FXCONST_DBL(0.6279716f
);
815 /* 3. Multiply all signal components with the boost factor */
816 for (k
= hFreq
->limiterBandTable
[c
]; k
< hFreq
->limiterBandTable
[c
+ 1]; k
++) {
817 pNrgs
->nrgGain
[k
] = fMultDiv2(pNrgs
->nrgGain
[k
],boostGain
);
818 pNrgs
->nrgGain_e
[k
] = pNrgs
->nrgGain_e
[k
] + boostGain_e
+ 1;
820 pNrgs
->nrgSine
[k
] = fMultDiv2(pNrgs
->nrgSine
[k
],boostGain
);
821 pNrgs
->nrgSine_e
[k
] = pNrgs
->nrgSine_e
[k
] + boostGain_e
+ 1;
823 pNrgs
->noiseLevel
[k
] = fMultDiv2(pNrgs
->noiseLevel
[k
],boostGain
);
824 pNrgs
->noiseLevel_e
[k
] = pNrgs
->noiseLevel_e
[k
] + boostGain_e
+ 1;
827 /* End of noise limiting */
830 aliasingReduction(degreeAlias
+lowSubband
,
835 /* For the timeslots within the range for the output frame,
836 use the same scale for the noise levels.
837 Drawback: If the envelope exceeds the frame border, the noise levels
838 will have to be rescaled later to fit final_e of
841 noise_e
= (start_pos
< no_cols
) ? adj_e
: final_e
;
844 Convert energies to amplitude levels
846 for (k
=0; k
<noSubbands
; k
++) {
847 FDK_sqrt_MantExp(&pNrgs
->nrgSine
[k
], &pNrgs
->nrgSine_e
[k
], &noise_e
);
848 FDK_sqrt_MantExp(&pNrgs
->nrgGain
[k
], &pNrgs
->nrgGain_e
[k
], &pNrgs
->nrgGain_e
[k
]);
849 FDK_sqrt_MantExp(&pNrgs
->noiseLevel
[k
], &pNrgs
->noiseLevel_e
[k
], &noise_e
);
855 Apply calculated gains and adaptive noise
858 /* assembleHfSignals() */
860 int scale_change
, sc_change
;
861 FIXP_SGL smooth_ratio
;
862 int filtBufferNoiseShift
=0;
864 /* Initialize smoothing buffers with the first valid values */
865 if (h_sbr_cal_env
->startUp
)
868 h_sbr_cal_env
->filtBufferNoise_e
= noise_e
;
870 FDKmemcpy(h_sbr_cal_env
->filtBuffer_e
, pNrgs
->nrgGain_e
, noSubbands
*sizeof(SCHAR
));
871 FDKmemcpy(h_sbr_cal_env
->filtBufferNoise
, pNrgs
->noiseLevel
, noSubbands
*sizeof(FIXP_DBL
));
872 FDKmemcpy(h_sbr_cal_env
->filtBuffer
, pNrgs
->nrgGain
, noSubbands
*sizeof(FIXP_DBL
));
875 h_sbr_cal_env
->startUp
= 0;
880 equalizeFiltBufferExp(h_sbr_cal_env
->filtBuffer
, /* buffered */
881 h_sbr_cal_env
->filtBuffer_e
, /* buffered */
882 pNrgs
->nrgGain
, /* current */
883 pNrgs
->nrgGain_e
, /* current */
886 /* Adapt exponent of buffered noise levels to the current exponent
887 so they can easily be smoothed */
888 if((h_sbr_cal_env
->filtBufferNoise_e
- noise_e
)>=0) {
889 int shift
= fixMin(DFRACT_BITS
-1,(int)(h_sbr_cal_env
->filtBufferNoise_e
- noise_e
));
890 for (k
=0; k
<noSubbands
; k
++)
891 h_sbr_cal_env
->filtBufferNoise
[k
] <<= shift
;
894 int shift
= fixMin(DFRACT_BITS
-1,-(int)(h_sbr_cal_env
->filtBufferNoise_e
- noise_e
));
895 for (k
=0; k
<noSubbands
; k
++)
896 h_sbr_cal_env
->filtBufferNoise
[k
] >>= shift
;
899 h_sbr_cal_env
->filtBufferNoise_e
= noise_e
;
902 /* find best scaling! */
903 scale_change
= -(DFRACT_BITS
-1);
904 for(k
=0;k
<noSubbands
;k
++) {
905 scale_change
= fixMax(scale_change
,(int)pNrgs
->nrgGain_e
[k
]);
907 sc_change
= (start_pos
<no_cols
)? adj_e
- input_e
: final_e
- input_e
;
909 if ((scale_change
-sc_change
+1)<0)
910 scale_change
-=(scale_change
-sc_change
+1);
912 scale_change
= (scale_change
-sc_change
)+1;
914 for(k
=0;k
<noSubbands
;k
++) {
915 int sc
= scale_change
-pNrgs
->nrgGain_e
[k
] + (sc_change
-1);
916 pNrgs
->nrgGain
[k
] >>= sc
;
917 pNrgs
->nrgGain_e
[k
] += sc
;
921 for(k
=0;k
<noSubbands
;k
++) {
922 int sc
= scale_change
-h_sbr_cal_env
->filtBuffer_e
[k
] + (sc_change
-1);
923 h_sbr_cal_env
->filtBuffer
[k
] >>= sc
;
927 for (j
= start_pos
; j
< stop_pos
; j
++)
929 /* This timeslot is located within the first part of the processing buffer
930 and will be fed into the QMF-synthesis for the current frame.
932 This timeslot will not yet be fed into the QMF so we do not care
934 sc_change = final_e - input_e
936 if ( (j
==no_cols
) && (start_pos
<no_cols
) )
938 int shift
= (int) (noise_e
- final_e
);
940 filtBufferNoiseShift
= shift
; /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */
942 shift
= fixMin(DFRACT_BITS
-1,shift
);
943 for (k
=0; k
<noSubbands
; k
++) {
944 pNrgs
->nrgSine
[k
] <<= shift
;
945 pNrgs
->noiseLevel
[k
] <<= shift
;
948 h_sbr_cal_env->filtBufferNoise[k] <<= shift;
953 shift
= fixMin(DFRACT_BITS
-1,-shift
);
954 for (k
=0; k
<noSubbands
; k
++) {
955 pNrgs
->nrgSine
[k
] >>= shift
;
956 pNrgs
->noiseLevel
[k
] >>= shift
;
959 h_sbr_cal_env->filtBufferNoise[k] >>= shift;
964 /* update noise scaling */
967 h_sbr_cal_env
->filtBufferNoise_e
= noise_e
; /* scaling value unused! */
969 /* update gain buffer*/
970 sc_change
-= (final_e
- input_e
);
973 for(k
=0;k
<noSubbands
;k
++) {
974 pNrgs
->nrgGain
[k
] >>= -sc_change
;
975 pNrgs
->nrgGain_e
[k
] += -sc_change
;
978 for(k
=0;k
<noSubbands
;k
++) {
979 h_sbr_cal_env
->filtBuffer
[k
] >>= -sc_change
;
983 scale_change
+=sc_change
;
990 /* Prevent the smoothing filter from running on constant levels */
991 if (j
-start_pos
< smooth_length
)
992 smooth_ratio
= FDK_sbrDecoder_sbr_smoothFilter
[j
-start_pos
];
995 smooth_ratio
= FL2FXCONST_SGL(0.0f
);
997 adjustTimeSlotHQ(&analysBufferReal
[j
][lowSubband
],
998 &analysBufferImag
[j
][lowSubband
],
1006 filtBufferNoiseShift
);
1010 adjustTimeSlotLC(&analysBufferReal
[j
][lowSubband
],
1012 &h_sbr_cal_env
->harmIndex
,
1017 &h_sbr_cal_env
->phaseIndex
,
1018 (flags
& SBRDEC_ELD_GRID
));
1023 /* Update time-smoothing-buffers for gains and noise levels
1024 The gains and the noise values of the current envelope are copied into the buffer.
1025 This has to be done at the end of each envelope as the values are required for
1026 a smooth transition to the next envelope. */
1027 FDKmemcpy(h_sbr_cal_env
->filtBuffer
, pNrgs
->nrgGain
, noSubbands
*sizeof(FIXP_DBL
));
1028 FDKmemcpy(h_sbr_cal_env
->filtBuffer_e
, pNrgs
->nrgGain_e
, noSubbands
*sizeof(SCHAR
));
1029 FDKmemcpy(h_sbr_cal_env
->filtBufferNoise
, pNrgs
->noiseLevel
, noSubbands
*sizeof(FIXP_DBL
));
1033 C_ALLOC_SCRATCH_END(pNrgs
, ENV_CALC_NRGS
, 1);
1036 /* Rescale output samples */
1039 int ov_reserve
, reserve
;
1041 /* Determine headroom in old adjusted samples */
1042 maxVal
= maxSubbandSample( analysBufferReal
,
1043 (useLP
) ? NULL
: analysBufferImag
,
1049 ov_reserve
= fNorm(maxVal
);
1051 /* Determine headroom in new adjusted samples */
1052 maxVal
= maxSubbandSample( analysBufferReal
,
1053 (useLP
) ? NULL
: analysBufferImag
,
1059 reserve
= fNorm(maxVal
);
1061 /* Determine common output exponent */
1062 if (ov_adj_e
- ov_reserve
> adj_e
- reserve
) /* set output_e to the maximum */
1063 output_e
= ov_adj_e
- ov_reserve
;
1065 output_e
= adj_e
- reserve
;
1067 /* Rescale old samples */
1068 rescaleSubbandSamples( analysBufferReal
,
1069 (useLP
) ? NULL
: analysBufferImag
,
1070 lowSubband
, highSubband
,
1072 ov_adj_e
- output_e
);
1074 /* Rescale new samples */
1075 rescaleSubbandSamples( analysBufferReal
,
1076 (useLP
) ? NULL
: analysBufferImag
,
1077 lowSubband
, highSubband
,
1078 first_start
, no_cols
,
1082 /* Update hb_scale */
1083 sbrScaleFactor
->hb_scale
= EXP2SCALE(output_e
);
1085 /* Save the current final exponent for the next frame: */
1086 sbrScaleFactor
->ov_hb_scale
= EXP2SCALE(final_e
);
1089 /* We need to remeber to the next frame that the transient
1090 will occur in the first envelope (if tranEnv == nEnvelopes). */
1091 if(hFrameData
->frameInfo
.tranEnv
== hFrameData
->frameInfo
.nEnvelopes
)
1092 h_sbr_cal_env
->prevTranEnv
= 0;
1094 h_sbr_cal_env
->prevTranEnv
= -1;
1100 \brief Create envelope instance
1102 Must be called once for each channel before calculateSbrEnvelope() can be used.
1104 \return errorCode, 0 if successful
1107 createSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs
, /*!< pointer to envelope instance */
1108 HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< static SBR control data, initialized with defaults */
1109 const int chan
, /*!< Channel for which to assign buffers */
1112 SBR_ERROR err
= SBRDEC_OK
;
1115 /* Clear previous missing harmonics flags */
1116 for (i
=0; i
<(MAX_FREQ_COEFFS
+15)>>4; i
++) {
1117 hs
->harmFlagsPrev
[i
] = 0;
1122 Setup pointers for time smoothing.
1123 The buffer itself will be initialized later triggered by the startUp-flag.
1125 hs
->prevTranEnv
= -1;
1128 /* initialization */
1129 resetSbrEnvelopeCalc(hs
);
1131 if (chan
==0) { /* do this only once */
1132 err
= resetFreqBandTables(hHeaderData
, flags
);
1139 \brief Create envelope instance
1141 Must be called once for each channel before calculateSbrEnvelope() can be used.
1143 \return errorCode, 0 if successful
1146 deleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs
)
1153 \brief Reset envelope instance
1155 This function must be called for each channel on a change of configuration.
1156 Note that resetFreqBandTables should also be called in this case.
1158 \return errorCode, 0 if successful
1161 resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv
) /*!< pointer to envelope instance */
1163 hCalEnv
->phaseIndex
= 0;
1165 /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */
1166 hCalEnv
->filtBufferNoise_e
= 0;
1168 hCalEnv
->startUp
= 1;
1173 \brief Equalize exponents of the buffered gain values and the new ones
1175 After equalization of exponents, the FIR-filter addition for smoothing
1177 This function is called once for each envelope before adjusting.
1179 /*static*/ void equalizeFiltBufferExp(FIXP_DBL
*filtBuffer
, /*!< bufferd gains */
1180 SCHAR
*filtBuffer_e
, /*!< exponents of bufferd gains */
1181 FIXP_DBL
*nrgGain
, /*!< gains for current envelope */
1182 SCHAR
*nrgGain_e
, /*!< exponents of gains for current envelope */
1183 int subbands
) /*!< Number of QMF subbands */
1188 for (band
=0; band
<subbands
; band
++){
1189 diff
= (int) (nrgGain_e
[band
] - filtBuffer_e
[band
]);
1191 filtBuffer
[band
] >>= diff
; /* Compensate for the scale change by shifting the mantissa. */
1192 filtBuffer_e
[band
] += diff
; /* New gain is bigger, use its exponent */
1195 /* The buffered gains seem to be larger, but maybe there
1196 are some unused bits left in the mantissa */
1198 int reserve
= CntLeadingZeros(fixp_abs(filtBuffer
[band
]))-1;
1200 if ((-diff
) <= reserve
) {
1201 /* There is enough space in the buffered mantissa so
1202 that we can take the new exponent as common.
1204 filtBuffer
[band
] <<= (-diff
);
1205 filtBuffer_e
[band
] += diff
; /* becomes equal to *ptrNewExp */
1208 filtBuffer
[band
] <<= reserve
; /* Shift the mantissa as far as possible: */
1209 filtBuffer_e
[band
] -= reserve
; /* Compensate in the exponent: */
1211 /* For the remaining difference, change the new gain value */
1212 diff
= fixMin(-(reserve
+ diff
),DFRACT_BITS
-1);
1213 nrgGain
[band
] >>= diff
;
1214 nrgGain_e
[band
] += diff
;
1221 \brief Shift left the mantissas of all subband samples
1222 in the giventime and frequency range by the specified number of bits.
1224 This function is used to rescale the audio data in the overlap buffer
1225 which has already been envelope adjusted with the last frame.
1227 void rescaleSubbandSamples(FIXP_DBL
** re
, /*!< Real part of input and output subband samples */
1228 FIXP_DBL
** im
, /*!< Imaginary part of input and output subband samples */
1229 int lowSubband
, /*!< Begin of frequency range to process */
1230 int highSubband
, /*!< End of frequency range to process */
1231 int start_pos
, /*!< Begin of time rage (QMF-timeslot) */
1232 int next_pos
, /*!< End of time rage (QMF-timeslot) */
1233 int shift
) /*!< number of bits to shift */
1235 int width
= highSubband
-lowSubband
;
1237 if ( (width
> 0) && (shift
!=0) ) {
1239 for (int l
=start_pos
; l
<next_pos
; l
++) {
1240 scaleValues(&re
[l
][lowSubband
], width
, shift
);
1241 scaleValues(&im
[l
][lowSubband
], width
, shift
);
1245 for (int l
=start_pos
; l
<next_pos
; l
++) {
1246 scaleValues(&re
[l
][lowSubband
], width
, shift
);
1254 \brief Determine headroom for shifting
1256 Determine by how much the spectrum can be shifted left
1257 for better accuracy in later processing.
1259 \return Number of free bits in the biggest spectral value
1262 FIXP_DBL
maxSubbandSample( FIXP_DBL
** re
, /*!< Real part of input and output subband samples */
1263 FIXP_DBL
** im
, /*!< Real part of input and output subband samples */
1264 int lowSubband
, /*!< Begin of frequency range to process */
1265 int highSubband
, /*!< Number of QMF bands to process */
1266 int start_pos
, /*!< Begin of time rage (QMF-timeslot) */
1267 int next_pos
/*!< End of time rage (QMF-timeslot) */
1270 FIXP_DBL maxVal
= FL2FX_DBL(0.0f
);
1271 unsigned int width
= highSubband
- lowSubband
;
1273 FDK_ASSERT(width
<= (64));
1278 for (int l
=start_pos
; l
<next_pos
; l
++)
1280 #ifdef FUNCTION_FDK_get_maxval
1281 maxVal
= FDK_get_maxval(maxVal
, &re
[l
][lowSubband
], &im
[l
][lowSubband
], width
);
1284 FIXP_DBL
*reTmp
= &re
[l
][lowSubband
];
1285 FIXP_DBL
*imTmp
= &im
[l
][lowSubband
];
1287 FIXP_DBL tmp1
= *(reTmp
++);
1288 FIXP_DBL tmp2
= *(imTmp
++);
1289 maxVal
|= (FIXP_DBL
)((LONG
)(tmp1
)^((LONG
)tmp1
>>(DFRACT_BITS
-1)));
1290 maxVal
|= (FIXP_DBL
)((LONG
)(tmp2
)^((LONG
)tmp2
>>(DFRACT_BITS
-1)));
1296 for (int l
=start_pos
; l
<next_pos
; l
++) {
1298 FIXP_DBL
*reTmp
= &re
[l
][lowSubband
];
1300 FIXP_DBL tmp
= *(reTmp
++);
1301 maxVal
|= (FIXP_DBL
)((LONG
)(tmp
)^((LONG
)tmp
>>(DFRACT_BITS
-1)));
1310 #define SHIFT_BEFORE_SQUARE (3) /* (7/2) */
1312 If the accumulator does not provide enough overflow bits or
1313 does not provide a high dynamic range, the below energy calculation
1314 requires an additional shift operation for each sample.
1315 On the other hand, doing the shift allows using a single-precision
1316 multiplication for the square (at least 16bit x 16bit).
1317 For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1318 is required for the energy accumulation.
1319 Theoretically, the sample-squares can sum up to a value of 76,
1320 requiring 7 overflow bits. However since such situations are *very*
1321 rare, accu can be limited to 64.
1322 In case native saturated arithmetic is not available, overflows
1323 can be prevented by replacing the above #define by
1324 #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1325 which will result in slightly reduced accuracy.
1329 \brief Estimates the mean energy of each filter-bank channel for the
1330 duration of the current envelope
1332 This function is used when interpolFreq is true.
1334 /*static*/ void calcNrgPerSubband(FIXP_DBL
**analysBufferReal
, /*!< Real part of subband samples */
1335 FIXP_DBL
**analysBufferImag
, /*!< Imaginary part of subband samples */
1336 int lowSubband
, /*!< Begin of the SBR frequency range */
1337 int highSubband
, /*!< High end of the SBR frequency range */
1338 int start_pos
, /*!< First QMF-slot of current envelope */
1339 int next_pos
, /*!< Last QMF-slot of current envelope + 1 */
1340 SCHAR frameExp
, /*!< Common exponent for all input samples */
1341 FIXP_DBL
*nrgEst
, /*!< resulting Energy (0..1) */
1342 SCHAR
*nrgEst_e
) /*!< Exponent of resulting Energy */
1350 /* Divide by width of envelope later: */
1351 invWidth
= FX_DBL2FX_SGL(GetInvInt(next_pos
- start_pos
));
1352 /* The common exponent needs to be doubled because all mantissas are squared: */
1353 frameExp
= frameExp
<< 1;
1355 for (k
=lowSubband
; k
<highSubband
; k
++) {
1356 FIXP_DBL bufferReal
[(((1024)/(32))+(6))];
1357 FIXP_DBL bufferImag
[(((1024)/(32))+(6))];
1358 FIXP_DBL maxVal
= FL2FX_DBL(0.0f
);
1360 if (analysBufferImag
!=NULL
)
1362 for (l
=start_pos
;l
<next_pos
;l
++)
1364 bufferImag
[l
] = analysBufferImag
[l
][k
];
1365 maxVal
|= (FIXP_DBL
)((LONG
)(bufferImag
[l
])^((LONG
)bufferImag
[l
]>>(DFRACT_BITS
-1)));
1366 bufferReal
[l
] = analysBufferReal
[l
][k
];
1367 maxVal
|= (FIXP_DBL
)((LONG
)(bufferReal
[l
])^((LONG
)bufferReal
[l
]>>(DFRACT_BITS
-1)));
1372 for (l
=start_pos
;l
<next_pos
;l
++)
1374 bufferReal
[l
] = analysBufferReal
[l
][k
];
1375 maxVal
|= (FIXP_DBL
)((LONG
)(bufferReal
[l
])^((LONG
)bufferReal
[l
]>>(DFRACT_BITS
-1)));
1379 if (maxVal
!=FL2FXCONST_DBL(0.f
)) {
1382 /* If the accu does not provide enough overflow bits, we cannot
1383 shift the samples up to the limit.
1384 Instead, keep up to 3 free bits in each sample, i.e. up to
1385 6 bits after calculation of square.
1386 Please note the comment on saturated arithmetic above!
1388 FIXP_DBL accu
= FL2FXCONST_DBL(0.0f
);
1389 preShift
= CntLeadingZeros(maxVal
)-1;
1390 preShift
-= SHIFT_BEFORE_SQUARE
;
1393 if (analysBufferImag
!=NULL
) {
1394 for (l
=start_pos
; l
<next_pos
; l
++) {
1395 FIXP_DBL temp1
= bufferReal
[l
] << (int)preShift
;
1396 FIXP_DBL temp2
= bufferImag
[l
] << (int)preShift
;
1397 accu
= fPow2AddDiv2(accu
, temp1
);
1398 accu
= fPow2AddDiv2(accu
, temp2
);
1402 for (l
=start_pos
; l
<next_pos
; l
++) {
1403 FIXP_DBL temp
= bufferReal
[l
] << (int)preShift
;
1404 accu
= fPow2AddDiv2(accu
, temp
);
1408 else { /* if negative shift value */
1409 int negpreShift
= -preShift
;
1410 if (analysBufferImag
!=NULL
) {
1411 for (l
=start_pos
; l
<next_pos
; l
++) {
1412 FIXP_DBL temp1
= bufferReal
[l
] >> (int)negpreShift
;
1413 FIXP_DBL temp2
= bufferImag
[l
] >> (int)negpreShift
;
1414 accu
= fPow2AddDiv2(accu
, temp1
);
1415 accu
= fPow2AddDiv2(accu
, temp2
);
1419 for (l
=start_pos
; l
<next_pos
; l
++) {
1420 FIXP_DBL temp
= bufferReal
[l
] >> (int)negpreShift
;
1421 accu
= fPow2AddDiv2(accu
, temp
);
1427 /* Convert double precision to Mantissa/Exponent: */
1428 shift
= fNorm(accu
);
1429 sum
= accu
<< (int)shift
;
1431 /* Divide by width of envelope and apply frame scale: */
1432 *nrgEst
++ = fMult(sum
, invWidth
);
1433 shift
+= 2 * preShift
;
1434 if (analysBufferImag
!=NULL
)
1435 *nrgEst_e
++ = frameExp
- shift
;
1437 *nrgEst_e
++ = frameExp
- shift
+ 1; /* +1 due to missing imag. part */
1441 /* Prevent a zero-mantissa-number from being misinterpreted
1442 due to its exponent. */
1443 *nrgEst
++ = FL2FXCONST_DBL(0.0f
);
1450 \brief Estimates the mean energy of each Scale factor band for the
1451 duration of the current envelope.
1453 This function is used when interpolFreq is false.
1455 /*static*/ void calcNrgPerSfb(FIXP_DBL
**analysBufferReal
, /*!< Real part of subband samples */
1456 FIXP_DBL
**analysBufferImag
, /*!< Imaginary part of subband samples */
1457 int nSfb
, /*!< Number of scale factor bands */
1458 UCHAR
*freqBandTable
, /*!< First Subband for each Sfb */
1459 int start_pos
, /*!< First QMF-slot of current envelope */
1460 int next_pos
, /*!< Last QMF-slot of current envelope + 1 */
1461 SCHAR input_e
, /*!< Common exponent for all input samples */
1462 FIXP_DBL
*nrgEst
, /*!< resulting Energy (0..1) */
1463 SCHAR
*nrgEst_e
) /*!< Exponent of resulting Energy */
1472 FIXP_DBL sumAll
, sumLine
; /* Single precision would be sufficient,
1473 but overflow bits are required for accumulation */
1475 /* Divide by width of envelope later: */
1476 invWidth
= FX_DBL2FX_SGL(GetInvInt(next_pos
- start_pos
));
1477 /* The common exponent needs to be doubled because all mantissas are squared: */
1478 input_e
= input_e
<< 1;
1480 for(j
=0; j
<nSfb
; j
++) {
1481 li
= freqBandTable
[j
];
1482 ui
= freqBandTable
[j
+1];
1484 FIXP_DBL maxVal
= maxSubbandSample( analysBufferReal
,
1491 if (maxVal
!=FL2FXCONST_DBL(0.f
)) {
1493 preShift
= CntLeadingZeros(maxVal
)-1;
1495 /* If the accu does not provide enough overflow bits, we cannot
1496 shift the samples up to the limit.
1497 Instead, keep up to 3 free bits in each sample, i.e. up to
1498 6 bits after calculation of square.
1499 Please note the comment on saturated arithmetic above!
1501 preShift
-= SHIFT_BEFORE_SQUARE
;
1503 sumAll
= FL2FXCONST_DBL(0.0f
);
1506 for (k
=li
; k
<ui
; k
++) {
1508 sumLine
= FL2FXCONST_DBL(0.0f
);
1510 if (analysBufferImag
!=NULL
) {
1512 for (l
=start_pos
; l
<next_pos
; l
++) {
1513 temp
= analysBufferReal
[l
][k
] << (int)preShift
;
1514 sumLine
+= fPow2Div2(temp
);
1515 temp
= analysBufferImag
[l
][k
] << (int)preShift
;
1516 sumLine
+= fPow2Div2(temp
);
1520 for (l
=start_pos
; l
<next_pos
; l
++) {
1521 temp
= analysBufferReal
[l
][k
] >> -(int)preShift
;
1522 sumLine
+= fPow2Div2(temp
);
1523 temp
= analysBufferImag
[l
][k
] >> -(int)preShift
;
1524 sumLine
+= fPow2Div2(temp
);
1530 for (l
=start_pos
; l
<next_pos
; l
++) {
1531 temp
= analysBufferReal
[l
][k
] << (int)preShift
;
1532 sumLine
+= fPow2Div2(temp
);
1535 for (l
=start_pos
; l
<next_pos
; l
++) {
1536 temp
= analysBufferReal
[l
][k
] >> -(int)preShift
;
1537 sumLine
+= fPow2Div2(temp
);
1542 /* The number of QMF-channels per SBR bands may be up to 15.
1543 Shift right to avoid overflows in sum over all channels. */
1544 sumLine
= sumLine
>> (4-1);
1548 /* Convert double precision to Mantissa/Exponent: */
1549 shift
= fNorm(sumAll
);
1550 sum
= sumAll
<< (int)shift
;
1552 /* Divide by width of envelope: */
1553 sum
= fMult(sum
,invWidth
);
1555 /* Divide by width of Sfb: */
1556 sum
= fMult(sum
, FX_DBL2FX_SGL(GetInvInt(ui
-li
)));
1558 /* Set all Subband energies in the Sfb to the average energy: */
1559 if (analysBufferImag
!=NULL
)
1560 sum_e
= input_e
+ 4 - shift
; /* -4 to compensate right-shift */
1562 sum_e
= input_e
+ 4 + 1 - shift
; /* -4 to compensate right-shift; +1 due to missing imag. part */
1564 sum_e
-= 2 * preShift
;
1568 /* Prevent a zero-mantissa-number from being misinterpreted
1569 due to its exponent. */
1570 sum
= FL2FXCONST_DBL(0.0f
);
1574 for (k
=li
; k
<ui
; k
++)
1577 *nrgEst_e
++ = sum_e
;
1584 \brief Calculate gain, noise, and additional sine level for one subband.
1586 The resulting energy gain is given by mantissa and exponent.
1588 /*static*/ void calcSubbandGain(FIXP_DBL nrgRef
, /*!< Reference Energy according to envelope data */
1589 SCHAR nrgRef_e
, /*!< Reference Energy according to envelope data (exponent) */
1590 ENV_CALC_NRGS
* nrgs
,
1592 FIXP_DBL tmpNoise
, /*!< Relative noise level */
1593 SCHAR tmpNoise_e
, /*!< Relative noise level (exponent) */
1594 UCHAR sinePresentFlag
, /*!< Indicates if sine is present on band */
1595 UCHAR sineMapped
, /*!< Indicates if sine must be added */
1596 int noNoiseFlag
) /*!< Flag to suppress noise addition */
1598 FIXP_DBL nrgEst
= nrgs
->nrgEst
[i
]; /*!< Energy in transposed signal */
1599 SCHAR nrgEst_e
= nrgs
->nrgEst_e
[i
]; /*!< Energy in transposed signal (exponent) */
1600 FIXP_DBL
*ptrNrgGain
= &nrgs
->nrgGain
[i
]; /*!< Resulting energy gain */
1601 SCHAR
*ptrNrgGain_e
= &nrgs
->nrgGain_e
[i
]; /*!< Resulting energy gain (exponent) */
1602 FIXP_DBL
*ptrNoiseLevel
= &nrgs
->noiseLevel
[i
]; /*!< Resulting absolute noise energy */
1603 SCHAR
*ptrNoiseLevel_e
= &nrgs
->noiseLevel_e
[i
]; /*!< Resulting absolute noise energy (exponent) */
1604 FIXP_DBL
*ptrNrgSine
= &nrgs
->nrgSine
[i
]; /*!< Additional sine energy */
1605 SCHAR
*ptrNrgSine_e
= &nrgs
->nrgSine_e
[i
]; /*!< Additional sine energy (exponent) */
1608 SCHAR a_e
, b_e
, c_e
;
1611 This addition of 1 prevents divisions by zero in the reference code.
1612 For very small energies in nrgEst, it prevents the gains from becoming
1613 very high which could cause some trouble due to the smoothing.
1615 b_e
= (int)(nrgEst_e
- 1);
1617 nrgEst
= (FL2FXCONST_DBL(0.5f
) >> (INT
)fixMin(b_e
+1,DFRACT_BITS
-1)) + (nrgEst
>> 1);
1618 nrgEst_e
+= 1; /* shift by 1 bit to avoid overflow */
1621 nrgEst
= (nrgEst
>> (INT
)(fixMin(-b_e
+1,DFRACT_BITS
-1))) + (FL2FXCONST_DBL(0.5f
) >> 1);
1622 nrgEst_e
= 2; /* shift by 1 bit to avoid overflow */
1625 /* A = NrgRef * TmpNoise */
1626 a
= fMult(nrgRef
,tmpNoise
);
1627 a_e
= nrgRef_e
+ tmpNoise_e
;
1629 /* B = 1 + TmpNoise */
1630 b_e
= (int)(tmpNoise_e
- 1);
1632 b
= (FL2FXCONST_DBL(0.5f
) >> (INT
)fixMin(b_e
+1,DFRACT_BITS
-1)) + (tmpNoise
>> 1);
1633 b_e
= tmpNoise_e
+ 1; /* shift by 1 bit to avoid overflow */
1635 b
= (tmpNoise
>> (INT
)(fixMin(-b_e
+1,DFRACT_BITS
-1))) + (FL2FXCONST_DBL(0.5f
) >> 1);
1636 b_e
= 2; /* shift by 1 bit to avoid overflow */
1639 /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
1640 FDK_divide_MantExp( a
, a_e
,
1642 ptrNoiseLevel
, ptrNoiseLevel_e
);
1644 if (sinePresentFlag
) {
1646 /* C = (1 + TmpNoise) * NrgEst */
1647 c
= fMult(b
,nrgEst
);
1648 c_e
= b_e
+ nrgEst_e
;
1650 /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
1651 FDK_divide_MantExp( a
, a_e
,
1653 ptrNrgGain
, ptrNrgGain_e
);
1657 /* sineLevel = nrgRef/ (1 + TmpNoise) */
1658 FDK_divide_MantExp( nrgRef
, nrgRef_e
,
1660 ptrNrgSine
, ptrNrgSine_e
);
1670 /* B = NrgEst * (1 + TmpNoise) */
1671 b
= fMult(b
,nrgEst
);
1672 b_e
= b_e
+ nrgEst_e
;
1676 /* gain = nrgRef / B */
1677 FDK_divide_MantExp( nrgRef
, nrgRef_e
,
1679 ptrNrgGain
, ptrNrgGain_e
);
1685 \brief Calculate "average gain" for the specified subband range.
1687 This is rather a gain of the average magnitude than the average
1689 The result is used as a relative limit for all gains within the
1690 current "limiter band" (a certain frequency range).
1692 /*static*/ void calcAvgGain(ENV_CALC_NRGS
* nrgs
,
1693 int lowSubband
, /*!< Begin of the limiter band */
1694 int highSubband
, /*!< High end of the limiter band */
1695 FIXP_DBL
*ptrSumRef
,
1697 FIXP_DBL
*ptrAvgGain
, /*!< Resulting overall gain (mantissa) */
1698 SCHAR
*ptrAvgGain_e
) /*!< Resulting overall gain (exponent) */
1700 FIXP_DBL
*nrgRef
= nrgs
->nrgRef
; /*!< Reference Energy according to envelope data */
1701 SCHAR
*nrgRef_e
= nrgs
->nrgRef_e
; /*!< Reference Energy according to envelope data (exponent) */
1702 FIXP_DBL
*nrgEst
= nrgs
->nrgEst
; /*!< Energy in transposed signal */
1703 SCHAR
*nrgEst_e
= nrgs
->nrgEst_e
; /*!< Energy in transposed signal (exponent) */
1705 FIXP_DBL sumRef
= 1;
1706 FIXP_DBL sumEst
= 1;
1707 SCHAR sumRef_e
= -FRACT_BITS
;
1708 SCHAR sumEst_e
= -FRACT_BITS
;
1711 for (k
=lowSubband
; k
<highSubband
; k
++){
1712 /* Add nrgRef[k] to sumRef: */
1713 FDK_add_MantExp( sumRef
, sumRef_e
,
1714 nrgRef
[k
], nrgRef_e
[k
],
1715 &sumRef
, &sumRef_e
);
1717 /* Add nrgEst[k] to sumEst: */
1718 FDK_add_MantExp( sumEst
, sumEst_e
,
1719 nrgEst
[k
], nrgEst_e
[k
],
1720 &sumEst
, &sumEst_e
);
1723 FDK_divide_MantExp(sumRef
, sumRef_e
,
1725 ptrAvgGain
, ptrAvgGain_e
);
1727 *ptrSumRef
= sumRef
;
1728 *ptrSumRef_e
= sumRef_e
;
1733 \brief Amplify one timeslot of the signal with the calculated gains
1734 and add the noisefloor.
1737 /*static*/ void adjustTimeSlotLC(FIXP_DBL
*ptrReal
, /*!< Subband samples to be adjusted, real part */
1738 ENV_CALC_NRGS
* nrgs
,
1739 UCHAR
*ptrHarmIndex
, /*!< Harmonic index */
1740 int lowSubband
, /*!< Lowest QMF-channel in the currently used SBR range. */
1741 int noSubbands
, /*!< Number of QMF subbands */
1742 int scale_change
, /*!< Number of bits to shift adjusted samples */
1743 int noNoiseFlag
, /*!< Flag to suppress noise addition */
1744 int *ptrPhaseIndex
, /*!< Start index to random number array */
1745 int fCldfb
) /*!< CLDFB 80 flag */
1747 FIXP_DBL
*pGain
= nrgs
->nrgGain
; /*!< Gains of current envelope */
1748 FIXP_DBL
*pNoiseLevel
= nrgs
->noiseLevel
; /*!< Noise levels of current envelope */
1749 FIXP_DBL
*pSineLevel
= nrgs
->nrgSine
; /*!< Sine levels */
1752 int index
= *ptrPhaseIndex
;
1753 UCHAR harmIndex
= *ptrHarmIndex
;
1754 UCHAR freqInvFlag
= (lowSubband
& 1);
1755 FIXP_DBL signalReal
, sineLevel
, sineLevelNext
, sineLevelPrev
;
1759 #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f))
1760 #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f))
1763 First pass for k=0 pulled out of the loop:
1766 index
= (index
+ 1) & (SBR_NF_NO_RANDOM_VAL
- 1);
1769 The next multiplication constitutes the actual envelope adjustment
1770 of the signal and should be carried out with full accuracy
1771 (supplying #FRACT_BITS valid bits).
1773 signalReal
= fMultDiv2(*ptrReal
,*pGain
++) << ((int)scale_change
);
1774 sineLevel
= *pSineLevel
++;
1775 sineLevelNext
= (noSubbands
> 1) ? pSineLevel
[0] : FL2FXCONST_DBL(0.0f
);
1777 if (sineLevel
!=FL2FXCONST_DBL(0.0f
)) tone_count
++;
1779 else if (!noNoiseFlag
)
1780 /* Add noisefloor to the amplified signal */
1781 signalReal
+= (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], pNoiseLevel
[0])<<4);
1785 if (!(harmIndex
&0x1)) {
1787 signalReal
+= (harmIndex
&0x2) ? -sineLevel
: sineLevel
;
1788 *ptrReal
++ = signalReal
;
1791 /* harmIndex 1,3 in combination with freqInvFlag */
1792 int shift
= (int) (scale_change
+1);
1793 shift
= (shift
>=0) ? fixMin(DFRACT_BITS
-1,shift
) : fixMax(-(DFRACT_BITS
-1),shift
);
1795 FIXP_DBL tmp1
= scaleValue( fMultDiv2(C1_CLDFB
, sineLevel
), -shift
);
1797 FIXP_DBL tmp2
= fMultDiv2(C1_CLDFB
, sineLevelNext
);
1800 /* save switch and compare operations and reduce to XOR statement */
1801 if ( ((harmIndex
>>1)&0x1)^freqInvFlag
) {
1802 *(ptrReal
-1) += tmp1
;
1805 *(ptrReal
-1) -= tmp1
;
1808 *ptrReal
++ = signalReal
;
1809 freqInvFlag
= !freqInvFlag
;
1814 if (!(harmIndex
&0x1)) {
1816 signalReal
+= (harmIndex
&0x2) ? -sineLevel
: sineLevel
;
1817 *ptrReal
++ = signalReal
;
1820 /* harmIndex 1,3 in combination with freqInvFlag */
1821 int shift
= (int) (scale_change
+1);
1822 shift
= (shift
>=0) ? fixMin(DFRACT_BITS
-1,shift
) : fixMax(-(DFRACT_BITS
-1),shift
);
1824 FIXP_DBL tmp1
= (shift
>=0) ? ( fMultDiv2(C1
, sineLevel
) >> shift
)
1825 : ( fMultDiv2(C1
, sineLevel
) << (-shift
) );
1826 FIXP_DBL tmp2
= fMultDiv2(C1
, sineLevelNext
);
1829 /* save switch and compare operations and reduce to XOR statement */
1830 if ( ((harmIndex
>>1)&0x1)^freqInvFlag
) {
1831 *(ptrReal
-1) += tmp1
;
1834 *(ptrReal
-1) -= tmp1
;
1837 *ptrReal
++ = signalReal
;
1838 freqInvFlag
= !freqInvFlag
;
1844 if ( noSubbands
> 2 ) {
1845 if (!(harmIndex
&0x1)) {
1852 for (k
=noSubbands
-2; k
!=0; k
--) {
1853 FIXP_DBL sinelevel
= *pSineLevel
++;
1855 if (((signalReal
= (sineSign
? -sinelevel
: sinelevel
)) == FL2FXCONST_DBL(0.0f
)) && !noNoiseFlag
)
1857 /* Add noisefloor to the amplified signal */
1858 index
&= (SBR_NF_NO_RANDOM_VAL
- 1);
1859 signalReal
+= (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], pNoiseLevel
[0])<<4);
1862 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1863 signalReal
+= fMultDiv2(*ptrReal
,*pGain
++) << ((int)scale_change
);
1866 *ptrReal
++ = signalReal
;
1870 /* harmIndex 1,3 in combination with freqInvFlag */
1871 if (harmIndex
==1) freqInvFlag
= !freqInvFlag
;
1873 for (k
=noSubbands
-2; k
!=0; k
--) {
1875 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1876 signalReal
= fMultDiv2(*ptrReal
,*pGain
++) << ((int)scale_change
);
1878 if (*pSineLevel
++!=FL2FXCONST_DBL(0.0f
)) tone_count
++;
1879 else if (!noNoiseFlag
) {
1880 /* Add noisefloor to the amplified signal */
1881 index
&= (SBR_NF_NO_RANDOM_VAL
- 1);
1882 signalReal
+= (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], pNoiseLevel
[0])<<4);
1887 if (tone_count
<= 16) {
1888 FIXP_DBL addSine
= fMultDiv2((pSineLevel
[-2] - pSineLevel
[0]), C1
);
1889 signalReal
+= (freqInvFlag
) ? (-addSine
) : (addSine
);
1892 *ptrReal
++ = signalReal
;
1893 freqInvFlag
= !freqInvFlag
;
1898 if (noSubbands
> -1) {
1900 /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1901 signalReal
= fMultDiv2(*ptrReal
,*pGain
) << ((int)scale_change
);
1902 sineLevelPrev
= fMultDiv2(pSineLevel
[-1],FL2FX_SGL(0.0163f
));
1903 sineLevel
= pSineLevel
[0];
1905 if (pSineLevel
[0]!=FL2FXCONST_DBL(0.0f
)) tone_count
++;
1906 else if (!noNoiseFlag
) {
1907 /* Add noisefloor to the amplified signal */
1908 index
&= (SBR_NF_NO_RANDOM_VAL
- 1);
1909 signalReal
= signalReal
+ (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], pNoiseLevel
[0])<<4);
1912 if (!(harmIndex
&0x1)) {
1914 *ptrReal
= signalReal
+ ( (sineSign
) ? -sineLevel
: sineLevel
);
1917 /* harmIndex 1,3 in combination with freqInvFlag */
1918 if(tone_count
<= 16){
1920 *ptrReal
++ = signalReal
- sineLevelPrev
;
1921 if (noSubbands
+ lowSubband
< 63)
1922 *ptrReal
= *ptrReal
+ fMultDiv2(C1
, sineLevel
);
1925 *ptrReal
++ = signalReal
+ sineLevelPrev
;
1926 if (noSubbands
+ lowSubband
< 63)
1927 *ptrReal
= *ptrReal
- fMultDiv2(C1
, sineLevel
);
1930 else *ptrReal
= signalReal
;
1933 *ptrHarmIndex
= (harmIndex
+ 1) & 3;
1934 *ptrPhaseIndex
= index
& (SBR_NF_NO_RANDOM_VAL
- 1);
1936 void adjustTimeSlotHQ(FIXP_DBL
*RESTRICT ptrReal
, /*!< Subband samples to be adjusted, real part */
1937 FIXP_DBL
*RESTRICT ptrImag
, /*!< Subband samples to be adjusted, imag part */
1938 HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env
,
1939 ENV_CALC_NRGS
* nrgs
,
1940 int lowSubband
, /*!< Lowest QMF-channel in the currently used SBR range. */
1941 int noSubbands
, /*!< Number of QMF subbands */
1942 int scale_change
, /*!< Number of bits to shift adjusted samples */
1943 FIXP_SGL smooth_ratio
, /*!< Impact of last envelope */
1944 int noNoiseFlag
, /*!< Start index to random number array */
1945 int filtBufferNoiseShift
) /*!< Shift factor of filtBufferNoise */
1948 FIXP_DBL
*RESTRICT gain
= nrgs
->nrgGain
; /*!< Gains of current envelope */
1949 FIXP_DBL
*RESTRICT noiseLevel
= nrgs
->noiseLevel
; /*!< Noise levels of current envelope */
1950 FIXP_DBL
*RESTRICT pSineLevel
= nrgs
->nrgSine
; /*!< Sine levels */
1952 FIXP_DBL
*RESTRICT filtBuffer
= h_sbr_cal_env
->filtBuffer
; /*!< Gains of last envelope */
1953 FIXP_DBL
*RESTRICT filtBufferNoise
= h_sbr_cal_env
->filtBufferNoise
; /*!< Noise levels of last envelope */
1954 UCHAR
*RESTRICT ptrHarmIndex
=&h_sbr_cal_env
->harmIndex
; /*!< Harmonic index */
1955 int *RESTRICT ptrPhaseIndex
=&h_sbr_cal_env
->phaseIndex
; /*!< Start index to random number array */
1958 FIXP_DBL signalReal
, signalImag
;
1959 FIXP_DBL noiseReal
, noiseImag
;
1960 FIXP_DBL smoothedGain
, smoothedNoise
;
1961 FIXP_SGL direct_ratio
= /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL
)MAXVAL_SGL
- smooth_ratio
;
1962 int index
= *ptrPhaseIndex
;
1963 UCHAR harmIndex
= *ptrHarmIndex
;
1964 register int freqInvFlag
= (lowSubband
& 1);
1968 *ptrPhaseIndex
= (index
+noSubbands
) & (SBR_NF_NO_RANDOM_VAL
- 1);
1969 *ptrHarmIndex
= (harmIndex
+ 1) & 3;
1972 Possible optimization:
1973 smooth_ratio and harmIndex stay constant during the loop.
1974 It might be faster to include a separate loop in each path.
1976 the check for smooth_ratio is now outside the loop and the workload
1977 of the whole function decreased by about 20 %
1980 filtBufferNoiseShift
+= 1; /* due to later use of fMultDiv2 instead of fMult */
1981 if (filtBufferNoiseShift
<0)
1982 shift
= fixMin(DFRACT_BITS
-1,-filtBufferNoiseShift
);
1984 shift
= fixMin(DFRACT_BITS
-1, filtBufferNoiseShift
);
1986 if (smooth_ratio
> FL2FXCONST_SGL(0.0f
)) {
1988 for (k
=0; k
<noSubbands
; k
++) {
1990 Smoothing: The old envelope has been bufferd and a certain ratio
1991 of the old gains and noise levels is used.
1994 smoothedGain
= fMult(smooth_ratio
,filtBuffer
[k
]) +
1995 fMult(direct_ratio
,gain
[k
]);
1997 if (filtBufferNoiseShift
<0) {
1998 smoothedNoise
= (fMultDiv2(smooth_ratio
,filtBufferNoise
[k
])>>shift
) +
1999 fMult(direct_ratio
,noiseLevel
[k
]);
2002 smoothedNoise
= (fMultDiv2(smooth_ratio
,filtBufferNoise
[k
])<<shift
) +
2003 fMult(direct_ratio
,noiseLevel
[k
]);
2007 The next 2 multiplications constitute the actual envelope adjustment
2008 of the signal and should be carried out with full accuracy
2009 (supplying #DFRACT_BITS valid bits).
2011 signalReal
= fMultDiv2(*ptrReal
,smoothedGain
)<<((int)scale_change
);
2012 signalImag
= fMultDiv2(*ptrImag
,smoothedGain
)<<((int)scale_change
);
2016 if (pSineLevel
[k
] != FL2FXCONST_DBL(0.0f
)) {
2017 sineLevel
= pSineLevel
[k
];
2021 *ptrReal
++ = (signalReal
+ sineLevel
);
2022 *ptrImag
++ = (signalImag
);
2025 *ptrReal
++ = (signalReal
- sineLevel
);
2026 *ptrImag
++ = (signalImag
);
2029 *ptrReal
++ = (signalReal
);
2031 *ptrImag
++ = (signalImag
- sineLevel
);
2033 *ptrImag
++ = (signalImag
+ sineLevel
);
2036 *ptrReal
++ = signalReal
;
2038 *ptrImag
++ = (signalImag
+ sineLevel
);
2040 *ptrImag
++ = (signalImag
- sineLevel
);
2046 /* Just the amplified signal is saved */
2047 *ptrReal
++ = (signalReal
);
2048 *ptrImag
++ = (signalImag
);
2051 /* Add noisefloor to the amplified signal */
2052 index
&= (SBR_NF_NO_RANDOM_VAL
- 1);
2053 noiseReal
= fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], smoothedNoise
)<<4;
2054 noiseImag
= fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][1], smoothedNoise
)<<4;
2055 *ptrReal
++ = (signalReal
+ noiseReal
);
2056 *ptrImag
++ = (signalImag
+ noiseImag
);
2065 for (k
=0; k
<noSubbands
; k
++)
2067 smoothedGain
= gain
[k
];
2068 signalReal
= fMultDiv2(*ptrReal
, smoothedGain
) << scale_change
;
2069 signalImag
= fMultDiv2(*ptrImag
, smoothedGain
) << scale_change
;
2073 if ((sineLevel
= pSineLevel
[k
]) != FL2FXCONST_DBL(0.0f
))
2078 signalReal
+= sineLevel
;
2082 signalImag
-= sineLevel
;
2084 signalImag
+= sineLevel
;
2087 signalReal
-= sineLevel
;
2091 signalImag
+= sineLevel
;
2093 signalImag
-= sineLevel
;
2099 if (noNoiseFlag
== 0)
2101 /* Add noisefloor to the amplified signal */
2102 smoothedNoise
= noiseLevel
[k
];
2103 index
&= (SBR_NF_NO_RANDOM_VAL
- 1);
2104 noiseReal
= fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][0], smoothedNoise
);
2105 noiseImag
= fMultDiv2(FDK_sbrDecoder_sbr_randomPhase
[index
][1], smoothedNoise
);
2106 signalReal
+= noiseReal
<<4;
2107 signalImag
+= noiseImag
<<4;
2110 *ptrReal
++ = signalReal
;
2111 *ptrImag
++ = signalImag
;
2120 \brief Reset limiter bands.
2122 Build frequency band table for the gain limiter dependent on
2123 the previously generated transposer patch areas.
2125 \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error
2128 ResetLimiterBands ( UCHAR
*limiterBandTable
, /*!< Resulting band borders in QMF channels */
2129 UCHAR
*noLimiterBands
, /*!< Resulting number of limiter band */
2130 UCHAR
*freqBandTable
, /*!< Table with possible band borders */
2131 int noFreqBands
, /*!< Number of bands in freqBandTable */
2132 const PATCH_PARAM
*patchParam
, /*!< Transposer patch parameters */
2133 int noPatches
, /*!< Number of transposer patches */
2134 int limiterBands
) /*!< Selected 'band density' from bitstream */
2136 int i
, k
, isPatchBorder
[2], loLimIndex
, hiLimIndex
, tempNoLim
, nBands
;
2137 UCHAR workLimiterBandTable
[MAX_FREQ_COEFFS
/ 2 + MAX_NUM_PATCHES
+ 1];
2138 int patchBorders
[MAX_NUM_PATCHES
+ 1];
2142 int lowSubband
= freqBandTable
[0];
2143 int highSubband
= freqBandTable
[noFreqBands
];
2145 /* 1 limiter band. */
2146 if(limiterBands
== 0) {
2147 limiterBandTable
[0] = 0;
2148 limiterBandTable
[1] = highSubband
- lowSubband
;
2151 for (i
= 0; i
< noPatches
; i
++) {
2152 patchBorders
[i
] = patchParam
[i
].guardStartBand
- lowSubband
;
2154 patchBorders
[i
] = highSubband
- lowSubband
;
2156 /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
2157 for (k
= 0; k
<= noFreqBands
; k
++) {
2158 workLimiterBandTable
[k
] = freqBandTable
[k
] - lowSubband
;
2160 for (k
= 1; k
< noPatches
; k
++) {
2161 workLimiterBandTable
[noFreqBands
+ k
] = patchBorders
[k
];
2164 tempNoLim
= nBands
= noFreqBands
+ noPatches
- 1;
2165 shellsort(workLimiterBandTable
, tempNoLim
+ 1);
2171 while (hiLimIndex
<= tempNoLim
) {
2172 k2
= workLimiterBandTable
[hiLimIndex
] + lowSubband
;
2173 kx
= workLimiterBandTable
[loLimIndex
] + lowSubband
;
2175 temp
= FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx
,k2
)); /* Number of octaves */
2176 temp
= fMult(temp
, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4
[limiterBands
]);
2178 if (temp
< FL2FXCONST_DBL (0.49f
)>>5) {
2179 if (workLimiterBandTable
[hiLimIndex
] == workLimiterBandTable
[loLimIndex
]) {
2180 workLimiterBandTable
[hiLimIndex
] = highSubband
;
2185 isPatchBorder
[0] = isPatchBorder
[1] = 0;
2186 for (k
= 0; k
<= noPatches
; k
++) {
2187 if (workLimiterBandTable
[hiLimIndex
] == patchBorders
[k
]) {
2188 isPatchBorder
[1] = 1;
2192 if (!isPatchBorder
[1]) {
2193 workLimiterBandTable
[hiLimIndex
] = highSubband
;
2198 for (k
= 0; k
<= noPatches
; k
++) {
2199 if (workLimiterBandTable
[loLimIndex
] == patchBorders
[k
]) {
2200 isPatchBorder
[0] = 1;
2204 if (!isPatchBorder
[0]) {
2205 workLimiterBandTable
[loLimIndex
] = highSubband
;
2209 loLimIndex
= hiLimIndex
;
2213 shellsort(workLimiterBandTable
, tempNoLim
+ 1);
2215 /* Test if algorithm exceeded maximum allowed limiterbands */
2216 if( nBands
> MAX_NUM_LIMITERS
|| nBands
<= 0) {
2217 return SBRDEC_UNSUPPORTED_CONFIG
;
2220 /* Copy limiterbands from working buffer into final destination */
2221 for (k
= 0; k
<= nBands
; k
++) {
2222 limiterBandTable
[k
] = workLimiterBandTable
[k
];
2225 *noLimiterBands
= nBands
;