env_dec.cpp revision 4f0d97057c5c640b25518358886f8c47da9fc052
1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84/*!
85  \file
86  \brief  envelope decoding
87  This module provides envelope decoding and error concealment algorithms. The main
88  entry point is decodeSbrData().
89
90  \sa decodeSbrData(),\ref documentationOverview
91*/
92
93#include "env_dec.h"
94
95#include "env_extr.h"
96#include "transcendent.h"
97
98#include "genericStds.h"
99
100
101static 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);
105static 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);
108static void requantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data,
109                                    int ampResolution);
110static void deltaToLinearPcmEnvelopeDecoding (HANDLE_SBR_HEADER_DATA hHeaderData,
111                                              HANDLE_SBR_FRAME_DATA h_sbr_data,
112                                              HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
113static void decodeNoiseFloorlevels (HANDLE_SBR_HEADER_DATA hHeaderData,
114                                    HANDLE_SBR_FRAME_DATA h_sbr_data,
115                                    HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
116static void timeCompensateFirstEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData,
117                                         HANDLE_SBR_FRAME_DATA h_sbr_data,
118                                         HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
119static int checkEnvelopeData (HANDLE_SBR_HEADER_DATA hHeaderData,
120                              HANDLE_SBR_FRAME_DATA h_sbr_data,
121                              HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
122
123
124
125#define SBR_ENERGY_PAN_OFFSET   (12 << ENV_EXP_FRACT)
126#define SBR_MAX_ENERGY          (35 << ENV_EXP_FRACT)
127
128#define DECAY                   ( 1 << ENV_EXP_FRACT)
129
130#if ENV_EXP_FRACT
131#define DECAY_COUPLING          ( 1 << (ENV_EXP_FRACT-1) ) /*!< corresponds to a value of 0.5 */
132#else
133#define DECAY_COUPLING            1  /*!< If the energy data is not shifted, use 1 instead of 0.5 */
134#endif
135
136
137/*!
138  \brief  Convert table index
139*/
140static int indexLow2High(int offset, /*!< mapping factor */
141                         int index,  /*!< index to scalefactor band */
142                         int res)    /*!< frequency resolution */
143{
144  if(res == 0)
145  {
146    if (offset >= 0)
147    {
148        if (index < offset)
149          return(index);
150        else
151          return(2*index - offset);
152    }
153    else
154    {
155        offset = -offset;
156        if (index < offset)
157          return(2*index+index);
158        else
159          return(2*index + offset);
160    }
161  }
162  else
163    return(index);
164}
165
166
167/*!
168  \brief  Update previous envelope value for delta-coding
169
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.
175*/
176static 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 */
181{
182  if(res == 0)
183  {
184    if (offset >= 0)
185    {
186        if(index < offset)
187            prevData[index] = currVal;
188        else
189        {
190            prevData[2*index - offset] = currVal;
191            prevData[2*index+1 - offset] = currVal;
192        }
193    }
194    else
195    {
196        offset = -offset;
197        if (index < offset)
198        {
199            prevData[3*index] = currVal;
200            prevData[3*index+1] = currVal;
201            prevData[3*index+2] = currVal;
202        }
203        else
204        {
205            prevData[2*index + offset] = currVal;
206            prevData[2*index + 1 + offset] = currVal;
207        }
208    }
209  }
210  else
211    prevData[index] = currVal;
212}
213
214
215
216/*!
217  \brief    Convert raw envelope and noisefloor data to energy levels
218
219  This function is being called by sbrDecoder_ParseElement() and provides two important algorithms:
220
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.
226*/
227void
228decodeSbrData (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 */
233{
234  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
235  int errLeft;
236
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));
239
240  decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
241  decodeNoiseFloorlevels (hHeaderData, h_data_left, h_prev_data_left);
242
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);
247
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
252         coupling mode.
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().
256      */
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));
260      /* Do concealment */
261      decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
262    }
263
264    if (h_data_left->coupling) {
265      sbr_envelope_unmapping (hHeaderData, h_data_left, h_data_right);
266    }
267  }
268
269  /* Display the data for debugging: */
270}
271
272
273/*!
274  \brief   Convert from coupled channels to independent L/R data
275*/
276static void
277sbr_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 */
280{
281  int i;
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;
284
285
286  /* 1. Unmap (already dequantized) coupled envelope energies */
287
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);
291
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);
295
296    tempL_e -= NRG_EXP_OFFSET;
297
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);
302
303    FDK_divide_MantExp( tempL_m, tempL_e+1,  /*  2 * tempLeft */
304                       tempRplus1_m, tempRplus1_e,
305                       &newR_m, &newR_e );
306
307    if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
308      newR_m >>= 1;
309      newR_e += 1;
310    }
311
312    newL_m = FX_DBL2FX_SGL(fMult(tempR_m,newR_m));
313    newL_e = tempR_e + newR_e;
314
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);
319  }
320
321  /* 2. Dequantize and unmap coupled noise floor levels */
322
323  for (i = 0; i < hHeaderData->freqBandData.nNfb * h_data_left->frameInfo.nNoiseEnvelopes; i++) {
324
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*/;
327
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);
332
333    /* Calculate 2*tempLeft/(tempR+1) */
334    FDK_divide_MantExp( FL2FXCONST_SGL(0.5f), tempL_e+2,  /*  2 * tempLeft */
335                       tempRplus1_m, tempRplus1_e,
336                       &newR_m, &newR_e );
337
338    /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
339      newR_m >>= 1;
340      newR_e += 1;
341    } */
342
343    /* L = tempR * R */
344    newL_m = newR_m;
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);
350  }
351}
352
353
354/*!
355  \brief    Simple alternative to the real SBR concealment
356
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.
361*/
362static void
363leanSbrConcealment(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 */
366                   )
367{
368  FIXP_SGL target;  /* targeted level for sfb_nrg_prev during fade-down */
369  FIXP_SGL step;    /* speed of fade */
370  int i;
371
372  int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots;
373  int currentStopPos = hHeaderData->numberTimeSlots;
374
375
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];
381
382  /* Generate concealing control data */
383
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;
392
393  h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1];
394
395  /* Generate fake envelope data */
396
397  h_sbr_data->domain_vec[0] = 1;
398
399  if (h_sbr_data->coupling == COUPLING_BAL) {
400    target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
401    step = (FIXP_SGL)DECAY_COUPLING;
402  }
403  else {
404    target = FL2FXCONST_SGL(0.0f);
405    step   = (FIXP_SGL)DECAY;
406  }
407  if (hHeaderData->bs_info.ampResolution == 0) {
408    target <<= 1;
409    step   <<= 1;
410  }
411
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;
415    else
416      h_sbr_data->iEnvelope[i] = step;
417  }
418
419  /* Noisefloor levels are always cleared ... */
420
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);
424
425  /* ... and so are the sines */
426  FDKmemclear(h_sbr_data->addHarmonics, MAX_FREQ_COEFFS);
427}
428
429
430/*!
431  \brief   Build reference energies and noise levels from bitstream elements
432*/
433static void
434decodeEnvelope (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 */
438                )
439{
440  int i;
441  int fFrameError = hHeaderData->frameErrorFlag;
442  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
443
444  if (!fFrameError) {
445    /*
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.
448    */
449    if ( h_prev_data->frameErrorFlag ) {
450      if (h_sbr_data->domain_vec[0] != 0) {
451        fFrameError = 1;
452      }
453    } else {
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 */
460          fFrameError = 1;
461        }
462        else {
463          /* Close the gap in time by triggering timeCompensateFirstEnvelope() */
464          fFrameError = 1;
465        }
466      }
467    }
468  }
469
470
471  if (fFrameError)       /* Error is detected */
472    {
473      leanSbrConcealment(hHeaderData,
474                         h_sbr_data,
475                         h_prev_data);
476
477      /* decode the envelope data to linear PCM */
478      deltaToLinearPcmEnvelopeDecoding (hHeaderData, h_sbr_data, h_prev_data);
479    }
480  else                          /*Do a temporary dummy decoding and check that the envelope values are within limits */
481    {
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) {
485          /*
486            Coupling mode has changed during concealment.
487             The stored energy levels need to be converted.
488           */
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;
498          }
499        }
500      }
501      FDKmemcpy (tempSfbNrgPrev, h_prev_data->sfb_nrg_prev,
502              MAX_FREQ_COEFFS * sizeof (FIXP_SGL));
503
504      deltaToLinearPcmEnvelopeDecoding (hHeaderData, h_sbr_data, h_prev_data);
505
506      fFrameError = checkEnvelopeData (hHeaderData, h_sbr_data, h_prev_data);
507
508      if (fFrameError)
509        {
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);
514          return;
515        }
516    }
517
518  requantizeEnvelopeData (h_sbr_data, h_sbr_data->ampResolutionCurrentFrame);
519
520  hHeaderData->frameErrorFlag = fFrameError;
521}
522
523
524/*!
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
527*/
528static int
529checkEnvelopeData (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 */
532                   )
533{
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);
539
540  /*
541    Range check for current energies
542  */
543  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
544    if (iEnvelope[i] > sbr_max_energy) {
545      errorFlag = 1;
546    }
547    if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) {
548      errorFlag = 1;
549      /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */
550    }
551  }
552
553  /*
554    Range check for previous energies
555  */
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);
559  }
560
561  return (errorFlag);
562}
563
564
565/*!
566  \brief   Verify that the noise levels are within the allowed range
567
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.
571*/
572static void
573limitNoiseLevels(HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
574                 HANDLE_SBR_FRAME_DATA h_sbr_data)       /*!< pointer to current data */
575{
576  int i;
577  int nNfb = hHeaderData->freqBandData.nNfb;
578
579  /*
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.
583  */
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 */
586
587  /*
588    Range check for current noise levels
589  */
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);
593  }
594}
595
596
597/*!
598  \brief   Compensate for the wrong timing that might occur after a frame error.
599*/
600static void
601timeCompensateFirstEnvelope (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 */
604{
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;
610  FIXP_SGL  deltaExp;
611
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;
616
617  if (newLen <= 0) {
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. */
621    newLen = refLen;
622    estimatedStartPos = pFrameInfo->borders[0];
623  }
624
625  deltaExp = FDK_getNumOctavesDiv8(newLen, refLen);
626
627  /* Shift by -3 to rescale ld-table, 1-ampRes 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;
632
633  if (h_sbr_data->coupling != COUPLING_BAL) {
634    nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0];
635
636    for (i = 0; i < nScalefactors; i++)
637      h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp;
638  }
639}
640
641
642
643/*!
644  \brief   Convert each envelope value from logarithmic to linear domain
645
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
652  can be represented.
653
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:
658
659  \image html  EnvelopeData.png
660
661  The data is then used in calculateSbrEnvelope().
662*/
663static void
664requantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data, int ampResolution)
665{
666  int i;
667  FIXP_SGL mantissa;
668  int ampShift = 1 - ampResolution;
669  int exponent;
670
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!
673  */
674#if ENV_EXP_FRACT
675  static const FIXP_SGL pow2[ENV_EXP_FRACT] =
676  {
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 */
685  };
686
687  int bit, mask;
688#endif
689
690  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
691    exponent = (LONG)h_sbr_data->iEnvelope[i];
692
693#if ENV_EXP_FRACT
694
695    exponent = exponent >> ampShift;
696    mantissa = 0.5f;
697
698    /* Amplify mantissa according to the fractional part of the
699       exponent (result will be between 0.500000 and 0.999999)
700    */
701    mask = 1;  /* begin with lowest bit of exponent */
702
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);
708      }
709      /* Advance to next bit */
710      mask = mask << 1;
711    }
712
713    /* Make integer part of exponent right aligned */
714    exponent = exponent >> ENV_EXP_FRACT;
715
716#else
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;
721#endif
722
723    /*
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
727    */
728    exponent += 7 + NRG_EXP_OFFSET;
729
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));
732
733  }
734}
735
736
737/*!
738  \brief   Build new reference energies from old ones and delta coded data
739*/
740static void
741deltaToLinearPcmEnvelopeDecoding (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 */
744{
745  int i, domain, no_of_bands, band, freqRes;
746
747  FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
748  FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope;
749
750  int offset = 2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1];
751
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];
755
756    FDK_ASSERT(freqRes >= 0 && freqRes <= 1);
757
758    no_of_bands = hHeaderData->freqBandData.nSfb[freqRes];
759
760    FDK_ASSERT(no_of_bands < (64));
761
762    if (domain == 0)
763    {
764      mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes);
765      ptr_nrg++;
766      for (band = 1; band < no_of_bands; band++)
767      {
768        *ptr_nrg = *ptr_nrg + *(ptr_nrg-1);
769        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
770        ptr_nrg++;
771      }
772    }
773    else
774    {
775      for (band = 0; band < no_of_bands; band++)
776      {
777        *ptr_nrg = *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)];
778        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
779        ptr_nrg++;
780      }
781    }
782  }
783}
784
785
786/*!
787  \brief   Build new noise levels from old ones and delta coded data
788*/
789static void
790decodeNoiseFloorlevels (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 */
793{
794  int i;
795  int nNfb = hHeaderData->freqBandData.nNfb;
796  int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes;
797
798  /* Decode first noise envelope */
799
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;
805    }
806  }
807  else {
808    for (i = 0; i < nNfb; i++) {
809      h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i];
810    }
811  }
812
813  /* If present, decode the second noise envelope
814     Note:  nNoiseFloorEnvelopes can only be 1 or 2 */
815
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;
822      }
823    }
824    else {
825      for (i = 0; i < nNfb; i++) {
826        h_sbr_data->sbrNoiseFloorLevel[i + nNfb] += h_sbr_data->sbrNoiseFloorLevel[i];
827      }
828    }
829  }
830
831  limitNoiseLevels(hHeaderData, h_sbr_data);
832
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)];
836
837
838  /* Requantize the noise floor levels in COUPLING_OFF-mode */
839  if (!h_sbr_data->coupling) {
840    int nf_e;
841
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 */
845
846      h_sbr_data->sbrNoiseFloorLevel[i] =
847        (FIXP_SGL)( ((LONG)FL2FXCONST_SGL(0.5f)) +  /* mantissa */
848                  (nf_e & MASK_E) ); /* exponent */
849
850    }
851  }
852}
853