/src/aac/libSBRdec/src/env_calc.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 27.0M | #define MAX_SFB_NRG_HEADROOM (1) |
155 | 26.2M | #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 | | */ |
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 | 404k | { |
259 | 404k | int i; |
260 | 404k | int bitcount = 31; |
261 | 404k | ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0}; |
262 | 404k | 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 | 404k | FDKmemset(sineMapped, 32, |
281 | 404k | MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */ |
282 | 404k | FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG)); |
283 | 4.55M | for (i = 0; i < nSfb; i++) { |
284 | 4.14M | ULONG maskSfb = |
285 | 4.14M | 1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */ |
286 | | |
287 | 4.14M | if (*curFlags & maskSfb) { /* There is a sine in this band */ |
288 | 89.3k | const int lsb = freqBandTable[0]; /* start of sbr range */ |
289 | | /* qmf band to which sine should be added */ |
290 | 89.3k | const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1; |
291 | 89.3k | const int qmfBandDiv32 = qmfBand >> 5; |
292 | 89.3k | const int maskQmfBand = |
293 | 89.3k | 1 << (qmfBand & |
294 | 89.3k | 31); /* mask to extract harmonic flag from prevFlags */ |
295 | | |
296 | | /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */ |
297 | 89.3k | 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 | 89.3k | sineMapped[qmfBand - lsb] = |
305 | 89.3k | (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv; |
306 | 89.3k | if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) { |
307 | 85.9k | harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand; |
308 | 85.9k | } |
309 | 89.3k | } |
310 | | |
311 | 4.14M | if (bitcount-- == 0) { |
312 | 8.57k | bitcount = 31; |
313 | 8.57k | curFlags++; |
314 | 8.57k | } |
315 | 4.14M | } |
316 | 404k | FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands, |
317 | 404k | sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE); |
318 | 404k | } |
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 | | */ |
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 | 115k | { |
344 | | /* Reset the output vector first */ |
345 | 115k | FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */ |
346 | | |
347 | 115k | if (trailingSbrFrame) { |
348 | | /* restore sineMapped[] of previous frame */ |
349 | 84.0k | int i; |
350 | 84.0k | const int lsb = freqBandTable[0]; |
351 | 84.0k | const int usb = freqBandTable[nSfb]; |
352 | 1.78M | for (i = lsb; i < usb; i++) { |
353 | 1.69M | const int qmfBandDiv32 = i >> 5; |
354 | 1.69M | const int maskQmfBand = |
355 | 1.69M | 1 << (i & 31); /* mask to extract harmonic flag from prevFlags */ |
356 | | |
357 | | /* Two cases need to be distinguished ... */ |
358 | 1.69M | if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) { |
359 | | /* the sine mapping already started last PVC frame -> seamlessly |
360 | | * continue */ |
361 | 402 | sineMapped[i - lsb] = 0; |
362 | 1.69M | } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) { |
363 | | /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts |
364 | | * in this frame */ |
365 | 542 | sineMapped[i - lsb] = |
366 | 542 | *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots |
367 | | ahead of last frame now */ |
368 | 542 | } |
369 | 1.69M | } |
370 | 84.0k | } |
371 | 115k | *sinusoidalPosPrev = sinusoidalPos; |
372 | 115k | } |
373 | | |
374 | | /*! |
375 | | \brief Reduce gain-adjustment induced aliasing for real valued filterbank. |
376 | | */ |
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 | 97.1k | { |
385 | 97.1k | FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */ |
386 | 97.1k | SCHAR *nrgGain_e = |
387 | 97.1k | nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */ |
388 | 97.1k | FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */ |
389 | 97.1k | SCHAR *nrgEst_e = |
390 | 97.1k | nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */ |
391 | 97.1k | int grouping = 0, index = 0, noGroups, k; |
392 | 97.1k | int groupVector[MAX_FREQ_COEFFS]; |
393 | | |
394 | | /* Calculate grouping*/ |
395 | 1.52M | for (k = 0; k < noSubbands - 1; k++) { |
396 | 1.42M | if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) { |
397 | 62.1k | if (grouping == 0) { |
398 | 39.9k | groupVector[index++] = k; |
399 | 39.9k | grouping = 1; |
400 | 39.9k | } else { |
401 | 22.1k | if (groupVector[index - 1] + 3 == k) { |
402 | 0 | groupVector[index++] = k + 1; |
403 | 0 | grouping = 0; |
404 | 0 | } |
405 | 22.1k | } |
406 | 1.36M | } else { |
407 | 1.36M | if (grouping) { |
408 | 36.4k | if (useAliasReduction[k]) |
409 | 36.1k | groupVector[index++] = k + 1; |
410 | 280 | else |
411 | 280 | groupVector[index++] = k; |
412 | 36.4k | grouping = 0; |
413 | 36.4k | } |
414 | 1.36M | } |
415 | 1.42M | } |
416 | | |
417 | 97.1k | if (grouping) { |
418 | 3.59k | groupVector[index++] = noSubbands; |
419 | 3.59k | } |
420 | 97.1k | noGroups = index >> 1; |
421 | | |
422 | | /*Calculate new gain*/ |
423 | 137k | for (int group = 0; group < noGroups; group++) { |
424 | 39.9k | FIXP_DBL nrgOrig = FL2FXCONST_DBL( |
425 | 39.9k | 0.0f); /* Original signal energy in current group of bands */ |
426 | 39.9k | SCHAR nrgOrig_e = 0; |
427 | 39.9k | FIXP_DBL nrgAmp = FL2FXCONST_DBL( |
428 | 39.9k | 0.0f); /* Amplified signal energy in group (using current gains) */ |
429 | 39.9k | SCHAR nrgAmp_e = 0; |
430 | 39.9k | FIXP_DBL nrgMod = FL2FXCONST_DBL( |
431 | 39.9k | 0.0f); /* Signal energy in group when applying modified gains */ |
432 | 39.9k | SCHAR nrgMod_e = 0; |
433 | 39.9k | FIXP_DBL groupGain; /* Total energy gain in group */ |
434 | 39.9k | SCHAR groupGain_e; |
435 | 39.9k | FIXP_DBL compensation; /* Compensation factor for the energy change when |
436 | | applying modified gains */ |
437 | 39.9k | SCHAR compensation_e; |
438 | | |
439 | 39.9k | int startGroup = groupVector[2 * group]; |
440 | 39.9k | int stopGroup = groupVector[2 * group + 1]; |
441 | | |
442 | | /* Calculate total energy in group before and after amplification with |
443 | | * current gains: */ |
444 | 141k | for (k = startGroup; k < stopGroup; k++) { |
445 | | /* Get original band energy */ |
446 | 101k | FIXP_DBL tmp = nrgEst[k]; |
447 | 101k | SCHAR tmp_e = nrgEst_e[k]; |
448 | | |
449 | 101k | FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e); |
450 | | |
451 | | /* Multiply band energy with current gain */ |
452 | 101k | tmp = fMult(tmp, nrgGain[k]); |
453 | 101k | tmp_e = tmp_e + nrgGain_e[k]; |
454 | | |
455 | 101k | FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e); |
456 | 101k | } |
457 | | |
458 | | /* Calculate total energy gain in group */ |
459 | 39.9k | FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain, |
460 | 39.9k | &groupGain_e); |
461 | | |
462 | 141k | for (k = startGroup; k < stopGroup; k++) { |
463 | 101k | FIXP_DBL tmp; |
464 | 101k | SCHAR tmp_e; |
465 | | |
466 | 101k | FIXP_DBL alpha = degreeAlias[k]; |
467 | 101k | if (k < noSubbands - 1) { |
468 | 98.2k | if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1]; |
469 | 98.2k | } |
470 | | |
471 | | /* Modify gain depending on the degree of aliasing */ |
472 | 101k | FDK_add_MantExp( |
473 | 101k | fMult(alpha, groupGain), groupGain_e, |
474 | 101k | fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha, |
475 | 101k | nrgGain[k]), |
476 | 101k | nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]); |
477 | | |
478 | | /* Apply modified gain to original energy */ |
479 | 101k | tmp = fMult(nrgGain[k], nrgEst[k]); |
480 | 101k | tmp_e = nrgGain_e[k] + nrgEst_e[k]; |
481 | | |
482 | | /* Accumulate energy with modified gains applied */ |
483 | 101k | FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e); |
484 | 101k | } |
485 | | |
486 | | /* Calculate compensation factor to retain the energy of the amplified |
487 | | * signal */ |
488 | 39.9k | FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation, |
489 | 39.9k | &compensation_e); |
490 | | |
491 | | /* Apply compensation factor to all gains of the group */ |
492 | 141k | for (k = startGroup; k < stopGroup; k++) { |
493 | 101k | nrgGain[k] = fMult(nrgGain[k], compensation); |
494 | 101k | nrgGain_e[k] = nrgGain_e[k] + compensation_e; |
495 | 101k | } |
496 | 39.9k | } |
497 | 97.1k | } |
498 | | |
499 | 22.4M | #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 | | |
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 | 40.8k | const UCHAR gamma_idx) { |
515 | 40.8k | int highSubband = lowSubband + nbSubband; |
516 | 40.8k | FIXP_DBL *subsample_power_high, *subsample_power_low; |
517 | 40.8k | SCHAR *subsample_power_high_sf, *subsample_power_low_sf; |
518 | 40.8k | FIXP_DBL total_power_high = (FIXP_DBL)0; |
519 | 40.8k | FIXP_DBL total_power_low = (FIXP_DBL)0; |
520 | 40.8k | FIXP_DBL *gain; |
521 | 40.8k | int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))]; |
522 | | |
523 | | /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */ |
524 | 40.8k | int gamma_sf = |
525 | 40.8k | (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */ |
526 | | |
527 | 40.8k | int nbSubsample = stopPos - startPos; |
528 | 40.8k | int i, j; |
529 | | |
530 | 40.8k | C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1); |
531 | 40.8k | subsample_power_high = pTmp->subsample_power_high; |
532 | 40.8k | subsample_power_low = pTmp->subsample_power_low; |
533 | 40.8k | subsample_power_high_sf = pTmp->subsample_power_high_sf; |
534 | 40.8k | subsample_power_low_sf = pTmp->subsample_power_low_sf; |
535 | 40.8k | gain = pTmp->gain; |
536 | | |
537 | 40.8k | if (gamma_idx > 0) { |
538 | 19.0k | int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample); |
539 | 19.0k | int total_power_low_sf = 1 - DFRACT_BITS; |
540 | 19.0k | int total_power_high_sf = 1 - DFRACT_BITS; |
541 | | |
542 | 830k | for (i = 0; i < nbSubsample; ++i) { |
543 | 811k | FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))]; |
544 | 811k | FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))]; |
545 | 811k | FIXP_DBL maxVal = (FIXP_DBL)0; |
546 | | |
547 | 811k | int ts = startPos + i; |
548 | | |
549 | 811k | int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale |
550 | 811k | : sbrScaleFactor->lb_scale; |
551 | 811k | low_sf = 15 - low_sf; |
552 | | |
553 | 16.0M | for (j = 0; j < lowSubband; ++j) { |
554 | 15.2M | bufferImag[j] = qmfImag[startPos + i][j]; |
555 | 15.2M | maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^ |
556 | 15.2M | ((LONG)bufferImag[j] >> (DFRACT_BITS - 1))); |
557 | 15.2M | bufferReal[j] = qmfReal[startPos + i][j]; |
558 | 15.2M | maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^ |
559 | 15.2M | ((LONG)bufferReal[j] >> (DFRACT_BITS - 1))); |
560 | 15.2M | } |
561 | | |
562 | 811k | subsample_power_low[i] = (FIXP_DBL)0; |
563 | 811k | subsample_power_low_sf[i] = 0; |
564 | | |
565 | 811k | if (maxVal != FL2FXCONST_DBL(0.f)) { |
566 | | /* multiply first, then shift for safe summation */ |
567 | 522k | int preShift = 1 - CntLeadingZeros(maxVal); |
568 | 522k | int postShift = 32 - fNormz((FIXP_DBL)lowSubband); |
569 | | |
570 | | /* reduce preShift because otherwise we risk to square -1.f */ |
571 | 522k | if (preShift != 0) preShift++; |
572 | | |
573 | 522k | subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1; |
574 | | |
575 | 522k | scaleValues(bufferReal, lowSubband, -preShift); |
576 | 522k | scaleValues(bufferImag, lowSubband, -preShift); |
577 | 10.8M | for (j = 0; j < lowSubband; ++j) { |
578 | 10.3M | FIXP_DBL addme; |
579 | 10.3M | addme = fPow2Div2(bufferReal[j]); |
580 | 10.3M | subsample_power_low[i] += addme >> postShift; |
581 | 10.3M | addme = fPow2Div2(bufferImag[j]); |
582 | 10.3M | subsample_power_low[i] += addme >> postShift; |
583 | 10.3M | } |
584 | 522k | } |
585 | | |
586 | | /* now get high */ |
587 | | |
588 | 811k | maxVal = (FIXP_DBL)0; |
589 | | |
590 | 811k | int high_sf = exp[(ts < 16 * RATE) ? 0 : 1]; |
591 | | |
592 | 13.9M | for (j = lowSubband; j < highSubband; ++j) { |
593 | 13.1M | bufferImag[j] = qmfImag[startPos + i][j]; |
594 | 13.1M | maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^ |
595 | 13.1M | ((LONG)bufferImag[j] >> (DFRACT_BITS - 1))); |
596 | 13.1M | bufferReal[j] = qmfReal[startPos + i][j]; |
597 | 13.1M | maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^ |
598 | 13.1M | ((LONG)bufferReal[j] >> (DFRACT_BITS - 1))); |
599 | 13.1M | } |
600 | | |
601 | 811k | subsample_power_high[i] = (FIXP_DBL)0; |
602 | 811k | subsample_power_high_sf[i] = 0; |
603 | | |
604 | 811k | if (maxVal != FL2FXCONST_DBL(0.f)) { |
605 | 737k | int preShift = 1 - CntLeadingZeros(maxVal); |
606 | | /* reduce preShift because otherwise we risk to square -1.f */ |
607 | 737k | if (preShift != 0) preShift++; |
608 | | |
609 | 737k | int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband)); |
610 | 737k | subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1; |
611 | | |
612 | 737k | scaleValues(&bufferReal[lowSubband], highSubband - lowSubband, |
613 | 737k | -preShift); |
614 | 737k | scaleValues(&bufferImag[lowSubband], highSubband - lowSubband, |
615 | 737k | -preShift); |
616 | 11.2M | for (j = lowSubband; j < highSubband; j++) { |
617 | 10.5M | subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift; |
618 | 10.5M | subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift; |
619 | 10.5M | } |
620 | 737k | } |
621 | | |
622 | | /* sum all together */ |
623 | 811k | FIXP_DBL new_summand = subsample_power_low[i]; |
624 | 811k | 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 | 811k | if (new_summand_sf > total_power_low_sf) { |
628 | 39.3k | int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf); |
629 | 39.3k | total_power_low >>= diff; |
630 | 39.3k | total_power_low_sf = new_summand_sf; |
631 | 771k | } else if (new_summand_sf < total_power_low_sf) { |
632 | 265k | new_summand >>= |
633 | 265k | fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf); |
634 | 265k | } |
635 | | |
636 | 811k | total_power_low += (new_summand >> preShift2); |
637 | | |
638 | 811k | new_summand = subsample_power_high[i]; |
639 | 811k | new_summand_sf = subsample_power_high_sf[i]; |
640 | 811k | if (new_summand_sf > total_power_high_sf) { |
641 | 37.5k | total_power_high >>= |
642 | 37.5k | fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf); |
643 | 37.5k | total_power_high_sf = new_summand_sf; |
644 | 773k | } else if (new_summand_sf < total_power_high_sf) { |
645 | 384k | new_summand >>= |
646 | 384k | fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf); |
647 | 384k | } |
648 | | |
649 | 811k | total_power_high += (new_summand >> preShift2); |
650 | 811k | } |
651 | | |
652 | 19.0k | total_power_low_sf += preShift2; |
653 | 19.0k | total_power_high_sf += preShift2; |
654 | | |
655 | | /* gain[i] = e_LOW[i] */ |
656 | 830k | for (i = 0; i < nbSubsample; ++i) { |
657 | 811k | int sf2; |
658 | 811k | FIXP_DBL mult = |
659 | 811k | fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2); |
660 | 811k | int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2; |
661 | | |
662 | 811k | if (total_power_low != FIXP_DBL(0)) { |
663 | 622k | gain[i] = fDivNorm(mult, total_power_low, &sf2); |
664 | 622k | gain_sf[i] = mult_sf - total_power_low_sf + sf2; |
665 | 622k | gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]); |
666 | 622k | if (gain_sf[i] < 0) { |
667 | 214k | gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]); |
668 | 214k | gain_sf[i] = 0; |
669 | 214k | } |
670 | 622k | } else { |
671 | 188k | if (mult == FIXP_DBL(0)) { |
672 | 185k | gain[i] = FIXP_DBL(0); |
673 | 185k | gain_sf[i] = 0; |
674 | 185k | } else { |
675 | 2.47k | gain[i] = (FIXP_DBL)MAXVAL_DBL; |
676 | 2.47k | gain_sf[i] = 0; |
677 | 2.47k | } |
678 | 188k | } |
679 | 811k | } |
680 | | |
681 | 19.0k | FIXP_DBL total_power_high_after = (FIXP_DBL)0; |
682 | 19.0k | int total_power_high_after_sf = 1 - DFRACT_BITS; |
683 | | |
684 | | /* gain[i] = g_inter[i] */ |
685 | 830k | for (i = 0; i < nbSubsample; ++i) { |
686 | | /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */ |
687 | 811k | FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >> |
688 | 811k | 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 | 811k | FIXP_DBL mult = (gain[i] - one) >> 1; |
693 | 811k | int mult_sf = gain_sf[i] + gamma_sf; |
694 | | |
695 | 811k | one = FL2FXCONST_DBL(0.5f) >> mult_sf; |
696 | 811k | gain[i] = one + mult; |
697 | 811k | 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 | 811k | FIXP_DBL gain_pow2; |
702 | 811k | int gain_pow2_sf; |
703 | | |
704 | 811k | if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) { |
705 | 454k | gain[i] = FL2FXCONST_DBL(0.8f); |
706 | 454k | gain_sf[i] = -2; |
707 | 454k | gain_pow2 = FL2FXCONST_DBL(0.64f); |
708 | 454k | gain_pow2_sf = -4; |
709 | 454k | } else { |
710 | | /* this upscaling seems quite important */ |
711 | 357k | int r = CountLeadingBits(gain[i]); |
712 | 357k | gain[i] <<= r; |
713 | 357k | gain_sf[i] -= r; |
714 | | |
715 | 357k | gain_pow2 = fPow2(gain[i]); |
716 | 357k | gain_pow2_sf = gain_sf[i] << 1; |
717 | 357k | } |
718 | | |
719 | 811k | int room; |
720 | 811k | subsample_power_high[i] = |
721 | 811k | fMultNorm(subsample_power_high[i], gain_pow2, &room); |
722 | 811k | subsample_power_high_sf[i] = |
723 | 811k | subsample_power_high_sf[i] + gain_pow2_sf + room; |
724 | | |
725 | 811k | int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */ |
726 | 811k | if (new_summand_sf > total_power_high_after_sf) { |
727 | 61.4k | total_power_high_after >>= |
728 | 61.4k | fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf); |
729 | 61.4k | total_power_high_after_sf = new_summand_sf; |
730 | 749k | } else if (new_summand_sf < total_power_high_after_sf) { |
731 | 535k | subsample_power_high[i] >>= |
732 | 535k | fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf); |
733 | 535k | } |
734 | 811k | total_power_high_after += subsample_power_high[i] >> preShift2; |
735 | 811k | } |
736 | | |
737 | 19.0k | total_power_high_after_sf += preShift2; |
738 | | |
739 | 19.0k | int sf2 = 0; |
740 | 19.0k | FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f); |
741 | 19.0k | int gain_adj_2_sf = 1; |
742 | | |
743 | 19.0k | if ((total_power_high != (FIXP_DBL)0) && |
744 | 19.0k | (total_power_high_after != (FIXP_DBL)0)) { |
745 | 17.5k | gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2); |
746 | 17.5k | gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2; |
747 | 17.5k | } |
748 | | |
749 | 19.0k | FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf); |
750 | 19.0k | int gain_adj_sf = gain_adj_2_sf; |
751 | | |
752 | 830k | for (i = 0; i < nbSubsample; ++i) { |
753 | 811k | int gain_e = fMax( |
754 | 811k | fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1), |
755 | 811k | -(DFRACT_BITS - 1)); |
756 | 811k | FIXP_DBL gain_final = fMult(gain[i], gain_adj); |
757 | 811k | gain_final = scaleValueSaturate(gain_final, gain_e); |
758 | | |
759 | 13.9M | for (j = lowSubband; j < highSubband; j++) { |
760 | 13.1M | qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final); |
761 | 13.1M | qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final); |
762 | 13.1M | } |
763 | 811k | } |
764 | 21.7k | } 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 | 828k | for (i = 0; i < nbSubsample; ++i) { |
768 | 11.6M | for (j = lowSubband; j < highSubband; j++) { |
769 | 10.7M | qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE; |
770 | 10.7M | qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE; |
771 | 10.7M | } |
772 | 806k | } |
773 | 21.7k | } |
774 | 40.8k | C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1); |
775 | 40.8k | } |
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 | | */ |
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 | 404k | const UINT flags, const int frameErrorFlag) { |
877 | 404k | int c, i, i_stop, j, envNoise = 0; |
878 | 404k | UCHAR *borders = hFrameData->frameInfo.borders; |
879 | 404k | UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders; |
880 | 404k | int pvc_mode = pPvcDynamicData->pvc_mode; |
881 | 404k | int first_start = |
882 | 404k | ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep; |
883 | 404k | FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel; |
884 | 404k | HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; |
885 | 404k | UCHAR **pFreqBandTable = hFreq->freqBandTable; |
886 | 404k | UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise; |
887 | | |
888 | 404k | int lowSubband = hFreq->lowSubband; |
889 | 404k | int highSubband = hFreq->highSubband; |
890 | 404k | int noSubbands = highSubband - lowSubband; |
891 | | |
892 | | /* old high subband before headerchange |
893 | | we asume no headerchange here */ |
894 | 404k | int ov_highSubband = hFreq->highSubband; |
895 | | |
896 | 404k | int noNoiseBands = hFreq->nNfb; |
897 | 404k | UCHAR *noSubFrameBands = hFreq->nSfb; |
898 | 404k | int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; |
899 | | |
900 | 404k | SCHAR sineMapped[MAX_FREQ_COEFFS]; |
901 | 404k | SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale); |
902 | 404k | SCHAR adj_e = 0; |
903 | 404k | SCHAR output_e; |
904 | 404k | SCHAR final_e = 0; |
905 | | /* inter-TES is active in one or more envelopes of the current SBR frame */ |
906 | 404k | const int iTES_enable = hFrameData->iTESactive; |
907 | 404k | const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0; |
908 | 404k | SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP; |
909 | | |
910 | 404k | UCHAR smooth_length = 0; |
911 | | |
912 | 404k | FIXP_SGL *pIenv = hFrameData->iEnvelope; |
913 | | |
914 | 404k | 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 | 404k | if (hFreq->highSubband < hFreq->ov_highSubband) { |
921 | 27.7k | ov_highSubband = hFreq->ov_highSubband; |
922 | 27.7k | } |
923 | | |
924 | 404k | if (pvc_mode > 0) { |
925 | 115k | if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) { |
926 | | /* noise envelope of previous frame is trailing into current PVC frame */ |
927 | 84.0k | envNoise = -1; |
928 | 84.0k | noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel; |
929 | 84.0k | noNoiseBands = h_sbr_cal_env->prevNNfb; |
930 | 84.0k | noSubFrameBands = h_sbr_cal_env->prevNSfb; |
931 | 84.0k | lowSubband = h_sbr_cal_env->prevLoSubband; |
932 | 84.0k | highSubband = h_sbr_cal_env->prevHiSubband; |
933 | | |
934 | 84.0k | noSubbands = highSubband - lowSubband; |
935 | 84.0k | ov_highSubband = highSubband; |
936 | 84.0k | if (highSubband < h_sbr_cal_env->prev_ov_highSubband) { |
937 | 7.49k | ov_highSubband = h_sbr_cal_env->prev_ov_highSubband; |
938 | 7.49k | } |
939 | | |
940 | 84.0k | pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo; |
941 | 84.0k | pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi; |
942 | 84.0k | pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise; |
943 | 84.0k | } |
944 | | |
945 | 115k | mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1], |
946 | 115k | h_sbr_cal_env->harmFlagsPrev, |
947 | 115k | h_sbr_cal_env->harmFlagsPrevActive, sineMapped, |
948 | 115k | hFrameData->sinusoidal_position, |
949 | 115k | &h_sbr_cal_env->sinusoidal_positionPrev, |
950 | 115k | (borders[0] > bordersPvc[0]) ? 1 : 0); |
951 | 289k | } else { |
952 | | /* |
953 | | Extract sine flags for all QMF bands |
954 | | */ |
955 | 289k | mapSineFlags(pFreqBandTable[1], noSubFrameBands[1], |
956 | 289k | hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev, |
957 | 289k | h_sbr_cal_env->harmFlagsPrevActive, |
958 | 289k | hFrameData->frameInfo.tranEnv, sineMapped); |
959 | 289k | } |
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 | 404k | if (!useLP) |
969 | 329k | adj_e = h_sbr_cal_env->filtBufferNoise_e - |
970 | 329k | getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) + |
971 | 329k | (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 | 404k | if (pvc_mode > 0) { |
978 | 115k | INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax; |
979 | | |
980 | | /* Energy -> magnitude (sqrt halfens exponent) */ |
981 | 115k | maxSfbNrg_e = |
982 | 115k | (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 | 115k | maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); |
992 | | |
993 | 115k | adj_e = maxSfbNrg_e; |
994 | | // final_e should not exist for PVC fixfix framing |
995 | 289k | } else { |
996 | 647k | for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { |
997 | 358k | INT maxSfbNrg_e = |
998 | 358k | -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */ |
999 | | |
1000 | | /* Fetch frequency resolution for current envelope: */ |
1001 | 3.76M | for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) { |
1002 | 3.40M | maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E)); |
1003 | 3.40M | } |
1004 | 358k | maxSfbNrg_e -= NRG_EXP_OFFSET; |
1005 | | |
1006 | | /* Energy -> magnitude (sqrt halfens exponent) */ |
1007 | 358k | maxSfbNrg_e = |
1008 | 358k | (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 | 358k | maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); |
1018 | | |
1019 | 358k | if (borders[i] < hHeaderData->numberTimeSlots) |
1020 | | /* This envelope affects timeslots that belong to the output frame */ |
1021 | 353k | adj_e = fMax(maxSfbNrg_e, adj_e); |
1022 | | |
1023 | 358k | if (borders[i + 1] > hHeaderData->numberTimeSlots) |
1024 | | /* This envelope affects timeslots after the output frame */ |
1025 | 15.8k | final_e = fMax(maxSfbNrg_e, final_e); |
1026 | 358k | } |
1027 | 289k | } |
1028 | | /* |
1029 | | Calculate adjustment factors and apply them for every envelope. |
1030 | | */ |
1031 | 404k | pIenv = hFrameData->iEnvelope; |
1032 | | |
1033 | 404k | if (pvc_mode > 0) { |
1034 | | /* iterate over SBR time slots starting with bordersPvc[i] */ |
1035 | 115k | i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to |
1036 | | PVC */ |
1037 | 115k | i_stop = PVC_NTIMESLOT; |
1038 | 115k | FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT); |
1039 | 289k | } else { |
1040 | | /* iterate over SBR envelopes starting with 0 */ |
1041 | 289k | i = 0; |
1042 | 289k | i_stop = hFrameData->frameInfo.nEnvelopes; |
1043 | 289k | } |
1044 | 2.60M | for (; i < i_stop; i++) { |
1045 | 2.20M | int k, noNoiseFlag; |
1046 | 2.20M | SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale); |
1047 | 2.20M | C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1); |
1048 | | |
1049 | | /* |
1050 | | Helper variables. |
1051 | | */ |
1052 | 2.20M | int start_pos, stop_pos, freq_res; |
1053 | 2.20M | if (pvc_mode > 0) { |
1054 | 1.84M | start_pos = |
1055 | 1.84M | hHeaderData->timeStep * |
1056 | 1.84M | i; /* Start-position in time (subband sample) for current envelope. */ |
1057 | 1.84M | stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time |
1058 | | (subband sample) for |
1059 | | current envelope. */ |
1060 | 1.84M | freq_res = |
1061 | 1.84M | hFrameData->frameInfo |
1062 | 1.84M | .freqRes[0]; /* Frequency resolution for current envelope. */ |
1063 | 1.84M | FDK_ASSERT( |
1064 | 1.84M | freq_res == |
1065 | 1.84M | hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]); |
1066 | 1.84M | } else { |
1067 | 358k | start_pos = hHeaderData->timeStep * |
1068 | 358k | borders[i]; /* Start-position in time (subband sample) for |
1069 | | current envelope. */ |
1070 | 358k | stop_pos = hHeaderData->timeStep * |
1071 | 358k | borders[i + 1]; /* Stop-position in time (subband sample) for |
1072 | | current envelope. */ |
1073 | 358k | freq_res = |
1074 | 358k | hFrameData->frameInfo |
1075 | 358k | .freqRes[i]; /* Frequency resolution for current envelope. */ |
1076 | 358k | } |
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 | 0 | FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS)); |
1084 | | |
1085 | 2.20M | if (pvc_mode > 0) { |
1086 | | /* get predicted energy values from PVC module */ |
1087 | 1.84M | expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef, |
1088 | 1.84M | pNrgs->nrgRef_e); |
1089 | | |
1090 | 1.84M | if (i == borders[0]) { |
1091 | 115k | mapSineFlags(pFreqBandTable[1], noSubFrameBands[1], |
1092 | 115k | hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev, |
1093 | 115k | h_sbr_cal_env->harmFlagsPrevActive, |
1094 | 115k | hFrameData->sinusoidal_position, sineMapped); |
1095 | 115k | } |
1096 | | |
1097 | 1.84M | if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) { |
1098 | 173k | if (envNoise >= 0) { |
1099 | 89.7k | noiseLevels += noNoiseBands; /* The noise floor data is stored in a |
1100 | | row [noiseFloor1 noiseFloor2...].*/ |
1101 | 89.7k | } else { |
1102 | | /* leave trailing noise envelope of past frame */ |
1103 | 84.0k | noNoiseBands = hFreq->nNfb; |
1104 | 84.0k | noSubFrameBands = hFreq->nSfb; |
1105 | 84.0k | noiseLevels = hFrameData->sbrNoiseFloorLevel; |
1106 | | |
1107 | 84.0k | lowSubband = hFreq->lowSubband; |
1108 | 84.0k | highSubband = hFreq->highSubband; |
1109 | | |
1110 | 84.0k | noSubbands = highSubband - lowSubband; |
1111 | 84.0k | ov_highSubband = highSubband; |
1112 | 84.0k | if (highSubband < hFreq->ov_highSubband) { |
1113 | 7.77k | ov_highSubband = hFreq->ov_highSubband; |
1114 | 7.77k | } |
1115 | | |
1116 | 84.0k | pFreqBandTable[0] = hFreq->freqBandTableLo; |
1117 | 84.0k | pFreqBandTable[1] = hFreq->freqBandTableHi; |
1118 | 84.0k | pFreqBandTableNoise = hFreq->freqBandTableNoise; |
1119 | 84.0k | } |
1120 | 173k | envNoise++; |
1121 | 173k | } |
1122 | 1.84M | } 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 | 358k | if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) { |
1127 | 55.0k | noiseLevels += noNoiseBands; /* The noise floor data is stored in a row |
1128 | | [noiseFloor1 noiseFloor2...].*/ |
1129 | 55.0k | envNoise++; |
1130 | 55.0k | } |
1131 | 358k | } |
1132 | 2.20M | if (i == hFrameData->frameInfo.tranEnv || |
1133 | 2.20M | i == h_sbr_cal_env->prevTranEnv) /* attack */ |
1134 | 13.9k | { |
1135 | 13.9k | noNoiseFlag = 1; |
1136 | 13.9k | if (!useLP) smooth_length = 0; /* No smoothing on attacks! */ |
1137 | 2.19M | } else { |
1138 | 2.19M | noNoiseFlag = 0; |
1139 | 2.19M | if (!useLP) |
1140 | 2.10M | smooth_length = (1 - hHeaderData->bs_data.smoothingLength) |
1141 | 2.10M | << 2; /* can become either 0 or 4 */ |
1142 | 2.19M | } |
1143 | | |
1144 | | /* |
1145 | | Energy estimation in transposed highband. |
1146 | | */ |
1147 | 2.20M | if (hHeaderData->bs_data.interpolFreq) |
1148 | 2.13M | calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1149 | 2.13M | lowSubband, highSubband, start_pos, stop_pos, input_e, |
1150 | 2.13M | pNrgs->nrgEst, pNrgs->nrgEst_e); |
1151 | 73.8k | else |
1152 | 73.8k | calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1153 | 73.8k | noSubFrameBands[freq_res], pFreqBandTable[freq_res], |
1154 | 73.8k | start_pos, stop_pos, input_e, pNrgs->nrgEst, |
1155 | 73.8k | pNrgs->nrgEst_e); |
1156 | | |
1157 | | /* |
1158 | | Calculate subband gains |
1159 | | */ |
1160 | 2.20M | { |
1161 | 2.20M | UCHAR *table = pFreqBandTable[freq_res]; |
1162 | 2.20M | UCHAR *pUiNoise = |
1163 | 2.20M | &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor |
1164 | | band. */ |
1165 | | |
1166 | 2.20M | FIXP_SGL *pNoiseLevels = noiseLevels; |
1167 | | |
1168 | 2.20M | FIXP_DBL tmpNoise = |
1169 | 2.20M | FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); |
1170 | 2.20M | SCHAR tmpNoise_e = |
1171 | 2.20M | (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; |
1172 | | |
1173 | 2.20M | int cc = 0; |
1174 | 2.20M | c = 0; |
1175 | 2.20M | if (pvc_mode > 0) { |
1176 | 9.10M | for (j = 0; j < noSubFrameBands[freq_res]; j++) { |
1177 | 7.25M | UCHAR sinePresentFlag = 0; |
1178 | 7.25M | int li = table[j]; |
1179 | 7.25M | int ui = table[j + 1]; |
1180 | | |
1181 | 50.0M | for (k = li; k < ui; k++) { |
1182 | 42.7M | sinePresentFlag |= (i >= sineMapped[cc]); |
1183 | 42.7M | cc++; |
1184 | 42.7M | } |
1185 | | |
1186 | 50.0M | for (k = li; k < ui; k++) { |
1187 | 42.7M | FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband]; |
1188 | 42.7M | SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband]; |
1189 | | |
1190 | 42.7M | if (k >= *pUiNoise) { |
1191 | 2.45M | tmpNoise = |
1192 | 2.45M | FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); |
1193 | 2.45M | tmpNoise_e = |
1194 | 2.45M | (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; |
1195 | | |
1196 | 2.45M | pUiNoise++; |
1197 | 2.45M | } |
1198 | | |
1199 | 42.7M | FDK_ASSERT(k >= lowSubband); |
1200 | | |
1201 | 42.7M | if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag; |
1202 | | |
1203 | 42.7M | pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); |
1204 | 42.7M | pNrgs->nrgSine_e[c] = 0; |
1205 | | |
1206 | 42.7M | calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e, |
1207 | 42.7M | sinePresentFlag, i >= sineMapped[c], noNoiseFlag); |
1208 | | |
1209 | 42.7M | c++; |
1210 | 42.7M | } |
1211 | 7.25M | } |
1212 | 1.84M | } else { |
1213 | 3.76M | for (j = 0; j < noSubFrameBands[freq_res]; j++) { |
1214 | 3.40M | FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M)); |
1215 | 3.40M | SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET; |
1216 | | |
1217 | 3.40M | UCHAR sinePresentFlag = 0; |
1218 | 3.40M | int li = table[j]; |
1219 | 3.40M | int ui = table[j + 1]; |
1220 | | |
1221 | 11.2M | for (k = li; k < ui; k++) { |
1222 | 7.87M | sinePresentFlag |= (i >= sineMapped[cc]); |
1223 | 7.87M | cc++; |
1224 | 7.87M | } |
1225 | | |
1226 | 11.2M | for (k = li; k < ui; k++) { |
1227 | 7.87M | if (k >= *pUiNoise) { |
1228 | 448k | tmpNoise = |
1229 | 448k | FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); |
1230 | 448k | tmpNoise_e = |
1231 | 448k | (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; |
1232 | | |
1233 | 448k | pUiNoise++; |
1234 | 448k | } |
1235 | | |
1236 | 7.87M | FDK_ASSERT(k >= lowSubband); |
1237 | | |
1238 | 7.87M | if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag; |
1239 | | |
1240 | 7.87M | pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); |
1241 | 7.87M | pNrgs->nrgSine_e[c] = 0; |
1242 | | |
1243 | 7.87M | calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e, |
1244 | 7.87M | sinePresentFlag, i >= sineMapped[c], noNoiseFlag); |
1245 | | |
1246 | 7.87M | pNrgs->nrgRef[c] = refNrg; |
1247 | 7.87M | pNrgs->nrgRef_e[c] = refNrg_e; |
1248 | | |
1249 | 7.87M | c++; |
1250 | 7.87M | } |
1251 | 3.40M | pIenv++; |
1252 | 3.40M | } |
1253 | 358k | } |
1254 | 2.20M | } |
1255 | | |
1256 | | /* |
1257 | | Noise limiting |
1258 | | */ |
1259 | | |
1260 | 9.38M | for (c = 0; c < hFreq->noLimiterBands; c++) { |
1261 | 7.18M | FIXP_DBL sumRef, boostGain, maxGain; |
1262 | 7.18M | FIXP_DBL accu = FL2FXCONST_DBL(0.0f); |
1263 | 7.18M | SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0; |
1264 | 7.18M | int maxGainLimGainSum_e = 0; |
1265 | | |
1266 | 7.18M | calcAvgGain(pNrgs, hFreq->limiterBandTable[c], |
1267 | 7.18M | hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain, |
1268 | 7.18M | &maxGain_e); |
1269 | | |
1270 | | /* Multiply maxGain with limiterGain: */ |
1271 | 7.18M | maxGain = fMult( |
1272 | 7.18M | maxGain, |
1273 | 7.18M | 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 | 7.18M | maxGainLimGainSum_e = |
1281 | 7.18M | maxGain_e + |
1282 | 7.18M | FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; |
1283 | 7.18M | maxGain_e = |
1284 | 7.18M | (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e; |
1285 | | |
1286 | | /* Scale mantissa of MaxGain into range between 0.5 and 1: */ |
1287 | 7.18M | if (maxGain == FL2FXCONST_DBL(0.0f)) |
1288 | 371 | maxGain_e = -FRACT_BITS; |
1289 | 7.18M | else { |
1290 | 7.18M | SCHAR charTemp = CountLeadingBits(maxGain); |
1291 | 7.18M | maxGain_e -= charTemp; |
1292 | 7.18M | maxGain <<= (int)charTemp; |
1293 | 7.18M | } |
1294 | | |
1295 | 7.18M | if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */ |
1296 | 1.55M | maxGain = FL2FXCONST_DBL(0.5f); |
1297 | 1.55M | maxGain_e = maxGainLimit_e; |
1298 | 1.55M | } |
1299 | | |
1300 | | /* Every subband gain is compared to the scaled "average gain" |
1301 | | and limited if necessary: */ |
1302 | 57.8M | for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; |
1303 | 50.6M | k++) { |
1304 | 50.6M | if ((pNrgs->nrgGain_e[k] > maxGain_e) || |
1305 | 50.6M | (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) { |
1306 | 18.3M | FIXP_DBL noiseAmp; |
1307 | 18.3M | SCHAR noiseAmp_e; |
1308 | | |
1309 | 18.3M | FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], |
1310 | 18.3M | pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e); |
1311 | 18.3M | pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp); |
1312 | 18.3M | pNrgs->noiseLevel_e[k] += noiseAmp_e; |
1313 | 18.3M | pNrgs->nrgGain[k] = maxGain; |
1314 | 18.3M | pNrgs->nrgGain_e[k] = maxGain_e; |
1315 | 18.3M | } |
1316 | 50.6M | } |
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 | 57.8M | for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; |
1325 | 50.6M | k++) { |
1326 | | /* 1.a Add energy of adjusted signal (using preliminary gain) */ |
1327 | 50.6M | FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]); |
1328 | 50.6M | SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k]; |
1329 | 50.6M | FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e); |
1330 | | |
1331 | | /* 1.b Add sine energy (if present) */ |
1332 | 50.6M | if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) { |
1333 | 111k | FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, |
1334 | 111k | &accu, &accu_e); |
1335 | 50.5M | } else { |
1336 | | /* 1.c Add noise energy (if present) */ |
1337 | 50.5M | if (noNoiseFlag == 0) { |
1338 | 50.2M | FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, |
1339 | 50.2M | accu_e, &accu, &accu_e); |
1340 | 50.2M | } |
1341 | 50.5M | } |
1342 | 50.6M | } |
1343 | | |
1344 | | /* 2.a Calculate ratio of wanted energy and accumulated energy */ |
1345 | 7.18M | if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */ |
1346 | 857k | boostGain = FL2FXCONST_DBL(0.6279716f); |
1347 | 857k | boostGain_e = 2; |
1348 | 6.32M | } else { |
1349 | 6.32M | INT div_e; |
1350 | 6.32M | boostGain = fDivNorm(sumRef, accu, &div_e); |
1351 | 6.32M | boostGain_e = sumRef_e - accu_e + div_e; |
1352 | 6.32M | } |
1353 | | |
1354 | | /* 2.b Result too high? --> Limit the boost factor to +4 dB */ |
1355 | 7.18M | if ((boostGain_e > 3) || |
1356 | 7.18M | (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) || |
1357 | 7.18M | (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) { |
1358 | 1.97M | boostGain = FL2FXCONST_DBL(0.6279716f); |
1359 | 1.97M | boostGain_e = 2; |
1360 | 1.97M | } |
1361 | | /* 3. Multiply all signal components with the boost factor */ |
1362 | 57.8M | for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; |
1363 | 50.6M | k++) { |
1364 | 50.6M | pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain); |
1365 | 50.6M | pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1; |
1366 | | |
1367 | 50.6M | pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain); |
1368 | 50.6M | pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1; |
1369 | | |
1370 | 50.6M | pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain); |
1371 | 50.6M | pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1; |
1372 | 50.6M | } |
1373 | 7.18M | } |
1374 | | /* End of noise limiting */ |
1375 | | |
1376 | 2.20M | if (useLP) |
1377 | 97.1k | aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction, |
1378 | 97.1k | 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 | 2.20M | noise_e = (start_pos < no_cols) ? adj_e : final_e; |
1387 | | |
1388 | 2.20M | if (start_pos >= no_cols) { |
1389 | 4.87k | int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e; |
1390 | 4.87k | if (diff > 0) { |
1391 | 119 | int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); |
1392 | 119 | if (diff > s) { |
1393 | 28 | final_e += diff - s; |
1394 | 28 | noise_e = final_e; |
1395 | 28 | } |
1396 | 119 | } |
1397 | 4.87k | } |
1398 | | |
1399 | | /* |
1400 | | Convert energies to amplitude levels |
1401 | | */ |
1402 | 52.8M | for (k = 0; k < noSubbands; k++) { |
1403 | 50.6M | FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e); |
1404 | 50.6M | FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], |
1405 | 50.6M | &pNrgs->nrgGain_e[k]); |
1406 | 50.6M | FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], |
1407 | 50.6M | &noise_e); |
1408 | 50.6M | } |
1409 | | |
1410 | | /* |
1411 | | Apply calculated gains and adaptive noise |
1412 | | */ |
1413 | | |
1414 | | /* assembleHfSignals() */ |
1415 | 2.20M | { |
1416 | 2.20M | int scale_change, sc_change; |
1417 | 2.20M | FIXP_SGL smooth_ratio; |
1418 | 2.20M | int filtBufferNoiseShift = 0; |
1419 | | |
1420 | | /* Initialize smoothing buffers with the first valid values */ |
1421 | 2.20M | if (h_sbr_cal_env->startUp) { |
1422 | 110k | if (!useLP) { |
1423 | 86.9k | h_sbr_cal_env->filtBufferNoise_e = noise_e; |
1424 | | |
1425 | 86.9k | FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, |
1426 | 86.9k | noSubbands * sizeof(SCHAR)); |
1427 | 86.9k | FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, |
1428 | 86.9k | noSubbands * sizeof(FIXP_DBL)); |
1429 | 86.9k | FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, |
1430 | 86.9k | noSubbands * sizeof(FIXP_DBL)); |
1431 | 86.9k | } |
1432 | 110k | h_sbr_cal_env->startUp = 0; |
1433 | 110k | } |
1434 | | |
1435 | 2.20M | if (!useLP) { |
1436 | 2.10M | equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */ |
1437 | 2.10M | h_sbr_cal_env->filtBuffer_e, /* buffered */ |
1438 | 2.10M | pNrgs->nrgGain, /* current */ |
1439 | 2.10M | pNrgs->nrgGain_e, /* current */ |
1440 | 2.10M | noSubbands); |
1441 | | |
1442 | | /* Adapt exponent of buffered noise levels to the current exponent |
1443 | | so they can easily be smoothed */ |
1444 | 2.10M | if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) { |
1445 | 2.07M | int shift = fixMin(DFRACT_BITS - 1, |
1446 | 2.07M | (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); |
1447 | 50.5M | for (k = 0; k < noSubbands; k++) |
1448 | 48.4M | h_sbr_cal_env->filtBufferNoise[k] <<= shift; |
1449 | 2.07M | } else { |
1450 | 28.7k | int shift = |
1451 | 28.7k | fixMin(DFRACT_BITS - 1, |
1452 | 28.7k | -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); |
1453 | 723k | for (k = 0; k < noSubbands; k++) |
1454 | 694k | h_sbr_cal_env->filtBufferNoise[k] >>= shift; |
1455 | 28.7k | } |
1456 | | |
1457 | 2.10M | h_sbr_cal_env->filtBufferNoise_e = noise_e; |
1458 | 2.10M | } |
1459 | | |
1460 | | /* find best scaling! */ |
1461 | 2.20M | scale_change = -(DFRACT_BITS - 1); |
1462 | 52.8M | for (k = 0; k < noSubbands; k++) { |
1463 | 50.6M | scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]); |
1464 | 50.6M | } |
1465 | 2.20M | sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e; |
1466 | | |
1467 | 2.20M | if ((scale_change - sc_change + 1) < 0) |
1468 | 730k | scale_change -= (scale_change - sc_change + 1); |
1469 | | |
1470 | 2.20M | scale_change = (scale_change - sc_change) + 1; |
1471 | | |
1472 | 52.8M | for (k = 0; k < noSubbands; k++) { |
1473 | 50.6M | int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1); |
1474 | 50.6M | pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1); |
1475 | 50.6M | pNrgs->nrgGain_e[k] += sc; |
1476 | 50.6M | } |
1477 | | |
1478 | 2.20M | if (!useLP) { |
1479 | 51.2M | for (k = 0; k < noSubbands; k++) { |
1480 | 49.1M | int sc = |
1481 | 49.1M | scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1); |
1482 | 49.1M | h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1); |
1483 | 49.1M | } |
1484 | 2.10M | } |
1485 | | |
1486 | 16.4M | 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 | 14.2M | if ((j == no_cols) && (start_pos < no_cols)) { |
1495 | 10.9k | int shift = (int)(noise_e - final_e); |
1496 | 10.9k | if (!useLP) |
1497 | 5.42k | filtBufferNoiseShift = shift; /* shifting of |
1498 | | h_sbr_cal_env->filtBufferNoise[k] |
1499 | | will be applied in function |
1500 | | adjustTimeSlotHQ() */ |
1501 | 10.9k | if (shift >= 0) { |
1502 | 7.08k | shift = fixMin(DFRACT_BITS - 1, shift); |
1503 | 174k | for (k = 0; k < noSubbands; k++) { |
1504 | 166k | pNrgs->nrgSine[k] <<= shift; |
1505 | 166k | pNrgs->noiseLevel[k] <<= shift; |
1506 | | /* |
1507 | | if (!useLP) |
1508 | | h_sbr_cal_env->filtBufferNoise[k] <<= shift; |
1509 | | */ |
1510 | 166k | } |
1511 | 7.08k | } else { |
1512 | 3.89k | shift = fixMin(DFRACT_BITS - 1, -shift); |
1513 | 31.4k | for (k = 0; k < noSubbands; k++) { |
1514 | 27.5k | pNrgs->nrgSine[k] >>= shift; |
1515 | 27.5k | pNrgs->noiseLevel[k] >>= shift; |
1516 | | /* |
1517 | | if (!useLP) |
1518 | | h_sbr_cal_env->filtBufferNoise[k] >>= shift; |
1519 | | */ |
1520 | 27.5k | } |
1521 | 3.89k | } |
1522 | | |
1523 | | /* update noise scaling */ |
1524 | 10.9k | noise_e = final_e; |
1525 | 10.9k | if (!useLP) |
1526 | 5.42k | h_sbr_cal_env->filtBufferNoise_e = |
1527 | 5.42k | noise_e; /* scaling value unused! */ |
1528 | | |
1529 | | /* update gain buffer*/ |
1530 | 10.9k | sc_change -= (final_e - input_e); |
1531 | | |
1532 | 10.9k | if (sc_change < 0) { |
1533 | 31.4k | for (k = 0; k < noSubbands; k++) { |
1534 | 27.5k | pNrgs->nrgGain[k] >>= -sc_change; |
1535 | 27.5k | pNrgs->nrgGain_e[k] += -sc_change; |
1536 | 27.5k | } |
1537 | 3.89k | if (!useLP) { |
1538 | 25.8k | for (k = 0; k < noSubbands; k++) { |
1539 | 22.2k | h_sbr_cal_env->filtBuffer[k] >>= -sc_change; |
1540 | 22.2k | } |
1541 | 3.60k | } |
1542 | 7.08k | } else { |
1543 | 7.08k | scale_change += sc_change; |
1544 | 7.08k | } |
1545 | | |
1546 | 10.9k | } /* if */ |
1547 | | |
1548 | 14.2M | if (!useLP) { |
1549 | | /* Prevent the smoothing filter from running on constant levels */ |
1550 | 12.0M | if (j - start_pos < smooth_length) |
1551 | 3.24M | smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos]; |
1552 | 8.82M | else |
1553 | 8.82M | smooth_ratio = FL2FXCONST_SGL(0.0f); |
1554 | | |
1555 | 12.0M | if (iTES_enable) { |
1556 | | /* adjustTimeSlotHQ() without adding of additional harmonics */ |
1557 | 1.61M | adjustTimeSlotHQ_GainAndNoise( |
1558 | 1.61M | &analysBufferReal[j][lowSubband], |
1559 | 1.61M | &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs, |
1560 | 1.61M | lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1), |
1561 | 1.61M | smooth_ratio, noNoiseFlag, filtBufferNoiseShift); |
1562 | 10.4M | } else { |
1563 | 10.4M | adjustTimeSlotHQ(&analysBufferReal[j][lowSubband], |
1564 | 10.4M | &analysBufferImag[j][lowSubband], h_sbr_cal_env, |
1565 | 10.4M | pNrgs, lowSubband, noSubbands, |
1566 | 10.4M | fMin(scale_change, DFRACT_BITS - 1), smooth_ratio, |
1567 | 10.4M | noNoiseFlag, filtBufferNoiseShift); |
1568 | 10.4M | } |
1569 | 12.0M | } else { |
1570 | 2.14M | FDK_ASSERT(!iTES_enable); /* not supported */ |
1571 | 2.14M | if (flags & SBRDEC_ELD_GRID) { |
1572 | | /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */ |
1573 | 237k | adjustTimeSlot_EldGrid( |
1574 | 237k | &analysBufferReal[j][lowSubband], pNrgs, |
1575 | 237k | &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, |
1576 | 237k | fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag, |
1577 | 237k | &h_sbr_cal_env->phaseIndex, |
1578 | 237k | fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale, |
1579 | 237k | -(DFRACT_BITS - 1))); |
1580 | 1.90M | } else { |
1581 | 1.90M | adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs, |
1582 | 1.90M | &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, |
1583 | 1.90M | fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag, |
1584 | 1.90M | &h_sbr_cal_env->phaseIndex); |
1585 | 1.90M | } |
1586 | 2.14M | } |
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 | 14.2M | pNrgs->exponent[(j < no_cols) ? 0 : 1] = |
1592 | 14.2M | (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 - |
1593 | 14.2M | scale_change); |
1594 | 14.2M | } /* for */ |
1595 | | |
1596 | 2.20M | if (iTES_enable) { |
1597 | 40.8k | apply_inter_tes( |
1598 | 40.8k | analysBufferReal, /* pABufR, */ |
1599 | 40.8k | analysBufferImag, /* pABufI, */ |
1600 | 40.8k | sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos, |
1601 | 40.8k | stop_pos, lowSubband, noSubbands, |
1602 | 40.8k | hFrameData |
1603 | 40.8k | ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */ |
1604 | 40.8k | ); |
1605 | | |
1606 | | /* add additional harmonics */ |
1607 | 1.65M | 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 | 1.61M | scale_change = 0; |
1611 | | |
1612 | 1.61M | 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 | 128k | scale_change = pNrgs->exponent[1] - pNrgs->exponent[0]; |
1618 | 128k | } |
1619 | | |
1620 | 1.61M | adjustTimeSlotHQ_AddHarmonics( |
1621 | 1.61M | &analysBufferReal[j][lowSubband], |
1622 | 1.61M | &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs, |
1623 | 1.61M | lowSubband, noSubbands, |
1624 | 1.61M | -iTES_scale_change + ((j < no_cols) ? scale_change : 0)); |
1625 | 1.61M | } |
1626 | 40.8k | } |
1627 | | |
1628 | 2.20M | 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 | 2.10M | FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, |
1635 | 2.10M | noSubbands * sizeof(FIXP_DBL)); |
1636 | 2.10M | FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, |
1637 | 2.10M | noSubbands * sizeof(SCHAR)); |
1638 | 2.10M | FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, |
1639 | 2.10M | noSubbands * sizeof(FIXP_DBL)); |
1640 | 2.10M | } |
1641 | 2.20M | } |
1642 | 2.20M | C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1); |
1643 | 2.20M | } |
1644 | | |
1645 | | /* adapt adj_e to the scale change caused by apply_inter_tes() */ |
1646 | 404k | adj_e += iTES_scale_change; |
1647 | | |
1648 | | /* Rescale output samples */ |
1649 | 404k | { |
1650 | 404k | FIXP_DBL maxVal; |
1651 | 404k | int ov_reserve, reserve; |
1652 | | |
1653 | | /* Determine headroom in old adjusted samples */ |
1654 | 404k | maxVal = |
1655 | 404k | maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1656 | 404k | lowSubband, ov_highSubband, 0, first_start); |
1657 | | |
1658 | 404k | ov_reserve = fNorm(maxVal); |
1659 | | |
1660 | | /* Determine headroom in new adjusted samples */ |
1661 | 404k | maxVal = |
1662 | 404k | maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1663 | 404k | lowSubband, highSubband, first_start, no_cols); |
1664 | | |
1665 | 404k | reserve = fNorm(maxVal); |
1666 | | |
1667 | | /* Determine common output exponent */ |
1668 | 404k | output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve); |
1669 | | |
1670 | | /* Rescale old samples */ |
1671 | 404k | rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1672 | 404k | lowSubband, ov_highSubband, 0, first_start, |
1673 | 404k | ov_adj_e - output_e); |
1674 | | |
1675 | | /* Rescale new samples */ |
1676 | 404k | rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag, |
1677 | 404k | lowSubband, highSubband, first_start, no_cols, |
1678 | 404k | adj_e - output_e); |
1679 | 404k | } |
1680 | | |
1681 | | /* Update hb_scale */ |
1682 | 404k | 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 | 404k | 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 | 404k | if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes) |
1691 | 4.40k | h_sbr_cal_env->prevTranEnv = 0; |
1692 | 400k | else |
1693 | 400k | h_sbr_cal_env->prevTranEnv = -1; |
1694 | | |
1695 | 404k | 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 | 115k | FDK_ASSERT(hFrameData->frameInfo |
1699 | 0 | .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] < |
1700 | 0 | PVC_NTIMESLOT); |
1701 | 115k | if (hFrameData->frameInfo |
1702 | 115k | .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] > |
1703 | 115k | PVC_NTIMESLOT) { |
1704 | 88.7k | FDK_ASSERT(noiseLevels == |
1705 | 0 | (hFrameData->sbrNoiseFloorLevel + |
1706 | 0 | (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands)); |
1707 | 0 | h_sbr_cal_env->prevNNfb = noNoiseBands; |
1708 | | |
1709 | 88.7k | h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0]; |
1710 | 88.7k | h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1]; |
1711 | | |
1712 | 88.7k | h_sbr_cal_env->prevLoSubband = lowSubband; |
1713 | 88.7k | h_sbr_cal_env->prevHiSubband = highSubband; |
1714 | 88.7k | h_sbr_cal_env->prev_ov_highSubband = ov_highSubband; |
1715 | | |
1716 | 88.7k | FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0], |
1717 | 88.7k | noSubFrameBands[0] + 1); |
1718 | 88.7k | FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1], |
1719 | 88.7k | noSubFrameBands[1] + 1); |
1720 | 88.7k | FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise, |
1721 | 88.7k | hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise)); |
1722 | | |
1723 | 88.7k | FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels, |
1724 | 88.7k | MAX_NOISE_COEFFS * sizeof(FIXP_SGL)); |
1725 | 88.7k | } |
1726 | 115k | } |
1727 | | |
1728 | 404k | C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64) |
1729 | 404k | } |
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 |
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 | 241k | const UINT flags) { |
1746 | 241k | SBR_ERROR err = SBRDEC_OK; |
1747 | 241k | int i; |
1748 | | |
1749 | | /* Clear previous missing harmonics flags */ |
1750 | 725k | for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) { |
1751 | 483k | hs->harmFlagsPrev[i] = 0; |
1752 | 483k | hs->harmFlagsPrevActive[i] = 0; |
1753 | 483k | } |
1754 | 241k | hs->harmIndex = 0; |
1755 | | |
1756 | 241k | FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel)); |
1757 | 241k | hs->prevNNfb = 0; |
1758 | 241k | FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise)); |
1759 | 241k | 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 | 241k | hs->prevTranEnv = -1; |
1766 | | |
1767 | | /* initialization */ |
1768 | 241k | resetSbrEnvelopeCalc(hs); |
1769 | | |
1770 | 241k | if (chan == 0) { /* do this only once */ |
1771 | 156k | err = resetFreqBandTables(hHeaderData, flags); |
1772 | 156k | } |
1773 | | |
1774 | 241k | return err; |
1775 | 241k | } |
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 | | */ |
1785 | 249k | 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 | | */ |
1795 | | void resetSbrEnvelopeCalc( |
1796 | | HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */ |
1797 | 645k | { |
1798 | 645k | hCalEnv->phaseIndex = 0; |
1799 | | |
1800 | | /* Noise exponent needs to be reset because the output exponent for the next |
1801 | | * frame depends on it */ |
1802 | 645k | hCalEnv->filtBufferNoise_e = 0; |
1803 | | |
1804 | 645k | hCalEnv->startUp = 1; |
1805 | 645k | } |
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 | | */ |
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 | 2.10M | { |
1821 | 2.10M | int band; |
1822 | 2.10M | int diff; |
1823 | | |
1824 | 51.2M | for (band = 0; band < subbands; band++) { |
1825 | 49.1M | diff = (int)(nrgGain_e[band] - filtBuffer_e[band]); |
1826 | 49.1M | if (diff > 0) { |
1827 | 2.18M | filtBuffer[band] >>= |
1828 | 2.18M | fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by |
1829 | | shifting the mantissa. */ |
1830 | 2.18M | filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ |
1831 | 46.9M | } 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 | 38.0M | int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1; |
1836 | | |
1837 | 38.0M | 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 | 33.2M | filtBuffer[band] <<= (-diff); |
1842 | 33.2M | filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */ |
1843 | 33.2M | } else { |
1844 | 4.82M | filtBuffer[band] <<= |
1845 | 4.82M | reserve; /* Shift the mantissa as far as possible: */ |
1846 | 4.82M | filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ |
1847 | | |
1848 | | /* For the remaining difference, change the new gain value */ |
1849 | 4.82M | diff = -(reserve + diff); |
1850 | 4.82M | nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1); |
1851 | 4.82M | nrgGain_e[band] += diff; |
1852 | 4.82M | } |
1853 | 38.0M | } |
1854 | 49.1M | } |
1855 | 2.10M | } |
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 | | */ |
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 | 1.51M | { |
1873 | 1.51M | int width = highSubband - lowSubband; |
1874 | | |
1875 | 1.51M | if ((width > 0) && (shift != 0)) { |
1876 | 1.39M | if (im != NULL) { |
1877 | 27.4M | for (int l = start_pos; l < next_pos; l++) { |
1878 | 26.4M | scaleValues(&re[l][lowSubband], width, shift); |
1879 | 26.4M | scaleValues(&im[l][lowSubband], width, shift); |
1880 | 26.4M | } |
1881 | 1.00M | } else { |
1882 | 7.96M | for (int l = start_pos; l < next_pos; l++) { |
1883 | 7.57M | scaleValues(&re[l][lowSubband], width, shift); |
1884 | 7.57M | } |
1885 | 394k | } |
1886 | 1.39M | } |
1887 | 1.51M | } |
1888 | | |
1889 | | static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp, |
1890 | 11.2M | INT width) { |
1891 | 11.2M | maxVal = (FIXP_DBL)0; |
1892 | 240M | while (width-- != 0) { |
1893 | 228M | FIXP_DBL tmp = *(reTmp++); |
1894 | 228M | maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1))); |
1895 | 228M | } |
1896 | | |
1897 | 11.2M | return maxVal; |
1898 | 11.2M | } |
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 | | |
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 | 2.10M | ) { |
1917 | 2.10M | FIXP_DBL maxVal = FL2FX_DBL(0.0f); |
1918 | 2.10M | unsigned int width = highSubband - lowSubband; |
1919 | | |
1920 | 2.10M | FDK_ASSERT(width <= (64)); |
1921 | | |
1922 | 2.10M | if (width > 0) { |
1923 | 2.10M | if (im != NULL) { |
1924 | 47.2M | for (int l = start_pos; l < next_pos; l++) { |
1925 | 45.6M | int k = width; |
1926 | 45.6M | FIXP_DBL *reTmp = &re[l][lowSubband]; |
1927 | 45.6M | FIXP_DBL *imTmp = &im[l][lowSubband]; |
1928 | 675M | do { |
1929 | 675M | FIXP_DBL tmp1 = *(reTmp++); |
1930 | 675M | FIXP_DBL tmp2 = *(imTmp++); |
1931 | 675M | maxVal |= |
1932 | 675M | (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1))); |
1933 | 675M | maxVal |= |
1934 | 675M | (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1))); |
1935 | 675M | } while (--k != 0); |
1936 | 45.6M | } |
1937 | 1.55M | } else { |
1938 | 11.8M | for (int l = start_pos; l < next_pos; l++) { |
1939 | 11.2M | maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width); |
1940 | 11.2M | } |
1941 | 547k | } |
1942 | 2.10M | } |
1943 | | |
1944 | 2.10M | 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 | 1.08M | FIXP_DBL lowerPow2 = |
1948 | 1.08M | (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal))); |
1949 | 1.08M | if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1; |
1950 | 1.08M | } |
1951 | | |
1952 | 2.10M | return (maxVal); |
1953 | 2.10M | } |
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 | 29.7M | #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 | | */ |
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 | 2.13M | { |
1995 | 2.13M | FIXP_SGL invWidth; |
1996 | 2.13M | SCHAR preShift; |
1997 | 2.13M | SCHAR shift; |
1998 | 2.13M | FIXP_DBL sum; |
1999 | 2.13M | int k; |
2000 | | |
2001 | | /* Divide by width of envelope later: */ |
2002 | 2.13M | invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); |
2003 | | /* The common exponent needs to be doubled because all mantissas are squared: |
2004 | | */ |
2005 | 2.13M | frameExp = frameExp << 1; |
2006 | | |
2007 | 51.4M | for (k = lowSubband; k < highSubband; k++) { |
2008 | 49.2M | FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))]; |
2009 | 49.2M | FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))]; |
2010 | 49.2M | FIXP_DBL maxVal; |
2011 | | |
2012 | 49.2M | if (analysBufferImag != NULL) { |
2013 | 48.1M | int l; |
2014 | 48.1M | maxVal = FL2FX_DBL(0.0f); |
2015 | 303M | for (l = start_pos; l < next_pos; l++) { |
2016 | 255M | bufferImag[l] = analysBufferImag[l][k]; |
2017 | 255M | maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^ |
2018 | 255M | ((LONG)bufferImag[l] >> (DFRACT_BITS - 1))); |
2019 | 255M | bufferReal[l] = analysBufferReal[l][k]; |
2020 | 255M | maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^ |
2021 | 255M | ((LONG)bufferReal[l] >> (DFRACT_BITS - 1))); |
2022 | 255M | } |
2023 | 48.1M | } else { |
2024 | 1.14M | int l; |
2025 | 1.14M | maxVal = FL2FX_DBL(0.0f); |
2026 | 33.4M | for (l = start_pos; l < next_pos; l++) { |
2027 | 32.3M | bufferReal[l] = analysBufferReal[l][k]; |
2028 | 32.3M | maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^ |
2029 | 32.3M | ((LONG)bufferReal[l] >> (DFRACT_BITS - 1))); |
2030 | 32.3M | } |
2031 | 1.14M | } |
2032 | | |
2033 | 49.2M | 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 | 29.4M | FIXP_DBL accu; |
2041 | 29.4M | preShift = CntLeadingZeros(maxVal) - 1; |
2042 | 29.4M | 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 | 29.4M | preShift = fMin(preShift, (SCHAR)25); |
2049 | | |
2050 | 29.4M | accu = FL2FXCONST_DBL(0.0f); |
2051 | 29.4M | if (preShift >= 0) { |
2052 | 28.0M | int l; |
2053 | 28.0M | if (analysBufferImag != NULL) { |
2054 | 150M | for (l = start_pos; l < next_pos; l++) { |
2055 | 122M | FIXP_DBL temp1 = bufferReal[l] << (int)preShift; |
2056 | 122M | FIXP_DBL temp2 = bufferImag[l] << (int)preShift; |
2057 | 122M | accu = fPow2AddDiv2(accu, temp1); |
2058 | 122M | accu = fPow2AddDiv2(accu, temp2); |
2059 | 122M | } |
2060 | 28.0M | } else { |
2061 | 843k | for (l = start_pos; l < next_pos; l++) { |
2062 | 796k | FIXP_DBL temp = bufferReal[l] << (int)preShift; |
2063 | 796k | accu = fPow2AddDiv2(accu, temp); |
2064 | 796k | } |
2065 | 46.8k | } |
2066 | 28.0M | } else { /* if negative shift value */ |
2067 | 1.37M | int l; |
2068 | 1.37M | int negpreShift = -preShift; |
2069 | 1.37M | if (analysBufferImag != NULL) { |
2070 | 9.82M | for (l = start_pos; l < next_pos; l++) { |
2071 | 8.45M | FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift; |
2072 | 8.45M | FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift; |
2073 | 8.45M | accu = fPow2AddDiv2(accu, temp1); |
2074 | 8.45M | accu = fPow2AddDiv2(accu, temp2); |
2075 | 8.45M | } |
2076 | 1.37M | } else { |
2077 | 155k | for (l = start_pos; l < next_pos; l++) { |
2078 | 147k | FIXP_DBL temp = bufferReal[l] >> (int)negpreShift; |
2079 | 147k | accu = fPow2AddDiv2(accu, temp); |
2080 | 147k | } |
2081 | 8.03k | } |
2082 | 1.37M | } |
2083 | 29.4M | accu <<= 1; |
2084 | | |
2085 | | /* Convert double precision to Mantissa/Exponent: */ |
2086 | 29.4M | shift = fNorm(accu); |
2087 | 29.4M | sum = accu << (int)shift; |
2088 | | |
2089 | | /* Divide by width of envelope and apply frame scale: */ |
2090 | 29.4M | *nrgEst++ = fMult(sum, invWidth); |
2091 | 29.4M | shift += 2 * preShift; |
2092 | 29.4M | if (analysBufferImag != NULL) |
2093 | 29.4M | *nrgEst_e++ = frameExp - shift; |
2094 | 54.9k | else |
2095 | 54.9k | *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */ |
2096 | 29.4M | } /* maxVal!=0 */ |
2097 | 19.8M | else { |
2098 | | /* Prevent a zero-mantissa-number from being misinterpreted |
2099 | | due to its exponent. */ |
2100 | 19.8M | *nrgEst++ = FL2FXCONST_DBL(0.0f); |
2101 | 19.8M | *nrgEst_e++ = 0; |
2102 | 19.8M | } |
2103 | 49.2M | } |
2104 | 2.13M | } |
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 | | */ |
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 | 73.8k | { |
2123 | 73.8k | FIXP_SGL invWidth; |
2124 | 73.8k | FIXP_DBL temp; |
2125 | 73.8k | SCHAR preShift; |
2126 | 73.8k | SCHAR shift, sum_e; |
2127 | 73.8k | FIXP_DBL sum; |
2128 | | |
2129 | 73.8k | int j, k, l, li, ui; |
2130 | 73.8k | 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 | 73.8k | invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); |
2135 | | /* The common exponent needs to be doubled because all mantissas are squared: |
2136 | | */ |
2137 | 73.8k | input_e = input_e << 1; |
2138 | | |
2139 | 654k | for (j = 0; j < nSfb; j++) { |
2140 | 580k | li = freqBandTable[j]; |
2141 | 580k | ui = freqBandTable[j + 1]; |
2142 | | |
2143 | 580k | FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li, |
2144 | 580k | ui, start_pos, next_pos); |
2145 | | |
2146 | 580k | if (maxVal != FL2FXCONST_DBL(0.f)) { |
2147 | 303k | 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 | 303k | preShift -= SHIFT_BEFORE_SQUARE; |
2156 | | |
2157 | 303k | sumAll = FL2FXCONST_DBL(0.0f); |
2158 | | |
2159 | 783k | for (k = li; k < ui; k++) { |
2160 | 479k | sumLine = FL2FXCONST_DBL(0.0f); |
2161 | | |
2162 | 479k | if (analysBufferImag != NULL) { |
2163 | 394k | if (preShift >= 0) { |
2164 | 16.2M | for (l = start_pos; l < next_pos; l++) { |
2165 | 15.9M | temp = analysBufferReal[l][k] << (int)preShift; |
2166 | 15.9M | sumLine += fPow2Div2(temp); |
2167 | 15.9M | temp = analysBufferImag[l][k] << (int)preShift; |
2168 | 15.9M | sumLine += fPow2Div2(temp); |
2169 | 15.9M | } |
2170 | 375k | } else { |
2171 | 212k | for (l = start_pos; l < next_pos; l++) { |
2172 | 193k | temp = analysBufferReal[l][k] >> -(int)preShift; |
2173 | 193k | sumLine += fPow2Div2(temp); |
2174 | 193k | temp = analysBufferImag[l][k] >> -(int)preShift; |
2175 | 193k | sumLine += fPow2Div2(temp); |
2176 | 193k | } |
2177 | 19.6k | } |
2178 | 394k | } else { |
2179 | 84.6k | if (preShift >= 0) { |
2180 | 2.48M | for (l = start_pos; l < next_pos; l++) { |
2181 | 2.40M | temp = analysBufferReal[l][k] << (int)preShift; |
2182 | 2.40M | sumLine += fPow2Div2(temp); |
2183 | 2.40M | } |
2184 | 78.3k | } else { |
2185 | 160k | for (l = start_pos; l < next_pos; l++) { |
2186 | 154k | temp = analysBufferReal[l][k] >> -(int)preShift; |
2187 | 154k | sumLine += fPow2Div2(temp); |
2188 | 154k | } |
2189 | 6.36k | } |
2190 | 84.6k | } |
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 | 479k | sumLine = sumLine >> (4 - 1); |
2195 | 479k | sumAll += sumLine; |
2196 | 479k | } |
2197 | | |
2198 | | /* Convert double precision to Mantissa/Exponent: */ |
2199 | 303k | shift = fNorm(sumAll); |
2200 | 303k | sum = sumAll << (int)shift; |
2201 | | |
2202 | | /* Divide by width of envelope: */ |
2203 | 303k | sum = fMult(sum, invWidth); |
2204 | | |
2205 | | /* Divide by width of Sfb: */ |
2206 | 303k | sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li))); |
2207 | | |
2208 | | /* Set all Subband energies in the Sfb to the average energy: */ |
2209 | 303k | if (analysBufferImag != NULL) |
2210 | 276k | sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */ |
2211 | 27.2k | else |
2212 | 27.2k | sum_e = input_e + 4 + 1 - |
2213 | 27.2k | shift; /* -4 to compensate right-shift; +1 due to missing |
2214 | | imag. part */ |
2215 | | |
2216 | 303k | sum_e -= 2 * preShift; |
2217 | 303k | } /* maxVal!=0 */ |
2218 | 277k | else { |
2219 | | /* Prevent a zero-mantissa-number from being misinterpreted |
2220 | | due to its exponent. */ |
2221 | 277k | sum = FL2FXCONST_DBL(0.0f); |
2222 | 277k | sum_e = 0; |
2223 | 277k | } |
2224 | | |
2225 | 1.93M | for (k = li; k < ui; k++) { |
2226 | 1.35M | *nrgEst++ = sum; |
2227 | 1.35M | *nrgEst_e++ = sum_e; |
2228 | 1.35M | } |
2229 | 580k | } |
2230 | 73.8k | } |
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 | | */ |
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 | 50.6M | { |
2247 | 50.6M | FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */ |
2248 | 50.6M | SCHAR nrgEst_e = |
2249 | 50.6M | nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */ |
2250 | 50.6M | FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */ |
2251 | 50.6M | SCHAR *ptrNrgGain_e = |
2252 | 50.6M | &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */ |
2253 | 50.6M | FIXP_DBL *ptrNoiseLevel = |
2254 | 50.6M | &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */ |
2255 | 50.6M | SCHAR *ptrNoiseLevel_e = |
2256 | 50.6M | &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */ |
2257 | 50.6M | FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */ |
2258 | 50.6M | SCHAR *ptrNrgSine_e = |
2259 | 50.6M | &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */ |
2260 | | |
2261 | 50.6M | FIXP_DBL a, b, c; |
2262 | 50.6M | 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 | 50.6M | b_e = (int)(nrgEst_e - 1); |
2270 | 50.6M | if (b_e >= 0) { |
2271 | 25.6M | nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) + |
2272 | 25.6M | (nrgEst >> 1); |
2273 | 25.6M | nrgEst_e += 1; /* shift by 1 bit to avoid overflow */ |
2274 | | |
2275 | 25.6M | } else { |
2276 | 24.9M | nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) + |
2277 | 24.9M | (FL2FXCONST_DBL(0.5f) >> 1); |
2278 | 24.9M | nrgEst_e = 2; /* shift by 1 bit to avoid overflow */ |
2279 | 24.9M | } |
2280 | | |
2281 | | /* A = NrgRef * TmpNoise */ |
2282 | 50.6M | a = fMult(nrgRef, tmpNoise); |
2283 | 50.6M | a_e = nrgRef_e + tmpNoise_e; |
2284 | | |
2285 | | /* B = 1 + TmpNoise */ |
2286 | 50.6M | b_e = (int)(tmpNoise_e - 1); |
2287 | 50.6M | if (b_e >= 0) { |
2288 | 10.7M | b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) + |
2289 | 10.7M | (tmpNoise >> 1); |
2290 | 10.7M | b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */ |
2291 | 39.8M | } else { |
2292 | 39.8M | b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) + |
2293 | 39.8M | (FL2FXCONST_DBL(0.5f) >> 1); |
2294 | 39.8M | b_e = 2; /* shift by 1 bit to avoid overflow */ |
2295 | 39.8M | } |
2296 | | |
2297 | | /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */ |
2298 | 50.6M | FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e); |
2299 | | |
2300 | 50.6M | if (sinePresentFlag) { |
2301 | | /* C = (1 + TmpNoise) * NrgEst */ |
2302 | 259k | c = fMult(b, nrgEst); |
2303 | 259k | c_e = b_e + nrgEst_e; |
2304 | | |
2305 | | /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */ |
2306 | 259k | FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e); |
2307 | | |
2308 | 259k | if (sineMapped) { |
2309 | | /* sineLevel = nrgRef/ (1 + TmpNoise) */ |
2310 | 111k | FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e); |
2311 | 111k | } |
2312 | 50.3M | } else { |
2313 | 50.3M | if (noNoiseFlag) { |
2314 | | /* B = NrgEst */ |
2315 | 273k | b = nrgEst; |
2316 | 273k | b_e = nrgEst_e; |
2317 | 50.1M | } else { |
2318 | | /* B = NrgEst * (1 + TmpNoise) */ |
2319 | 50.1M | b = fMult(b, nrgEst); |
2320 | 50.1M | b_e = b_e + nrgEst_e; |
2321 | 50.1M | } |
2322 | | |
2323 | | /* gain = nrgRef / B */ |
2324 | 50.3M | INT result_exp = 0; |
2325 | 50.3M | *ptrNrgGain = fDivNorm(nrgRef, b, &result_exp); |
2326 | 50.3M | *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 | 50.3M | int headroom = CountLeadingBits(*ptrNrgGain); |
2331 | 50.3M | *ptrNrgGain <<= headroom; |
2332 | 50.3M | *ptrNrgGain_e -= headroom; |
2333 | 50.3M | } |
2334 | 50.6M | } |
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 | | */ |
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 | 7.18M | { |
2351 | 7.18M | FIXP_DBL *nrgRef = |
2352 | 7.18M | nrgs->nrgRef; /*!< Reference Energy according to envelope data */ |
2353 | 7.18M | SCHAR *nrgRef_e = |
2354 | 7.18M | nrgs->nrgRef_e; /*!< Reference Energy according to envelope data |
2355 | | (exponent) */ |
2356 | 7.18M | FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */ |
2357 | 7.18M | SCHAR *nrgEst_e = |
2358 | 7.18M | nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */ |
2359 | | |
2360 | 7.18M | FIXP_DBL sumRef = 1; |
2361 | 7.18M | FIXP_DBL sumEst = 1; |
2362 | 7.18M | SCHAR sumRef_e = -FRACT_BITS; |
2363 | 7.18M | SCHAR sumEst_e = -FRACT_BITS; |
2364 | 7.18M | int k; |
2365 | | |
2366 | 57.8M | for (k = lowSubband; k < highSubband; k++) { |
2367 | | /* Add nrgRef[k] to sumRef: */ |
2368 | 50.6M | FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef, |
2369 | 50.6M | &sumRef_e); |
2370 | | |
2371 | | /* Add nrgEst[k] to sumEst: */ |
2372 | 50.6M | FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst, |
2373 | 50.6M | &sumEst_e); |
2374 | 50.6M | } |
2375 | | |
2376 | 7.18M | FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain, |
2377 | 7.18M | ptrAvgGain_e); |
2378 | | |
2379 | 7.18M | *ptrSumRef = sumRef; |
2380 | 7.18M | *ptrSumRef_e = sumRef_e; |
2381 | 7.18M | } |
2382 | | |
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 | 237k | { |
2395 | 237k | int k; |
2396 | 237k | FIXP_DBL signalReal, sbNoise; |
2397 | 237k | int tone_count = 0; |
2398 | | |
2399 | 237k | FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ |
2400 | 237k | FIXP_DBL *RESTRICT pNoiseLevel = |
2401 | 237k | nrgs->noiseLevel; /*!< Noise levels of current envelope */ |
2402 | 237k | FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ |
2403 | | |
2404 | 237k | int phaseIndex = *ptrPhaseIndex; |
2405 | 237k | UCHAR harmIndex = *ptrHarmIndex; |
2406 | | |
2407 | 237k | static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; |
2408 | | |
2409 | 237k | static const FIXP_DBL harmonicPhaseX[4][2] = { |
2410 | 237k | {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001), |
2411 | 237k | FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)}, |
2412 | 237k | {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001), |
2413 | 237k | FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)}, |
2414 | 237k | {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001), |
2415 | 237k | FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)}, |
2416 | 237k | {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001), |
2417 | 237k | FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}}; |
2418 | | |
2419 | 237k | const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0]; |
2420 | 237k | const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0]; |
2421 | | |
2422 | 237k | const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; |
2423 | 237k | const FIXP_DBL min_val = -max_val; |
2424 | | |
2425 | 237k | *(ptrReal - 1) = fAddSaturate( |
2426 | 237k | *(ptrReal - 1), |
2427 | 237k | SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]), |
2428 | 237k | scale_diff_low, DFRACT_BITS)); |
2429 | 237k | FIXP_DBL pSineLevel_prev = (FIXP_DBL)0; |
2430 | | |
2431 | 237k | int idx_k = lowSubband & 1; |
2432 | | |
2433 | 1.67M | for (k = 0; k < noSubbands; k++) { |
2434 | 1.43M | FIXP_DBL sineLevel_curr = *pSineLevel++; |
2435 | 1.43M | phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); |
2436 | | |
2437 | 1.43M | signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) |
2438 | 1.43M | << scale_change; |
2439 | 1.43M | sbNoise = *pNoiseLevel++; |
2440 | 1.43M | if (((INT)sineLevel_curr | noNoiseFlag) == 0) { |
2441 | 1.31M | signalReal += |
2442 | 1.31M | fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise); |
2443 | 1.31M | } |
2444 | 1.43M | signalReal += sineLevel_curr * p_harmonicPhase[0]; |
2445 | 1.43M | signalReal = |
2446 | 1.43M | fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]); |
2447 | 1.43M | pSineLevel_prev = sineLevel_curr; |
2448 | 1.43M | idx_k = !idx_k; |
2449 | 1.43M | if (k < noSubbands - 1) { |
2450 | 1.19M | signalReal = |
2451 | 1.19M | fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]); |
2452 | 1.19M | } else /* (k == noSubbands - 1) */ |
2453 | 237k | { |
2454 | 237k | if (k + lowSubband + 1 < 63) { |
2455 | 233k | *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]); |
2456 | 233k | } |
2457 | 237k | } |
2458 | 1.43M | *ptrReal++ = signalReal; |
2459 | | |
2460 | 1.43M | if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) { |
2461 | 47.4k | if (++tone_count == 16) { |
2462 | 246 | k++; |
2463 | 246 | break; |
2464 | 246 | } |
2465 | 47.4k | } |
2466 | 1.43M | } |
2467 | | /* Run again, if previous loop got breaked with tone_count = 16 */ |
2468 | 239k | for (; k < noSubbands; k++) { |
2469 | 2.01k | FIXP_DBL sineLevel_curr = *pSineLevel++; |
2470 | 2.01k | phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); |
2471 | | |
2472 | 2.01k | signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) |
2473 | 2.01k | << scale_change; |
2474 | 2.01k | sbNoise = *pNoiseLevel++; |
2475 | 2.01k | if (((INT)sineLevel_curr | noNoiseFlag) == 0) { |
2476 | 935 | signalReal += |
2477 | 935 | fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise); |
2478 | 935 | } |
2479 | 2.01k | signalReal += sineLevel_curr * p_harmonicPhase[0]; |
2480 | 2.01k | *ptrReal++ = signalReal; |
2481 | 2.01k | } |
2482 | | |
2483 | 237k | *ptrHarmIndex = (harmIndex + 1) & 3; |
2484 | 237k | *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1); |
2485 | 237k | } |
2486 | | |
2487 | | /*! |
2488 | | \brief Amplify one timeslot of the signal with the calculated gains |
2489 | | and add the noisefloor. |
2490 | | */ |
2491 | | |
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 | 1.90M | { |
2501 | 1.90M | FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ |
2502 | 1.90M | FIXP_DBL *pNoiseLevel = |
2503 | 1.90M | nrgs->noiseLevel; /*!< Noise levels of current envelope */ |
2504 | 1.90M | FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ |
2505 | | |
2506 | 1.90M | int k; |
2507 | 1.90M | int index = *ptrPhaseIndex; |
2508 | 1.90M | UCHAR harmIndex = *ptrHarmIndex; |
2509 | 1.90M | UCHAR freqInvFlag = (lowSubband & 1); |
2510 | 1.90M | FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; |
2511 | 1.90M | int tone_count = 0; |
2512 | 1.90M | int sineSign = 1; |
2513 | 1.90M | const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; |
2514 | 1.90M | const FIXP_DBL min_val = -max_val; |
2515 | | |
2516 | 21.7M | #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f)) |
2517 | 1.90M | #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 | 1.90M | 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 | 1.90M | signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) |
2531 | 1.90M | << scale_change; |
2532 | 1.90M | sineLevel = *pSineLevel++; |
2533 | 1.90M | sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); |
2534 | | |
2535 | 1.90M | if (sineLevel != FL2FXCONST_DBL(0.0f)) |
2536 | 79.3k | tone_count++; |
2537 | 1.82M | else if (!noNoiseFlag) |
2538 | | /* Add noisefloor to the amplified signal */ |
2539 | 1.79M | signalReal += |
2540 | 1.79M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]); |
2541 | | |
2542 | 1.90M | { |
2543 | 1.90M | if (!(harmIndex & 0x1)) { |
2544 | | /* harmIndex 0,2 */ |
2545 | 952k | signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel; |
2546 | 952k | *ptrReal++ = signalReal; |
2547 | 952k | } else { |
2548 | | /* harmIndex 1,3 in combination with freqInvFlag */ |
2549 | 952k | int shift = (int)(scale_change + 1); |
2550 | 952k | shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift) |
2551 | 952k | : fixMax(-(DFRACT_BITS - 1), shift); |
2552 | | |
2553 | 952k | FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift) |
2554 | 952k | : (fMultDiv2(C1, sineLevel) << (-shift)); |
2555 | 952k | FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext); |
2556 | | |
2557 | | /* save switch and compare operations and reduce to XOR statement */ |
2558 | 952k | if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) { |
2559 | 474k | *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1); |
2560 | 474k | signalReal -= tmp2; |
2561 | 477k | } else { |
2562 | 477k | *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1); |
2563 | 477k | signalReal += tmp2; |
2564 | 477k | } |
2565 | 952k | *ptrReal++ = signalReal; |
2566 | 952k | freqInvFlag = !freqInvFlag; |
2567 | 952k | } |
2568 | 1.90M | } |
2569 | | |
2570 | 1.90M | pNoiseLevel++; |
2571 | | |
2572 | 1.90M | if (noSubbands > 2) { |
2573 | 1.90M | if (!(harmIndex & 0x1)) { |
2574 | | /* harmIndex 0,2 */ |
2575 | 951k | if (!harmIndex) { |
2576 | 476k | sineSign = 0; |
2577 | 476k | } |
2578 | | |
2579 | 20.1M | for (k = noSubbands - 2; k != 0; k--) { |
2580 | 19.2M | FIXP_DBL sinelevel = *pSineLevel++; |
2581 | 19.2M | index++; |
2582 | 19.2M | if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == |
2583 | 19.2M | FL2FXCONST_DBL(0.0f)) && |
2584 | 19.2M | !noNoiseFlag) { |
2585 | | /* Add noisefloor to the amplified signal */ |
2586 | 18.0M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2587 | 18.0M | signalReal += |
2588 | 18.0M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]); |
2589 | 18.0M | } |
2590 | | |
2591 | | /* The next multiplication constitutes the actual envelope adjustment of |
2592 | | * the signal. */ |
2593 | 19.2M | signalReal += |
2594 | 19.2M | fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) |
2595 | 19.2M | << scale_change; |
2596 | | |
2597 | 19.2M | pNoiseLevel++; |
2598 | 19.2M | *ptrReal++ = signalReal; |
2599 | 19.2M | } /* for ... */ |
2600 | 951k | } else { |
2601 | | /* harmIndex 1,3 in combination with freqInvFlag */ |
2602 | 951k | if (harmIndex == 1) freqInvFlag = !freqInvFlag; |
2603 | | |
2604 | 20.1M | for (k = noSubbands - 2; k != 0; k--) { |
2605 | 19.2M | index++; |
2606 | | /* The next multiplication constitutes the actual envelope adjustment of |
2607 | | * the signal. */ |
2608 | 19.2M | signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) |
2609 | 19.2M | << scale_change; |
2610 | | |
2611 | 19.2M | if (*pSineLevel++ != FL2FXCONST_DBL(0.0f)) |
2612 | 789k | tone_count++; |
2613 | 18.4M | else if (!noNoiseFlag) { |
2614 | | /* Add noisefloor to the amplified signal */ |
2615 | 18.0M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2616 | 18.0M | signalReal += |
2617 | 18.0M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]); |
2618 | 18.0M | } |
2619 | | |
2620 | 19.2M | pNoiseLevel++; |
2621 | | |
2622 | 19.2M | if (tone_count <= 16) { |
2623 | 18.9M | FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1); |
2624 | 18.9M | signalReal += (freqInvFlag) ? (-addSine) : (addSine); |
2625 | 18.9M | } |
2626 | | |
2627 | 19.2M | *ptrReal++ = signalReal; |
2628 | 19.2M | freqInvFlag = !freqInvFlag; |
2629 | 19.2M | } /* for ... */ |
2630 | 951k | } |
2631 | 1.90M | } |
2632 | | |
2633 | 1.90M | if (noSubbands > -1) { |
2634 | 1.90M | index++; |
2635 | | /* The next multiplication constitutes the actual envelope adjustment of the |
2636 | | * signal. */ |
2637 | 1.90M | signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val) |
2638 | 1.90M | << scale_change; |
2639 | 1.90M | sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f)); |
2640 | 1.90M | sineLevel = pSineLevel[0]; |
2641 | | |
2642 | 1.90M | if (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) |
2643 | 50.6k | tone_count++; |
2644 | 1.85M | else if (!noNoiseFlag) { |
2645 | | /* Add noisefloor to the amplified signal */ |
2646 | 1.82M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2647 | 1.82M | signalReal = signalReal + fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], |
2648 | 1.82M | pNoiseLevel[0]); |
2649 | 1.82M | } |
2650 | | |
2651 | 1.90M | if (!(harmIndex & 0x1)) { |
2652 | | /* harmIndex 0,2 */ |
2653 | 952k | *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel); |
2654 | 952k | } else { |
2655 | | /* harmIndex 1,3 in combination with freqInvFlag */ |
2656 | 952k | if (tone_count <= 16) { |
2657 | 921k | if (freqInvFlag) { |
2658 | 461k | *ptrReal++ = signalReal - sineLevelPrev; |
2659 | 461k | if (noSubbands + lowSubband < 63) |
2660 | 453k | *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel); |
2661 | 461k | } else { |
2662 | 460k | *ptrReal++ = signalReal + sineLevelPrev; |
2663 | 460k | if (noSubbands + lowSubband < 63) |
2664 | 453k | *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel); |
2665 | 460k | } |
2666 | 921k | } else |
2667 | 30.6k | *ptrReal = signalReal; |
2668 | 952k | } |
2669 | 1.90M | } |
2670 | 1.90M | *ptrHarmIndex = (harmIndex + 1) & 3; |
2671 | 1.90M | *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); |
2672 | 1.90M | } |
2673 | | |
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 | 1.61M | { |
2687 | 1.61M | FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ |
2688 | 1.61M | FIXP_DBL *RESTRICT noiseLevel = |
2689 | 1.61M | nrgs->noiseLevel; /*!< Noise levels of current envelope */ |
2690 | 1.61M | FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ |
2691 | | |
2692 | 1.61M | FIXP_DBL *RESTRICT filtBuffer = |
2693 | 1.61M | h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ |
2694 | 1.61M | FIXP_DBL *RESTRICT filtBufferNoise = |
2695 | 1.61M | h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ |
2696 | 1.61M | int *RESTRICT ptrPhaseIndex = |
2697 | 1.61M | &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ |
2698 | | |
2699 | 1.61M | int k; |
2700 | 1.61M | FIXP_DBL signalReal, signalImag; |
2701 | 1.61M | FIXP_DBL noiseReal, noiseImag; |
2702 | 1.61M | FIXP_DBL smoothedGain, smoothedNoise; |
2703 | 1.61M | FIXP_SGL direct_ratio = |
2704 | 1.61M | /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; |
2705 | 1.61M | int index = *ptrPhaseIndex; |
2706 | 1.61M | int shift; |
2707 | 1.61M | FIXP_DBL max_val_noise = 0, min_val_noise = 0; |
2708 | 1.61M | const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; |
2709 | 1.61M | const FIXP_DBL min_val = -max_val; |
2710 | | |
2711 | 1.61M | *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); |
2712 | | |
2713 | 1.61M | filtBufferNoiseShift += |
2714 | 1.61M | 1; /* due to later use of fMultDiv2 instead of fMult */ |
2715 | 1.61M | if (filtBufferNoiseShift < 0) { |
2716 | 5.88k | shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); |
2717 | 1.61M | } else { |
2718 | 1.61M | shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); |
2719 | 1.61M | max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; |
2720 | 1.61M | min_val_noise = -max_val_noise; |
2721 | 1.61M | } |
2722 | | |
2723 | 1.61M | if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { |
2724 | 571k | 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 | 550k | smoothedGain = |
2730 | 550k | fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]); |
2731 | | |
2732 | 550k | if (filtBufferNoiseShift < 0) { |
2733 | 244 | smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + |
2734 | 244 | fMult(direct_ratio, noiseLevel[k]); |
2735 | 549k | } else { |
2736 | 549k | smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); |
2737 | 549k | smoothedNoise = |
2738 | 549k | (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + |
2739 | 549k | fMult(direct_ratio, noiseLevel[k]); |
2740 | 549k | } |
2741 | | |
2742 | 550k | smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)), |
2743 | 550k | (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 | 550k | signalReal = |
2751 | 550k | fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) |
2752 | 550k | << scale_change; |
2753 | 550k | signalImag = |
2754 | 550k | fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) |
2755 | 550k | << scale_change; |
2756 | | |
2757 | 550k | index++; |
2758 | | |
2759 | 550k | if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) { |
2760 | | /* Just the amplified signal is saved */ |
2761 | 1.42k | *ptrReal++ = signalReal; |
2762 | 1.42k | *ptrImag++ = signalImag; |
2763 | 548k | } else { |
2764 | | /* Add noisefloor to the amplified signal */ |
2765 | 548k | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2766 | 548k | noiseReal = |
2767 | 548k | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); |
2768 | 548k | noiseImag = |
2769 | 548k | fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); |
2770 | 548k | *ptrReal++ = (signalReal + noiseReal); |
2771 | 548k | *ptrImag++ = (signalImag + noiseImag); |
2772 | 548k | } |
2773 | 550k | } |
2774 | 1.59M | } else { |
2775 | 24.9M | for (k = 0; k < noSubbands; k++) { |
2776 | 23.3M | smoothedGain = gain[k]; |
2777 | 23.3M | signalReal = |
2778 | 23.3M | fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) |
2779 | 23.3M | << scale_change; |
2780 | 23.3M | signalImag = |
2781 | 23.3M | fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) |
2782 | 23.3M | << scale_change; |
2783 | | |
2784 | 23.3M | index++; |
2785 | | |
2786 | 23.3M | if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) { |
2787 | | /* Add noisefloor to the amplified signal */ |
2788 | 19.3M | smoothedNoise = noiseLevel[k]; |
2789 | 19.3M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2790 | 19.3M | noiseReal = |
2791 | 19.3M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); |
2792 | 19.3M | noiseImag = |
2793 | 19.3M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); |
2794 | | |
2795 | 19.3M | signalReal += noiseReal; |
2796 | 19.3M | signalImag += noiseImag; |
2797 | 19.3M | } |
2798 | 23.3M | *ptrReal++ = signalReal; |
2799 | 23.3M | *ptrImag++ = signalImag; |
2800 | 23.3M | } |
2801 | 1.59M | } |
2802 | 1.61M | } |
2803 | | |
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 | 1.61M | ) { |
2815 | 1.61M | FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ |
2816 | 1.61M | UCHAR *RESTRICT ptrHarmIndex = |
2817 | 1.61M | &h_sbr_cal_env->harmIndex; /*!< Harmonic index */ |
2818 | | |
2819 | 1.61M | int k; |
2820 | 1.61M | FIXP_DBL signalReal, signalImag; |
2821 | 1.61M | UCHAR harmIndex = *ptrHarmIndex; |
2822 | 1.61M | int freqInvFlag = (lowSubband & 1); |
2823 | 1.61M | FIXP_DBL sineLevel; |
2824 | | |
2825 | 1.61M | *ptrHarmIndex = (harmIndex + 1) & 3; |
2826 | | |
2827 | 25.5M | for (k = 0; k < noSubbands; k++) { |
2828 | 23.9M | sineLevel = pSineLevel[k]; |
2829 | 23.9M | freqInvFlag ^= 1; |
2830 | 23.9M | if (sineLevel != FL2FXCONST_DBL(0.f)) { |
2831 | 63.0k | signalReal = ptrReal[k]; |
2832 | 63.0k | signalImag = ptrImag[k]; |
2833 | 63.0k | sineLevel = scaleValue(sineLevel, scale_change); |
2834 | 63.0k | if (harmIndex & 2) { |
2835 | | /* case 2,3 */ |
2836 | 31.4k | sineLevel = -sineLevel; |
2837 | 31.4k | } |
2838 | 63.0k | if (!(harmIndex & 1)) { |
2839 | | /* case 0,2: */ |
2840 | 31.5k | ptrReal[k] = signalReal + sineLevel; |
2841 | 31.5k | } else { |
2842 | | /* case 1,3 */ |
2843 | 31.5k | if (!freqInvFlag) sineLevel = -sineLevel; |
2844 | 31.5k | ptrImag[k] = signalImag + sineLevel; |
2845 | 31.5k | } |
2846 | 63.0k | } |
2847 | 23.9M | } |
2848 | 1.61M | } |
2849 | | |
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 | 10.4M | { |
2863 | 10.4M | FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ |
2864 | 10.4M | FIXP_DBL *RESTRICT noiseLevel = |
2865 | 10.4M | nrgs->noiseLevel; /*!< Noise levels of current envelope */ |
2866 | 10.4M | FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ |
2867 | | |
2868 | 10.4M | FIXP_DBL *RESTRICT filtBuffer = |
2869 | 10.4M | h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ |
2870 | 10.4M | FIXP_DBL *RESTRICT filtBufferNoise = |
2871 | 10.4M | h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ |
2872 | 10.4M | UCHAR *RESTRICT ptrHarmIndex = |
2873 | 10.4M | &h_sbr_cal_env->harmIndex; /*!< Harmonic index */ |
2874 | 10.4M | int *RESTRICT ptrPhaseIndex = |
2875 | 10.4M | &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ |
2876 | | |
2877 | 10.4M | int k; |
2878 | 10.4M | FIXP_DBL signalReal, signalImag; |
2879 | 10.4M | FIXP_DBL noiseReal, noiseImag; |
2880 | 10.4M | FIXP_DBL smoothedGain, smoothedNoise; |
2881 | 10.4M | FIXP_SGL direct_ratio = |
2882 | 10.4M | /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; |
2883 | 10.4M | int index = *ptrPhaseIndex; |
2884 | 10.4M | UCHAR harmIndex = *ptrHarmIndex; |
2885 | 10.4M | int freqInvFlag = (lowSubband & 1); |
2886 | 10.4M | FIXP_DBL sineLevel; |
2887 | 10.4M | int shift; |
2888 | 10.4M | FIXP_DBL max_val_noise = 0, min_val_noise = 0; |
2889 | 10.4M | const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; |
2890 | 10.4M | const FIXP_DBL min_val = -max_val; |
2891 | | |
2892 | 10.4M | *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); |
2893 | 10.4M | *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 | 10.4M | filtBufferNoiseShift += |
2905 | 10.4M | 1; /* due to later use of fMultDiv2 instead of fMult */ |
2906 | 10.4M | if (filtBufferNoiseShift < 0) { |
2907 | 1.32k | shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); |
2908 | 10.4M | } else { |
2909 | 10.4M | shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); |
2910 | 10.4M | max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; |
2911 | 10.4M | min_val_noise = -max_val_noise; |
2912 | 10.4M | } |
2913 | | |
2914 | 10.4M | if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { |
2915 | 68.7M | 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 | 65.5M | smoothedGain = |
2922 | 65.5M | fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]); |
2923 | | |
2924 | 65.5M | if (filtBufferNoiseShift < 0) { |
2925 | 238 | smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + |
2926 | 238 | fMult(direct_ratio, noiseLevel[k]); |
2927 | 65.5M | } else { |
2928 | 65.5M | smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); |
2929 | 65.5M | smoothedNoise = |
2930 | 65.5M | (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + |
2931 | 65.5M | fMult(direct_ratio, noiseLevel[k]); |
2932 | 65.5M | } |
2933 | | |
2934 | 65.5M | smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)), |
2935 | 65.5M | (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 | 65.5M | signalReal = |
2943 | 65.5M | fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) |
2944 | 65.5M | << scale_change; |
2945 | 65.5M | signalImag = |
2946 | 65.5M | fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) |
2947 | 65.5M | << scale_change; |
2948 | | |
2949 | 65.5M | index++; |
2950 | | |
2951 | 65.5M | if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) { |
2952 | 76.5k | sineLevel = pSineLevel[k]; |
2953 | | |
2954 | 76.5k | switch (harmIndex) { |
2955 | 19.1k | case 0: |
2956 | 19.1k | *ptrReal++ = (signalReal + sineLevel); |
2957 | 19.1k | *ptrImag++ = (signalImag); |
2958 | 19.1k | break; |
2959 | 19.1k | case 2: |
2960 | 19.1k | *ptrReal++ = (signalReal - sineLevel); |
2961 | 19.1k | *ptrImag++ = (signalImag); |
2962 | 19.1k | break; |
2963 | 19.1k | case 1: |
2964 | 19.1k | *ptrReal++ = (signalReal); |
2965 | 19.1k | if (freqInvFlag) |
2966 | 16.7k | *ptrImag++ = (signalImag - sineLevel); |
2967 | 2.38k | else |
2968 | 2.38k | *ptrImag++ = (signalImag + sineLevel); |
2969 | 19.1k | break; |
2970 | 19.1k | case 3: |
2971 | 19.1k | *ptrReal++ = signalReal; |
2972 | 19.1k | if (freqInvFlag) |
2973 | 16.7k | *ptrImag++ = (signalImag + sineLevel); |
2974 | 2.39k | else |
2975 | 2.39k | *ptrImag++ = (signalImag - sineLevel); |
2976 | 19.1k | break; |
2977 | 76.5k | } |
2978 | 65.4M | } else { |
2979 | 65.4M | if (noNoiseFlag) { |
2980 | | /* Just the amplified signal is saved */ |
2981 | 0 | *ptrReal++ = (signalReal); |
2982 | 0 | *ptrImag++ = (signalImag); |
2983 | 65.4M | } else { |
2984 | | /* Add noisefloor to the amplified signal */ |
2985 | 65.4M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
2986 | 65.4M | noiseReal = |
2987 | 65.4M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); |
2988 | 65.4M | noiseImag = |
2989 | 65.4M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); |
2990 | 65.4M | *ptrReal++ = (signalReal + noiseReal); |
2991 | 65.4M | *ptrImag++ = (signalImag + noiseImag); |
2992 | 65.4M | } |
2993 | 65.4M | } |
2994 | 65.5M | freqInvFlag ^= 1; |
2995 | 65.5M | } |
2996 | | |
2997 | 7.23M | } else { |
2998 | 195M | for (k = 0; k < noSubbands; k++) { |
2999 | 187M | smoothedGain = gain[k]; |
3000 | 187M | signalReal = |
3001 | 187M | fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) |
3002 | 187M | << scale_change; |
3003 | 187M | signalImag = |
3004 | 187M | fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) |
3005 | 187M | << scale_change; |
3006 | | |
3007 | 187M | index++; |
3008 | | |
3009 | 187M | if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) { |
3010 | 134k | switch (harmIndex) { |
3011 | 33.5k | case 0: |
3012 | 33.5k | signalReal += sineLevel; |
3013 | 33.5k | break; |
3014 | 33.5k | case 1: |
3015 | 33.5k | if (freqInvFlag) |
3016 | 22.1k | signalImag -= sineLevel; |
3017 | 11.4k | else |
3018 | 11.4k | signalImag += sineLevel; |
3019 | 33.5k | break; |
3020 | 33.5k | case 2: |
3021 | 33.5k | signalReal -= sineLevel; |
3022 | 33.5k | break; |
3023 | 33.5k | case 3: |
3024 | 33.5k | if (freqInvFlag) |
3025 | 22.0k | signalImag += sineLevel; |
3026 | 11.4k | else |
3027 | 11.4k | signalImag -= sineLevel; |
3028 | 33.5k | break; |
3029 | 134k | } |
3030 | 187M | } else { |
3031 | 187M | if (noNoiseFlag == 0) { |
3032 | | /* Add noisefloor to the amplified signal */ |
3033 | 185M | smoothedNoise = noiseLevel[k]; |
3034 | 185M | index &= (SBR_NF_NO_RANDOM_VAL - 1); |
3035 | 185M | noiseReal = |
3036 | 185M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); |
3037 | 185M | noiseImag = |
3038 | 185M | fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); |
3039 | | |
3040 | 185M | signalReal += noiseReal; |
3041 | 185M | signalImag += noiseImag; |
3042 | 185M | } |
3043 | 187M | } |
3044 | 187M | *ptrReal++ = signalReal; |
3045 | 187M | *ptrImag++ = signalImag; |
3046 | | |
3047 | 187M | freqInvFlag ^= 1; |
3048 | 187M | } |
3049 | 7.23M | } |
3050 | 10.4M | } |
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 |
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 | 430k | UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) { |
3070 | 430k | int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands; |
3071 | 430k | UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; |
3072 | 430k | int patchBorders[MAX_NUM_PATCHES + 1]; |
3073 | 430k | int kx, k2; |
3074 | | |
3075 | 430k | int lowSubband = freqBandTable[0]; |
3076 | 430k | int highSubband = freqBandTable[noFreqBands]; |
3077 | | |
3078 | | /* 1 limiter band. */ |
3079 | 430k | if (limiterBands == 0) { |
3080 | 12.8k | limiterBandTable[0] = 0; |
3081 | 12.8k | limiterBandTable[1] = highSubband - lowSubband; |
3082 | 12.8k | nBands = 1; |
3083 | 418k | } else { |
3084 | 418k | if (!sbrPatchingMode && xOverQmf != NULL) { |
3085 | 42.6k | noPatches = 0; |
3086 | | |
3087 | 42.6k | if (b41Sbr == 1) { |
3088 | 142k | for (i = 1; i < MAX_NUM_PATCHES_HBE; i++) |
3089 | 118k | if (xOverQmf[i] != 0) noPatches++; |
3090 | 23.7k | } else { |
3091 | 75.4k | for (i = 1; i < MAX_STRETCH_HBE; i++) |
3092 | 56.5k | if (xOverQmf[i] != 0) noPatches++; |
3093 | 18.8k | } |
3094 | 136k | for (i = 0; i < noPatches; i++) { |
3095 | 94.0k | patchBorders[i] = xOverQmf[i] - lowSubband; |
3096 | 94.0k | } |
3097 | 375k | } else { |
3098 | 1.02M | for (i = 0; i < noPatches; i++) { |
3099 | 647k | patchBorders[i] = patchParam[i].guardStartBand - lowSubband; |
3100 | 647k | } |
3101 | 375k | } |
3102 | 418k | patchBorders[i] = highSubband - lowSubband; |
3103 | | |
3104 | | /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */ |
3105 | 3.22M | for (k = 0; k <= noFreqBands; k++) { |
3106 | 2.80M | workLimiterBandTable[k] = freqBandTable[k] - lowSubband; |
3107 | 2.80M | } |
3108 | 882k | for (k = 1; k < noPatches; k++) { |
3109 | 464k | workLimiterBandTable[noFreqBands + k] = patchBorders[k]; |
3110 | 464k | } |
3111 | | |
3112 | 418k | tempNoLim = nBands = noFreqBands + noPatches - 1; |
3113 | 418k | shellsort(workLimiterBandTable, tempNoLim + 1); |
3114 | | |
3115 | 418k | loLimIndex = 0; |
3116 | 418k | hiLimIndex = 1; |
3117 | | |
3118 | 3.13M | while (hiLimIndex <= tempNoLim) { |
3119 | 2.71M | FIXP_DBL div_m, oct_m, temp; |
3120 | 2.71M | INT div_e = 0, oct_e = 0, temp_e = 0; |
3121 | | |
3122 | 2.71M | k2 = workLimiterBandTable[hiLimIndex] + lowSubband; |
3123 | 2.71M | kx = workLimiterBandTable[loLimIndex] + lowSubband; |
3124 | | |
3125 | 2.71M | div_m = fDivNorm(k2, kx, &div_e); |
3126 | | |
3127 | | /* calculate number of octaves */ |
3128 | 2.71M | 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 | 2.71M | temp = fMultNorm( |
3133 | 2.71M | oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], |
3134 | 2.71M | &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 | 2.71M | 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 | 2.71M | if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) { |
3148 | 1.62M | if (workLimiterBandTable[hiLimIndex] == |
3149 | 1.62M | workLimiterBandTable[loLimIndex]) { |
3150 | 87.8k | workLimiterBandTable[hiLimIndex] = highSubband; |
3151 | 87.8k | nBands--; |
3152 | 87.8k | hiLimIndex++; |
3153 | 87.8k | continue; |
3154 | 87.8k | } |
3155 | 1.53M | isPatchBorder[0] = isPatchBorder[1] = 0; |
3156 | 6.15M | for (k = 0; k <= noPatches; k++) { |
3157 | 5.11M | if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) { |
3158 | 502k | isPatchBorder[1] = 1; |
3159 | 502k | break; |
3160 | 502k | } |
3161 | 5.11M | } |
3162 | 1.53M | if (!isPatchBorder[1]) { |
3163 | 1.03M | workLimiterBandTable[hiLimIndex] = highSubband; |
3164 | 1.03M | nBands--; |
3165 | 1.03M | hiLimIndex++; |
3166 | 1.03M | continue; |
3167 | 1.03M | } |
3168 | 2.02M | for (k = 0; k <= noPatches; k++) { |
3169 | 1.74M | if (workLimiterBandTable[loLimIndex] == patchBorders[k]) { |
3170 | 218k | isPatchBorder[0] = 1; |
3171 | 218k | break; |
3172 | 218k | } |
3173 | 1.74M | } |
3174 | 502k | if (!isPatchBorder[0]) { |
3175 | 284k | workLimiterBandTable[loLimIndex] = highSubband; |
3176 | 284k | nBands--; |
3177 | 284k | } |
3178 | 502k | } |
3179 | 1.58M | loLimIndex = hiLimIndex; |
3180 | 1.58M | hiLimIndex++; |
3181 | 1.58M | } |
3182 | 418k | shellsort(workLimiterBandTable, tempNoLim + 1); |
3183 | | |
3184 | | /* Test if algorithm exceeded maximum allowed limiterbands */ |
3185 | 418k | if (nBands > MAX_NUM_LIMITERS || nBands <= 0) { |
3186 | 4.69k | return SBRDEC_UNSUPPORTED_CONFIG; |
3187 | 4.69k | } |
3188 | | |
3189 | | /* Restrict maximum value of limiter band table */ |
3190 | 413k | if (workLimiterBandTable[tempNoLim] > highSubband) { |
3191 | 623 | return SBRDEC_UNSUPPORTED_CONFIG; |
3192 | 623 | } |
3193 | | |
3194 | | /* Copy limiterbands from working buffer into final destination */ |
3195 | 2.12M | for (k = 0; k <= nBands; k++) { |
3196 | 1.71M | limiterBandTable[k] = workLimiterBandTable[k]; |
3197 | 1.71M | } |
3198 | 412k | } |
3199 | 425k | *noLimiterBands = nBands; |
3200 | | |
3201 | 425k | return SBRDEC_OK; |
3202 | 430k | } |