/src/aac/libSBRenc/src/env_est.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 - 2020 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 encoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "env_est.h" |
104 | | #include "tran_det.h" |
105 | | |
106 | | #include "qmf.h" |
107 | | |
108 | | #include "fram_gen.h" |
109 | | #include "bit_sbr.h" |
110 | | #include "cmondata.h" |
111 | | #include "sbrenc_ram.h" |
112 | | |
113 | | #include "genericStds.h" |
114 | | |
115 | | #define QUANT_ERROR_THRES 200 |
116 | | #define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */ |
117 | | #define MAX_NRG_SLOTS_LD 16 |
118 | | |
119 | | static const UCHAR panTable[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24}, |
120 | | {0, 2, 4, 8, 12, 0, 0, 0, 0}}; |
121 | | static const UCHAR maxIndex[2] = {9, 5}; |
122 | | |
123 | | /****************************************************************************** |
124 | | Functionname: FDKsbrEnc_GetTonality |
125 | | ******************************************************************************/ |
126 | | /***************************************************************************/ |
127 | | /*! |
128 | | |
129 | | \brief Calculates complete energy per band from the energy values |
130 | | of the QMF subsamples. |
131 | | |
132 | | \brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas() |
133 | | \brief noEstPerFrame - number of estimations per frame |
134 | | \brief startIndex - start index for the quota matrix |
135 | | \brief Energies - energy matrix |
136 | | \brief startBand - start band |
137 | | \brief stopBand - number of QMF bands |
138 | | \brief numberCols - number of QMF subsamples |
139 | | |
140 | | \return mean tonality of the 5 bands with the highest energy |
141 | | scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT |
142 | | |
143 | | ****************************************************************************/ |
144 | | static FIXP_DBL FDKsbrEnc_GetTonality(const FIXP_DBL *const *quotaMatrix, |
145 | | const INT noEstPerFrame, |
146 | | const INT startIndex, |
147 | | const FIXP_DBL *const *Energies, |
148 | | const UCHAR startBand, const INT stopBand, |
149 | 0 | const INT numberCols) { |
150 | 0 | UCHAR b, e, k; |
151 | 0 | INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = {-1, -1, -1, -1, -1}; |
152 | 0 | FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { |
153 | 0 | FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), |
154 | 0 | FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)}; |
155 | 0 | FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */ |
156 | 0 | UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */ |
157 | 0 | FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { |
158 | 0 | FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), |
159 | 0 | FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)}; |
160 | 0 | FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f); |
161 | 0 | FIXP_DBL energyBand[64]; |
162 | 0 | INT maxNEnergyValues; /* max. number of max. energy values */ |
163 | | |
164 | | /*** Sum up energies for each band ***/ |
165 | 0 | FDK_ASSERT(numberCols == 15 || numberCols == 16); |
166 | | /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the |
167 | | energyBands are initialized with the [15]th column. |
168 | | The rest of the column energies are added in the next step. */ |
169 | 0 | if (numberCols == 15) { |
170 | 0 | for (b = startBand; b < stopBand; b++) { |
171 | 0 | energyBand[b] = FL2FXCONST_DBL(0.0f); |
172 | 0 | } |
173 | 0 | } else { |
174 | 0 | for (b = startBand; b < stopBand; b++) { |
175 | 0 | energyBand[b] = Energies[15][b] >> 4; |
176 | 0 | } |
177 | 0 | } |
178 | |
|
179 | 0 | for (k = 0; k < 15; k++) { |
180 | 0 | for (b = startBand; b < stopBand; b++) { |
181 | 0 | energyBand[b] += Energies[k][b] >> 4; |
182 | 0 | } |
183 | 0 | } |
184 | | |
185 | | /*** Determine 5 highest band-energies ***/ |
186 | 0 | maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand - startBand); |
187 | | |
188 | | /* Get min. value in energyMax array */ |
189 | 0 | energyMaxMin = energyMax[0] = energyBand[startBand]; |
190 | 0 | no_enMaxBand[0] = startBand; |
191 | 0 | posEnergyMaxMin = 0; |
192 | 0 | for (k = 1; k < maxNEnergyValues; k++) { |
193 | 0 | energyMax[k] = energyBand[startBand + k]; |
194 | 0 | no_enMaxBand[k] = startBand + k; |
195 | 0 | if (energyMaxMin > energyMax[k]) { |
196 | 0 | energyMaxMin = energyMax[k]; |
197 | 0 | posEnergyMaxMin = k; |
198 | 0 | } |
199 | 0 | } |
200 | |
|
201 | 0 | for (b = startBand + maxNEnergyValues; b < stopBand; b++) { |
202 | 0 | if (energyBand[b] > energyMaxMin) { |
203 | 0 | energyMax[posEnergyMaxMin] = energyBand[b]; |
204 | 0 | no_enMaxBand[posEnergyMaxMin] = b; |
205 | | |
206 | | /* Again, get min. value in energyMax array */ |
207 | 0 | energyMaxMin = energyMax[0]; |
208 | 0 | posEnergyMaxMin = 0; |
209 | 0 | for (k = 1; k < maxNEnergyValues; k++) { |
210 | 0 | if (energyMaxMin > energyMax[k]) { |
211 | 0 | energyMaxMin = energyMax[k]; |
212 | 0 | posEnergyMaxMin = k; |
213 | 0 | } |
214 | 0 | } |
215 | 0 | } |
216 | 0 | } |
217 | | /*** End determine 5 highest band-energies ***/ |
218 | | |
219 | | /* Get tonality values for 5 highest energies */ |
220 | 0 | for (e = 0; e < maxNEnergyValues; e++) { |
221 | 0 | tonalityBand[e] = FL2FXCONST_DBL(0.0f); |
222 | 0 | for (k = 0; k < noEstPerFrame; k++) { |
223 | 0 | tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1; |
224 | 0 | } |
225 | 0 | globalTonality += |
226 | 0 | tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */ |
227 | 0 | } |
228 | |
|
229 | 0 | return globalTonality; |
230 | 0 | } |
231 | | |
232 | | /***************************************************************************/ |
233 | | /*! |
234 | | |
235 | | \brief Calculates energy form real and imaginary part of |
236 | | the QMF subsamples |
237 | | |
238 | | \return none |
239 | | |
240 | | ****************************************************************************/ |
241 | | LNK_SECTION_CODE_L1 |
242 | | static void FDKsbrEnc_getEnergyFromCplxQmfData( |
243 | | FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */ |
244 | | FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */ |
245 | | FIXP_DBL **RESTRICT |
246 | | imagValues, /*!< the imaginary part of the QMF subsamples */ |
247 | | INT numberBands, /*!< number of QMF bands */ |
248 | | INT numberCols, /*!< number of QMF subsamples */ |
249 | | INT *qmfScale, /*!< sclefactor of QMF subsamples */ |
250 | | INT *energyScale) /*!< scalefactor of energies */ |
251 | 0 | { |
252 | 0 | int j, k; |
253 | 0 | int scale; |
254 | 0 | FIXP_DBL max_val = FL2FXCONST_DBL(0.0f); |
255 | | |
256 | | /* Get Scratch buffer */ |
257 | 0 | C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2) |
258 | | |
259 | | /* Get max possible scaling of QMF data */ |
260 | 0 | scale = DFRACT_BITS; |
261 | 0 | for (k = 0; k < numberCols; k++) { |
262 | 0 | scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), |
263 | 0 | getScalefactor(imagValues[k], numberBands))); |
264 | 0 | } |
265 | | |
266 | | /* Tweak scaling stability for zero signal to non-zero signal transitions */ |
267 | 0 | if (scale >= DFRACT_BITS - 1) { |
268 | 0 | scale = (FRACT_BITS - 1 - *qmfScale); |
269 | 0 | } |
270 | | /* prevent scaling of QMF values to -1.f */ |
271 | 0 | scale = fixMax(0, scale - 1); |
272 | | |
273 | | /* Update QMF scale */ |
274 | 0 | *qmfScale += scale; |
275 | | |
276 | | /* |
277 | | Calculate energy of each time slot pair, max energy |
278 | | and shift QMF values as far as possible to the left. |
279 | | */ |
280 | 0 | { |
281 | 0 | FIXP_DBL *nrgValues = tmpNrg; |
282 | 0 | for (k = 0; k < numberCols; k += 2) { |
283 | | /* Load band vector addresses of 2 consecutive timeslots */ |
284 | 0 | FIXP_DBL *RESTRICT r0 = realValues[k]; |
285 | 0 | FIXP_DBL *RESTRICT i0 = imagValues[k]; |
286 | 0 | FIXP_DBL *RESTRICT r1 = realValues[k + 1]; |
287 | 0 | FIXP_DBL *RESTRICT i1 = imagValues[k + 1]; |
288 | 0 | for (j = 0; j < numberBands; j++) { |
289 | 0 | FIXP_DBL energy; |
290 | 0 | FIXP_DBL tr0, tr1, ti0, ti1; |
291 | | |
292 | | /* Read QMF values of 2 timeslots */ |
293 | 0 | tr0 = r0[j]; |
294 | 0 | tr1 = r1[j]; |
295 | 0 | ti0 = i0[j]; |
296 | 0 | ti1 = i1[j]; |
297 | | |
298 | | /* Scale QMF Values and Calc Energy average of both timeslots */ |
299 | 0 | tr0 <<= scale; |
300 | 0 | ti0 <<= scale; |
301 | 0 | energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1; |
302 | |
|
303 | 0 | tr1 <<= scale; |
304 | 0 | ti1 <<= scale; |
305 | 0 | energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1; |
306 | | |
307 | | /* Write timeslot pair energy to scratch */ |
308 | 0 | *nrgValues++ = energy; |
309 | 0 | max_val = fixMax(max_val, energy); |
310 | | |
311 | | /* Write back scaled QMF values */ |
312 | 0 | r0[j] = tr0; |
313 | 0 | r1[j] = tr1; |
314 | 0 | i0[j] = ti0; |
315 | 0 | i1[j] = ti1; |
316 | 0 | } |
317 | 0 | } |
318 | 0 | } |
319 | | /* energyScale: scalefactor energies of current frame */ |
320 | 0 | *energyScale = |
321 | 0 | 2 * (*qmfScale) - |
322 | 0 | 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */ |
323 | | |
324 | | /* Scale timeslot pair energies and write to output buffer */ |
325 | 0 | scale = CountLeadingBits(max_val); |
326 | 0 | { |
327 | 0 | FIXP_DBL *nrgValues = tmpNrg; |
328 | 0 | for (k = 0; k<numberCols>> 1; k++) { |
329 | 0 | scaleValues(energyValues[k], nrgValues, numberBands, scale); |
330 | 0 | nrgValues += numberBands; |
331 | 0 | } |
332 | 0 | *energyScale += scale; |
333 | 0 | } |
334 | | |
335 | | /* Free Scratch buffer */ |
336 | 0 | C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2) |
337 | 0 | } |
338 | | |
339 | | LNK_SECTION_CODE_L1 |
340 | | static void FDKsbrEnc_getEnergyFromCplxQmfDataFull( |
341 | | FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */ |
342 | | FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */ |
343 | | FIXP_DBL **RESTRICT |
344 | | imagValues, /*!< the imaginary part of the QMF subsamples */ |
345 | | int numberBands, /*!< number of QMF bands */ |
346 | | int numberCols, /*!< number of QMF subsamples */ |
347 | | int *qmfScale, /*!< scalefactor of QMF subsamples */ |
348 | | int *energyScale) /*!< scalefactor of energies */ |
349 | 0 | { |
350 | 0 | int j, k; |
351 | 0 | int scale; |
352 | 0 | FIXP_DBL max_val = FL2FXCONST_DBL(0.0f); |
353 | | |
354 | | /* Get Scratch buffer */ |
355 | 0 | C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64) |
356 | |
|
357 | 0 | FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD); |
358 | 0 | FDK_ASSERT(numberBands <= 64); |
359 | | |
360 | | /* Get max possible scaling of QMF data */ |
361 | 0 | scale = DFRACT_BITS; |
362 | 0 | for (k = 0; k < numberCols; k++) { |
363 | 0 | scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), |
364 | 0 | getScalefactor(imagValues[k], numberBands))); |
365 | 0 | } |
366 | | |
367 | | /* Tweak scaling stability for zero signal to non-zero signal transitions */ |
368 | 0 | if (scale >= DFRACT_BITS - 1) { |
369 | 0 | scale = (FRACT_BITS - 1 - *qmfScale); |
370 | 0 | } |
371 | | /* prevent scaling of QFM values to -1.f */ |
372 | 0 | scale = fixMax(0, scale - 1); |
373 | | |
374 | | /* Update QMF scale */ |
375 | 0 | *qmfScale += scale; |
376 | | |
377 | | /* |
378 | | Calculate energy of each time slot pair, max energy |
379 | | and shift QMF values as far as possible to the left. |
380 | | */ |
381 | 0 | { |
382 | 0 | FIXP_DBL *nrgValues = tmpNrg; |
383 | 0 | for (k = 0; k < numberCols; k++) { |
384 | | /* Load band vector addresses of 1 timeslot */ |
385 | 0 | FIXP_DBL *RESTRICT r0 = realValues[k]; |
386 | 0 | FIXP_DBL *RESTRICT i0 = imagValues[k]; |
387 | 0 | for (j = 0; j < numberBands; j++) { |
388 | 0 | FIXP_DBL energy; |
389 | 0 | FIXP_DBL tr0, ti0; |
390 | | |
391 | | /* Read QMF values of 1 timeslot */ |
392 | 0 | tr0 = r0[j]; |
393 | 0 | ti0 = i0[j]; |
394 | | |
395 | | /* Scale QMF Values and Calc Energy */ |
396 | 0 | tr0 <<= scale; |
397 | 0 | ti0 <<= scale; |
398 | 0 | energy = fPow2AddDiv2(fPow2Div2(tr0), ti0); |
399 | 0 | *nrgValues++ = energy; |
400 | |
|
401 | 0 | max_val = fixMax(max_val, energy); |
402 | | |
403 | | /* Write back scaled QMF values */ |
404 | 0 | r0[j] = tr0; |
405 | 0 | i0[j] = ti0; |
406 | 0 | } |
407 | 0 | } |
408 | 0 | } |
409 | | /* energyScale: scalefactor energies of current frame */ |
410 | 0 | *energyScale = |
411 | 0 | 2 * (*qmfScale) - |
412 | 0 | 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */ |
413 | | |
414 | | /* Scale timeslot pair energies and write to output buffer */ |
415 | 0 | scale = CountLeadingBits(max_val); |
416 | 0 | { |
417 | 0 | FIXP_DBL *nrgValues = tmpNrg; |
418 | 0 | for (k = 0; k < numberCols; k++) { |
419 | 0 | scaleValues(energyValues[k], nrgValues, numberBands, scale); |
420 | 0 | nrgValues += numberBands; |
421 | 0 | } |
422 | 0 | *energyScale += scale; |
423 | 0 | } |
424 | | |
425 | | /* Free Scratch buffer */ |
426 | 0 | C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64) |
427 | 0 | } |
428 | | |
429 | | /***************************************************************************/ |
430 | | /*! |
431 | | |
432 | | \brief Quantisation of the panorama value (balance) |
433 | | |
434 | | \return the quantized pan value |
435 | | |
436 | | ****************************************************************************/ |
437 | | static INT mapPanorama(INT nrgVal, /*! integer value of the energy */ |
438 | | INT ampRes, /*! amplitude resolution [1.5/3dB] */ |
439 | | INT *quantError /*! quantization error of energy val*/ |
440 | 0 | ) { |
441 | 0 | int i; |
442 | 0 | INT min_val, val; |
443 | 0 | UCHAR panIndex; |
444 | 0 | INT sign; |
445 | |
|
446 | 0 | sign = nrgVal > 0 ? 1 : -1; |
447 | |
|
448 | 0 | nrgVal *= sign; |
449 | |
|
450 | 0 | min_val = FDK_INT_MAX; |
451 | 0 | panIndex = 0; |
452 | 0 | for (i = 0; i < maxIndex[ampRes]; i++) { |
453 | 0 | val = fixp_abs((nrgVal - (INT)panTable[ampRes][i])); |
454 | |
|
455 | 0 | if (val < min_val) { |
456 | 0 | min_val = val; |
457 | 0 | panIndex = i; |
458 | 0 | } |
459 | 0 | } |
460 | |
|
461 | 0 | *quantError = min_val; |
462 | |
|
463 | 0 | return panTable[ampRes][maxIndex[ampRes] - 1] + |
464 | 0 | sign * panTable[ampRes][panIndex]; |
465 | 0 | } |
466 | | |
467 | | /***************************************************************************/ |
468 | | /*! |
469 | | |
470 | | \brief Quantisation of the noise floor levels |
471 | | |
472 | | \return void |
473 | | |
474 | | ****************************************************************************/ |
475 | | static void sbrNoiseFloorLevelsQuantisation( |
476 | | SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */ |
477 | | FIXP_DBL *RESTRICT |
478 | | NoiseLevels, /*! the noise levels. Exponent = LD_DATA_SHIFT */ |
479 | | INT coupling /*! the coupling flag */ |
480 | 0 | ) { |
481 | 0 | INT i; |
482 | 0 | INT tmp, dummy; |
483 | | |
484 | | /* Quantisation, similar to sfb quant... */ |
485 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { |
486 | | /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] + |
487 | | * (PFLOAT)0.5); */ |
488 | | /* 30>>LD_DATA_SHIFT = 0.46875 */ |
489 | 0 | if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) { |
490 | 0 | tmp = 30; |
491 | 0 | } else { |
492 | | /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/ |
493 | | /* FRACT_BITS+ */ /* 6-1)));*/ |
494 | | /* tmp = tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT); */ /* conversion to integer |
495 | | happens here */ |
496 | | /* rounding is done by shifting one bit less than necessary to the right, |
497 | | * adding '1' and then shifting the final bit */ |
498 | 0 | tmp = ((((INT)NoiseLevels[i]) >> |
499 | 0 | (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */ |
500 | 0 | if (tmp != 0) tmp += 1; |
501 | 0 | } |
502 | |
|
503 | 0 | if (coupling) { |
504 | 0 | tmp = tmp < -30 ? -30 : tmp; |
505 | 0 | tmp = mapPanorama(tmp, 1, &dummy); |
506 | 0 | } |
507 | 0 | iNoiseLevels[i] = tmp; |
508 | 0 | } |
509 | 0 | } |
510 | | |
511 | | /***************************************************************************/ |
512 | | /*! |
513 | | |
514 | | \brief Calculation of noise floor for coupling |
515 | | |
516 | | \return void |
517 | | |
518 | | ****************************************************************************/ |
519 | | static void coupleNoiseFloor( |
520 | | FIXP_DBL *RESTRICT noise_level_left, /*! noise level left (modified)*/ |
521 | | FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/ |
522 | 0 | ) { |
523 | 0 | FIXP_DBL cmpValLeft, cmpValRight; |
524 | 0 | INT i; |
525 | 0 | FIXP_DBL temp1, temp2; |
526 | |
|
527 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { |
528 | | /* Calculation of the power function using ld64: |
529 | | z = x^y; |
530 | | z' = CalcLd64(z) = y*CalcLd64(x)/64; |
531 | | z = CalcInvLd64(z'); |
532 | | */ |
533 | 0 | cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i]; |
534 | 0 | cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i]; |
535 | |
|
536 | 0 | if (cmpValRight < FL2FXCONST_DBL(0.0f)) { |
537 | 0 | temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]); |
538 | 0 | } else { |
539 | 0 | temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]); |
540 | 0 | temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT - |
541 | 0 | 1); /* INT to fract conversion of result, if input of |
542 | | CalcInvLdData is positiv */ |
543 | 0 | } |
544 | |
|
545 | 0 | if (cmpValLeft < FL2FXCONST_DBL(0.0f)) { |
546 | 0 | temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]); |
547 | 0 | } else { |
548 | 0 | temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]); |
549 | 0 | temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT - |
550 | 0 | 1); /* INT to fract conversion of result, if input of |
551 | | CalcInvLdData is positiv */ |
552 | 0 | } |
553 | |
|
554 | 0 | if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && |
555 | 0 | (cmpValRight < FL2FXCONST_DBL(0.0f))) { |
556 | 0 | noise_level_left[i] = |
557 | 0 | NOISE_FLOOR_OFFSET_64 - |
558 | 0 | (CalcLdData( |
559 | 0 | ((temp1 >> 1) + |
560 | 0 | (temp2 >> 1)))); /* no scaling needed! both values are dfract */ |
561 | 0 | noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1); |
562 | 0 | } |
563 | |
|
564 | 0 | if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && |
565 | 0 | (cmpValRight >= FL2FXCONST_DBL(0.0f))) { |
566 | 0 | noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - |
567 | 0 | (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) + |
568 | 0 | FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ |
569 | 0 | noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1); |
570 | 0 | } |
571 | |
|
572 | 0 | if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && |
573 | 0 | (cmpValRight < FL2FXCONST_DBL(0.0f))) { |
574 | 0 | noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - |
575 | 0 | (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) + |
576 | 0 | FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ |
577 | 0 | noise_level_right[i] = |
578 | 0 | (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1); |
579 | 0 | } |
580 | |
|
581 | 0 | if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && |
582 | 0 | (cmpValRight >= FL2FXCONST_DBL(0.0f))) { |
583 | 0 | noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - |
584 | 0 | (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) + |
585 | 0 | FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ |
586 | 0 | noise_level_right[i] = CalcLdData(temp2) - |
587 | 0 | (CalcLdData(temp1) + |
588 | 0 | FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ |
589 | 0 | } |
590 | 0 | } |
591 | 0 | } |
592 | | |
593 | | /***************************************************************************/ |
594 | | /*! |
595 | | |
596 | | \brief Calculation of energy starting in lower band (li) up to upper band |
597 | | (ui) over slots (start_pos) to (stop_pos) |
598 | | |
599 | | \return void |
600 | | |
601 | | ****************************************************************************/ |
602 | | |
603 | | static FIXP_DBL getEnvSfbEnergy( |
604 | | INT li, /*! lower band */ |
605 | | INT ui, /*! upper band */ |
606 | | INT start_pos, /*! start slot */ |
607 | | INT stop_pos, /*! stop slot */ |
608 | | INT border_pos, /*! slots scaling border */ |
609 | | FIXP_DBL **YBuffer, /*! sfb energy buffer */ |
610 | | INT YBufferSzShift, /*! Energy buffer index scale */ |
611 | | INT scaleNrg0, /*! scaling of lower slots */ |
612 | | INT scaleNrg1) /*! scaling of upper slots */ |
613 | 0 | { |
614 | | /* use dynamic scaling for outer energy loop; |
615 | | energies are critical and every bit is important */ |
616 | 0 | int sc0, sc1, k, l; |
617 | |
|
618 | 0 | FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2; |
619 | 0 | INT dynScale, dynScale1, dynScale2; |
620 | 0 | if (ui - li == 0) |
621 | 0 | dynScale = DFRACT_BITS - 1; |
622 | 0 | else |
623 | 0 | dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT); |
624 | |
|
625 | 0 | sc0 = fixMin(scaleNrg0, Y_NRG_SCALE); |
626 | 0 | sc1 = fixMin(scaleNrg1, Y_NRG_SCALE); |
627 | | /* dynScale{1,2} is set such that the right shift below is positive */ |
628 | 0 | dynScale1 = fixMin((scaleNrg0 - sc0), dynScale); |
629 | 0 | dynScale2 = fixMin((scaleNrg1 - sc1), dynScale); |
630 | 0 | nrgSum = accu1 = accu2 = (FIXP_DBL)0; |
631 | |
|
632 | 0 | for (k = li; k < ui; k++) { |
633 | 0 | nrg1 = nrg2 = (FIXP_DBL)0; |
634 | 0 | for (l = start_pos; l < border_pos; l++) { |
635 | 0 | nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0; |
636 | 0 | } |
637 | 0 | for (; l < stop_pos; l++) { |
638 | 0 | nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1; |
639 | 0 | } |
640 | 0 | accu1 += (nrg1 >> dynScale1); |
641 | 0 | accu2 += (nrg2 >> dynScale2); |
642 | 0 | } |
643 | | /* This shift factor is always positive. See comment above. */ |
644 | 0 | nrgSum += |
645 | 0 | (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) + |
646 | 0 | (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1))); |
647 | |
|
648 | 0 | return nrgSum; |
649 | 0 | } |
650 | | |
651 | | /***************************************************************************/ |
652 | | /*! |
653 | | |
654 | | \brief Energy compensation in missing harmonic mode |
655 | | |
656 | | \return void |
657 | | |
658 | | ****************************************************************************/ |
659 | 0 | static FIXP_DBL mhLoweringEnergy(FIXP_DBL nrg, INT M) { |
660 | | /* |
661 | | Compensating for the fact that we in the decoder map the "average energy to |
662 | | every QMF band, and use this when we calculate the boost-factor. Since the |
663 | | mapped energy isn't the average energy but the maximum energy in case of |
664 | | missing harmonic creation, we will in the boost function calculate that too |
665 | | much limiting has been applied and hence we will boost the signal although |
666 | | it isn't called for. Hence we need to compensate for this by lowering the |
667 | | transmitted energy values for the sines so they will get the correct level |
668 | | after the boost is applied. |
669 | | */ |
670 | 0 | if (M > 2) { |
671 | 0 | INT tmpScale; |
672 | 0 | tmpScale = CountLeadingBits(nrg); |
673 | 0 | nrg <<= tmpScale; |
674 | 0 | nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost |
675 | | is 1.584893, so the |
676 | | maximum attenuation |
677 | | should be |
678 | | square(1/1.584893) = |
679 | | 0.398107267 */ |
680 | 0 | nrg >>= tmpScale; |
681 | 0 | } else { |
682 | 0 | if (M > 1) { |
683 | 0 | nrg >>= 1; |
684 | 0 | } |
685 | 0 | } |
686 | |
|
687 | 0 | return nrg; |
688 | 0 | } |
689 | | |
690 | | /***************************************************************************/ |
691 | | /*! |
692 | | |
693 | | \brief Energy compensation in none missing harmonic mode |
694 | | |
695 | | \return void |
696 | | |
697 | | ****************************************************************************/ |
698 | | static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum, |
699 | 0 | const INT nrgSum_scale, const INT M) { |
700 | 0 | if (nrg > FL2FXCONST_DBL(0)) { |
701 | 0 | int sc = 0; |
702 | | /* gain = nrgSum / (nrg*(M+1)) */ |
703 | 0 | FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1)); |
704 | 0 | sc += nrgSum_scale; |
705 | | |
706 | | /* reduce nrg if gain smaller 1.f */ |
707 | 0 | if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) { |
708 | 0 | nrg = fMult(scaleValue(gain, sc), nrg); |
709 | 0 | } |
710 | 0 | } |
711 | 0 | return nrg; |
712 | 0 | } |
713 | | |
714 | | /***************************************************************************/ |
715 | | /*! |
716 | | |
717 | | \brief calculates the envelope values from the energies, depending on |
718 | | framing and stereo mode |
719 | | |
720 | | \return void |
721 | | |
722 | | ****************************************************************************/ |
723 | | static void calculateSbrEnvelope( |
724 | | FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left */ |
725 | | FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */ |
726 | | int *RESTRICT YBufferScaleLeft, /*! scale energy buffer left */ |
727 | | int *RESTRICT YBufferScaleRight, /*! scale energy buffer right */ |
728 | | const SBR_FRAME_INFO *frame_info, /*! frame info vector */ |
729 | | SCHAR *RESTRICT sfb_nrgLeft, /*! sfb energy buffer left */ |
730 | | SCHAR *RESTRICT sfb_nrgRight, /*! sfb energy buffer right */ |
731 | | HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ |
732 | | HANDLE_ENV_CHANNEL h_sbr, /*! envelope channel handle */ |
733 | | SBR_STEREO_MODE stereoMode, /*! stereo coding mode */ |
734 | | INT *maxQuantError, /*! maximum quantization error, for panorama. */ |
735 | | int YBufferSzShift) /*! Energy buffer index scale */ |
736 | | |
737 | 0 | { |
738 | 0 | int env, j, m = 0; |
739 | 0 | INT no_of_bands, start_pos, stop_pos, li, ui; |
740 | 0 | FREQ_RES freq_res; |
741 | |
|
742 | 0 | INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res; |
743 | 0 | INT oneBitLess = 0; |
744 | 0 | if (ca == 2) |
745 | 0 | oneBitLess = |
746 | 0 | 1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */ |
747 | |
|
748 | 0 | INT quantError; |
749 | 0 | INT nEnvelopes = frame_info->nEnvelopes; |
750 | 0 | INT short_env = frame_info->shortEnv - 1; |
751 | 0 | INT timeStep = h_sbr->sbrExtractEnvelope.time_step; |
752 | 0 | INT commonScale, scaleLeft0, scaleLeft1; |
753 | 0 | INT scaleRight0 = 0, scaleRight1 = 0; |
754 | |
|
755 | 0 | commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]); |
756 | |
|
757 | 0 | if (stereoMode == SBR_COUPLING) { |
758 | 0 | commonScale = fixMin(commonScale, YBufferScaleRight[0]); |
759 | 0 | commonScale = fixMin(commonScale, YBufferScaleRight[1]); |
760 | 0 | } |
761 | |
|
762 | 0 | commonScale = commonScale - 7; |
763 | |
|
764 | 0 | scaleLeft0 = YBufferScaleLeft[0] - commonScale; |
765 | 0 | scaleLeft1 = YBufferScaleLeft[1] - commonScale; |
766 | 0 | FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0)); |
767 | | |
768 | 0 | if (stereoMode == SBR_COUPLING) { |
769 | 0 | scaleRight0 = YBufferScaleRight[0] - commonScale; |
770 | 0 | scaleRight1 = YBufferScaleRight[1] - commonScale; |
771 | 0 | FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0)); |
772 | 0 | *maxQuantError = 0; |
773 | 0 | } |
774 | | |
775 | 0 | for (env = 0; env < nEnvelopes; env++) { |
776 | 0 | FIXP_DBL pNrgLeft[32]; |
777 | 0 | FIXP_DBL pNrgRight[32]; |
778 | 0 | int envNrg_scale; |
779 | 0 | FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f); |
780 | 0 | FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f); |
781 | 0 | int missingHarmonic[32]; |
782 | 0 | int count[32]; |
783 | |
|
784 | 0 | start_pos = timeStep * frame_info->borders[env]; |
785 | 0 | stop_pos = timeStep * frame_info->borders[env + 1]; |
786 | 0 | freq_res = frame_info->freqRes[env]; |
787 | 0 | no_of_bands = h_con->nSfb[freq_res]; |
788 | 0 | envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands); |
789 | 0 | if (env == short_env) { |
790 | 0 | j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short |
791 | | envelopes (envelopes just before transients) */ |
792 | 0 | if ((stop_pos - start_pos - j) > 0) { |
793 | 0 | stop_pos = stop_pos - j; |
794 | 0 | } |
795 | 0 | } |
796 | 0 | for (j = 0; j < no_of_bands; j++) { |
797 | 0 | FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f); |
798 | 0 | FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f); |
799 | |
|
800 | 0 | li = h_con->freqBandTable[freq_res][j]; |
801 | 0 | ui = h_con->freqBandTable[freq_res][j + 1]; |
802 | |
|
803 | 0 | if (freq_res == FREQ_RES_HIGH) { |
804 | 0 | if (j == 0 && ui - li > 1) { |
805 | 0 | li++; |
806 | 0 | } |
807 | 0 | } else { |
808 | 0 | if (j == 0 && ui - li > 2) { |
809 | 0 | li++; |
810 | 0 | } |
811 | 0 | } |
812 | | |
813 | | /* |
814 | | Find out whether a sine will be missing in the scale-factor |
815 | | band that we're currently processing. |
816 | | */ |
817 | 0 | missingHarmonic[j] = 0; |
818 | |
|
819 | 0 | if (h_sbr->encEnvData.addHarmonicFlag) { |
820 | 0 | if (freq_res == FREQ_RES_HIGH) { |
821 | 0 | if (h_sbr->encEnvData |
822 | 0 | .addHarmonic[j]) { /*A missing sine in the current band*/ |
823 | 0 | missingHarmonic[j] = 1; |
824 | 0 | } |
825 | 0 | } else { |
826 | 0 | INT i; |
827 | 0 | INT startBandHigh = 0; |
828 | 0 | INT stopBandHigh = 0; |
829 | |
|
830 | 0 | while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] < |
831 | 0 | h_con->freqBandTable[FREQ_RES_LOW][j]) |
832 | 0 | startBandHigh++; |
833 | 0 | while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] < |
834 | 0 | h_con->freqBandTable[FREQ_RES_LOW][j + 1]) |
835 | 0 | stopBandHigh++; |
836 | |
|
837 | 0 | for (i = startBandHigh; i < stopBandHigh; i++) { |
838 | 0 | if (h_sbr->encEnvData.addHarmonic[i]) { |
839 | 0 | missingHarmonic[j] = 1; |
840 | 0 | } |
841 | 0 | } |
842 | 0 | } |
843 | 0 | } |
844 | | |
845 | | /* |
846 | | If a sine is missing in a scalefactorband, with more than one qmf |
847 | | channel use the nrg from the channel with the largest nrg rather than |
848 | | the mean. Compensate for the boost calculation in the decdoder. |
849 | | */ |
850 | 0 | int border_pos = |
851 | 0 | fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset |
852 | 0 | << YBufferSzShift); |
853 | |
|
854 | 0 | if (missingHarmonic[j]) { |
855 | 0 | int k; |
856 | 0 | count[j] = stop_pos - start_pos; |
857 | 0 | nrgLeft = FL2FXCONST_DBL(0.0f); |
858 | |
|
859 | 0 | for (k = li; k < ui; k++) { |
860 | 0 | FIXP_DBL tmpNrg; |
861 | 0 | tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos, |
862 | 0 | YBufferLeft, YBufferSzShift, scaleLeft0, |
863 | 0 | scaleLeft1); |
864 | |
|
865 | 0 | nrgLeft = fixMax(nrgLeft, tmpNrg); |
866 | 0 | } |
867 | | |
868 | | /* Energy lowering compensation */ |
869 | 0 | nrgLeft = mhLoweringEnergy(nrgLeft, ui - li); |
870 | |
|
871 | 0 | if (stereoMode == SBR_COUPLING) { |
872 | 0 | nrgRight = FL2FXCONST_DBL(0.0f); |
873 | |
|
874 | 0 | for (k = li; k < ui; k++) { |
875 | 0 | FIXP_DBL tmpNrg; |
876 | 0 | tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos, |
877 | 0 | YBufferRight, YBufferSzShift, scaleRight0, |
878 | 0 | scaleRight1); |
879 | |
|
880 | 0 | nrgRight = fixMax(nrgRight, tmpNrg); |
881 | 0 | } |
882 | | |
883 | | /* Energy lowering compensation */ |
884 | 0 | nrgRight = mhLoweringEnergy(nrgRight, ui - li); |
885 | 0 | } |
886 | 0 | } /* end missingHarmonic */ |
887 | 0 | else { |
888 | 0 | count[j] = (stop_pos - start_pos) * (ui - li); |
889 | |
|
890 | 0 | nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos, |
891 | 0 | YBufferLeft, YBufferSzShift, scaleLeft0, |
892 | 0 | scaleLeft1); |
893 | |
|
894 | 0 | if (stereoMode == SBR_COUPLING) { |
895 | 0 | nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos, |
896 | 0 | YBufferRight, YBufferSzShift, scaleRight0, |
897 | 0 | scaleRight1); |
898 | 0 | } |
899 | 0 | } /* !missingHarmonic */ |
900 | | |
901 | | /* save energies */ |
902 | 0 | pNrgLeft[j] = nrgLeft; |
903 | 0 | pNrgRight[j] = nrgRight; |
904 | 0 | envNrgLeft += (nrgLeft >> envNrg_scale); |
905 | 0 | envNrgRight += (nrgRight >> envNrg_scale); |
906 | 0 | } /* j */ |
907 | |
|
908 | 0 | for (j = 0; j < no_of_bands; j++) { |
909 | 0 | FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f); |
910 | 0 | FIXP_DBL nrgLeft = pNrgLeft[j]; |
911 | 0 | FIXP_DBL nrgRight = pNrgRight[j]; |
912 | | |
913 | | /* None missing harmonic Energy lowering compensation */ |
914 | 0 | if (!missingHarmonic[j] && h_sbr->fLevelProtect) { |
915 | | /* in case of missing energy in base band, |
916 | | reduce reference energy to prevent overflows in decoder output */ |
917 | 0 | nrgLeft = |
918 | 0 | nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands); |
919 | 0 | if (stereoMode == SBR_COUPLING) { |
920 | 0 | nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale, |
921 | 0 | no_of_bands); |
922 | 0 | } |
923 | 0 | } |
924 | |
|
925 | 0 | if (stereoMode == SBR_COUPLING) { |
926 | | /* calc operation later with log */ |
927 | 0 | nrgLeft2 = nrgLeft; |
928 | 0 | nrgLeft = (nrgRight + nrgLeft) >> 1; |
929 | 0 | } |
930 | | |
931 | | /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */ |
932 | | /* If nrgLeft == 0 then the Log calculations below do fail. */ |
933 | 0 | if (nrgLeft > FL2FXCONST_DBL(0.0f)) { |
934 | 0 | FIXP_DBL tmp0, tmp1, tmp2, tmp3; |
935 | 0 | INT tmpScale; |
936 | |
|
937 | 0 | tmpScale = CountLeadingBits(nrgLeft); |
938 | 0 | nrgLeft = nrgLeft << tmpScale; |
939 | |
|
940 | 0 | tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */ |
941 | 0 | tmp1 = ((FIXP_DBL)(commonScale + tmpScale)) |
942 | 0 | << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */ |
943 | 0 | tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1); |
944 | 0 | tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */ |
945 | 0 | tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >> |
946 | 0 | 1; /* scaled by 1/64 */ |
947 | |
|
948 | 0 | nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1); |
949 | 0 | } else { |
950 | 0 | nrgLeft = FL2FXCONST_DBL(-1.0f); |
951 | 0 | } |
952 | | |
953 | | /* ld64 to integer conversion */ |
954 | 0 | nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)), |
955 | 0 | (FL2FXCONST_DBL(0.5f) >> oneBitLess)); |
956 | 0 | nrgLeft = (FIXP_DBL)(LONG)nrgLeft >> |
957 | 0 | (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1); |
958 | 0 | sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */ |
959 | |
|
960 | 0 | if (stereoMode == SBR_COUPLING) { |
961 | 0 | FIXP_DBL scaleFract; |
962 | 0 | int sc0, sc1; |
963 | |
|
964 | 0 | nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2); |
965 | 0 | nrgRight = fixMax((FIXP_DBL)0x1, nrgRight); |
966 | |
|
967 | 0 | sc0 = CountLeadingBits(nrgLeft2); |
968 | 0 | sc1 = CountLeadingBits(nrgRight); |
969 | |
|
970 | 0 | scaleFract = |
971 | 0 | ((FIXP_DBL)(sc0 - sc1)) |
972 | 0 | << (DFRACT_BITS - 1 - |
973 | 0 | LD_DATA_SHIFT); /* scale value in ld64 representation */ |
974 | 0 | nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) - |
975 | 0 | scaleFract; |
976 | | |
977 | | /* ld64 to integer conversion */ |
978 | 0 | nrgRight = (FIXP_DBL)(LONG)(nrgRight) >> |
979 | 0 | (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess); |
980 | 0 | nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */ |
981 | |
|
982 | 0 | sfb_nrgRight[m] = mapPanorama( |
983 | 0 | nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError); |
984 | |
|
985 | 0 | *maxQuantError = fixMax(quantError, *maxQuantError); |
986 | 0 | } |
987 | |
|
988 | 0 | m++; |
989 | 0 | } /* j */ |
990 | | |
991 | | /* Do energy compensation for sines that are present in two |
992 | | QMF-bands in the original, but will only occur in one band in |
993 | | the decoder due to the synthetic sine coding.*/ |
994 | 0 | if (h_con->useParametricCoding) { |
995 | 0 | m -= no_of_bands; |
996 | 0 | for (j = 0; j < no_of_bands; j++) { |
997 | 0 | if (freq_res == FREQ_RES_HIGH && |
998 | 0 | h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) { |
999 | 0 | sfb_nrgLeft[m] -= |
1000 | 0 | (ca * |
1001 | 0 | fixp_abs( |
1002 | 0 | (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j])); |
1003 | 0 | } |
1004 | 0 | sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]); |
1005 | 0 | m++; |
1006 | 0 | } |
1007 | 0 | } /* useParametricCoding */ |
1008 | |
|
1009 | 0 | } /* env loop */ |
1010 | 0 | } |
1011 | | |
1012 | | /***************************************************************************/ |
1013 | | /*! |
1014 | | |
1015 | | \brief calculates the noise floor and the envelope values from the |
1016 | | energies, depending on framing and stereo mode |
1017 | | |
1018 | | FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the |
1019 | | envelope and the noise floor. The function includes the following processes: |
1020 | | |
1021 | | -Analysis subband filtering. |
1022 | | -Encoding SA and pan parameters (if enabled). |
1023 | | -Transient detection. |
1024 | | |
1025 | | ****************************************************************************/ |
1026 | | |
1027 | | LNK_SECTION_CODE_L1 |
1028 | | void FDKsbrEnc_extractSbrEnvelope1( |
1029 | | HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ |
1030 | | HANDLE_SBR_HEADER_DATA sbrHeaderData, |
1031 | | HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL hEnvChan, |
1032 | | HANDLE_COMMON_DATA hCmonData, SBR_ENV_TEMP_DATA *eData, |
1033 | 0 | SBR_FRAME_TEMP_DATA *fData) { |
1034 | 0 | HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope; |
1035 | |
|
1036 | 0 | if (sbrExtrEnv->YBufferSzShift == 0) |
1037 | 0 | FDKsbrEnc_getEnergyFromCplxQmfDataFull( |
1038 | 0 | &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset], |
1039 | 0 | sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset, |
1040 | 0 | sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands, |
1041 | 0 | sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]); |
1042 | 0 | else |
1043 | 0 | FDKsbrEnc_getEnergyFromCplxQmfData( |
1044 | 0 | &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset], |
1045 | 0 | sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset, |
1046 | 0 | sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands, |
1047 | 0 | sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]); |
1048 | | |
1049 | | /* Energie values = |
1050 | | * sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset][x].floatVal * |
1051 | | * (1<<2*7-sbrExtrEnv->YBufferScale[1]) */ |
1052 | | |
1053 | | /* |
1054 | | Precalculation of Tonality Quotas COEFF Transform OK |
1055 | | */ |
1056 | 0 | FDKsbrEnc_CalculateTonalityQuotas( |
1057 | 0 | &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer, |
1058 | 0 | h_con->freqBandTable[HI][h_con->nSfb[HI]], hEnvChan->qmfScale); |
1059 | |
|
1060 | 0 | if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { |
1061 | 0 | FIXP_DBL tonality = FDKsbrEnc_GetTonality( |
1062 | 0 | hEnvChan->TonCorr.quotaMatrix, |
1063 | 0 | hEnvChan->TonCorr.numberOfEstimatesPerFrame, |
1064 | 0 | hEnvChan->TonCorr.startIndexMatrix, |
1065 | 0 | sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset, |
1066 | 0 | h_con->freqBandTable[HI][0] + 1, h_con->noQmfBands, |
1067 | 0 | sbrExtrEnv->no_cols); |
1068 | |
|
1069 | 0 | hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0]; |
1070 | 0 | hEnvChan->encEnvData.ton_HF[0] = tonality; |
1071 | | |
1072 | | /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */ |
1073 | 0 | hEnvChan->encEnvData.global_tonality = |
1074 | 0 | (hEnvChan->encEnvData.ton_HF[0] >> 1) + |
1075 | 0 | (hEnvChan->encEnvData.ton_HF[1] >> 1); |
1076 | 0 | } |
1077 | | |
1078 | | /* |
1079 | | Transient detection COEFF Transform OK |
1080 | | */ |
1081 | |
|
1082 | 0 | if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { |
1083 | 0 | FDKsbrEnc_fastTransientDetect(&hEnvChan->sbrFastTransientDetector, |
1084 | 0 | sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale, |
1085 | 0 | sbrExtrEnv->YBufferWriteOffset, |
1086 | 0 | eData->transient_info); |
1087 | |
|
1088 | 0 | } else { |
1089 | 0 | FDKsbrEnc_transientDetect( |
1090 | 0 | &hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer, |
1091 | 0 | sbrExtrEnv->YBufferScale, eData->transient_info, |
1092 | 0 | sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift, |
1093 | 0 | sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot); |
1094 | 0 | } |
1095 | | |
1096 | | /* |
1097 | | Generate flags for 2 env in a FIXFIX-frame. |
1098 | | Remove this function to get always 1 env per FIXFIX-frame. |
1099 | | */ |
1100 | | |
1101 | | /* |
1102 | | frame Splitter COEFF Transform OK |
1103 | | */ |
1104 | 0 | FDKsbrEnc_frameSplitter( |
1105 | 0 | sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale, |
1106 | 0 | &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1], |
1107 | 0 | eData->transient_info, sbrExtrEnv->YBufferWriteOffset, |
1108 | 0 | sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step, |
1109 | 0 | sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality); |
1110 | 0 | } |
1111 | | |
1112 | | /***************************************************************************/ |
1113 | | /*! |
1114 | | |
1115 | | \brief calculates the noise floor and the envelope values from the |
1116 | | energies, depending on framing and stereo mode |
1117 | | |
1118 | | FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the |
1119 | | envelope and the noise floor. The function includes the following processes: |
1120 | | |
1121 | | -Determine time/frequency division of current granule. |
1122 | | -Sending transient info to bitstream. |
1123 | | -Set amp_res to 1.5 dB if the current frame contains only one envelope. |
1124 | | -Lock dynamic bandwidth frequency change if the next envelope not starts on a |
1125 | | frame boundary. |
1126 | | -MDCT transposer (needed to detect where harmonics will be missing). |
1127 | | -Spectrum Estimation (used for pulse train and missing harmonics detection). |
1128 | | -Pulse train detection. |
1129 | | -Inverse Filtering detection. |
1130 | | -Waveform Coding. |
1131 | | -Missing Harmonics detection. |
1132 | | -Extract envelope of current frame. |
1133 | | -Noise floor estimation. |
1134 | | -Noise floor quantisation and coding. |
1135 | | -Encode envelope of current frame. |
1136 | | -Send the encoded data to the bitstream. |
1137 | | -Write to bitstream. |
1138 | | |
1139 | | ****************************************************************************/ |
1140 | | |
1141 | | LNK_SECTION_CODE_L1 |
1142 | | void FDKsbrEnc_extractSbrEnvelope2( |
1143 | | HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ |
1144 | | HANDLE_SBR_HEADER_DATA sbrHeaderData, |
1145 | | HANDLE_PARAMETRIC_STEREO hParametricStereo, |
1146 | | HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL h_envChan0, |
1147 | | HANDLE_ENV_CHANNEL h_envChan1, HANDLE_COMMON_DATA hCmonData, |
1148 | 0 | SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) { |
1149 | 0 | HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1}; |
1150 | 0 | int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift; |
1151 | |
|
1152 | 0 | SBR_STEREO_MODE stereoMode = h_con->stereoMode; |
1153 | 0 | int nChannels = h_con->nChannels; |
1154 | 0 | const int *v_tuning; |
1155 | 0 | static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0}; |
1156 | |
|
1157 | 0 | static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0}; |
1158 | |
|
1159 | 0 | if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) |
1160 | 0 | v_tuning = v_tuningELD; |
1161 | 0 | else |
1162 | 0 | v_tuning = v_tuningHEAAC; |
1163 | | |
1164 | | /* |
1165 | | Select stereo mode. |
1166 | | */ |
1167 | 0 | if (stereoMode == SBR_COUPLING) { |
1168 | 0 | if (eData[0].transient_info[1] && eData[1].transient_info[1]) { |
1169 | 0 | eData[0].transient_info[0] = |
1170 | 0 | fixMin(eData[1].transient_info[0], eData[0].transient_info[0]); |
1171 | 0 | eData[1].transient_info[0] = eData[0].transient_info[0]; |
1172 | 0 | } else { |
1173 | 0 | if (eData[0].transient_info[1] && !eData[1].transient_info[1]) { |
1174 | 0 | eData[1].transient_info[0] = eData[0].transient_info[0]; |
1175 | 0 | } else { |
1176 | 0 | if (!eData[0].transient_info[1] && eData[1].transient_info[1]) |
1177 | 0 | eData[0].transient_info[0] = eData[1].transient_info[0]; |
1178 | 0 | else { |
1179 | 0 | eData[0].transient_info[0] = |
1180 | 0 | fixMax(eData[1].transient_info[0], eData[0].transient_info[0]); |
1181 | 0 | eData[1].transient_info[0] = eData[0].transient_info[0]; |
1182 | 0 | } |
1183 | 0 | } |
1184 | 0 | } |
1185 | 0 | } |
1186 | | |
1187 | | /* |
1188 | | Determine time/frequency division of current granule |
1189 | | */ |
1190 | 0 | eData[0].frame_info = FDKsbrEnc_frameInfoGenerator( |
1191 | 0 | &h_envChan[0]->SbrEnvFrame, eData[0].transient_info, |
1192 | 0 | sbrBitstreamData->rightBorderFIX, |
1193 | 0 | h_envChan[0]->sbrExtractEnvelope.pre_transient_info, |
1194 | 0 | h_envChan[0]->encEnvData.ldGrid, v_tuning); |
1195 | |
|
1196 | 0 | h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid; |
1197 | | |
1198 | | /* AAC LD patch for transient prediction */ |
1199 | 0 | if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) { |
1200 | | /* if next frame will start with transient, set shortEnv to |
1201 | | * numEnvelopes(shortend Envelope = shortEnv-1)*/ |
1202 | 0 | h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv = |
1203 | 0 | h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes; |
1204 | 0 | } |
1205 | |
|
1206 | 0 | switch (stereoMode) { |
1207 | 0 | case SBR_LEFT_RIGHT: |
1208 | 0 | case SBR_SWITCH_LRC: |
1209 | 0 | eData[1].frame_info = FDKsbrEnc_frameInfoGenerator( |
1210 | 0 | &h_envChan[1]->SbrEnvFrame, eData[1].transient_info, |
1211 | 0 | sbrBitstreamData->rightBorderFIX, |
1212 | 0 | h_envChan[1]->sbrExtractEnvelope.pre_transient_info, |
1213 | 0 | h_envChan[1]->encEnvData.ldGrid, v_tuning); |
1214 | |
|
1215 | 0 | h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid; |
1216 | |
|
1217 | 0 | if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) { |
1218 | | /* if next frame will start with transient, set shortEnv to |
1219 | | * numEnvelopes(shortend Envelope = shortEnv-1)*/ |
1220 | 0 | h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv = |
1221 | 0 | h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes; |
1222 | 0 | } |
1223 | | |
1224 | | /* compare left and right frame_infos */ |
1225 | 0 | if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) { |
1226 | 0 | stereoMode = SBR_LEFT_RIGHT; |
1227 | 0 | } else { |
1228 | 0 | for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) { |
1229 | 0 | if (eData[0].frame_info->borders[i] != |
1230 | 0 | eData[1].frame_info->borders[i]) { |
1231 | 0 | stereoMode = SBR_LEFT_RIGHT; |
1232 | 0 | break; |
1233 | 0 | } |
1234 | 0 | } |
1235 | 0 | for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) { |
1236 | 0 | if (eData[0].frame_info->freqRes[i] != |
1237 | 0 | eData[1].frame_info->freqRes[i]) { |
1238 | 0 | stereoMode = SBR_LEFT_RIGHT; |
1239 | 0 | break; |
1240 | 0 | } |
1241 | 0 | } |
1242 | 0 | if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) { |
1243 | 0 | stereoMode = SBR_LEFT_RIGHT; |
1244 | 0 | } |
1245 | 0 | } |
1246 | 0 | break; |
1247 | 0 | case SBR_COUPLING: |
1248 | 0 | eData[1].frame_info = eData[0].frame_info; |
1249 | 0 | h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid; |
1250 | 0 | break; |
1251 | 0 | case SBR_MONO: |
1252 | | /* nothing to do */ |
1253 | 0 | break; |
1254 | 0 | default: |
1255 | 0 | FDK_ASSERT(0); |
1256 | 0 | } |
1257 | | |
1258 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1259 | 0 | HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch]; |
1260 | 0 | HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope; |
1261 | 0 | SBR_ENV_TEMP_DATA *ed = &eData[ch]; |
1262 | | |
1263 | | /* |
1264 | | Send transient info to bitstream and store for next call |
1265 | | */ |
1266 | 0 | sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */ |
1267 | 0 | sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */ |
1268 | 0 | hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes = |
1269 | 0 | ed->frame_info->nEnvelopes; /* number of envelopes of current frame */ |
1270 | 0 | hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF; |
1271 | | |
1272 | | /* |
1273 | | Check if the current frame is divided into one envelope only. If so, set |
1274 | | the amplitude resolution to 1.5 dB, otherwise may set back to chosen value |
1275 | | */ |
1276 | 0 | if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) && |
1277 | 0 | (ed->nEnvelopes == 1)) { |
1278 | 0 | AMP_RES currentAmpResFF = SBR_AMP_RES_1_5; |
1279 | 0 | if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { |
1280 | | /* Note: global_tonality_float_value == |
1281 | | ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0))); |
1282 | | threshold_float_value == |
1283 | | ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); |
1284 | | */ |
1285 | | /* decision of SBR_AMP_RES */ |
1286 | 0 | if (fIsLessThan(/* global_tonality > threshold ? */ |
1287 | 0 | h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e, |
1288 | 0 | hEnvChan->encEnvData.global_tonality, |
1289 | 0 | RELAXATION_SHIFT + 2)) { |
1290 | 0 | hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; |
1291 | 0 | } else { |
1292 | 0 | hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0; |
1293 | 0 | } |
1294 | 0 | currentAmpResFF = hEnvChan->encEnvData.currentAmpResFF; |
1295 | 0 | } |
1296 | |
|
1297 | 0 | if (currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) { |
1298 | 0 | FDKsbrEnc_InitSbrHuffmanTables( |
1299 | 0 | &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, |
1300 | 0 | &hEnvChan->sbrCodeNoiseFloor, currentAmpResFF); |
1301 | 0 | } |
1302 | 0 | } else { |
1303 | 0 | if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) { |
1304 | 0 | FDKsbrEnc_InitSbrHuffmanTables( |
1305 | 0 | &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, |
1306 | 0 | &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res); |
1307 | 0 | } |
1308 | 0 | } |
1309 | |
|
1310 | 0 | if (!clearOutput) { |
1311 | | /* |
1312 | | Tonality correction parameter extraction (inverse filtering level, noise |
1313 | | floor additional sines). |
1314 | | */ |
1315 | 0 | FDKsbrEnc_TonCorrParamExtr( |
1316 | 0 | &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec, |
1317 | 0 | ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag, |
1318 | 0 | hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation, |
1319 | 0 | ed->frame_info, ed->transient_info, h_con->freqBandTable[HI], |
1320 | 0 | h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode, |
1321 | 0 | h_con->sbrSyntaxFlags); |
1322 | 0 | } |
1323 | | |
1324 | | /* Low energy in low band fix */ |
1325 | 0 | if (hEnvChan->sbrTransientDetector.prevLowBandEnergy < |
1326 | 0 | hEnvChan->sbrTransientDetector.prevHighBandEnergy && |
1327 | 0 | hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03) |
1328 | | /* The fix needs the non-fast transient detector running. |
1329 | | It sets prevLowBandEnergy and prevHighBandEnergy. */ |
1330 | 0 | && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) { |
1331 | 0 | hEnvChan->fLevelProtect = 1; |
1332 | |
|
1333 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) |
1334 | 0 | hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL; |
1335 | 0 | } else { |
1336 | 0 | hEnvChan->fLevelProtect = 0; |
1337 | 0 | } |
1338 | |
|
1339 | 0 | hEnvChan->encEnvData.sbr_invf_mode = |
1340 | 0 | hEnvChan->encEnvData.sbr_invf_mode_vec[0]; |
1341 | |
|
1342 | 0 | hEnvChan->encEnvData.noOfnoisebands = |
1343 | 0 | hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; |
1344 | |
|
1345 | 0 | } /* ch */ |
1346 | | |
1347 | | /* |
1348 | | Save number of scf bands per envelope |
1349 | | */ |
1350 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1351 | 0 | for (i = 0; i < eData[ch].nEnvelopes; i++) { |
1352 | 0 | h_envChan[ch]->encEnvData.noScfBands[i] = |
1353 | 0 | (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH |
1354 | 0 | ? h_con->nSfb[FREQ_RES_HIGH] |
1355 | 0 | : h_con->nSfb[FREQ_RES_LOW]); |
1356 | 0 | } |
1357 | 0 | } |
1358 | |
|
1359 | 0 | if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY && |
1360 | 0 | stereoMode == SBR_SWITCH_LRC && |
1361 | 0 | h_envChan[0]->encEnvData.currentAmpResFF != |
1362 | 0 | h_envChan[1]->encEnvData.currentAmpResFF) { |
1363 | 0 | stereoMode = SBR_LEFT_RIGHT; |
1364 | 0 | } |
1365 | | |
1366 | | /* |
1367 | | Extract envelope of current frame. |
1368 | | */ |
1369 | 0 | switch (stereoMode) { |
1370 | 0 | case SBR_MONO: |
1371 | 0 | calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, |
1372 | 0 | h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, |
1373 | 0 | eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, |
1374 | 0 | h_envChan[0], SBR_MONO, NULL, YSzShift); |
1375 | 0 | break; |
1376 | 0 | case SBR_LEFT_RIGHT: |
1377 | 0 | calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, |
1378 | 0 | h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, |
1379 | 0 | eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, |
1380 | 0 | h_envChan[0], SBR_MONO, NULL, YSzShift); |
1381 | 0 | calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL, |
1382 | 0 | h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL, |
1383 | 0 | eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con, |
1384 | 0 | h_envChan[1], SBR_MONO, NULL, YSzShift); |
1385 | 0 | break; |
1386 | 0 | case SBR_COUPLING: |
1387 | 0 | calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, |
1388 | 0 | h_envChan[1]->sbrExtractEnvelope.YBuffer, |
1389 | 0 | h_envChan[0]->sbrExtractEnvelope.YBufferScale, |
1390 | 0 | h_envChan[1]->sbrExtractEnvelope.YBufferScale, |
1391 | 0 | eData[0].frame_info, eData[0].sfb_nrg, |
1392 | 0 | eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING, |
1393 | 0 | &fData->maxQuantError, YSzShift); |
1394 | 0 | break; |
1395 | 0 | case SBR_SWITCH_LRC: |
1396 | 0 | calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, |
1397 | 0 | h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, |
1398 | 0 | eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, |
1399 | 0 | h_envChan[0], SBR_MONO, NULL, YSzShift); |
1400 | 0 | calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL, |
1401 | 0 | h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL, |
1402 | 0 | eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con, |
1403 | 0 | h_envChan[1], SBR_MONO, NULL, YSzShift); |
1404 | 0 | calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, |
1405 | 0 | h_envChan[1]->sbrExtractEnvelope.YBuffer, |
1406 | 0 | h_envChan[0]->sbrExtractEnvelope.YBufferScale, |
1407 | 0 | h_envChan[1]->sbrExtractEnvelope.YBufferScale, |
1408 | 0 | eData[0].frame_info, eData[0].sfb_nrg_coupling, |
1409 | 0 | eData[1].sfb_nrg_coupling, h_con, h_envChan[0], |
1410 | 0 | SBR_COUPLING, &fData->maxQuantError, YSzShift); |
1411 | 0 | break; |
1412 | 0 | } |
1413 | | |
1414 | | /* |
1415 | | Noise floor quantisation and coding. |
1416 | | */ |
1417 | | |
1418 | 0 | switch (stereoMode) { |
1419 | 0 | case SBR_MONO: |
1420 | 0 | sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, |
1421 | 0 | 0); |
1422 | |
|
1423 | 0 | FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, |
1424 | 0 | &h_envChan[0]->sbrCodeNoiseFloor, |
1425 | 0 | h_envChan[0]->encEnvData.domain_vec_noise, 0, |
1426 | 0 | (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1427 | 0 | sbrBitstreamData->HeaderActive); |
1428 | |
|
1429 | 0 | break; |
1430 | 0 | case SBR_LEFT_RIGHT: |
1431 | 0 | sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, |
1432 | 0 | 0); |
1433 | |
|
1434 | 0 | FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, |
1435 | 0 | &h_envChan[0]->sbrCodeNoiseFloor, |
1436 | 0 | h_envChan[0]->encEnvData.domain_vec_noise, 0, |
1437 | 0 | (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1438 | 0 | sbrBitstreamData->HeaderActive); |
1439 | |
|
1440 | 0 | sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, |
1441 | 0 | 0); |
1442 | |
|
1443 | 0 | FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, |
1444 | 0 | &h_envChan[1]->sbrCodeNoiseFloor, |
1445 | 0 | h_envChan[1]->encEnvData.domain_vec_noise, 0, |
1446 | 0 | (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1447 | 0 | sbrBitstreamData->HeaderActive); |
1448 | |
|
1449 | 0 | break; |
1450 | | |
1451 | 0 | case SBR_COUPLING: |
1452 | 0 | coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor); |
1453 | |
|
1454 | 0 | sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, |
1455 | 0 | 0); |
1456 | |
|
1457 | 0 | FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, |
1458 | 0 | &h_envChan[0]->sbrCodeNoiseFloor, |
1459 | 0 | h_envChan[0]->encEnvData.domain_vec_noise, 1, |
1460 | 0 | (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1461 | 0 | sbrBitstreamData->HeaderActive); |
1462 | |
|
1463 | 0 | sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, |
1464 | 0 | 1); |
1465 | |
|
1466 | 0 | FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, |
1467 | 0 | &h_envChan[1]->sbrCodeNoiseFloor, |
1468 | 0 | h_envChan[1]->encEnvData.domain_vec_noise, 1, |
1469 | 0 | (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1, |
1470 | 0 | sbrBitstreamData->HeaderActive); |
1471 | |
|
1472 | 0 | break; |
1473 | 0 | case SBR_SWITCH_LRC: |
1474 | 0 | sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, |
1475 | 0 | 0); |
1476 | 0 | sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, |
1477 | 0 | 0); |
1478 | 0 | coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor); |
1479 | 0 | sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling, |
1480 | 0 | eData[0].noiseFloor, 0); |
1481 | 0 | sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling, |
1482 | 0 | eData[1].noiseFloor, 1); |
1483 | 0 | break; |
1484 | 0 | } |
1485 | | |
1486 | | /* |
1487 | | Encode envelope of current frame. |
1488 | | */ |
1489 | 0 | switch (stereoMode) { |
1490 | 0 | case SBR_MONO: |
1491 | 0 | sbrHeaderData->coupling = 0; |
1492 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1493 | 0 | FDKsbrEnc_codeEnvelope( |
1494 | 0 | eData[0].sfb_nrg, eData[0].frame_info->freqRes, |
1495 | 0 | &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, |
1496 | 0 | sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, |
1497 | 0 | sbrBitstreamData->HeaderActive); |
1498 | 0 | break; |
1499 | 0 | case SBR_LEFT_RIGHT: |
1500 | 0 | sbrHeaderData->coupling = 0; |
1501 | |
|
1502 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1503 | 0 | h_envChan[1]->encEnvData.balance = 0; |
1504 | |
|
1505 | 0 | FDKsbrEnc_codeEnvelope( |
1506 | 0 | eData[0].sfb_nrg, eData[0].frame_info->freqRes, |
1507 | 0 | &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, |
1508 | 0 | sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, |
1509 | 0 | sbrBitstreamData->HeaderActive); |
1510 | 0 | FDKsbrEnc_codeEnvelope( |
1511 | 0 | eData[1].sfb_nrg, eData[1].frame_info->freqRes, |
1512 | 0 | &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, |
1513 | 0 | sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0, |
1514 | 0 | sbrBitstreamData->HeaderActive); |
1515 | 0 | break; |
1516 | 0 | case SBR_COUPLING: |
1517 | 0 | sbrHeaderData->coupling = 1; |
1518 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1519 | 0 | h_envChan[1]->encEnvData.balance = 1; |
1520 | |
|
1521 | 0 | FDKsbrEnc_codeEnvelope( |
1522 | 0 | eData[0].sfb_nrg, eData[0].frame_info->freqRes, |
1523 | 0 | &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, |
1524 | 0 | sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, |
1525 | 0 | sbrBitstreamData->HeaderActive); |
1526 | 0 | FDKsbrEnc_codeEnvelope( |
1527 | 0 | eData[1].sfb_nrg, eData[1].frame_info->freqRes, |
1528 | 0 | &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, |
1529 | 0 | sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1, |
1530 | 0 | sbrBitstreamData->HeaderActive); |
1531 | 0 | break; |
1532 | 0 | case SBR_SWITCH_LRC: { |
1533 | 0 | INT payloadbitsLR; |
1534 | 0 | INT payloadbitsCOUPLING; |
1535 | |
|
1536 | 0 | SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS]; |
1537 | 0 | SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS]; |
1538 | 0 | INT upDateNrgTemp[MAX_NUM_CHANNELS]; |
1539 | 0 | INT upDateNoiseTemp[MAX_NUM_CHANNELS]; |
1540 | 0 | INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES]; |
1541 | 0 | INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES]; |
1542 | |
|
1543 | 0 | INT tempFlagRight = 0; |
1544 | 0 | INT tempFlagLeft = 0; |
1545 | | |
1546 | | /* |
1547 | | Store previous values, in order to be able to "undo" what is being |
1548 | | done. |
1549 | | */ |
1550 | |
|
1551 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1552 | 0 | FDKmemcpy(sfbNrgPrevTemp[ch], |
1553 | 0 | h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev, |
1554 | 0 | MAX_FREQ_COEFFS * sizeof(SCHAR)); |
1555 | |
|
1556 | 0 | FDKmemcpy(noisePrevTemp[ch], |
1557 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev, |
1558 | 0 | MAX_NUM_NOISE_COEFFS * sizeof(SCHAR)); |
1559 | |
|
1560 | 0 | upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate; |
1561 | 0 | upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate; |
1562 | | |
1563 | | /* |
1564 | | forbid time coding in the first envelope in case of a different |
1565 | | previous stereomode |
1566 | | */ |
1567 | 0 | if (sbrHeaderData->prev_coupling) { |
1568 | 0 | h_envChan[ch]->sbrCodeEnvelope.upDate = 0; |
1569 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0; |
1570 | 0 | } |
1571 | 0 | } /* ch */ |
1572 | | |
1573 | | /* |
1574 | | Code ordinary Left/Right stereo |
1575 | | */ |
1576 | 0 | FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes, |
1577 | 0 | &h_envChan[0]->sbrCodeEnvelope, |
1578 | 0 | h_envChan[0]->encEnvData.domain_vec, 0, |
1579 | 0 | eData[0].frame_info->nEnvelopes, 0, |
1580 | 0 | sbrBitstreamData->HeaderActive); |
1581 | 0 | FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes, |
1582 | 0 | &h_envChan[1]->sbrCodeEnvelope, |
1583 | 0 | h_envChan[1]->encEnvData.domain_vec, 0, |
1584 | 0 | eData[1].frame_info->nEnvelopes, 0, |
1585 | 0 | sbrBitstreamData->HeaderActive); |
1586 | |
|
1587 | 0 | c = 0; |
1588 | 0 | for (i = 0; i < eData[0].nEnvelopes; i++) { |
1589 | 0 | for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) { |
1590 | 0 | h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c]; |
1591 | 0 | h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c]; |
1592 | 0 | c++; |
1593 | 0 | } |
1594 | 0 | } |
1595 | |
|
1596 | 0 | FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, |
1597 | 0 | &h_envChan[0]->sbrCodeNoiseFloor, |
1598 | 0 | h_envChan[0]->encEnvData.domain_vec_noise, 0, |
1599 | 0 | (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1600 | 0 | sbrBitstreamData->HeaderActive); |
1601 | |
|
1602 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) |
1603 | 0 | h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i]; |
1604 | |
|
1605 | 0 | FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, |
1606 | 0 | &h_envChan[1]->sbrCodeNoiseFloor, |
1607 | 0 | h_envChan[1]->encEnvData.domain_vec_noise, 0, |
1608 | 0 | (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1609 | 0 | sbrBitstreamData->HeaderActive); |
1610 | |
|
1611 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) |
1612 | 0 | h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i]; |
1613 | |
|
1614 | 0 | sbrHeaderData->coupling = 0; |
1615 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1616 | 0 | h_envChan[1]->encEnvData.balance = 0; |
1617 | |
|
1618 | 0 | payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement( |
1619 | 0 | sbrHeaderData, hParametricStereo, sbrBitstreamData, |
1620 | 0 | &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, |
1621 | 0 | h_con->sbrSyntaxFlags); |
1622 | | |
1623 | | /* |
1624 | | swap saved stored with current values |
1625 | | */ |
1626 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1627 | 0 | INT itmp; |
1628 | 0 | for (i = 0; i < MAX_FREQ_COEFFS; i++) { |
1629 | | /* |
1630 | | swap sfb energies |
1631 | | */ |
1632 | 0 | itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i]; |
1633 | 0 | h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] = |
1634 | 0 | sfbNrgPrevTemp[ch][i]; |
1635 | 0 | sfbNrgPrevTemp[ch][i] = itmp; |
1636 | 0 | } |
1637 | 0 | for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) { |
1638 | | /* |
1639 | | swap noise energies |
1640 | | */ |
1641 | 0 | itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i]; |
1642 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] = |
1643 | 0 | noisePrevTemp[ch][i]; |
1644 | 0 | noisePrevTemp[ch][i] = itmp; |
1645 | 0 | } |
1646 | | /* swap update flags */ |
1647 | 0 | itmp = h_envChan[ch]->sbrCodeEnvelope.upDate; |
1648 | 0 | h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch]; |
1649 | 0 | upDateNrgTemp[ch] = itmp; |
1650 | |
|
1651 | 0 | itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate; |
1652 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch]; |
1653 | 0 | upDateNoiseTemp[ch] = itmp; |
1654 | | |
1655 | | /* |
1656 | | save domain vecs |
1657 | | */ |
1658 | 0 | FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec, |
1659 | 0 | sizeof(INT) * MAX_ENVELOPES); |
1660 | 0 | FDKmemcpy(domainVecNoiseTemp[ch], |
1661 | 0 | h_envChan[ch]->encEnvData.domain_vec_noise, |
1662 | 0 | sizeof(INT) * MAX_ENVELOPES); |
1663 | | |
1664 | | /* |
1665 | | forbid time coding in the first envelope in case of a different |
1666 | | previous stereomode |
1667 | | */ |
1668 | |
|
1669 | 0 | if (!sbrHeaderData->prev_coupling) { |
1670 | 0 | h_envChan[ch]->sbrCodeEnvelope.upDate = 0; |
1671 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0; |
1672 | 0 | } |
1673 | 0 | } /* ch */ |
1674 | | |
1675 | | /* |
1676 | | Coupling |
1677 | | */ |
1678 | |
|
1679 | 0 | FDKsbrEnc_codeEnvelope( |
1680 | 0 | eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes, |
1681 | 0 | &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, |
1682 | 0 | 1, eData[0].frame_info->nEnvelopes, 0, |
1683 | 0 | sbrBitstreamData->HeaderActive); |
1684 | |
|
1685 | 0 | FDKsbrEnc_codeEnvelope( |
1686 | 0 | eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes, |
1687 | 0 | &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, |
1688 | 0 | 1, eData[1].frame_info->nEnvelopes, 1, |
1689 | 0 | sbrBitstreamData->HeaderActive); |
1690 | |
|
1691 | 0 | c = 0; |
1692 | 0 | for (i = 0; i < eData[0].nEnvelopes; i++) { |
1693 | 0 | for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) { |
1694 | 0 | h_envChan[0]->encEnvData.ienvelope[i][j] = |
1695 | 0 | eData[0].sfb_nrg_coupling[c]; |
1696 | 0 | h_envChan[1]->encEnvData.ienvelope[i][j] = |
1697 | 0 | eData[1].sfb_nrg_coupling[c]; |
1698 | 0 | c++; |
1699 | 0 | } |
1700 | 0 | } |
1701 | |
|
1702 | 0 | FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res, |
1703 | 0 | &h_envChan[0]->sbrCodeNoiseFloor, |
1704 | 0 | h_envChan[0]->encEnvData.domain_vec_noise, 1, |
1705 | 0 | (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, |
1706 | 0 | sbrBitstreamData->HeaderActive); |
1707 | |
|
1708 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) |
1709 | 0 | h_envChan[0]->encEnvData.sbr_noise_levels[i] = |
1710 | 0 | eData[0].noise_level_coupling[i]; |
1711 | |
|
1712 | 0 | FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res, |
1713 | 0 | &h_envChan[1]->sbrCodeNoiseFloor, |
1714 | 0 | h_envChan[1]->encEnvData.domain_vec_noise, 1, |
1715 | 0 | (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1, |
1716 | 0 | sbrBitstreamData->HeaderActive); |
1717 | |
|
1718 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) |
1719 | 0 | h_envChan[1]->encEnvData.sbr_noise_levels[i] = |
1720 | 0 | eData[1].noise_level_coupling[i]; |
1721 | |
|
1722 | 0 | sbrHeaderData->coupling = 1; |
1723 | |
|
1724 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1725 | 0 | h_envChan[1]->encEnvData.balance = 1; |
1726 | |
|
1727 | 0 | tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag; |
1728 | 0 | tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag; |
1729 | |
|
1730 | 0 | payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement( |
1731 | 0 | sbrHeaderData, hParametricStereo, sbrBitstreamData, |
1732 | 0 | &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, |
1733 | 0 | h_con->sbrSyntaxFlags); |
1734 | |
|
1735 | 0 | h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft; |
1736 | 0 | h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight; |
1737 | |
|
1738 | 0 | if (payloadbitsCOUPLING < payloadbitsLR) { |
1739 | | /* |
1740 | | copy coded coupling envelope and noise data to l/r |
1741 | | */ |
1742 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1743 | 0 | SBR_ENV_TEMP_DATA *ed = &eData[ch]; |
1744 | 0 | FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling, |
1745 | 0 | MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR)); |
1746 | 0 | FDKmemcpy(ed->noise_level, ed->noise_level_coupling, |
1747 | 0 | MAX_NUM_NOISE_VALUES * sizeof(SCHAR)); |
1748 | 0 | } |
1749 | |
|
1750 | 0 | sbrHeaderData->coupling = 1; |
1751 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1752 | 0 | h_envChan[1]->encEnvData.balance = 1; |
1753 | 0 | } else { |
1754 | | /* |
1755 | | restore saved l/r items |
1756 | | */ |
1757 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1758 | 0 | FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev, |
1759 | 0 | sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR)); |
1760 | |
|
1761 | 0 | h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch]; |
1762 | |
|
1763 | 0 | FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev, |
1764 | 0 | noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR)); |
1765 | |
|
1766 | 0 | FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch], |
1767 | 0 | sizeof(INT) * MAX_ENVELOPES); |
1768 | 0 | FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise, |
1769 | 0 | domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES); |
1770 | |
|
1771 | 0 | h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch]; |
1772 | 0 | } |
1773 | |
|
1774 | 0 | sbrHeaderData->coupling = 0; |
1775 | 0 | h_envChan[0]->encEnvData.balance = 0; |
1776 | 0 | h_envChan[1]->encEnvData.balance = 0; |
1777 | 0 | } |
1778 | 0 | } break; |
1779 | 0 | } /* switch */ |
1780 | | |
1781 | | /* tell the envelope encoders how long it has been, since we last sent |
1782 | | a frame starting with a dF-coded envelope */ |
1783 | 0 | if (stereoMode == SBR_MONO) { |
1784 | 0 | if (h_envChan[0]->encEnvData.domain_vec[0] == TIME) |
1785 | 0 | h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++; |
1786 | 0 | else |
1787 | 0 | h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0; |
1788 | 0 | } else { |
1789 | 0 | if (h_envChan[0]->encEnvData.domain_vec[0] == TIME || |
1790 | 0 | h_envChan[1]->encEnvData.domain_vec[0] == TIME) { |
1791 | 0 | h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++; |
1792 | 0 | h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++; |
1793 | 0 | } else { |
1794 | 0 | h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0; |
1795 | 0 | h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0; |
1796 | 0 | } |
1797 | 0 | } |
1798 | | |
1799 | | /* |
1800 | | Send the encoded data to the bitstream |
1801 | | */ |
1802 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1803 | 0 | SBR_ENV_TEMP_DATA *ed = &eData[ch]; |
1804 | 0 | c = 0; |
1805 | 0 | for (i = 0; i < ed->nEnvelopes; i++) { |
1806 | 0 | for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) { |
1807 | 0 | h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c]; |
1808 | |
|
1809 | 0 | c++; |
1810 | 0 | } |
1811 | 0 | } |
1812 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { |
1813 | 0 | h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i]; |
1814 | 0 | } |
1815 | 0 | } /* ch */ |
1816 | | |
1817 | | /* |
1818 | | Write bitstream |
1819 | | */ |
1820 | 0 | if (nChannels == 2) { |
1821 | 0 | FDKsbrEnc_WriteEnvChannelPairElement( |
1822 | 0 | sbrHeaderData, hParametricStereo, sbrBitstreamData, |
1823 | 0 | &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, |
1824 | 0 | h_con->sbrSyntaxFlags); |
1825 | 0 | } else { |
1826 | 0 | FDKsbrEnc_WriteEnvSingleChannelElement( |
1827 | 0 | sbrHeaderData, hParametricStereo, sbrBitstreamData, |
1828 | 0 | &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags); |
1829 | 0 | } |
1830 | | |
1831 | | /* |
1832 | | * Update buffers. |
1833 | | */ |
1834 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1835 | 0 | int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >> |
1836 | 0 | h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift; |
1837 | 0 | for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) { |
1838 | 0 | FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i], |
1839 | 0 | h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength], |
1840 | 0 | sizeof(FIXP_DBL) * 64); |
1841 | 0 | } |
1842 | 0 | h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] = |
1843 | 0 | h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1]; |
1844 | 0 | } |
1845 | |
|
1846 | 0 | sbrHeaderData->prev_coupling = sbrHeaderData->coupling; |
1847 | 0 | } |
1848 | | |
1849 | | /***************************************************************************/ |
1850 | | /*! |
1851 | | |
1852 | | \brief creates an envelope extractor handle |
1853 | | |
1854 | | \return error status |
1855 | | |
1856 | | ****************************************************************************/ |
1857 | | INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, |
1858 | | INT channel, INT chInEl, |
1859 | 0 | UCHAR *dynamic_RAM) { |
1860 | 0 | INT i; |
1861 | 0 | FIXP_DBL *rBuffer, *iBuffer; |
1862 | 0 | INT n; |
1863 | 0 | FIXP_DBL *YBufferDyn; |
1864 | |
|
1865 | 0 | FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE)); |
1866 | |
|
1867 | 0 | if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) { |
1868 | 0 | goto bail; |
1869 | 0 | } |
1870 | | |
1871 | 0 | for (i = 0; i < (32 >> 1); i++) { |
1872 | 0 | hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64); |
1873 | 0 | } |
1874 | 0 | YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM); |
1875 | 0 | for (n = 0; i < 32; i++, n++) { |
1876 | 0 | hSbrCut->YBuffer[i] = YBufferDyn + (n * 64); |
1877 | 0 | } |
1878 | |
|
1879 | 0 | rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM); |
1880 | 0 | iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM); |
1881 | |
|
1882 | 0 | for (i = 0; i < 32; i++) { |
1883 | 0 | hSbrCut->rBuffer[i] = rBuffer + (i * 64); |
1884 | 0 | hSbrCut->iBuffer[i] = iBuffer + (i * 64); |
1885 | 0 | } |
1886 | |
|
1887 | 0 | return 0; |
1888 | | |
1889 | 0 | bail: |
1890 | 0 | FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut); |
1891 | |
|
1892 | 0 | return -1; |
1893 | 0 | } |
1894 | | |
1895 | | /***************************************************************************/ |
1896 | | /*! |
1897 | | |
1898 | | \brief Initialize an envelope extractor instance. |
1899 | | |
1900 | | \return error status |
1901 | | |
1902 | | ****************************************************************************/ |
1903 | | INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, |
1904 | | int no_cols, int no_rows, int start_index, |
1905 | | int time_slots, int time_step, |
1906 | | int tran_off, ULONG statesInitFlag, |
1907 | | int chInEl, UCHAR *dynamic_RAM, |
1908 | 0 | UINT sbrSyntaxFlags) { |
1909 | 0 | int YBufferLength, rBufferLength; |
1910 | 0 | int i; |
1911 | |
|
1912 | 0 | if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { |
1913 | 0 | int off = TRANSIENT_OFFSET_LD; |
1914 | 0 | hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step; |
1915 | 0 | } else { |
1916 | 0 | hSbrCut->YBufferWriteOffset = tran_off * time_step; |
1917 | 0 | } |
1918 | 0 | hSbrCut->rBufferReadOffset = 0; |
1919 | |
|
1920 | 0 | YBufferLength = hSbrCut->YBufferWriteOffset + no_cols; |
1921 | 0 | rBufferLength = no_cols; |
1922 | |
|
1923 | 0 | hSbrCut->pre_transient_info[0] = 0; |
1924 | 0 | hSbrCut->pre_transient_info[1] = 0; |
1925 | |
|
1926 | 0 | hSbrCut->no_cols = no_cols; |
1927 | 0 | hSbrCut->no_rows = no_rows; |
1928 | 0 | hSbrCut->start_index = start_index; |
1929 | |
|
1930 | 0 | hSbrCut->time_slots = time_slots; |
1931 | 0 | hSbrCut->time_step = time_step; |
1932 | |
|
1933 | 0 | FDK_ASSERT(no_rows <= 64); |
1934 | | |
1935 | | /* Use half the Energy values if time step is 2 or greater */ |
1936 | 0 | if (time_step >= 2) |
1937 | 0 | hSbrCut->YBufferSzShift = 1; |
1938 | 0 | else |
1939 | 0 | hSbrCut->YBufferSzShift = 0; |
1940 | |
|
1941 | 0 | YBufferLength >>= hSbrCut->YBufferSzShift; |
1942 | 0 | hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift; |
1943 | |
|
1944 | 0 | FDK_ASSERT(YBufferLength <= 32); |
1945 | | |
1946 | 0 | FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM); |
1947 | 0 | INT n = 0; |
1948 | 0 | for (i = (32 >> 1); i < 32; i++, n++) { |
1949 | 0 | hSbrCut->YBuffer[i] = YBufferDyn + (n * 64); |
1950 | 0 | } |
1951 | |
|
1952 | 0 | if (statesInitFlag) { |
1953 | 0 | for (i = 0; i < YBufferLength; i++) { |
1954 | 0 | FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL)); |
1955 | 0 | } |
1956 | 0 | } |
1957 | |
|
1958 | 0 | for (i = 0; i < rBufferLength; i++) { |
1959 | 0 | FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL)); |
1960 | 0 | FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL)); |
1961 | 0 | } |
1962 | |
|
1963 | 0 | FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS); |
1964 | |
|
1965 | 0 | if (statesInitFlag) { |
1966 | 0 | hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1; |
1967 | 0 | } |
1968 | |
|
1969 | 0 | return (0); |
1970 | 0 | } |
1971 | | |
1972 | | /***************************************************************************/ |
1973 | | /*! |
1974 | | |
1975 | | \brief deinitializes an envelope extractor handle |
1976 | | |
1977 | | \return void |
1978 | | |
1979 | | ****************************************************************************/ |
1980 | | |
1981 | 0 | void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) { |
1982 | 0 | if (hSbrCut) { |
1983 | 0 | FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer); |
1984 | 0 | } |
1985 | 0 | } |
1986 | | |
1987 | 0 | INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) { |
1988 | 0 | return hSbr->no_rows * |
1989 | 0 | ((hSbr->YBufferWriteOffset) * |
1990 | 0 | 2 /* mult 2 because nrg's are grouped half */ |
1991 | 0 | - hSbr->rBufferReadOffset); /* in reference hold half spec and calc |
1992 | | nrg's on overlapped spec */ |
1993 | 0 | } |