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 ----------------------------------------------------------------------------------------------------------- */
95 #include "genericStds.h"
97 #define QUANT_ERROR_THRES 200
98 #define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */
101 static const UCHAR panTable
[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24},
102 { 0, 2, 4, 8,12, 0, 0, 0, 0 } };
103 static const UCHAR maxIndex
[2] = {9, 5};
106 /***************************************************************************/
109 \brief Calculates energy form real and imaginary part of
114 ****************************************************************************/
117 FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL
**RESTRICT energyValues
,/*!< the result of the operation */
118 FIXP_DBL
**RESTRICT realValues
, /*!< the real part of the QMF subsamples */
119 FIXP_DBL
**RESTRICT imagValues
, /*!< the imaginary part of the QMF subsamples */
120 INT numberBands
, /*!< number of QMF bands */
121 INT numberCols
, /*!< number of QMF subsamples */
122 INT
*qmfScale
, /*!< sclefactor of QMF subsamples */
123 INT
*energyScale
) /*!< scalefactor of energies */
127 FIXP_DBL max_val
= FL2FXCONST_DBL(0.0f
);
129 /* Get Scratch buffer */
130 C_ALLOC_SCRATCH_START(tmpNrg
, FIXP_DBL
, QMF_CHANNELS
*QMF_MAX_TIME_SLOTS
/2);
132 /* Get max possible scaling of QMF data */
134 for (k
=0; k
<numberCols
; k
++) {
135 scale
= fixMin(scale
, fixMin(getScalefactor(realValues
[k
], numberBands
), getScalefactor(imagValues
[k
], numberBands
)));
138 /* Tweak scaling stability for zero signal to non-zero signal transitions */
139 if (scale
>= DFRACT_BITS
-1) {
140 scale
= (FRACT_BITS
-1-*qmfScale
);
142 /* prevent scaling of QFM values to -1.f */
143 scale
= fixMax(0,scale
-1);
145 /* Update QMF scale */
149 Calculate energy of each time slot pair, max energy
150 and shift QMF values as far as possible to the left.
153 FIXP_DBL
*nrgValues
= tmpNrg
;
154 for (k
=0; k
<numberCols
; k
+=2)
156 /* Load band vector addresses of 2 consecutive timeslots */
157 FIXP_DBL
*RESTRICT r0
= realValues
[k
];
158 FIXP_DBL
*RESTRICT i0
= imagValues
[k
];
159 FIXP_DBL
*RESTRICT r1
= realValues
[k
+1];
160 FIXP_DBL
*RESTRICT i1
= imagValues
[k
+1];
161 for (j
=0; j
<numberBands
; j
++)
164 FIXP_DBL tr0
,tr1
,ti0
,ti1
;
166 /* Read QMF values of 2 timeslots */
167 tr0
= r0
[j
]; tr1
= r1
[j
]; ti0
= i0
[j
]; ti1
= i1
[j
];
169 /* Scale QMF Values and Calc Energy of both timeslots */
172 energy
= fPow2AddDiv2(fPow2Div2(tr0
), ti0
) >> 1;
176 energy
+= fPow2AddDiv2(fPow2Div2(tr1
), ti1
) >> 1;
178 /* Write timeslot pair energy to scratch */
179 *nrgValues
++ = energy
;
180 max_val
= fixMax(max_val
, energy
);
182 /* Write back scaled QMF values */
183 r0
[j
] = tr0
; r1
[j
] = tr1
; i0
[j
] = ti0
; i1
[j
] = ti1
;
187 /* energyScale: scalefactor energies of current frame */
188 *energyScale
= 2*(*qmfScale
)-1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
190 /* Scale timeslot pair energies and write to output buffer */
191 scale
= CountLeadingBits(max_val
);
193 FIXP_DBL
*nrgValues
= tmpNrg
;
194 for (k
=0; k
<numberCols
>>1; k
++) {
195 scaleValues(energyValues
[k
], nrgValues
, numberBands
, scale
);
196 nrgValues
+= numberBands
;
198 *energyScale
+= scale
;
201 /* Free Scratch buffer */
202 C_ALLOC_SCRATCH_END(tmpNrg
, FIXP_DBL
, QMF_CHANNELS
*QMF_MAX_TIME_SLOTS
/2);
207 FDKsbrEnc_getEnergyFromCplxQmfDataFull(FIXP_DBL
**RESTRICT energyValues
,/*!< the result of the operation */
208 FIXP_DBL
**RESTRICT realValues
, /*!< the real part of the QMF subsamples */
209 FIXP_DBL
**RESTRICT imagValues
, /*!< the imaginary part of the QMF subsamples */
210 int numberBands
, /*!< number of QMF bands */
211 int numberCols
, /*!< number of QMF subsamples */
212 int *qmfScale
, /*!< sclefactor of QMF subsamples */
213 int *energyScale
) /*!< scalefactor of energies */
217 FIXP_DBL max_val
= FL2FXCONST_DBL(0.0f
);
219 /* Get Scratch buffer */
220 C_ALLOC_SCRATCH_START(tmpNrg
, FIXP_DBL
, QMF_MAX_TIME_SLOTS
*QMF_CHANNELS
/2);
222 FDK_ASSERT(numberBands
<= QMF_CHANNELS
);
223 FDK_ASSERT(numberCols
<= QMF_MAX_TIME_SLOTS
/2);
225 /* Get max possible scaling of QMF data */
227 for (k
=0; k
<numberCols
; k
++) {
228 scale
= fixMin(scale
, fixMin(getScalefactor(realValues
[k
], numberBands
), getScalefactor(imagValues
[k
], numberBands
)));
231 /* Tweak scaling stability for zero signal to non-zero signal transitions */
232 if (scale
>= DFRACT_BITS
-1) {
233 scale
= (FRACT_BITS
-1-*qmfScale
);
235 /* prevent scaling of QFM values to -1.f */
236 scale
= fixMax(0,scale
-1);
238 /* Update QMF scale */
242 Calculate energy of each time slot pair, max energy
243 and shift QMF values as far as possible to the left.
246 FIXP_DBL
*nrgValues
= tmpNrg
;
247 for (k
=0; k
<numberCols
; k
++)
249 /* Load band vector addresses of 2 consecutive timeslots */
250 FIXP_DBL
*RESTRICT r0
= realValues
[k
];
251 FIXP_DBL
*RESTRICT i0
= imagValues
[k
];
252 for (j
=0; j
<numberBands
; j
++)
257 /* Read QMF values of 2 timeslots */
258 tr0
= r0
[j
]; ti0
= i0
[j
];
260 /* Scale QMF Values and Calc Energy of both timeslots */
263 energy
= fPow2AddDiv2(fPow2Div2(tr0
), ti0
);
264 *nrgValues
++ = energy
;
266 max_val
= fixMax(max_val
, energy
);
268 /* Write back scaled QMF values */
269 r0
[j
] = tr0
; i0
[j
] = ti0
;
273 /* energyScale: scalefactor energies of current frame */
274 *energyScale
= 2*(*qmfScale
)-1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
276 /* Scale timeslot pair energies and write to output buffer */
277 scale
= CountLeadingBits(max_val
);
279 FIXP_DBL
*nrgValues
= tmpNrg
;
280 for (k
=0; k
<numberCols
; k
++) {
281 scaleValues(energyValues
[k
], nrgValues
, numberBands
, scale
);
282 nrgValues
+= numberBands
;
284 *energyScale
+= scale
;
287 /* Free Scratch buffer */
288 C_ALLOC_SCRATCH_END(tmpNrg
, FIXP_DBL
, QMF_MAX_TIME_SLOTS
*QMF_CHANNELS
/2);
291 /***************************************************************************/
294 \brief Quantisation of the panorama value (balance)
296 \return the quantized pan value
298 ****************************************************************************/
300 mapPanorama(INT nrgVal
, /*! integer value of the energy */
301 INT ampRes
, /*! amplitude resolution [1.5/3dB] */
302 INT
*quantError
/*! quantization error of energy val*/
310 sign
= nrgVal
> 0 ? 1 : -1;
314 min_val
= FDK_INT_MAX
;
316 for (i
= 0; i
< maxIndex
[ampRes
]; i
++) {
317 val
= fixp_abs ((nrgVal
- (INT
)panTable
[ampRes
][i
]));
327 return panTable
[ampRes
][maxIndex
[ampRes
]-1] + sign
* panTable
[ampRes
][panIndex
];
331 /***************************************************************************/
334 \brief Quantisation of the noise floor levels
338 ****************************************************************************/
340 sbrNoiseFloorLevelsQuantisation(SCHAR
*RESTRICT iNoiseLevels
, /*! quantized noise levels */
341 FIXP_DBL
*RESTRICT NoiseLevels
, /*! the noise levels */
342 INT coupling
/*! the coupling flag */
348 /* Quantisation, similar to sfb quant... */
349 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++) {
350 /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] + (PFLOAT)0.5); */
351 /* 30>>6 = 0.46875 */
352 if ((FIXP_DBL
)NoiseLevels
[i
] > FL2FXCONST_DBL(0.46875f
)) {
356 /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/ /* FRACT_BITS+ */ /* 6-1)));*/
357 /* tmp = tmp >> (DFRACT_BITS-1-6); */ /* conversion to integer happens here */
358 /* rounding is done by shifting one bit less than necessary to the right, adding '1' and then shifting the final bit */
359 tmp
= ((((INT
)NoiseLevels
[i
])>>(DFRACT_BITS
-1-LD_DATA_SHIFT
)) ); /* conversion to integer */
365 tmp
= tmp
< -30 ? -30 : tmp
;
366 tmp
= mapPanorama (tmp
,1,&dummy
);
368 iNoiseLevels
[i
] = tmp
;
372 /***************************************************************************/
375 \brief Calculation of noise floor for coupling
379 ****************************************************************************/
381 coupleNoiseFloor(FIXP_DBL
*RESTRICT noise_level_left
, /*! noise level left (modified)*/
382 FIXP_DBL
*RESTRICT noise_level_right
/*! noise level right (modified)*/
385 FIXP_DBL cmpValLeft
,cmpValRight
;
387 FIXP_DBL temp1
,temp2
;
389 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++) {
391 /* Calculation of the power function using ld64:
393 z' = CalcLd64(z) = y*CalcLd64(x)/64;
396 cmpValLeft
= NOISE_FLOOR_OFFSET_64
- noise_level_left
[i
];
397 cmpValRight
= NOISE_FLOOR_OFFSET_64
- noise_level_right
[i
];
399 if (cmpValRight
< FL2FXCONST_DBL(0.0f
)) {
400 temp1
= CalcInvLdData(NOISE_FLOOR_OFFSET_64
- noise_level_right
[i
]);
403 temp1
= CalcInvLdData(NOISE_FLOOR_OFFSET_64
- noise_level_right
[i
]);
404 temp1
= temp1
<< (DFRACT_BITS
-1-LD_DATA_SHIFT
-1); /* INT to fract conversion of result, if input of CalcInvLdData is positiv */
407 if (cmpValLeft
< FL2FXCONST_DBL(0.0f
)) {
408 temp2
= CalcInvLdData(NOISE_FLOOR_OFFSET_64
- noise_level_left
[i
]);
411 temp2
= CalcInvLdData(NOISE_FLOOR_OFFSET_64
- noise_level_left
[i
]);
412 temp2
= temp2
<< (DFRACT_BITS
-1-LD_DATA_SHIFT
-1); /* INT to fract conversion of result, if input of CalcInvLdData is positiv */
416 if ((cmpValLeft
< FL2FXCONST_DBL(0.0f
)) && (cmpValRight
< FL2FXCONST_DBL(0.0f
))) {
417 noise_level_left
[i
] = NOISE_FLOOR_OFFSET_64
- (CalcLdData(((temp1
>>1) + (temp2
>>1)))); /* no scaling needed! both values are dfract */
418 noise_level_right
[i
] = CalcLdData(temp2
) - CalcLdData(temp1
);
421 if ((cmpValLeft
>= FL2FXCONST_DBL(0.0f
)) && (cmpValRight
>= FL2FXCONST_DBL(0.0f
))) {
422 noise_level_left
[i
] = NOISE_FLOOR_OFFSET_64
- (CalcLdData(((temp1
>>1) + (temp2
>>1))) + FL2FXCONST_DBL(0.109375f
)); /* scaled with 7/64 */
423 noise_level_right
[i
] = CalcLdData(temp2
) - CalcLdData(temp1
);
426 if ((cmpValLeft
>= FL2FXCONST_DBL(0.0f
)) && (cmpValRight
< FL2FXCONST_DBL(0.0f
))) {
427 noise_level_left
[i
] = NOISE_FLOOR_OFFSET_64
- (CalcLdData(((temp1
>>(7+1)) + (temp2
>>1))) + FL2FXCONST_DBL(0.109375f
)); /* scaled with 7/64 */
428 noise_level_right
[i
] = (CalcLdData(temp2
) + FL2FXCONST_DBL(0.109375f
)) - CalcLdData(temp1
);
431 if ((cmpValLeft
< FL2FXCONST_DBL(0.0f
)) && (cmpValRight
>= FL2FXCONST_DBL(0.0f
))) {
432 noise_level_left
[i
] = NOISE_FLOOR_OFFSET_64
- (CalcLdData(((temp1
>>1) + (temp2
>>(7+1)))) + FL2FXCONST_DBL(0.109375f
)); /* scaled with 7/64 */
433 noise_level_right
[i
] = CalcLdData(temp2
) - (CalcLdData(temp1
) + FL2FXCONST_DBL(0.109375f
)); /* scaled with 7/64 */
438 /***************************************************************************/
441 \brief Calculation of energy starting in lower band (li) up to upper band (ui)
442 over slots (start_pos) to (stop_pos)
446 ****************************************************************************/
448 getEnvSfbEnergy(INT li
, /*! lower band */
449 INT ui
, /*! upper band */
450 INT start_pos
, /*! start slot */
451 INT stop_pos
, /*! stop slot */
452 INT border_pos
, /*! slots scaling border */
453 FIXP_DBL
**YBuffer
, /*! sfb energy buffer */
454 INT YBufferSzShift
, /*! Energy buffer index scale */
455 INT scaleNrg0
, /*! scaling of lower slots */
456 INT scaleNrg1
) /*! scaling of upper slots */
458 /* use dynamic scaling for outer energy loop;
459 energies are critical and every bit is important */
462 FIXP_DBL nrgSum
, nrg1
, nrg2
, accu1
, accu2
;
463 INT dynScale
, dynScale1
, dynScale2
;
464 if(ui
-li
==0) dynScale
= DFRACT_BITS
-1;
466 dynScale
= CalcLdInt(ui
-li
)>>(DFRACT_BITS
-1-LD_DATA_SHIFT
);
468 sc0
= fixMin(scaleNrg0
,Y_NRG_SCALE
); sc1
= fixMin(scaleNrg1
,Y_NRG_SCALE
);
469 /* dynScale{1,2} is set such that the right shift below is positive */
470 dynScale1
= fixMin((scaleNrg0
-sc0
),dynScale
);
471 dynScale2
= fixMin((scaleNrg1
-sc1
),dynScale
);
472 nrgSum
= accu1
= accu2
= (FIXP_DBL
)0;
474 for (k
= li
; k
< ui
; k
++) {
475 nrg1
= nrg2
= (FIXP_DBL
)0;
476 for (l
= start_pos
; l
< border_pos
; l
++) {
477 nrg1
+= YBuffer
[l
>>YBufferSzShift
][k
] >> sc0
;
479 for (; l
< stop_pos
; l
++) {
480 nrg2
+= YBuffer
[l
>>YBufferSzShift
][k
] >> sc1
;
482 accu1
+= (nrg1
>>dynScale1
);
483 accu2
+= (nrg2
>>dynScale2
);
485 /* This shift factor is always positive. See comment above. */
486 nrgSum
+= ( accu1
>> fixMin((scaleNrg0
-sc0
-dynScale1
),(DFRACT_BITS
-1)) )
487 + ( accu2
>> fixMin((scaleNrg1
-sc1
-dynScale2
),(DFRACT_BITS
-1)) );
492 /***************************************************************************/
495 \brief Energy compensation in missing harmonic mode
499 ****************************************************************************/
501 mhLoweringEnergy(FIXP_DBL nrg
, INT M
)
504 Compensating for the fact that we in the decoder map the "average energy to every QMF
505 band, and use this when we calculate the boost-factor. Since the mapped energy isn't
506 the average energy but the maximum energy in case of missing harmonic creation, we will
507 in the boost function calculate that too much limiting has been applied and hence we will
508 boost the signal although it isn't called for. Hence we need to compensate for this by
509 lowering the transmitted energy values for the sines so they will get the correct level
510 after the boost is applied.
514 tmpScale
= CountLeadingBits(nrg
);
516 nrg
= fMult(nrg
, FL2FXCONST_DBL(0.398107267f
)); /* The maximum boost is 1.584893, so the maximum attenuation should be square(1/1.584893) = 0.398107267 */
528 /***************************************************************************/
531 \brief Energy compensation in none missing harmonic mode
535 ****************************************************************************/
536 static FIXP_DBL
nmhLoweringEnergy(
538 const FIXP_DBL nrgSum
,
539 const INT nrgSum_scale
,
543 if (nrg
>FL2FXCONST_DBL(0)) {
545 /* gain = nrgSum / (nrg*(M+1)) */
546 FIXP_DBL gain
= fMult(fDivNorm(nrgSum
, nrg
, &sc
), GetInvInt(M
+1));
549 /* reduce nrg if gain smaller 1.f */
550 if ( !((sc
>=0) && ( gain
> ((FIXP_DBL
)MAXVAL_DBL
>>sc
) )) ) {
551 nrg
= fMult(scaleValue(gain
,sc
), nrg
);
557 /***************************************************************************/
560 \brief calculates the envelope values from the energies, depending on
561 framing and stereo mode
565 ****************************************************************************/
567 calculateSbrEnvelope (FIXP_DBL
**RESTRICT YBufferLeft
, /*! energy buffer left */
568 FIXP_DBL
**RESTRICT YBufferRight
, /*! energy buffer right */
569 int *RESTRICT YBufferScaleLeft
, /*! scale energy buffer left */
570 int *RESTRICT YBufferScaleRight
, /*! scale energy buffer right */
571 const SBR_FRAME_INFO
*frame_info
, /*! frame info vector */
572 SCHAR
*RESTRICT sfb_nrgLeft
, /*! sfb energy buffer left */
573 SCHAR
*RESTRICT sfb_nrgRight
, /*! sfb energy buffer right */
574 HANDLE_SBR_CONFIG_DATA h_con
, /*! handle to config data */
575 HANDLE_ENV_CHANNEL h_sbr
, /*! envelope channel handle */
576 SBR_STEREO_MODE stereoMode
, /*! stereo coding mode */
577 INT
* maxQuantError
, /*! maximum quantization error, for panorama. */
578 int YBufferSzShift
) /*! Energy buffer index scale */
582 INT no_of_bands
, start_pos
, stop_pos
, li
, ui
;
585 INT ca
= 2 - h_sbr
->encEnvData
.init_sbr_amp_res
;
588 oneBitLess
= 1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
591 INT nEnvelopes
= frame_info
->nEnvelopes
;
592 INT short_env
= frame_info
->shortEnv
- 1;
593 INT timeStep
= h_sbr
->sbrExtractEnvelope
.time_step
;
594 INT commonScale
,scaleLeft0
,scaleLeft1
;
595 INT scaleRight0
=0,scaleRight1
=0;
597 commonScale
= fixMin(YBufferScaleLeft
[0],YBufferScaleLeft
[1]);
599 if (stereoMode
== SBR_COUPLING
) {
600 commonScale
= fixMin(commonScale
,YBufferScaleRight
[0]);
601 commonScale
= fixMin(commonScale
,YBufferScaleRight
[1]);
604 commonScale
= commonScale
- 7;
606 scaleLeft0
= YBufferScaleLeft
[0] - commonScale
;
607 scaleLeft1
= YBufferScaleLeft
[1] - commonScale
;
608 FDK_ASSERT ((scaleLeft0
>= 0) && (scaleLeft1
>= 0));
610 if (stereoMode
== SBR_COUPLING
) {
611 scaleRight0
= YBufferScaleRight
[0] - commonScale
;
612 scaleRight1
= YBufferScaleRight
[1] - commonScale
;
613 FDK_ASSERT ((scaleRight0
>= 0) && (scaleRight1
>= 0));
617 for (i
= 0; i
< nEnvelopes
; i
++) {
619 FIXP_DBL pNrgLeft
[QMF_MAX_TIME_SLOTS
];
620 FIXP_DBL pNrgRight
[QMF_MAX_TIME_SLOTS
];
622 FIXP_DBL envNrgLeft
= FL2FXCONST_DBL(0.0f
);
623 FIXP_DBL envNrgRight
= FL2FXCONST_DBL(0.0f
);
624 int missingHarmonic
[QMF_MAX_TIME_SLOTS
];
625 int count
[QMF_MAX_TIME_SLOTS
];
627 start_pos
= timeStep
* frame_info
->borders
[i
];
628 stop_pos
= timeStep
* frame_info
->borders
[i
+ 1];
629 freq_res
= frame_info
->freqRes
[i
];
630 no_of_bands
= h_con
->nSfb
[freq_res
];
631 envNrg_scale
= DFRACT_BITS
-fNormz((FIXP_DBL
)no_of_bands
);
633 if (i
== short_env
) {
634 stop_pos
-= fixMax(2, timeStep
); /* consider at least 2 QMF slots less for short envelopes (envelopes just before transients) */
637 for (j
= 0; j
< no_of_bands
; j
++) {
638 FIXP_DBL nrgLeft
= FL2FXCONST_DBL(0.0f
);
639 FIXP_DBL nrgRight
= FL2FXCONST_DBL(0.0f
);
641 li
= h_con
->freqBandTable
[freq_res
][j
];
642 ui
= h_con
->freqBandTable
[freq_res
][j
+ 1];
644 if(freq_res
== FREQ_RES_HIGH
){
645 if(j
== 0 && ui
-li
> 1){
650 if(j
== 0 && ui
-li
> 2){
656 Find out whether a sine will be missing in the scale-factor
657 band that we're currently processing.
659 missingHarmonic
[j
] = 0;
661 if(h_sbr
->encEnvData
.addHarmonicFlag
){
663 if(freq_res
== FREQ_RES_HIGH
){
664 if(h_sbr
->encEnvData
.addHarmonic
[j
]){ /*A missing sine in the current band*/
665 missingHarmonic
[j
] = 1;
670 INT startBandHigh
= 0;
671 INT stopBandHigh
= 0;
673 while(h_con
->freqBandTable
[FREQ_RES_HIGH
][startBandHigh
] < h_con
->freqBandTable
[FREQ_RES_LOW
][j
])
675 while(h_con
->freqBandTable
[FREQ_RES_HIGH
][stopBandHigh
] < h_con
->freqBandTable
[FREQ_RES_LOW
][j
+ 1])
678 for(i
= startBandHigh
; i
<stopBandHigh
; i
++){
679 if(h_sbr
->encEnvData
.addHarmonic
[i
]){
680 missingHarmonic
[j
] = 1;
687 If a sine is missing in a scalefactorband, with more than one qmf channel
688 use the nrg from the channel with the largest nrg rather than the mean.
689 Compensate for the boost calculation in the decdoder.
691 int border_pos
= fixMin(stop_pos
, h_sbr
->sbrExtractEnvelope
.YBufferWriteOffset
<<YBufferSzShift
);
693 if(missingHarmonic
[j
]){
696 count
[j
] = stop_pos
- start_pos
;
697 nrgLeft
= FL2FXCONST_DBL(0.0f
);
699 for (k
= li
; k
< ui
; k
++) {
701 tmpNrg
= getEnvSfbEnergy(k
,
711 nrgLeft
= fixMax(nrgLeft
, tmpNrg
);
714 /* Energy lowering compensation */
715 nrgLeft
= mhLoweringEnergy(nrgLeft
, ui
-li
);
717 if (stereoMode
== SBR_COUPLING
) {
719 nrgRight
= FL2FXCONST_DBL(0.0f
);
721 for (k
= li
; k
< ui
; k
++) {
723 tmpNrg
= getEnvSfbEnergy(k
,
733 nrgRight
= fixMax(nrgRight
, tmpNrg
);
736 /* Energy lowering compensation */
737 nrgRight
= mhLoweringEnergy(nrgRight
, ui
-li
);
739 } /* end missingHarmonic */
741 count
[j
] = (stop_pos
- start_pos
) * (ui
- li
);
743 nrgLeft
= getEnvSfbEnergy(li
,
753 if (stereoMode
== SBR_COUPLING
) {
754 nrgRight
= getEnvSfbEnergy(li
,
764 } /* !missingHarmonic */
767 pNrgLeft
[j
] = nrgLeft
;
768 pNrgRight
[j
] = nrgRight
;
769 envNrgLeft
+= (nrgLeft
>>envNrg_scale
);
770 envNrgRight
+= (nrgRight
>>envNrg_scale
);
773 for (j
= 0; j
< no_of_bands
; j
++) {
775 FIXP_DBL nrgLeft2
= FL2FXCONST_DBL(0.0f
);
776 FIXP_DBL nrgLeft
= pNrgLeft
[j
];
777 FIXP_DBL nrgRight
= pNrgRight
[j
];
779 /* None missing harmonic Energy lowering compensation */
780 if(!missingHarmonic
[j
] && h_sbr
->fLevelProtect
) {
781 /* in case of missing energy in base band,
782 reduce reference energy to prevent overflows in decoder output */
783 nrgLeft
= nmhLoweringEnergy(nrgLeft
, envNrgLeft
, envNrg_scale
, no_of_bands
);
784 if (stereoMode
== SBR_COUPLING
) {
785 nrgRight
= nmhLoweringEnergy(nrgRight
, envNrgRight
, envNrg_scale
, no_of_bands
);
789 if (stereoMode
== SBR_COUPLING
) {
790 /* calc operation later with log */
792 nrgLeft
= (nrgRight
+ nrgLeft
) >> 1;
795 /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * h_sbr->sbrQmf.no_channels))+(PFLOAT)44; */
796 /* If nrgLeft == 0 then the Log calculations below do fail. */
797 if (nrgLeft
> FL2FXCONST_DBL(0.0f
))
799 FIXP_DBL tmp0
,tmp1
,tmp2
,tmp3
;
802 tmpScale
= CountLeadingBits(nrgLeft
);
803 nrgLeft
= nrgLeft
<< tmpScale
;
805 tmp0
= CalcLdData(nrgLeft
); /* scaled by 1/64 */
806 tmp1
= ((FIXP_DBL
) (commonScale
+tmpScale
)) << (DFRACT_BITS
-1-LD_DATA_SHIFT
-1); /* scaled by 1/64 */
807 tmp2
= ((FIXP_DBL
)(count
[j
]*h_con
->noQmfBands
)) << (DFRACT_BITS
-1-14-1);
808 tmp2
= CalcLdData(tmp2
); /* scaled by 1/64 */
809 tmp3
= FL2FXCONST_DBL(0.6875f
-0.21875f
-0.015625f
)>>1; /* scaled by 1/64 */
811 nrgLeft
= ((tmp0
-tmp2
)>>1) + (tmp3
- tmp1
);
813 nrgLeft
= FL2FXCONST_DBL(-1.0f
);
816 /* ld64 to integer conversion */
817 nrgLeft
= fixMin(fixMax(nrgLeft
,FL2FXCONST_DBL(0.0f
)),(FL2FXCONST_DBL(0.5f
)>>oneBitLess
));
818 nrgLeft
= (FIXP_DBL
)(LONG
)nrgLeft
>> (DFRACT_BITS
-1-LD_DATA_SHIFT
-1-oneBitLess
-1);
819 sfb_nrgLeft
[m
] = ((INT
)nrgLeft
+1)>>1; /* rounding */
821 if (stereoMode
== SBR_COUPLING
) {
825 nrgLeft2
= fixMax((FIXP_DBL
)0x1, nrgLeft2
);
826 nrgRight
= fixMax((FIXP_DBL
)0x1, nrgRight
);
828 sc0
= CountLeadingBits(nrgLeft2
);
829 sc1
= CountLeadingBits(nrgRight
);
831 scaleFract
= ((FIXP_DBL
)(sc0
-sc1
)) << (DFRACT_BITS
-1-LD_DATA_SHIFT
); /* scale value in ld64 representation */
832 nrgRight
= CalcLdData(nrgLeft2
<<sc0
) - CalcLdData(nrgRight
<<sc1
) - scaleFract
;
834 /* ld64 to integer conversion */
835 nrgRight
= (FIXP_DBL
)(LONG
)(nrgRight
) >> (DFRACT_BITS
-1-LD_DATA_SHIFT
-1-oneBitLess
);
836 nrgRight
= (nrgRight
+(FIXP_DBL
)1)>>1; /* rounding */
838 sfb_nrgRight
[m
] = mapPanorama (nrgRight
,h_sbr
->encEnvData
.init_sbr_amp_res
,&quantError
);
840 *maxQuantError
= fixMax(quantError
, *maxQuantError
);
846 /* Do energy compensation for sines that are present in two
847 QMF-bands in the original, but will only occur in one band in
848 the decoder due to the synthetic sine coding.*/
849 if (h_con
->useParametricCoding
) {
851 for (j
= 0; j
< no_of_bands
; j
++) {
852 if (freq_res
==FREQ_RES_HIGH
&& h_sbr
->sbrExtractEnvelope
.envelopeCompensation
[j
]){
853 sfb_nrgLeft
[m
] -= (ca
* fixp_abs((INT
)h_sbr
->sbrExtractEnvelope
.envelopeCompensation
[j
]));
855 sfb_nrgLeft
[m
] = fixMax(0, sfb_nrgLeft
[m
]);
858 } /* useParametricCoding */
863 /***************************************************************************/
866 \brief calculates the noise floor and the envelope values from the
867 energies, depending on framing and stereo mode
869 FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
870 envelope and the noise floor. The function includes the following processes:
872 -Analysis subband filtering.
873 -Encoding SA and pan parameters (if enabled).
874 -Transient detection.
876 ****************************************************************************/
880 FDKsbrEnc_extractSbrEnvelope1 (
881 HANDLE_SBR_CONFIG_DATA h_con
, /*! handle to config data */
882 HANDLE_SBR_HEADER_DATA sbrHeaderData
,
883 HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData
,
884 HANDLE_ENV_CHANNEL hEnvChan
,
885 HANDLE_COMMON_DATA hCmonData
,
886 SBR_ENV_TEMP_DATA
*eData
,
887 SBR_FRAME_TEMP_DATA
*fData
891 HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv
= &hEnvChan
->sbrExtractEnvelope
;
893 if (sbrExtrEnv
->YBufferSzShift
== 0)
894 FDKsbrEnc_getEnergyFromCplxQmfDataFull(&sbrExtrEnv
->YBuffer
[sbrExtrEnv
->YBufferWriteOffset
],
895 sbrExtrEnv
->rBuffer
+ sbrExtrEnv
->rBufferReadOffset
,
896 sbrExtrEnv
->iBuffer
+ sbrExtrEnv
->rBufferReadOffset
,
900 &sbrExtrEnv
->YBufferScale
[1]);
902 FDKsbrEnc_getEnergyFromCplxQmfData(&sbrExtrEnv
->YBuffer
[sbrExtrEnv
->YBufferWriteOffset
],
903 sbrExtrEnv
->rBuffer
+ sbrExtrEnv
->rBufferReadOffset
,
904 sbrExtrEnv
->iBuffer
+ sbrExtrEnv
->rBufferReadOffset
,
908 &sbrExtrEnv
->YBufferScale
[1]);
913 Precalculation of Tonality Quotas COEFF Transform OK
915 FDKsbrEnc_CalculateTonalityQuotas(&hEnvChan
->TonCorr
,
918 h_con
->freqBandTable
[HI
][h_con
->nSfb
[HI
]],
924 Transient detection COEFF Transform OK
926 FDKsbrEnc_transientDetect(&hEnvChan
->sbrTransientDetector
,
928 sbrExtrEnv
->YBufferScale
,
929 eData
->transient_info
,
930 sbrExtrEnv
->YBufferWriteOffset
,
931 sbrExtrEnv
->YBufferSzShift
,
932 sbrExtrEnv
->time_step
,
933 hEnvChan
->SbrEnvFrame
.frameMiddleSlot
);
938 Generate flags for 2 env in a FIXFIX-frame.
939 Remove this function to get always 1 env per FIXFIX-frame.
943 frame Splitter COEFF Transform OK
945 FDKsbrEnc_frameSplitter(sbrExtrEnv
->YBuffer
,
946 sbrExtrEnv
->YBufferScale
,
947 &hEnvChan
->sbrTransientDetector
,
948 h_con
->freqBandTable
[1],
949 eData
->transient_info
,
950 sbrExtrEnv
->YBufferWriteOffset
,
951 sbrExtrEnv
->YBufferSzShift
,
953 sbrExtrEnv
->time_step
,
954 sbrExtrEnv
->no_cols
);
959 /***************************************************************************/
962 \brief calculates the noise floor and the envelope values from the
963 energies, depending on framing and stereo mode
965 FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
966 envelope and the noise floor. The function includes the following processes:
968 -Determine time/frequency division of current granule.
969 -Sending transient info to bitstream.
970 -Set amp_res to 1.5 dB if the current frame contains only one envelope.
971 -Lock dynamic bandwidth frequency change if the next envelope not starts on a
973 -MDCT transposer (needed to detect where harmonics will be missing).
974 -Spectrum Estimation (used for pulse train and missing harmonics detection).
975 -Pulse train detection.
976 -Inverse Filtering detection.
978 -Missing Harmonics detection.
979 -Extract envelope of current frame.
980 -Noise floor estimation.
981 -Noise floor quantisation and coding.
982 -Encode envelope of current frame.
983 -Send the encoded data to the bitstream.
986 ****************************************************************************/
990 FDKsbrEnc_extractSbrEnvelope2 (
991 HANDLE_SBR_CONFIG_DATA h_con
, /*! handle to config data */
992 HANDLE_SBR_HEADER_DATA sbrHeaderData
,
993 HANDLE_PARAMETRIC_STEREO hParametricStereo
,
994 HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData
,
995 HANDLE_ENV_CHANNEL h_envChan0
,
996 HANDLE_ENV_CHANNEL h_envChan1
,
997 HANDLE_COMMON_DATA hCmonData
,
998 SBR_ENV_TEMP_DATA
*eData
,
999 SBR_FRAME_TEMP_DATA
*fData
,
1003 HANDLE_ENV_CHANNEL h_envChan
[MAX_NUM_CHANNELS
] = {h_envChan0
, h_envChan1
};
1004 int ch
, i
, j
, c
, YSzShift
= h_envChan
[0]->sbrExtractEnvelope
.YBufferSzShift
;
1006 SBR_STEREO_MODE stereoMode
= h_con
->stereoMode
;
1007 int nChannels
= h_con
->nChannels
;
1008 const int *v_tuning
;
1009 static const int v_tuningHEAAC
[6] = { 0, 2, 4, 0, 0, 0 };
1011 static const int v_tuningELD
[6] = { 0, 2, 3, 0, 0, 0 };
1013 if (h_con
->sbrSyntaxFlags
& SBR_SYNTAX_LOW_DELAY
)
1014 v_tuning
= v_tuningELD
;
1016 v_tuning
= v_tuningHEAAC
;
1022 if (stereoMode
== SBR_COUPLING
) {
1023 if (eData
[0].transient_info
[1] && eData
[1].transient_info
[1]) {
1024 eData
[0].transient_info
[0] = fixMin(eData
[1].transient_info
[0], eData
[0].transient_info
[0]);
1025 eData
[1].transient_info
[0] = eData
[0].transient_info
[0];
1028 if (eData
[0].transient_info
[1] && !eData
[1].transient_info
[1]) {
1029 eData
[1].transient_info
[0] = eData
[0].transient_info
[0];
1032 if (!eData
[0].transient_info
[1] && eData
[1].transient_info
[1])
1033 eData
[0].transient_info
[0] = eData
[1].transient_info
[0];
1035 eData
[0].transient_info
[0] = fixMax(eData
[1].transient_info
[0], eData
[0].transient_info
[0]);
1036 eData
[1].transient_info
[0] = eData
[0].transient_info
[0];
1043 Determine time/frequency division of current granule
1045 eData
[0].frame_info
= FDKsbrEnc_frameInfoGenerator(&h_envChan
[0]->SbrEnvFrame
,
1046 eData
[0].transient_info
,
1047 h_envChan
[0]->sbrExtractEnvelope
.pre_transient_info
,
1048 h_envChan
[0]->encEnvData
.ldGrid
,
1051 h_envChan
[0]->encEnvData
.hSbrBSGrid
= &h_envChan
[0]->SbrEnvFrame
.SbrGrid
;
1053 /* AAC LD patch for transient prediction */
1054 if (h_envChan
[0]->encEnvData
.ldGrid
&& eData
[0].transient_info
[2]) {
1055 /* if next frame will start with transient, set shortEnv to numEnvelopes(shortend Envelope = shortEnv-1)*/
1056 h_envChan
[0]->SbrEnvFrame
.SbrFrameInfo
.shortEnv
= h_envChan
[0]->SbrEnvFrame
.SbrFrameInfo
.nEnvelopes
;
1060 switch (stereoMode
) {
1061 case SBR_LEFT_RIGHT
:
1062 case SBR_SWITCH_LRC
:
1063 eData
[1].frame_info
= FDKsbrEnc_frameInfoGenerator(&h_envChan
[1]->SbrEnvFrame
,
1064 eData
[1].transient_info
,
1065 h_envChan
[1]->sbrExtractEnvelope
.pre_transient_info
,
1066 h_envChan
[1]->encEnvData
.ldGrid
,
1069 h_envChan
[1]->encEnvData
.hSbrBSGrid
= &h_envChan
[1]->SbrEnvFrame
.SbrGrid
;
1071 if (h_envChan
[1]->encEnvData
.ldGrid
&& eData
[1].transient_info
[2]) {
1072 /* if next frame will start with transient, set shortEnv to numEnvelopes(shortend Envelope = shortEnv-1)*/
1073 h_envChan
[1]->SbrEnvFrame
.SbrFrameInfo
.shortEnv
= h_envChan
[1]->SbrEnvFrame
.SbrFrameInfo
.nEnvelopes
;
1076 /* compare left and right frame_infos */
1077 if (eData
[0].frame_info
->nEnvelopes
!= eData
[1].frame_info
->nEnvelopes
) {
1078 stereoMode
= SBR_LEFT_RIGHT
;
1080 for (i
= 0; i
< eData
[0].frame_info
->nEnvelopes
+ 1; i
++) {
1081 if (eData
[0].frame_info
->borders
[i
] != eData
[1].frame_info
->borders
[i
]) {
1082 stereoMode
= SBR_LEFT_RIGHT
;
1086 for (i
= 0; i
< eData
[0].frame_info
->nEnvelopes
; i
++) {
1087 if (eData
[0].frame_info
->freqRes
[i
] != eData
[1].frame_info
->freqRes
[i
]) {
1088 stereoMode
= SBR_LEFT_RIGHT
;
1092 if (eData
[0].frame_info
->shortEnv
!= eData
[1].frame_info
->shortEnv
) {
1093 stereoMode
= SBR_LEFT_RIGHT
;
1098 eData
[1].frame_info
= eData
[0].frame_info
;
1099 h_envChan
[1]->encEnvData
.hSbrBSGrid
= &h_envChan
[0]->SbrEnvFrame
.SbrGrid
;
1109 for (ch
= 0; ch
< nChannels
;ch
++)
1111 HANDLE_ENV_CHANNEL hEnvChan
= h_envChan
[ch
];
1112 HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv
= &hEnvChan
->sbrExtractEnvelope
;
1113 SBR_ENV_TEMP_DATA
*ed
= &eData
[ch
];
1117 Send transient info to bitstream and store for next call
1119 sbrExtrEnv
->pre_transient_info
[0] = ed
->transient_info
[0];/* tran_pos */
1120 sbrExtrEnv
->pre_transient_info
[1] = ed
->transient_info
[1];/* tran_flag */
1121 hEnvChan
->encEnvData
.noOfEnvelopes
= ed
->nEnvelopes
= ed
->frame_info
->nEnvelopes
; /* number of envelopes of current frame */
1124 Check if the current frame is divided into one envelope only. If so, set the amplitude
1125 resolution to 1.5 dB, otherwise may set back to chosen value
1127 if( ( hEnvChan
->encEnvData
.hSbrBSGrid
->frameClass
== FIXFIX
)
1128 && ( ed
->nEnvelopes
== 1 ) )
1131 if (hEnvChan
->encEnvData
.ldGrid
)
1132 hEnvChan
->encEnvData
.currentAmpResFF
= (AMP_RES
)h_con
->initAmpResFF
;
1134 hEnvChan
->encEnvData
.currentAmpResFF
= SBR_AMP_RES_1_5
;
1136 if ( hEnvChan
->encEnvData
.currentAmpResFF
!= hEnvChan
->encEnvData
.init_sbr_amp_res
) {
1138 FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan
->encEnvData
,
1139 &hEnvChan
->sbrCodeEnvelope
,
1140 &hEnvChan
->sbrCodeNoiseFloor
,
1141 hEnvChan
->encEnvData
.currentAmpResFF
);
1145 if(sbrHeaderData
->sbr_amp_res
!= hEnvChan
->encEnvData
.init_sbr_amp_res
) {
1147 FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan
->encEnvData
,
1148 &hEnvChan
->sbrCodeEnvelope
,
1149 &hEnvChan
->sbrCodeNoiseFloor
,
1150 sbrHeaderData
->sbr_amp_res
);
1157 Tonality correction parameter extraction (inverse filtering level, noise floor additional sines).
1159 FDKsbrEnc_TonCorrParamExtr(&hEnvChan
->TonCorr
,
1160 hEnvChan
->encEnvData
.sbr_invf_mode_vec
,
1162 &hEnvChan
->encEnvData
.addHarmonicFlag
,
1163 hEnvChan
->encEnvData
.addHarmonic
,
1164 sbrExtrEnv
->envelopeCompensation
,
1167 h_con
->freqBandTable
[HI
],
1169 hEnvChan
->encEnvData
.sbr_xpos_mode
,
1170 h_con
->sbrSyntaxFlags
);
1174 /* Low energy in low band fix */
1175 if ( hEnvChan
->sbrTransientDetector
.prevLowBandEnergy
< hEnvChan
->sbrTransientDetector
.prevHighBandEnergy
&& hEnvChan
->sbrTransientDetector
.prevHighBandEnergy
> FL2FX_DBL(0.03))
1179 hEnvChan
->fLevelProtect
= 1;
1181 for (i
=0; i
<MAX_NUM_NOISE_VALUES
; i
++)
1182 hEnvChan
->encEnvData
.sbr_invf_mode_vec
[i
] = INVF_HIGH_LEVEL
;
1184 hEnvChan
->fLevelProtect
= 0;
1187 hEnvChan
->encEnvData
.sbr_invf_mode
= hEnvChan
->encEnvData
.sbr_invf_mode_vec
[0];
1189 hEnvChan
->encEnvData
.noOfnoisebands
= hEnvChan
->TonCorr
.sbrNoiseFloorEstimate
.noNoiseBands
;
1197 Save number of scf bands per envelope
1199 for (ch
= 0; ch
< nChannels
;ch
++) {
1200 for (i
= 0; i
< eData
[ch
].nEnvelopes
; i
++){
1201 h_envChan
[ch
]->encEnvData
.noScfBands
[i
] =
1202 (eData
[ch
].frame_info
->freqRes
[i
] == FREQ_RES_HIGH
? h_con
->nSfb
[FREQ_RES_HIGH
] : h_con
->nSfb
[FREQ_RES_LOW
]);
1207 Extract envelope of current frame.
1209 switch (stereoMode
) {
1211 calculateSbrEnvelope (h_envChan
[0]->sbrExtractEnvelope
.YBuffer
, NULL
,
1212 h_envChan
[0]->sbrExtractEnvelope
.YBufferScale
, NULL
,
1213 eData
[0].frame_info
, eData
[0].sfb_nrg
, NULL
,
1214 h_con
, h_envChan
[0], SBR_MONO
, NULL
, YSzShift
);
1216 case SBR_LEFT_RIGHT
:
1217 calculateSbrEnvelope (h_envChan
[0]->sbrExtractEnvelope
.YBuffer
, NULL
,
1218 h_envChan
[0]->sbrExtractEnvelope
.YBufferScale
, NULL
,
1219 eData
[0].frame_info
, eData
[0].sfb_nrg
, NULL
,
1220 h_con
, h_envChan
[0], SBR_MONO
, NULL
, YSzShift
);
1221 calculateSbrEnvelope (h_envChan
[1]->sbrExtractEnvelope
.YBuffer
, NULL
,
1222 h_envChan
[1]->sbrExtractEnvelope
.YBufferScale
, NULL
,
1223 eData
[1].frame_info
,eData
[1].sfb_nrg
, NULL
,
1224 h_con
, h_envChan
[1], SBR_MONO
, NULL
, YSzShift
);
1227 calculateSbrEnvelope (h_envChan
[0]->sbrExtractEnvelope
.YBuffer
, h_envChan
[1]->sbrExtractEnvelope
.YBuffer
,
1228 h_envChan
[0]->sbrExtractEnvelope
.YBufferScale
, h_envChan
[1]->sbrExtractEnvelope
.YBufferScale
,
1229 eData
[0].frame_info
, eData
[0].sfb_nrg
, eData
[1].sfb_nrg
,
1230 h_con
, h_envChan
[0], SBR_COUPLING
, &fData
->maxQuantError
, YSzShift
);
1232 case SBR_SWITCH_LRC
:
1233 calculateSbrEnvelope (h_envChan
[0]->sbrExtractEnvelope
.YBuffer
, NULL
,
1234 h_envChan
[0]->sbrExtractEnvelope
.YBufferScale
, NULL
,
1235 eData
[0].frame_info
, eData
[0].sfb_nrg
, NULL
,
1236 h_con
, h_envChan
[0], SBR_MONO
, NULL
, YSzShift
);
1237 calculateSbrEnvelope (h_envChan
[1]->sbrExtractEnvelope
.YBuffer
, NULL
,
1238 h_envChan
[1]->sbrExtractEnvelope
.YBufferScale
, NULL
,
1239 eData
[1].frame_info
, eData
[1].sfb_nrg
, NULL
,
1240 h_con
, h_envChan
[1], SBR_MONO
,NULL
, YSzShift
);
1241 calculateSbrEnvelope (h_envChan
[0]->sbrExtractEnvelope
.YBuffer
, h_envChan
[1]->sbrExtractEnvelope
.YBuffer
,
1242 h_envChan
[0]->sbrExtractEnvelope
.YBufferScale
, h_envChan
[1]->sbrExtractEnvelope
.YBufferScale
,
1243 eData
[0].frame_info
, eData
[0].sfb_nrg_coupling
, eData
[1].sfb_nrg_coupling
,
1244 h_con
, h_envChan
[0], SBR_COUPLING
, &fData
->maxQuantError
, YSzShift
);
1251 Noise floor quantisation and coding.
1254 switch (stereoMode
) {
1256 sbrNoiseFloorLevelsQuantisation(eData
[0].noise_level
, eData
[0].noiseFloor
, 0);
1258 FDKsbrEnc_codeEnvelope(eData
[0].noise_level
, fData
->res
,
1259 &h_envChan
[0]->sbrCodeNoiseFloor
,
1260 h_envChan
[0]->encEnvData
.domain_vec_noise
, 0,
1261 (eData
[0].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1262 sbrBitstreamData
->HeaderActive
);
1265 case SBR_LEFT_RIGHT
:
1266 sbrNoiseFloorLevelsQuantisation(eData
[0].noise_level
,eData
[0].noiseFloor
, 0);
1268 FDKsbrEnc_codeEnvelope (eData
[0].noise_level
, fData
->res
,
1269 &h_envChan
[0]->sbrCodeNoiseFloor
,
1270 h_envChan
[0]->encEnvData
.domain_vec_noise
, 0,
1271 (eData
[0].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1272 sbrBitstreamData
->HeaderActive
);
1274 sbrNoiseFloorLevelsQuantisation(eData
[1].noise_level
,eData
[1].noiseFloor
, 0);
1276 FDKsbrEnc_codeEnvelope (eData
[1].noise_level
, fData
->res
,
1277 &h_envChan
[1]->sbrCodeNoiseFloor
,
1278 h_envChan
[1]->encEnvData
.domain_vec_noise
, 0,
1279 (eData
[1].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1280 sbrBitstreamData
->HeaderActive
);
1285 coupleNoiseFloor(eData
[0].noiseFloor
,eData
[1].noiseFloor
);
1287 sbrNoiseFloorLevelsQuantisation(eData
[0].noise_level
,eData
[0].noiseFloor
, 0);
1289 FDKsbrEnc_codeEnvelope (eData
[0].noise_level
, fData
->res
,
1290 &h_envChan
[0]->sbrCodeNoiseFloor
,
1291 h_envChan
[0]->encEnvData
.domain_vec_noise
, 1,
1292 (eData
[0].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1293 sbrBitstreamData
->HeaderActive
);
1295 sbrNoiseFloorLevelsQuantisation(eData
[1].noise_level
,eData
[1].noiseFloor
, 1);
1297 FDKsbrEnc_codeEnvelope (eData
[1].noise_level
, fData
->res
,
1298 &h_envChan
[1]->sbrCodeNoiseFloor
,
1299 h_envChan
[1]->encEnvData
.domain_vec_noise
, 1,
1300 (eData
[1].frame_info
->nEnvelopes
> 1 ? 2 : 1), 1,
1301 sbrBitstreamData
->HeaderActive
);
1304 case SBR_SWITCH_LRC
:
1305 sbrNoiseFloorLevelsQuantisation(eData
[0].noise_level
,eData
[0].noiseFloor
, 0);
1306 sbrNoiseFloorLevelsQuantisation(eData
[1].noise_level
,eData
[1].noiseFloor
, 0);
1307 coupleNoiseFloor(eData
[0].noiseFloor
,eData
[1].noiseFloor
);
1308 sbrNoiseFloorLevelsQuantisation(eData
[0].noise_level_coupling
,eData
[0].noiseFloor
, 0);
1309 sbrNoiseFloorLevelsQuantisation(eData
[1].noise_level_coupling
,eData
[1].noiseFloor
, 1);
1316 Encode envelope of current frame.
1318 switch (stereoMode
) {
1320 sbrHeaderData
->coupling
= 0;
1321 h_envChan
[0]->encEnvData
.balance
= 0;
1322 FDKsbrEnc_codeEnvelope (eData
[0].sfb_nrg
, eData
[0].frame_info
->freqRes
,
1323 &h_envChan
[0]->sbrCodeEnvelope
,
1324 h_envChan
[0]->encEnvData
.domain_vec
,
1325 sbrHeaderData
->coupling
,
1326 eData
[0].frame_info
->nEnvelopes
, 0,
1327 sbrBitstreamData
->HeaderActive
);
1329 case SBR_LEFT_RIGHT
:
1330 sbrHeaderData
->coupling
= 0;
1332 h_envChan
[0]->encEnvData
.balance
= 0;
1333 h_envChan
[1]->encEnvData
.balance
= 0;
1336 FDKsbrEnc_codeEnvelope (eData
[0].sfb_nrg
, eData
[0].frame_info
->freqRes
,
1337 &h_envChan
[0]->sbrCodeEnvelope
,
1338 h_envChan
[0]->encEnvData
.domain_vec
,
1339 sbrHeaderData
->coupling
,
1340 eData
[0].frame_info
->nEnvelopes
, 0,
1341 sbrBitstreamData
->HeaderActive
);
1342 FDKsbrEnc_codeEnvelope (eData
[1].sfb_nrg
, eData
[1].frame_info
->freqRes
,
1343 &h_envChan
[1]->sbrCodeEnvelope
,
1344 h_envChan
[1]->encEnvData
.domain_vec
,
1345 sbrHeaderData
->coupling
,
1346 eData
[1].frame_info
->nEnvelopes
, 0,
1347 sbrBitstreamData
->HeaderActive
);
1350 sbrHeaderData
->coupling
= 1;
1351 h_envChan
[0]->encEnvData
.balance
= 0;
1352 h_envChan
[1]->encEnvData
.balance
= 1;
1354 FDKsbrEnc_codeEnvelope (eData
[0].sfb_nrg
, eData
[0].frame_info
->freqRes
,
1355 &h_envChan
[0]->sbrCodeEnvelope
,
1356 h_envChan
[0]->encEnvData
.domain_vec
,
1357 sbrHeaderData
->coupling
,
1358 eData
[0].frame_info
->nEnvelopes
, 0,
1359 sbrBitstreamData
->HeaderActive
);
1360 FDKsbrEnc_codeEnvelope (eData
[1].sfb_nrg
, eData
[1].frame_info
->freqRes
,
1361 &h_envChan
[1]->sbrCodeEnvelope
,
1362 h_envChan
[1]->encEnvData
.domain_vec
,
1363 sbrHeaderData
->coupling
,
1364 eData
[1].frame_info
->nEnvelopes
, 1,
1365 sbrBitstreamData
->HeaderActive
);
1367 case SBR_SWITCH_LRC
:
1370 INT payloadbitsCOUPLING
;
1372 SCHAR sfbNrgPrevTemp
[MAX_NUM_CHANNELS
][MAX_FREQ_COEFFS
];
1373 SCHAR noisePrevTemp
[MAX_NUM_CHANNELS
][MAX_NUM_NOISE_COEFFS
];
1374 INT upDateNrgTemp
[MAX_NUM_CHANNELS
];
1375 INT upDateNoiseTemp
[MAX_NUM_CHANNELS
];
1376 INT domainVecTemp
[MAX_NUM_CHANNELS
][MAX_ENVELOPES
];
1377 INT domainVecNoiseTemp
[MAX_NUM_CHANNELS
][MAX_ENVELOPES
];
1379 INT tempFlagRight
= 0;
1380 INT tempFlagLeft
= 0;
1383 Store previous values, in order to be able to "undo" what is being done.
1386 for(ch
= 0; ch
< nChannels
;ch
++){
1387 FDKmemcpy (sfbNrgPrevTemp
[ch
], h_envChan
[ch
]->sbrCodeEnvelope
.sfb_nrg_prev
,
1388 MAX_FREQ_COEFFS
* sizeof (SCHAR
));
1390 FDKmemcpy (noisePrevTemp
[ch
], h_envChan
[ch
]->sbrCodeNoiseFloor
.sfb_nrg_prev
,
1391 MAX_NUM_NOISE_COEFFS
* sizeof (SCHAR
));
1393 upDateNrgTemp
[ch
] = h_envChan
[ch
]->sbrCodeEnvelope
.upDate
;
1394 upDateNoiseTemp
[ch
] = h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
;
1397 forbid time coding in the first envelope in case of a different
1400 if(sbrHeaderData
->prev_coupling
){
1401 h_envChan
[ch
]->sbrCodeEnvelope
.upDate
= 0;
1402 h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
= 0;
1408 Code ordinary Left/Right stereo
1410 FDKsbrEnc_codeEnvelope (eData
[0].sfb_nrg
, eData
[0].frame_info
->freqRes
,
1411 &h_envChan
[0]->sbrCodeEnvelope
,
1412 h_envChan
[0]->encEnvData
.domain_vec
, 0,
1413 eData
[0].frame_info
->nEnvelopes
, 0,
1414 sbrBitstreamData
->HeaderActive
);
1415 FDKsbrEnc_codeEnvelope (eData
[1].sfb_nrg
, eData
[1].frame_info
->freqRes
,
1416 &h_envChan
[1]->sbrCodeEnvelope
,
1417 h_envChan
[1]->encEnvData
.domain_vec
, 0,
1418 eData
[1].frame_info
->nEnvelopes
, 0,
1419 sbrBitstreamData
->HeaderActive
);
1422 for (i
= 0; i
< eData
[0].nEnvelopes
; i
++) {
1423 for (j
= 0; j
< h_envChan
[0]->encEnvData
.noScfBands
[i
]; j
++)
1425 h_envChan
[0]->encEnvData
.ienvelope
[i
][j
] = eData
[0].sfb_nrg
[c
];
1426 h_envChan
[1]->encEnvData
.ienvelope
[i
][j
] = eData
[1].sfb_nrg
[c
];
1433 FDKsbrEnc_codeEnvelope (eData
[0].noise_level
, fData
->res
,
1434 &h_envChan
[0]->sbrCodeNoiseFloor
,
1435 h_envChan
[0]->encEnvData
.domain_vec_noise
, 0,
1436 (eData
[0].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1437 sbrBitstreamData
->HeaderActive
);
1440 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++)
1441 h_envChan
[0]->encEnvData
.sbr_noise_levels
[i
] = eData
[0].noise_level
[i
];
1444 FDKsbrEnc_codeEnvelope (eData
[1].noise_level
, fData
->res
,
1445 &h_envChan
[1]->sbrCodeNoiseFloor
,
1446 h_envChan
[1]->encEnvData
.domain_vec_noise
, 0,
1447 (eData
[1].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1448 sbrBitstreamData
->HeaderActive
);
1450 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++)
1451 h_envChan
[1]->encEnvData
.sbr_noise_levels
[i
] = eData
[1].noise_level
[i
];
1454 sbrHeaderData
->coupling
= 0;
1455 h_envChan
[0]->encEnvData
.balance
= 0;
1456 h_envChan
[1]->encEnvData
.balance
= 0;
1458 payloadbitsLR
= FDKsbrEnc_CountSbrChannelPairElement (sbrHeaderData
,
1461 &h_envChan
[0]->encEnvData
,
1462 &h_envChan
[1]->encEnvData
,
1464 h_con
->sbrSyntaxFlags
);
1467 swap saved stored with current values
1469 for(ch
= 0; ch
< nChannels
;ch
++){
1471 for(i
=0;i
<MAX_FREQ_COEFFS
;i
++){
1475 itmp
= h_envChan
[ch
]->sbrCodeEnvelope
.sfb_nrg_prev
[i
];
1476 h_envChan
[ch
]->sbrCodeEnvelope
.sfb_nrg_prev
[i
]=sfbNrgPrevTemp
[ch
][i
];
1477 sfbNrgPrevTemp
[ch
][i
]=itmp
;
1479 for(i
=0;i
<MAX_NUM_NOISE_COEFFS
;i
++){
1483 itmp
= h_envChan
[ch
]->sbrCodeNoiseFloor
.sfb_nrg_prev
[i
];
1484 h_envChan
[ch
]->sbrCodeNoiseFloor
.sfb_nrg_prev
[i
]=noisePrevTemp
[ch
][i
];
1485 noisePrevTemp
[ch
][i
]=itmp
;
1487 /* swap update flags */
1488 itmp
= h_envChan
[ch
]->sbrCodeEnvelope
.upDate
;
1489 h_envChan
[ch
]->sbrCodeEnvelope
.upDate
=upDateNrgTemp
[ch
];
1490 upDateNrgTemp
[ch
] = itmp
;
1492 itmp
= h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
;
1493 h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
=upDateNoiseTemp
[ch
];
1494 upDateNoiseTemp
[ch
]=itmp
;
1499 FDKmemcpy(domainVecTemp
[ch
],h_envChan
[ch
]->encEnvData
.domain_vec
,sizeof(INT
)*MAX_ENVELOPES
);
1500 FDKmemcpy(domainVecNoiseTemp
[ch
],h_envChan
[ch
]->encEnvData
.domain_vec_noise
,sizeof(INT
)*MAX_ENVELOPES
);
1503 forbid time coding in the first envelope in case of a different
1507 if(!sbrHeaderData
->prev_coupling
){
1508 h_envChan
[ch
]->sbrCodeEnvelope
.upDate
= 0;
1509 h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
= 0;
1518 FDKsbrEnc_codeEnvelope (eData
[0].sfb_nrg_coupling
, eData
[0].frame_info
->freqRes
,
1519 &h_envChan
[0]->sbrCodeEnvelope
,
1520 h_envChan
[0]->encEnvData
.domain_vec
, 1,
1521 eData
[0].frame_info
->nEnvelopes
, 0,
1522 sbrBitstreamData
->HeaderActive
);
1524 FDKsbrEnc_codeEnvelope (eData
[1].sfb_nrg_coupling
, eData
[1].frame_info
->freqRes
,
1525 &h_envChan
[1]->sbrCodeEnvelope
,
1526 h_envChan
[1]->encEnvData
.domain_vec
, 1,
1527 eData
[1].frame_info
->nEnvelopes
, 1,
1528 sbrBitstreamData
->HeaderActive
);
1532 for (i
= 0; i
< eData
[0].nEnvelopes
; i
++) {
1533 for (j
= 0; j
< h_envChan
[0]->encEnvData
.noScfBands
[i
]; j
++) {
1534 h_envChan
[0]->encEnvData
.ienvelope
[i
][j
] = eData
[0].sfb_nrg_coupling
[c
];
1535 h_envChan
[1]->encEnvData
.ienvelope
[i
][j
] = eData
[1].sfb_nrg_coupling
[c
];
1540 FDKsbrEnc_codeEnvelope (eData
[0].noise_level_coupling
, fData
->res
,
1541 &h_envChan
[0]->sbrCodeNoiseFloor
,
1542 h_envChan
[0]->encEnvData
.domain_vec_noise
, 1,
1543 (eData
[0].frame_info
->nEnvelopes
> 1 ? 2 : 1), 0,
1544 sbrBitstreamData
->HeaderActive
);
1546 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++)
1547 h_envChan
[0]->encEnvData
.sbr_noise_levels
[i
] = eData
[0].noise_level_coupling
[i
];
1550 FDKsbrEnc_codeEnvelope (eData
[1].noise_level_coupling
, fData
->res
,
1551 &h_envChan
[1]->sbrCodeNoiseFloor
,
1552 h_envChan
[1]->encEnvData
.domain_vec_noise
, 1,
1553 (eData
[1].frame_info
->nEnvelopes
> 1 ? 2 : 1), 1,
1554 sbrBitstreamData
->HeaderActive
);
1556 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++)
1557 h_envChan
[1]->encEnvData
.sbr_noise_levels
[i
] = eData
[1].noise_level_coupling
[i
];
1559 sbrHeaderData
->coupling
= 1;
1561 h_envChan
[0]->encEnvData
.balance
= 0;
1562 h_envChan
[1]->encEnvData
.balance
= 1;
1564 tempFlagLeft
= h_envChan
[0]->encEnvData
.addHarmonicFlag
;
1565 tempFlagRight
= h_envChan
[1]->encEnvData
.addHarmonicFlag
;
1567 payloadbitsCOUPLING
=
1568 FDKsbrEnc_CountSbrChannelPairElement (sbrHeaderData
,
1571 &h_envChan
[0]->encEnvData
,
1572 &h_envChan
[1]->encEnvData
,
1574 h_con
->sbrSyntaxFlags
);
1577 h_envChan
[0]->encEnvData
.addHarmonicFlag
= tempFlagLeft
;
1578 h_envChan
[1]->encEnvData
.addHarmonicFlag
= tempFlagRight
;
1580 if (payloadbitsCOUPLING
< payloadbitsLR
) {
1583 copy coded coupling envelope and noise data to l/r
1585 for(ch
= 0; ch
< nChannels
;ch
++){
1586 SBR_ENV_TEMP_DATA
*ed
= &eData
[ch
];
1587 FDKmemcpy (ed
->sfb_nrg
, ed
->sfb_nrg_coupling
,
1588 MAX_NUM_ENVELOPE_VALUES
* sizeof (SCHAR
));
1589 FDKmemcpy (ed
->noise_level
, ed
->noise_level_coupling
,
1590 MAX_NUM_NOISE_VALUES
* sizeof (SCHAR
));
1593 sbrHeaderData
->coupling
= 1;
1594 h_envChan
[0]->encEnvData
.balance
= 0;
1595 h_envChan
[1]->encEnvData
.balance
= 1;
1599 restore saved l/r items
1601 for(ch
= 0; ch
< nChannels
;ch
++){
1603 FDKmemcpy (h_envChan
[ch
]->sbrCodeEnvelope
.sfb_nrg_prev
,
1604 sfbNrgPrevTemp
[ch
], MAX_FREQ_COEFFS
* sizeof (SCHAR
));
1606 h_envChan
[ch
]->sbrCodeEnvelope
.upDate
= upDateNrgTemp
[ch
];
1608 FDKmemcpy (h_envChan
[ch
]->sbrCodeNoiseFloor
.sfb_nrg_prev
,
1609 noisePrevTemp
[ch
], MAX_NUM_NOISE_COEFFS
* sizeof (SCHAR
));
1611 FDKmemcpy (h_envChan
[ch
]->encEnvData
.domain_vec
,domainVecTemp
[ch
],sizeof(INT
)*MAX_ENVELOPES
);
1612 FDKmemcpy (h_envChan
[ch
]->encEnvData
.domain_vec_noise
,domainVecNoiseTemp
[ch
],sizeof(INT
)*MAX_ENVELOPES
);
1614 h_envChan
[ch
]->sbrCodeNoiseFloor
.upDate
= upDateNoiseTemp
[ch
];
1617 sbrHeaderData
->coupling
= 0;
1618 h_envChan
[0]->encEnvData
.balance
= 0;
1619 h_envChan
[1]->encEnvData
.balance
= 0;
1626 /* tell the envelope encoders how long it has been, since we last sent
1627 a frame starting with a dF-coded envelope */
1628 if (stereoMode
== SBR_MONO
) {
1629 if (h_envChan
[0]->encEnvData
.domain_vec
[0] == TIME
)
1630 h_envChan
[0]->sbrCodeEnvelope
.dF_edge_incr_fac
++;
1632 h_envChan
[0]->sbrCodeEnvelope
.dF_edge_incr_fac
= 0;
1635 if (h_envChan
[0]->encEnvData
.domain_vec
[0] == TIME
||
1636 h_envChan
[1]->encEnvData
.domain_vec
[0] == TIME
) {
1637 h_envChan
[0]->sbrCodeEnvelope
.dF_edge_incr_fac
++;
1638 h_envChan
[1]->sbrCodeEnvelope
.dF_edge_incr_fac
++;
1641 h_envChan
[0]->sbrCodeEnvelope
.dF_edge_incr_fac
= 0;
1642 h_envChan
[1]->sbrCodeEnvelope
.dF_edge_incr_fac
= 0;
1647 Send the encoded data to the bitstream
1649 for(ch
= 0; ch
< nChannels
;ch
++){
1650 SBR_ENV_TEMP_DATA
*ed
= &eData
[ch
];
1652 for (i
= 0; i
< ed
->nEnvelopes
; i
++) {
1653 for (j
= 0; j
< h_envChan
[ch
]->encEnvData
.noScfBands
[i
]; j
++) {
1654 h_envChan
[ch
]->encEnvData
.ienvelope
[i
][j
] = ed
->sfb_nrg
[c
];
1659 for (i
= 0; i
< MAX_NUM_NOISE_VALUES
; i
++){
1660 h_envChan
[ch
]->encEnvData
.sbr_noise_levels
[i
] = ed
->noise_level
[i
];
1668 if (nChannels
== 2) {
1669 FDKsbrEnc_WriteEnvChannelPairElement(sbrHeaderData
,
1672 &h_envChan
[0]->encEnvData
,
1673 &h_envChan
[1]->encEnvData
,
1675 h_con
->sbrSyntaxFlags
);
1678 FDKsbrEnc_WriteEnvSingleChannelElement(sbrHeaderData
,
1681 &h_envChan
[0]->encEnvData
,
1683 h_con
->sbrSyntaxFlags
);
1689 for (ch
=0; ch
<nChannels
; ch
++)
1691 int YBufferLength
= h_envChan
[ch
]->sbrExtractEnvelope
.no_cols
>> h_envChan
[ch
]->sbrExtractEnvelope
.YBufferSzShift
;
1692 for (i
= 0; i
< h_envChan
[ch
]->sbrExtractEnvelope
.YBufferWriteOffset
; i
++) {
1693 FDKmemcpy(h_envChan
[ch
]->sbrExtractEnvelope
.YBuffer
[i
],
1694 h_envChan
[ch
]->sbrExtractEnvelope
.YBuffer
[i
+ YBufferLength
],
1695 sizeof(FIXP_DBL
)*QMF_CHANNELS
);
1697 h_envChan
[ch
]->sbrExtractEnvelope
.YBufferScale
[0] = h_envChan
[ch
]->sbrExtractEnvelope
.YBufferScale
[1];
1700 sbrHeaderData
->prev_coupling
= sbrHeaderData
->coupling
;
1703 /***************************************************************************/
1706 \brief creates an envelope extractor handle
1708 \return error status
1710 ****************************************************************************/
1712 FDKsbrEnc_CreateExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut
,
1719 FIXP_DBL
* YBuffer
= GetRam_Sbr_envYBuffer(channel
);
1721 FDKmemclear(hSbrCut
,sizeof(SBR_EXTRACT_ENVELOPE
));
1722 hSbrCut
->p_YBuffer
= YBuffer
;
1725 for (i
= 0; i
< (QMF_MAX_TIME_SLOTS
>>1); i
++) {
1726 hSbrCut
->YBuffer
[i
] = YBuffer
+ (i
*QMF_CHANNELS
);
1728 FIXP_DBL
*YBufferDyn
= GetRam_Sbr_envYBuffer(chInEl
, dynamic_RAM
);
1730 for (; i
< QMF_MAX_TIME_SLOTS
; i
++,n
++) {
1731 hSbrCut
->YBuffer
[i
] = YBufferDyn
+ (n
*QMF_CHANNELS
);
1734 FIXP_DBL
* rBuffer
= GetRam_Sbr_envRBuffer(0, dynamic_RAM
);
1735 FIXP_DBL
* iBuffer
= GetRam_Sbr_envIBuffer(0, dynamic_RAM
);
1737 for (i
= 0; i
< QMF_MAX_TIME_SLOTS
; i
++) {
1738 hSbrCut
->rBuffer
[i
] = rBuffer
+ (i
*QMF_CHANNELS
);
1739 hSbrCut
->iBuffer
[i
] = iBuffer
+ (i
*QMF_CHANNELS
);
1746 /***************************************************************************/
1749 \brief Initialize an envelope extractor instance.
1751 \return error status
1753 ****************************************************************************/
1755 FDKsbrEnc_InitExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut
,
1762 ULONG statesInitFlag
1765 ,UINT sbrSyntaxFlags
1768 int YBufferLength
, rBufferLength
;
1771 if (sbrSyntaxFlags
& SBR_SYNTAX_LOW_DELAY
) {
1772 int off
= TRANSIENT_OFFSET_LD
;
1774 hSbrCut
->YBufferWriteOffset
= (no_cols
>>1)+off
*time_step
;
1776 hSbrCut
->YBufferWriteOffset
= no_cols
+off
*time_step
;
1780 hSbrCut
->YBufferWriteOffset
= tran_off
*time_step
;
1782 hSbrCut
->rBufferReadOffset
= 0;
1785 YBufferLength
= hSbrCut
->YBufferWriteOffset
+ no_cols
;
1786 rBufferLength
= no_cols
;
1788 hSbrCut
->pre_transient_info
[0] = 0;
1789 hSbrCut
->pre_transient_info
[1] = 0;
1792 hSbrCut
->no_cols
= no_cols
;
1793 hSbrCut
->no_rows
= no_rows
;
1794 hSbrCut
->start_index
= start_index
;
1796 hSbrCut
->time_slots
= time_slots
;
1797 hSbrCut
->time_step
= time_step
;
1799 FDK_ASSERT(no_rows
<= QMF_CHANNELS
);
1801 /* Use half the Energy values if time step is 2 or greater */
1803 hSbrCut
->YBufferSzShift
= 1;
1805 hSbrCut
->YBufferSzShift
= 0;
1807 YBufferLength
>>= hSbrCut
->YBufferSzShift
;
1808 hSbrCut
->YBufferWriteOffset
>>= hSbrCut
->YBufferSzShift
;
1810 FDK_ASSERT(YBufferLength
<=QMF_MAX_TIME_SLOTS
);
1812 FIXP_DBL
*YBufferDyn
= GetRam_Sbr_envYBuffer(chInEl
, dynamic_RAM
);
1814 for (i
=(QMF_MAX_TIME_SLOTS
>>1); i
< QMF_MAX_TIME_SLOTS
; i
++,n
++) {
1815 hSbrCut
->YBuffer
[i
] = YBufferDyn
+ (n
*QMF_CHANNELS
);
1818 if(statesInitFlag
) {
1819 for (i
=0; i
<YBufferLength
; i
++) {
1820 FDKmemclear( hSbrCut
->YBuffer
[i
],QMF_CHANNELS
*sizeof(FIXP_DBL
));
1824 for (i
= 0; i
< rBufferLength
; i
++) {
1825 FDKmemclear( hSbrCut
->rBuffer
[i
],QMF_CHANNELS
*sizeof(FIXP_DBL
));
1826 FDKmemclear( hSbrCut
->iBuffer
[i
],QMF_CHANNELS
*sizeof(FIXP_DBL
));
1829 FDKmemclear (hSbrCut
->envelopeCompensation
,sizeof(UCHAR
)*MAX_FREQ_COEFFS
);
1831 if(statesInitFlag
) {
1832 hSbrCut
->YBufferScale
[0] = hSbrCut
->YBufferScale
[1] = FRACT_BITS
-1;
1841 /***************************************************************************/
1844 \brief deinitializes an envelope extractor handle
1848 ****************************************************************************/
1851 FDKsbrEnc_deleteExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut
)
1855 FreeRam_Sbr_envYBuffer(&hSbrCut
->p_YBuffer
);
1860 FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr
)
1862 return hSbr
->no_rows
*((hSbr
->YBufferWriteOffset
)*2 /* mult 2 because nrg's are grouped half */
1863 - hSbr
->rBufferReadOffset
); /* in reference hold half spec and calc nrg's on overlapped spec */