2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
86 \brief envelope decoding
87 This module provides envelope decoding and error concealment algorithms. The main
88 entry point is decodeSbrData().
90 \sa decodeSbrData(),\ref documentationOverview
96 #include "transcendent.h"
98 #include "genericStds.h"
101 static void decodeEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData
,
102 HANDLE_SBR_FRAME_DATA h_sbr_data
,
103 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
,
104 HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel
);
105 static void sbr_envelope_unmapping (HANDLE_SBR_HEADER_DATA hHeaderData
,
106 HANDLE_SBR_FRAME_DATA h_data_left
,
107 HANDLE_SBR_FRAME_DATA h_data_right
);
108 static void requantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data
,
110 static void deltaToLinearPcmEnvelopeDecoding (HANDLE_SBR_HEADER_DATA hHeaderData
,
111 HANDLE_SBR_FRAME_DATA h_sbr_data
,
112 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
);
113 static void decodeNoiseFloorlevels (HANDLE_SBR_HEADER_DATA hHeaderData
,
114 HANDLE_SBR_FRAME_DATA h_sbr_data
,
115 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
);
116 static void timeCompensateFirstEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData
,
117 HANDLE_SBR_FRAME_DATA h_sbr_data
,
118 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
);
119 static int checkEnvelopeData (HANDLE_SBR_HEADER_DATA hHeaderData
,
120 HANDLE_SBR_FRAME_DATA h_sbr_data
,
121 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
);
125 #define SBR_ENERGY_PAN_OFFSET (12 << ENV_EXP_FRACT)
126 #define SBR_MAX_ENERGY (35 << ENV_EXP_FRACT)
128 #define DECAY ( 1 << ENV_EXP_FRACT)
131 #define DECAY_COUPLING ( 1 << (ENV_EXP_FRACT-1) ) /*!< corresponds to a value of 0.5 */
133 #define DECAY_COUPLING 1 /*!< If the energy data is not shifted, use 1 instead of 0.5 */
138 \brief Convert table index
140 static int indexLow2High(int offset
, /*!< mapping factor */
141 int index
, /*!< index to scalefactor band */
142 int res
) /*!< frequency resolution */
151 return(2*index
- offset
);
157 return(2*index
+index
);
159 return(2*index
+ offset
);
168 \brief Update previous envelope value for delta-coding
170 The current envelope values needs to be stored for delta-coding
171 in the next frame. The stored envelope is always represented with
172 the high frequency resolution. If the current envelope uses the
173 low frequency resolution, the energy value will be mapped to the
174 corresponding high-res bands.
176 static void mapLowResEnergyVal(FIXP_SGL currVal
, /*!< current energy value */
177 FIXP_SGL
* prevData
,/*!< pointer to previous data vector */
178 int offset
, /*!< mapping factor */
179 int index
, /*!< index to scalefactor band */
180 int res
) /*!< frequeny resolution */
187 prevData
[index
] = currVal
;
190 prevData
[2*index
- offset
] = currVal
;
191 prevData
[2*index
+1 - offset
] = currVal
;
199 prevData
[3*index
] = currVal
;
200 prevData
[3*index
+1] = currVal
;
201 prevData
[3*index
+2] = currVal
;
205 prevData
[2*index
+ offset
] = currVal
;
206 prevData
[2*index
+ 1 + offset
] = currVal
;
211 prevData
[index
] = currVal
;
217 \brief Convert raw envelope and noisefloor data to energy levels
219 This function is being called by sbrDecoder_ParseElement() and provides two important algorithms:
221 First the function decodes envelopes and noise floor levels as described in requantizeEnvelopeData()
222 and sbr_envelope_unmapping(). The function also implements concealment algorithms in case there are errors
223 within the sbr data. For both operations fractional arithmetic is used.
224 Therefore you might encounter different output values on your target
225 system compared to the reference implementation.
228 decodeSbrData (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
229 HANDLE_SBR_FRAME_DATA h_data_left
, /*!< pointer to left channel frame data */
230 HANDLE_SBR_PREV_FRAME_DATA h_prev_data_left
, /*!< pointer to left channel previous frame data */
231 HANDLE_SBR_FRAME_DATA h_data_right
, /*!< pointer to right channel frame data */
232 HANDLE_SBR_PREV_FRAME_DATA h_prev_data_right
)/*!< pointer to right channel previous frame data */
234 FIXP_SGL tempSfbNrgPrev
[MAX_FREQ_COEFFS
];
237 /* Save previous energy values to be able to reuse them later for concealment. */
238 FDKmemcpy (tempSfbNrgPrev
, h_prev_data_left
->sfb_nrg_prev
, MAX_FREQ_COEFFS
* sizeof(FIXP_SGL
));
240 decodeEnvelope (hHeaderData
, h_data_left
, h_prev_data_left
, h_prev_data_right
);
241 decodeNoiseFloorlevels (hHeaderData
, h_data_left
, h_prev_data_left
);
243 if(h_data_right
!= NULL
) {
244 errLeft
= hHeaderData
->frameErrorFlag
;
245 decodeEnvelope (hHeaderData
, h_data_right
, h_prev_data_right
, h_prev_data_left
);
246 decodeNoiseFloorlevels (hHeaderData
, h_data_right
, h_prev_data_right
);
248 if (!errLeft
&& hHeaderData
->frameErrorFlag
) {
249 /* If an error occurs in the right channel where the left channel seemed ok,
250 we apply concealment also on the left channel. This ensures that the coupling
251 modes of both channels match and that we have the same number of envelopes in
253 However, as the left channel has already been processed before, the resulting
254 energy levels are not the same as if the left channel had been concealed
255 during the first call of decodeEnvelope().
257 /* Restore previous energy values for concealment, because the values have been
258 overwritten by the first call of decodeEnvelope(). */
259 FDKmemcpy (h_prev_data_left
->sfb_nrg_prev
, tempSfbNrgPrev
, MAX_FREQ_COEFFS
* sizeof(FIXP_SGL
));
261 decodeEnvelope (hHeaderData
, h_data_left
, h_prev_data_left
, h_prev_data_right
);
264 if (h_data_left
->coupling
) {
265 sbr_envelope_unmapping (hHeaderData
, h_data_left
, h_data_right
);
269 /* Display the data for debugging: */
274 \brief Convert from coupled channels to independent L/R data
277 sbr_envelope_unmapping (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
278 HANDLE_SBR_FRAME_DATA h_data_left
, /*!< pointer to left channel */
279 HANDLE_SBR_FRAME_DATA h_data_right
) /*!< pointer to right channel */
282 FIXP_SGL tempL_m
, tempR_m
, tempRplus1_m
, newL_m
, newR_m
;
283 SCHAR tempL_e
, tempR_e
, tempRplus1_e
, newL_e
, newR_e
;
286 /* 1. Unmap (already dequantized) coupled envelope energies */
288 for (i
= 0; i
< h_data_left
->nScaleFactors
; i
++) {
289 tempR_m
= (FIXP_SGL
)((LONG
)h_data_right
->iEnvelope
[i
] & MASK_M
);
290 tempR_e
= (SCHAR
)((LONG
)h_data_right
->iEnvelope
[i
] & MASK_E
);
292 tempR_e
-= (18 + NRG_EXP_OFFSET
); /* -18 = ld(UNMAPPING_SCALE / h_data_right->nChannels) */
293 tempL_m
= (FIXP_SGL
)((LONG
)h_data_left
->iEnvelope
[i
] & MASK_M
);
294 tempL_e
= (SCHAR
)((LONG
)h_data_left
->iEnvelope
[i
] & MASK_E
);
296 tempL_e
-= NRG_EXP_OFFSET
;
298 /* Calculate tempRight+1 */
299 FDK_add_MantExp( tempR_m
, tempR_e
,
300 FL2FXCONST_SGL(0.5f
), 1, /* 1.0 */
301 &tempRplus1_m
, &tempRplus1_e
);
303 FDK_divide_MantExp( tempL_m
, tempL_e
+1, /* 2 * tempLeft */
304 tempRplus1_m
, tempRplus1_e
,
307 if (newR_m
>= ((FIXP_SGL
)MAXVAL_SGL
- ROUNDING
)) {
312 newL_m
= FX_DBL2FX_SGL(fMult(tempR_m
,newR_m
));
313 newL_e
= tempR_e
+ newR_e
;
315 h_data_right
->iEnvelope
[i
] = ((FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newR_m
+ ROUNDING
) & MASK_M
)) +
316 (FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newR_e
+ NRG_EXP_OFFSET
) & MASK_E
);
317 h_data_left
->iEnvelope
[i
] = ((FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newL_m
+ ROUNDING
) & MASK_M
)) +
318 (FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newL_e
+ NRG_EXP_OFFSET
) & MASK_E
);
321 /* 2. Dequantize and unmap coupled noise floor levels */
323 for (i
= 0; i
< hHeaderData
->freqBandData
.nNfb
* h_data_left
->frameInfo
.nNoiseEnvelopes
; i
++) {
325 tempL_e
= (SCHAR
)(6 - (LONG
)h_data_left
->sbrNoiseFloorLevel
[i
]);
326 tempR_e
= (SCHAR
)((LONG
)h_data_right
->sbrNoiseFloorLevel
[i
] - 12) /*SBR_ENERGY_PAN_OFFSET*/;
328 /* Calculate tempR+1 */
329 FDK_add_MantExp( FL2FXCONST_SGL(0.5f
), 1+tempR_e
, /* tempR */
330 FL2FXCONST_SGL(0.5f
), 1, /* 1.0 */
331 &tempRplus1_m
, &tempRplus1_e
);
333 /* Calculate 2*tempLeft/(tempR+1) */
334 FDK_divide_MantExp( FL2FXCONST_SGL(0.5f
), tempL_e
+2, /* 2 * tempLeft */
335 tempRplus1_m
, tempRplus1_e
,
338 /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
345 newL_e
= newR_e
+ tempR_e
;
346 h_data_right
->sbrNoiseFloorLevel
[i
] = ((FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newR_m
+ ROUNDING
) & MASK_M
)) +
347 (FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newR_e
+ NOISE_EXP_OFFSET
) & MASK_E
);
348 h_data_left
->sbrNoiseFloorLevel
[i
] = ((FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newL_m
+ ROUNDING
) & MASK_M
)) +
349 (FIXP_SGL
)((SHORT
)(FIXP_SGL
)(newL_e
+ NOISE_EXP_OFFSET
) & MASK_E
);
355 \brief Simple alternative to the real SBR concealment
357 If the real frameInfo is not available due to a frame loss, a replacement will
358 be constructed with 1 envelope spanning the whole frame (FIX-FIX).
359 The delta-coded energies are set to negative values, resulting in a fade-down.
360 In case of coupling, the balance-channel will move towards the center.
363 leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
364 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to current data */
365 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
/*!< pointer to data of last frame */
368 FIXP_SGL target
; /* targeted level for sfb_nrg_prev during fade-down */
369 FIXP_SGL step
; /* speed of fade */
372 int currentStartPos
= h_prev_data
->stopPos
- hHeaderData
->numberTimeSlots
;
373 int currentStopPos
= hHeaderData
->numberTimeSlots
;
376 /* Use some settings of the previous frame */
377 h_sbr_data
->ampResolutionCurrentFrame
= h_prev_data
->ampRes
;
378 h_sbr_data
->coupling
= h_prev_data
->coupling
;
379 for(i
=0;i
<MAX_INVF_BANDS
;i
++)
380 h_sbr_data
->sbr_invf_mode
[i
] = h_prev_data
->sbr_invf_mode
[i
];
382 /* Generate concealing control data */
384 h_sbr_data
->frameInfo
.nEnvelopes
= 1;
385 h_sbr_data
->frameInfo
.borders
[0] = currentStartPos
;
386 h_sbr_data
->frameInfo
.borders
[1] = currentStopPos
;
387 h_sbr_data
->frameInfo
.freqRes
[0] = 1;
388 h_sbr_data
->frameInfo
.tranEnv
= -1; /* no transient */
389 h_sbr_data
->frameInfo
.nNoiseEnvelopes
= 1;
390 h_sbr_data
->frameInfo
.bordersNoise
[0] = currentStartPos
;
391 h_sbr_data
->frameInfo
.bordersNoise
[1] = currentStopPos
;
393 h_sbr_data
->nScaleFactors
= hHeaderData
->freqBandData
.nSfb
[1];
395 /* Generate fake envelope data */
397 h_sbr_data
->domain_vec
[0] = 1;
399 if (h_sbr_data
->coupling
== COUPLING_BAL
) {
400 target
= (FIXP_SGL
)SBR_ENERGY_PAN_OFFSET
;
401 step
= (FIXP_SGL
)DECAY_COUPLING
;
404 target
= FL2FXCONST_SGL(0.0f
);
405 step
= (FIXP_SGL
)DECAY
;
407 if (hHeaderData
->bs_info
.ampResolution
== 0) {
412 for (i
=0; i
< h_sbr_data
->nScaleFactors
; i
++) {
413 if (h_prev_data
->sfb_nrg_prev
[i
] > target
)
414 h_sbr_data
->iEnvelope
[i
] = -step
;
416 h_sbr_data
->iEnvelope
[i
] = step
;
419 /* Noisefloor levels are always cleared ... */
421 h_sbr_data
->domain_vec_noise
[0] = 1;
422 for (i
=0; i
< hHeaderData
->freqBandData
.nNfb
; i
++)
423 h_sbr_data
->sbrNoiseFloorLevel
[i
] = FL2FXCONST_SGL(0.0f
);
425 /* ... and so are the sines */
426 FDKmemclear(h_sbr_data
->addHarmonics
, MAX_FREQ_COEFFS
);
431 \brief Build reference energies and noise levels from bitstream elements
434 decodeEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
435 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to current data */
436 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
, /*!< pointer to data of last frame */
437 HANDLE_SBR_PREV_FRAME_DATA otherChannel
/*!< other channel's last frame data */
441 int fFrameError
= hHeaderData
->frameErrorFlag
;
442 FIXP_SGL tempSfbNrgPrev
[MAX_FREQ_COEFFS
];
446 To avoid distortions after bad frames, set the error flag if delta coding in time occurs.
447 However, SBR can take a little longer to come up again.
449 if ( h_prev_data
->frameErrorFlag
) {
450 if (h_sbr_data
->domain_vec
[0] != 0) {
454 /* Check that the previous stop position and the current start position match.
455 (Could be done in checkFrameInfo(), but the previous frame data is not available there) */
456 if ( h_sbr_data
->frameInfo
.borders
[0] != h_prev_data
->stopPos
- hHeaderData
->numberTimeSlots
) {
457 /* Both the previous as well as the current frame are flagged to be ok, but they do not match! */
458 if (h_sbr_data
->domain_vec
[0] == 1) {
459 /* Prefer concealment over delta-time coding between the mismatching frames */
463 /* Close the gap in time by triggering timeCompensateFirstEnvelope() */
471 if (fFrameError
) /* Error is detected */
473 leanSbrConcealment(hHeaderData
,
477 /* decode the envelope data to linear PCM */
478 deltaToLinearPcmEnvelopeDecoding (hHeaderData
, h_sbr_data
, h_prev_data
);
480 else /*Do a temporary dummy decoding and check that the envelope values are within limits */
482 if (h_prev_data
->frameErrorFlag
) {
483 timeCompensateFirstEnvelope (hHeaderData
, h_sbr_data
, h_prev_data
);
484 if (h_sbr_data
->coupling
!= h_prev_data
->coupling
) {
486 Coupling mode has changed during concealment.
487 The stored energy levels need to be converted.
489 for (i
= 0; i
< hHeaderData
->freqBandData
.nSfb
[1]; i
++) {
490 /* Former Level-Channel will be used for both channels */
491 if (h_prev_data
->coupling
== COUPLING_BAL
)
492 h_prev_data
->sfb_nrg_prev
[i
] = otherChannel
->sfb_nrg_prev
[i
];
493 /* Former L/R will be combined as the new Level-Channel */
494 else if (h_sbr_data
->coupling
== COUPLING_LEVEL
)
495 h_prev_data
->sfb_nrg_prev
[i
] = (h_prev_data
->sfb_nrg_prev
[i
] + otherChannel
->sfb_nrg_prev
[i
]) >> 1;
496 else if (h_sbr_data
->coupling
== COUPLING_BAL
)
497 h_prev_data
->sfb_nrg_prev
[i
] = (FIXP_SGL
)SBR_ENERGY_PAN_OFFSET
;
501 FDKmemcpy (tempSfbNrgPrev
, h_prev_data
->sfb_nrg_prev
,
502 MAX_FREQ_COEFFS
* sizeof (FIXP_SGL
));
504 deltaToLinearPcmEnvelopeDecoding (hHeaderData
, h_sbr_data
, h_prev_data
);
506 fFrameError
= checkEnvelopeData (hHeaderData
, h_sbr_data
, h_prev_data
);
510 hHeaderData
->frameErrorFlag
= 1;
511 FDKmemcpy (h_prev_data
->sfb_nrg_prev
, tempSfbNrgPrev
,
512 MAX_FREQ_COEFFS
* sizeof (FIXP_SGL
));
513 decodeEnvelope (hHeaderData
, h_sbr_data
, h_prev_data
, otherChannel
);
518 requantizeEnvelopeData (h_sbr_data
, h_sbr_data
->ampResolutionCurrentFrame
);
520 hHeaderData
->frameErrorFlag
= fFrameError
;
525 \brief Verify that envelope energies are within the allowed range
526 \return 0 if all is fine, 1 if an envelope value was too high
529 checkEnvelopeData (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
530 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to current data */
531 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
/*!< pointer to data of last frame */
534 FIXP_SGL
*iEnvelope
= h_sbr_data
->iEnvelope
;
535 FIXP_SGL
*sfb_nrg_prev
= h_prev_data
->sfb_nrg_prev
;
536 int i
= 0, errorFlag
= 0;
537 FIXP_SGL sbr_max_energy
=
538 (h_sbr_data
->ampResolutionCurrentFrame
== 1) ? SBR_MAX_ENERGY
: (SBR_MAX_ENERGY
<< 1);
541 Range check for current energies
543 for (i
= 0; i
< h_sbr_data
->nScaleFactors
; i
++) {
544 if (iEnvelope
[i
] > sbr_max_energy
) {
547 if (iEnvelope
[i
] < FL2FXCONST_SGL(0.0f
)) {
549 /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */
554 Range check for previous energies
556 for (i
= 0; i
< hHeaderData
->freqBandData
.nSfb
[1]; i
++) {
557 sfb_nrg_prev
[i
] = fixMax(sfb_nrg_prev
[i
], FL2FXCONST_SGL(0.0f
));
558 sfb_nrg_prev
[i
] = fixMin(sfb_nrg_prev
[i
], sbr_max_energy
);
566 \brief Verify that the noise levels are within the allowed range
568 The function is equivalent to checkEnvelopeData().
569 When the noise-levels are being decoded, it is already too late for
570 concealment. Therefore the noise levels are simply limited here.
573 limitNoiseLevels(HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
574 HANDLE_SBR_FRAME_DATA h_sbr_data
) /*!< pointer to current data */
577 int nNfb
= hHeaderData
->freqBandData
.nNfb
;
580 Set range limits. The exact values depend on the coupling mode.
581 However this limitation is primarily intended to avoid unlimited
582 accumulation of the delta-coded noise levels.
584 #define lowerLimit ((FIXP_SGL)0) /* lowerLimit actually refers to the _highest_ noise energy */
585 #define upperLimit ((FIXP_SGL)35) /* upperLimit actually refers to the _lowest_ noise energy */
588 Range check for current noise levels
590 for (i
= 0; i
< h_sbr_data
->frameInfo
.nNoiseEnvelopes
* nNfb
; i
++) {
591 h_sbr_data
->sbrNoiseFloorLevel
[i
] = fixMin(h_sbr_data
->sbrNoiseFloorLevel
[i
], upperLimit
);
592 h_sbr_data
->sbrNoiseFloorLevel
[i
] = fixMax(h_sbr_data
->sbrNoiseFloorLevel
[i
], lowerLimit
);
598 \brief Compensate for the wrong timing that might occur after a frame error.
601 timeCompensateFirstEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
602 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to actual data */
603 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
) /*!< pointer to data of last frame */
605 int i
, nScalefactors
;
606 FRAME_INFO
*pFrameInfo
= &h_sbr_data
->frameInfo
;
607 UCHAR
*nSfb
= hHeaderData
->freqBandData
.nSfb
;
608 int estimatedStartPos
= h_prev_data
->stopPos
- hHeaderData
->numberTimeSlots
;
609 int refLen
, newLen
, shift
;
612 /* Original length of first envelope according to bitstream */
613 refLen
= pFrameInfo
->borders
[1] - pFrameInfo
->borders
[0];
614 /* Corrected length of first envelope (concealing can make the first envelope longer) */
615 newLen
= pFrameInfo
->borders
[1] - estimatedStartPos
;
618 /* An envelope length of <= 0 would not work, so we don't use it.
619 May occur if the previous frame was flagged bad due to a mismatch
620 of the old and new frame infos. */
622 estimatedStartPos
= pFrameInfo
->borders
[0];
625 deltaExp
= FDK_getNumOctavesDiv8(newLen
, refLen
);
627 /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */
628 shift
= (FRACT_BITS
- 1 - ENV_EXP_FRACT
- 1 + h_sbr_data
->ampResolutionCurrentFrame
- 3);
629 deltaExp
= deltaExp
>> shift
;
630 pFrameInfo
->borders
[0] = estimatedStartPos
;
631 pFrameInfo
->bordersNoise
[0] = estimatedStartPos
;
633 if (h_sbr_data
->coupling
!= COUPLING_BAL
) {
634 nScalefactors
= (pFrameInfo
->freqRes
[0]) ? nSfb
[1] : nSfb
[0];
636 for (i
= 0; i
< nScalefactors
; i
++)
637 h_sbr_data
->iEnvelope
[i
] = h_sbr_data
->iEnvelope
[i
] + deltaExp
;
644 \brief Convert each envelope value from logarithmic to linear domain
646 Energy levels are transmitted in powers of 2, i.e. only the exponent
647 is extracted from the bitstream.
648 Therefore, normally only integer exponents can occur. However during
649 fading (in case of a corrupt bitstream), a fractional part can also
650 occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT
651 compared to an integer representation so that numbers smaller than 1
654 This function calculates a mantissa corresponding to the fractional
655 part of the exponent for each reference energy. The array iEnvelope
656 is converted in place to save memory. Input and output data must
657 be interpreted differently, as shown in the below figure:
659 \image html EnvelopeData.png
661 The data is then used in calculateSbrEnvelope().
664 requantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data
, int ampResolution
)
668 int ampShift
= 1 - ampResolution
;
671 /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8,
672 the initialization of this array has to be adapted!
675 static const FIXP_SGL pow2
[ENV_EXP_FRACT
] =
677 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 1))), /* 0.7071 */
678 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 2))), /* 0.5946 */
679 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 3))),
680 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 4))),
681 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 5))),
682 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 6))),
683 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 7))),
684 FL2FXCONST_SGL(0.5f
* pow(2.0f
, pow(0.5f
, 8))) /* 0.5013 */
690 for (i
= 0; i
< h_sbr_data
->nScaleFactors
; i
++) {
691 exponent
= (LONG
)h_sbr_data
->iEnvelope
[i
];
695 exponent
= exponent
>> ampShift
;
698 /* Amplify mantissa according to the fractional part of the
699 exponent (result will be between 0.500000 and 0.999999)
701 mask
= 1; /* begin with lowest bit of exponent */
703 for ( bit
=ENV_EXP_FRACT
-1; bit
>=0; bit
-- ) {
704 if (exponent
& mask
) {
705 /* The current bit of the exponent is set,
706 multiply mantissa with the corresponding factor: */
707 mantissa
= (FIXP_SGL
)( (mantissa
* pow2
[bit
]) << 1);
709 /* Advance to next bit */
713 /* Make integer part of exponent right aligned */
714 exponent
= exponent
>> ENV_EXP_FRACT
;
717 /* In case of the high amplitude resolution, 1 bit of the exponent gets lost by the shift.
718 This will be compensated by a mantissa of 0.5*sqrt(2) instead of 0.5 if that bit is 1. */
719 mantissa
= (exponent
& ampShift
) ? FL2FXCONST_SGL(0.707106781186548f
) : FL2FXCONST_SGL(0.5f
);
720 exponent
= exponent
>> ampShift
;
724 Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by 1).
725 Multiply by L=nChannels=64 by increasing exponent by another 6.
726 => Increase exponent by 7
728 exponent
+= 7 + NRG_EXP_OFFSET
;
730 /* Combine mantissa and exponent and write back the result */
731 h_sbr_data
->iEnvelope
[i
] = (FIXP_SGL
)(((LONG
)mantissa
& MASK_M
) | (exponent
& MASK_E
));
738 \brief Build new reference energies from old ones and delta coded data
741 deltaToLinearPcmEnvelopeDecoding (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
742 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to current data */
743 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
) /*!< pointer to previous data */
745 int i
, domain
, no_of_bands
, band
, freqRes
;
747 FIXP_SGL
*sfb_nrg_prev
= h_prev_data
->sfb_nrg_prev
;
748 FIXP_SGL
*ptr_nrg
= h_sbr_data
->iEnvelope
;
750 int offset
= 2 * hHeaderData
->freqBandData
.nSfb
[0] - hHeaderData
->freqBandData
.nSfb
[1];
752 for (i
= 0; i
< h_sbr_data
->frameInfo
.nEnvelopes
; i
++) {
753 domain
= h_sbr_data
->domain_vec
[i
];
754 freqRes
= h_sbr_data
->frameInfo
.freqRes
[i
];
756 FDK_ASSERT(freqRes
>= 0 && freqRes
<= 1);
758 no_of_bands
= hHeaderData
->freqBandData
.nSfb
[freqRes
];
760 FDK_ASSERT(no_of_bands
< (64));
764 mapLowResEnergyVal(*ptr_nrg
, sfb_nrg_prev
, offset
, 0, freqRes
);
766 for (band
= 1; band
< no_of_bands
; band
++)
768 *ptr_nrg
= *ptr_nrg
+ *(ptr_nrg
-1);
769 mapLowResEnergyVal(*ptr_nrg
, sfb_nrg_prev
, offset
, band
, freqRes
);
775 for (band
= 0; band
< no_of_bands
; band
++)
777 *ptr_nrg
= *ptr_nrg
+ sfb_nrg_prev
[indexLow2High(offset
, band
, freqRes
)];
778 mapLowResEnergyVal(*ptr_nrg
, sfb_nrg_prev
, offset
, band
, freqRes
);
787 \brief Build new noise levels from old ones and delta coded data
790 decodeNoiseFloorlevels (HANDLE_SBR_HEADER_DATA hHeaderData
, /*!< Static control data */
791 HANDLE_SBR_FRAME_DATA h_sbr_data
, /*!< pointer to current data */
792 HANDLE_SBR_PREV_FRAME_DATA h_prev_data
) /*!< pointer to previous data */
795 int nNfb
= hHeaderData
->freqBandData
.nNfb
;
796 int nNoiseFloorEnvelopes
= h_sbr_data
->frameInfo
.nNoiseEnvelopes
;
798 /* Decode first noise envelope */
800 if (h_sbr_data
->domain_vec_noise
[0] == 0) {
801 FIXP_SGL noiseLevel
= h_sbr_data
->sbrNoiseFloorLevel
[0];
802 for (i
= 1; i
< nNfb
; i
++) {
803 noiseLevel
+= h_sbr_data
->sbrNoiseFloorLevel
[i
];
804 h_sbr_data
->sbrNoiseFloorLevel
[i
] = noiseLevel
;
808 for (i
= 0; i
< nNfb
; i
++) {
809 h_sbr_data
->sbrNoiseFloorLevel
[i
] += h_prev_data
->prevNoiseLevel
[i
];
813 /* If present, decode the second noise envelope
814 Note: nNoiseFloorEnvelopes can only be 1 or 2 */
816 if (nNoiseFloorEnvelopes
> 1) {
817 if (h_sbr_data
->domain_vec_noise
[1] == 0) {
818 FIXP_SGL noiseLevel
= h_sbr_data
->sbrNoiseFloorLevel
[nNfb
];
819 for (i
= nNfb
+ 1; i
< 2*nNfb
; i
++) {
820 noiseLevel
+= h_sbr_data
->sbrNoiseFloorLevel
[i
];
821 h_sbr_data
->sbrNoiseFloorLevel
[i
] = noiseLevel
;
825 for (i
= 0; i
< nNfb
; i
++) {
826 h_sbr_data
->sbrNoiseFloorLevel
[i
+ nNfb
] += h_sbr_data
->sbrNoiseFloorLevel
[i
];
831 limitNoiseLevels(hHeaderData
, h_sbr_data
);
833 /* Update prevNoiseLevel with the last noise envelope */
834 for (i
= 0; i
< nNfb
; i
++)
835 h_prev_data
->prevNoiseLevel
[i
] = h_sbr_data
->sbrNoiseFloorLevel
[i
+ nNfb
*(nNoiseFloorEnvelopes
-1)];
838 /* Requantize the noise floor levels in COUPLING_OFF-mode */
839 if (!h_sbr_data
->coupling
) {
842 for (i
= 0; i
< nNoiseFloorEnvelopes
*nNfb
; i
++) {
843 nf_e
= 6 - (LONG
)h_sbr_data
->sbrNoiseFloorLevel
[i
] + 1 + NOISE_EXP_OFFSET
;
844 /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */
846 h_sbr_data
->sbrNoiseFloorLevel
[i
] =
847 (FIXP_SGL
)( ((LONG
)FL2FXCONST_SGL(0.5f
)) + /* mantissa */
848 (nf_e
& MASK_E
) ); /* exponent */