/src/aac/libSBRdec/src/sbr_dec.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** SBR decoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | /*! |
104 | | \file |
105 | | \brief Sbr decoder |
106 | | This module provides the actual decoder implementation. The SBR data (side |
107 | | information) is already decoded. Only three functions are provided: |
108 | | |
109 | | \li 1.) createSbrDec(): One time initialization |
110 | | \li 2.) resetSbrDec(): Called by sbr_Apply() when the information contained in |
111 | | an SBR_HEADER_ELEMENT requires a reset and recalculation of important SBR |
112 | | structures. \li 3.) sbr_dec(): The actual decoder. Calls the different tools |
113 | | such as filterbanks, lppTransposer(), and calculateSbrEnvelope() [the envelope |
114 | | adjuster]. |
115 | | |
116 | | \sa sbr_dec(), \ref documentationOverview |
117 | | */ |
118 | | |
119 | | #include "sbr_dec.h" |
120 | | |
121 | | #include "sbr_ram.h" |
122 | | #include "env_extr.h" |
123 | | #include "env_calc.h" |
124 | | #include "scale.h" |
125 | | #include "FDK_matrixCalloc.h" |
126 | | #include "hbe.h" |
127 | | |
128 | | #include "genericStds.h" |
129 | | |
130 | | #include "sbrdec_drc.h" |
131 | | |
132 | | static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal, |
133 | | FIXP_DBL **qmfImag, int noCols, int overlap, |
134 | 0 | KEEP_STATES_SYNCED_MODE keepStatesSynced) { |
135 | 0 | int patchBands; |
136 | 0 | int patch, band, col, target, sourceBands, i; |
137 | 0 | int numPatches = 0; |
138 | 0 | int slotOffset = 0; |
139 | |
|
140 | 0 | FIXP_DBL **ppqmfReal = qmfReal + overlap; |
141 | 0 | FIXP_DBL **ppqmfImag = qmfImag + overlap; |
142 | |
|
143 | 0 | if (keepStatesSynced == KEEP_STATES_SYNCED_NORMAL) { |
144 | 0 | slotOffset = noCols - overlap - LPC_ORDER; |
145 | 0 | } |
146 | |
|
147 | 0 | if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) { |
148 | 0 | ppqmfReal = qmfReal; |
149 | 0 | ppqmfImag = qmfImag; |
150 | 0 | } |
151 | |
|
152 | 0 | for (i = 1; i < MAX_NUM_PATCHES; i++) { |
153 | 0 | if (xOverQmf[i] != 0) { |
154 | 0 | numPatches++; |
155 | 0 | } |
156 | 0 | } |
157 | |
|
158 | 0 | for (patch = (MAX_STRETCH_HBE - 1); patch < numPatches; patch++) { |
159 | 0 | patchBands = xOverQmf[patch + 1] - xOverQmf[patch]; |
160 | 0 | target = xOverQmf[patch]; |
161 | 0 | sourceBands = xOverQmf[MAX_STRETCH_HBE - 1] - xOverQmf[MAX_STRETCH_HBE - 2]; |
162 | |
|
163 | 0 | while (patchBands > 0) { |
164 | 0 | int numBands = sourceBands; |
165 | 0 | int startBand = xOverQmf[MAX_STRETCH_HBE - 1] - 1; |
166 | 0 | if (target + numBands >= xOverQmf[patch + 1]) { |
167 | 0 | numBands = xOverQmf[patch + 1] - target; |
168 | 0 | } |
169 | 0 | if ((((target + numBands - 1) % 2) + |
170 | 0 | ((xOverQmf[MAX_STRETCH_HBE - 1] - 1) % 2)) % |
171 | 0 | 2) { |
172 | 0 | if (numBands == sourceBands) { |
173 | 0 | numBands--; |
174 | 0 | } else { |
175 | 0 | startBand--; |
176 | 0 | } |
177 | 0 | } |
178 | 0 | if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) { |
179 | 0 | for (col = slotOffset; col < overlap + LPC_ORDER; col++) { |
180 | 0 | i = 0; |
181 | 0 | for (band = numBands; band > 0; band--) { |
182 | 0 | if ((target + band - 1 < 64) && |
183 | 0 | (target + band - 1 < xOverQmf[patch + 1])) { |
184 | 0 | ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i]; |
185 | 0 | ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i]; |
186 | 0 | i++; |
187 | 0 | } |
188 | 0 | } |
189 | 0 | } |
190 | 0 | } else { |
191 | 0 | for (col = slotOffset; col < noCols; col++) { |
192 | 0 | i = 0; |
193 | 0 | for (band = numBands; band > 0; band--) { |
194 | 0 | if ((target + band - 1 < 64) && |
195 | 0 | (target + band - 1 < xOverQmf[patch + 1])) { |
196 | 0 | ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i]; |
197 | 0 | ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i]; |
198 | 0 | i++; |
199 | 0 | } |
200 | 0 | } |
201 | 0 | } |
202 | 0 | } |
203 | 0 | target += numBands; |
204 | 0 | patchBands -= numBands; |
205 | 0 | } |
206 | 0 | } |
207 | 0 | } |
208 | | |
209 | | /*! |
210 | | \brief SBR decoder core function for one channel |
211 | | |
212 | | \image html BufferMgmtDetailed-1632.png |
213 | | |
214 | | Besides the filter states of the QMF filter bank and the LPC-states of |
215 | | the LPP-Transposer, processing is mainly based on four buffers: |
216 | | #timeIn, #timeOut, #WorkBuffer2 and #OverlapBuffer. The #WorkBuffer2 |
217 | | is reused for all channels and might be used by the core decoder, a |
218 | | static overlap buffer is required for each channel. Due to in-place |
219 | | processing, #timeIn and #timeOut point to identical locations. |
220 | | |
221 | | The spectral data is organized in so-called slots. Each slot |
222 | | contains 64 bands of complex data. The number of slots per frame |
223 | | depends on the frame size. For mp3PRO, there are 18 slots per frame |
224 | | and 6 slots per #OverlapBuffer. It is not necessary to have the slots |
225 | | in located consecutive address ranges. |
226 | | |
227 | | To optimize memory usage and to minimize the number of memory |
228 | | accesses, the memory management is organized as follows (slot numbers |
229 | | based on mp3PRO): |
230 | | |
231 | | 1.) Input time domain signal is located in #timeIn. The last slots |
232 | | (0..5) of the spectral data of the previous frame are located in the |
233 | | #OverlapBuffer. In addition, #frameData of the current frame resides |
234 | | in the upper part of #timeIn. |
235 | | |
236 | | 2.) During the cplxAnalysisQmfFiltering(), 32 samples from #timeIn are |
237 | | transformed into a slot of up to 32 complex spectral low band values at a |
238 | | time. The first spectral slot -- nr. 6 -- is written at slot number |
239 | | zero of #WorkBuffer2. #WorkBuffer2 will be completely filled with |
240 | | spectral data. |
241 | | |
242 | | 3.) LPP-Transposition in lppTransposer() is processed on 24 slots. During the |
243 | | transposition, the high band part of the spectral data is replicated |
244 | | based on the low band data. |
245 | | |
246 | | Envelope Adjustment is processed on the high band part of the spectral |
247 | | data only by calculateSbrEnvelope(). |
248 | | |
249 | | 4.) The cplxSynthesisQmfFiltering() creates 64 time domain samples out |
250 | | of a slot of 64 complex spectral values at a time. The first 6 slots |
251 | | in #timeOut are filled from the results of spectral slots 0..5 in the |
252 | | #OverlapBuffer. The consecutive slots in timeOut are now filled with |
253 | | the results of spectral slots 6..17. |
254 | | |
255 | | 5.) The preprocessed slots 18..23 have to be stored in the |
256 | | #OverlapBuffer. |
257 | | |
258 | | */ |
259 | | |
260 | | void sbr_dec( |
261 | | HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ |
262 | | LONG *timeIn, /*!< pointer to input time signal */ |
263 | | LONG *timeOut, /*!< pointer to output time signal */ |
264 | | HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ |
265 | | LONG *timeOutRight, /*!< pointer to output time signal */ |
266 | | const int strideOut, /*!< Time data traversal strideOut */ |
267 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
268 | | HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ |
269 | | HANDLE_SBR_PREV_FRAME_DATA |
270 | | hPrevFrameData, /*!< Some control data of last frame */ |
271 | | const int applyProcessing, /*!< Flag for SBR operation */ |
272 | | HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize, |
273 | 0 | const INT sbrInDataHeadroom) { |
274 | 0 | int i, slot, reserve; |
275 | 0 | int saveLbScale; |
276 | 0 | int lastSlotOffs; |
277 | 0 | FIXP_DBL maxVal; |
278 | | |
279 | | /* temporary pointer / variable for QMF; |
280 | | required as we want to use temporary buffer |
281 | | creating one frame delay for HBE in LP mode */ |
282 | 0 | LONG *pTimeInQmf = timeIn; |
283 | | |
284 | | /* Number of QMF timeslots in the overlap buffer: */ |
285 | 0 | int ov_len = hSbrDec->LppTrans.pSettings->overlap; |
286 | | |
287 | | /* Number of QMF slots per frame */ |
288 | 0 | int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; |
289 | | |
290 | | /* create pointer array for data to use for HBE and legacy sbr */ |
291 | 0 | FIXP_DBL *pLowBandReal[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)]; |
292 | 0 | FIXP_DBL *pLowBandImag[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)]; |
293 | | |
294 | | /* set pReal to where QMF analysis writes in case of legacy SBR */ |
295 | 0 | FIXP_DBL **pReal = pLowBandReal + ov_len; |
296 | 0 | FIXP_DBL **pImag = pLowBandImag + ov_len; |
297 | | |
298 | | /* map QMF buffer to pointer array (Overlap + Frame)*/ |
299 | 0 | for (i = 0; i < noCols + ov_len; i++) { |
300 | 0 | pLowBandReal[i] = hSbrDec->qmfDomainInCh->hQmfSlotsReal[i]; |
301 | 0 | pLowBandImag[i] = hSbrDec->qmfDomainInCh->hQmfSlotsImag[i]; |
302 | 0 | } |
303 | |
|
304 | 0 | if ((flags & SBRDEC_USAC_HARMONICSBR)) { |
305 | | /* in case of harmonic SBR and no HBE_LP map additional buffer for |
306 | | one more frame to pointer arry */ |
307 | 0 | for (i = 0; i < noCols; i++) { |
308 | 0 | pLowBandReal[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsReal[i]; |
309 | 0 | pLowBandImag[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsImag[i]; |
310 | 0 | } |
311 | | |
312 | | /* shift scale values according to buffer */ |
313 | 0 | hSbrDec->scale_ov = hSbrDec->scale_lb; |
314 | 0 | hSbrDec->scale_lb = hSbrDec->scale_hbe; |
315 | | |
316 | | /* set pReal to where QMF analysis writes in case of HBE */ |
317 | 0 | pReal += noCols; |
318 | 0 | pImag += noCols; |
319 | 0 | if (flags & SBRDEC_SKIP_QMF_ANA) { |
320 | | /* stereoCfgIndex3 with HBE */ |
321 | 0 | FDK_QmfDomain_QmfData2HBE(hSbrDec->qmfDomainInCh, |
322 | 0 | hSbrDec->hQmfHBESlotsReal, |
323 | 0 | hSbrDec->hQmfHBESlotsImag); |
324 | 0 | } else { |
325 | | /* We have to move old hbe frame data to lb area of buffer */ |
326 | 0 | for (i = 0; i < noCols; i++) { |
327 | 0 | FDKmemcpy(pLowBandReal[ov_len + i], hSbrDec->hQmfHBESlotsReal[i], |
328 | 0 | hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL)); |
329 | 0 | FDKmemcpy(pLowBandImag[ov_len + i], hSbrDec->hQmfHBESlotsImag[i], |
330 | 0 | hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL)); |
331 | 0 | } |
332 | 0 | } |
333 | 0 | } |
334 | | |
335 | | /* |
336 | | low band codec signal subband filtering |
337 | | */ |
338 | |
|
339 | 0 | if (flags & SBRDEC_SKIP_QMF_ANA) { |
340 | 0 | if (!(flags & SBRDEC_USAC_HARMONICSBR)) /* stereoCfgIndex3 w/o HBE */ |
341 | 0 | FDK_QmfDomain_WorkBuffer2ProcChannel(hSbrDec->qmfDomainInCh); |
342 | 0 | } else { |
343 | 0 | C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64)); |
344 | 0 | qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag, |
345 | 0 | &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, |
346 | 0 | 0 + sbrInDataHeadroom, 1, qmfTemp); |
347 | |
|
348 | 0 | C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64)); |
349 | 0 | } |
350 | | |
351 | | /* |
352 | | Clear upper half of spectrum |
353 | | */ |
354 | 0 | if (!((flags & SBRDEC_USAC_HARMONICSBR) && |
355 | 0 | (hFrameData->sbrPatchingMode == 0))) { |
356 | 0 | int nAnalysisBands = hHeaderData->numberOfAnalysisBands; |
357 | |
|
358 | 0 | if (!(flags & SBRDEC_LOW_POWER)) { |
359 | 0 | for (slot = ov_len; slot < noCols + ov_len; slot++) { |
360 | 0 | FDKmemclear(&pLowBandReal[slot][nAnalysisBands], |
361 | 0 | ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); |
362 | 0 | FDKmemclear(&pLowBandImag[slot][nAnalysisBands], |
363 | 0 | ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); |
364 | 0 | } |
365 | 0 | } else { |
366 | 0 | for (slot = ov_len; slot < noCols + ov_len; slot++) { |
367 | 0 | FDKmemclear(&pLowBandReal[slot][nAnalysisBands], |
368 | 0 | ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); |
369 | 0 | } |
370 | 0 | } |
371 | 0 | } |
372 | | |
373 | | /* |
374 | | Shift spectral data left to gain accuracy in transposer and adjustor |
375 | | */ |
376 | | /* Range was increased from lsb to no_channels because in some cases (e.g. |
377 | | USAC conf eSbr_4_Pvc.mp4 and some HBE cases) it could be observed that the |
378 | | signal between lsb and no_channels is used for the patching process. |
379 | | */ |
380 | 0 | maxVal = maxSubbandSample(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0, |
381 | 0 | hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols); |
382 | |
|
383 | 0 | reserve = fixMax(0, CntLeadingZeros(maxVal) - 1); |
384 | 0 | reserve = fixMin(reserve, |
385 | 0 | DFRACT_BITS - 1 - hSbrDec->qmfDomainInCh->scaling.lb_scale); |
386 | | |
387 | | /* If all data is zero, lb_scale could become too large */ |
388 | 0 | rescaleSubbandSamples(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0, |
389 | 0 | hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols, |
390 | 0 | reserve); |
391 | |
|
392 | 0 | hSbrDec->qmfDomainInCh->scaling.lb_scale += reserve; |
393 | |
|
394 | 0 | if ((flags & SBRDEC_USAC_HARMONICSBR)) { |
395 | | /* actually this is our hbe_scale */ |
396 | 0 | hSbrDec->scale_hbe = hSbrDec->qmfDomainInCh->scaling.lb_scale; |
397 | | /* the real lb_scale is stored in scale_lb from sbr */ |
398 | 0 | hSbrDec->qmfDomainInCh->scaling.lb_scale = hSbrDec->scale_lb; |
399 | 0 | } |
400 | | /* |
401 | | save low band scale, wavecoding or parametric stereo may modify it |
402 | | */ |
403 | 0 | saveLbScale = hSbrDec->qmfDomainInCh->scaling.lb_scale; |
404 | |
|
405 | 0 | if (applyProcessing) { |
406 | 0 | UCHAR *borders = hFrameData->frameInfo.borders; |
407 | 0 | lastSlotOffs = borders[hFrameData->frameInfo.nEnvelopes] - |
408 | 0 | hHeaderData->numberTimeSlots; |
409 | |
|
410 | 0 | FIXP_DBL degreeAlias[(64)]; |
411 | 0 | PVC_DYNAMIC_DATA pvcDynamicData; |
412 | 0 | pvcInitFrame( |
413 | 0 | &hSbrDec->PvcStaticData, &pvcDynamicData, |
414 | 0 | (hHeaderData->frameErrorFlag ? 0 : hHeaderData->bs_info.pvc_mode), |
415 | 0 | hFrameData->ns, hHeaderData->timeStep, |
416 | 0 | hHeaderData->freqBandData.lowSubband, |
417 | 0 | hFrameData->frameInfo.pvcBorders[0], hFrameData->pvcID); |
418 | |
|
419 | 0 | if (!hHeaderData->frameErrorFlag && (hHeaderData->bs_info.pvc_mode > 0)) { |
420 | 0 | pvcDecodeFrame(&hSbrDec->PvcStaticData, &pvcDynamicData, pLowBandReal, |
421 | 0 | pLowBandImag, ov_len, |
422 | 0 | SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale), |
423 | 0 | SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale)); |
424 | 0 | } |
425 | 0 | pvcEndFrame(&hSbrDec->PvcStaticData, &pvcDynamicData); |
426 | | |
427 | | /* The transposer will override most values in degreeAlias[]. |
428 | | The array needs to be cleared at least from lowSubband to highSubband |
429 | | before. */ |
430 | 0 | if (flags & SBRDEC_LOW_POWER) |
431 | 0 | FDKmemclear(°reeAlias[hHeaderData->freqBandData.lowSubband], |
432 | 0 | (hHeaderData->freqBandData.highSubband - |
433 | 0 | hHeaderData->freqBandData.lowSubband) * |
434 | 0 | sizeof(FIXP_DBL)); |
435 | | |
436 | | /* |
437 | | Inverse filtering of lowband and transposition into the SBR-frequency |
438 | | range |
439 | | */ |
440 | |
|
441 | 0 | { |
442 | 0 | KEEP_STATES_SYNCED_MODE keepStatesSyncedMode = |
443 | 0 | ((flags & SBRDEC_USAC_HARMONICSBR) && |
444 | 0 | (hFrameData->sbrPatchingMode != 0)) |
445 | 0 | ? KEEP_STATES_SYNCED_NORMAL |
446 | 0 | : KEEP_STATES_SYNCED_OFF; |
447 | |
|
448 | 0 | if (flags & SBRDEC_USAC_HARMONICSBR) { |
449 | 0 | if (flags & SBRDEC_QUAD_RATE) { |
450 | 0 | pReal -= 32; |
451 | 0 | pImag -= 32; |
452 | 0 | } |
453 | |
|
454 | 0 | if ((hSbrDec->savedStates == 0) && (hFrameData->sbrPatchingMode == 1)) { |
455 | | /* copy saved states from previous frame to legacy SBR lpc filterstate |
456 | | * buffer */ |
457 | 0 | for (i = 0; i < LPC_ORDER + ov_len; i++) { |
458 | 0 | FDKmemcpy( |
459 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], |
460 | 0 | hSbrDec->codecQMFBufferReal[noCols - LPC_ORDER - ov_len + i], |
461 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
462 | 0 | FDKmemcpy( |
463 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], |
464 | 0 | hSbrDec->codecQMFBufferImag[noCols - LPC_ORDER - ov_len + i], |
465 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
466 | 0 | } |
467 | 0 | } |
468 | | |
469 | | /* saving unmodified QMF states in case we are switching from legacy SBR |
470 | | * to HBE */ |
471 | 0 | for (i = 0; i < hSbrDec->hHBE->noCols; i++) { |
472 | 0 | FDKmemcpy(hSbrDec->codecQMFBufferReal[i], pLowBandReal[ov_len + i], |
473 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
474 | 0 | FDKmemcpy(hSbrDec->codecQMFBufferImag[i], pLowBandImag[ov_len + i], |
475 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
476 | 0 | } |
477 | |
|
478 | 0 | QmfTransposerApply( |
479 | 0 | hSbrDec->hHBE, pReal, pImag, noCols, pLowBandReal, pLowBandImag, |
480 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealHBE, |
481 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagHBE, |
482 | 0 | hFrameData->sbrPitchInBins, hSbrDec->scale_lb, hSbrDec->scale_hbe, |
483 | 0 | &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep, |
484 | 0 | borders[0], ov_len, keepStatesSyncedMode); |
485 | |
|
486 | 0 | if (flags & SBRDEC_QUAD_RATE) { |
487 | 0 | int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE); |
488 | |
|
489 | 0 | copyHarmonicSpectrum(xOverQmf, pLowBandReal, pLowBandImag, noCols, |
490 | 0 | ov_len, keepStatesSyncedMode); |
491 | 0 | } |
492 | 0 | } |
493 | 0 | } |
494 | |
|
495 | 0 | if ((flags & SBRDEC_USAC_HARMONICSBR) && |
496 | 0 | (hFrameData->sbrPatchingMode == 0)) { |
497 | 0 | hSbrDec->prev_frame_lSbr = 0; |
498 | 0 | hSbrDec->prev_frame_hbeSbr = 1; |
499 | |
|
500 | 0 | lppTransposerHBE( |
501 | 0 | &hSbrDec->LppTrans, hSbrDec->hHBE, &hSbrDec->qmfDomainInCh->scaling, |
502 | 0 | pLowBandReal, pLowBandImag, hHeaderData->timeStep, borders[0], |
503 | 0 | lastSlotOffs, hHeaderData->freqBandData.nInvfBands, |
504 | 0 | hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode); |
505 | |
|
506 | 0 | } else { |
507 | 0 | if (flags & SBRDEC_USAC_HARMONICSBR) { |
508 | 0 | for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) { |
509 | | /* |
510 | | Store the unmodified qmf Slots values for upper part of spectrum |
511 | | (required for LPC filtering) required if next frame is a HBE frame |
512 | | */ |
513 | 0 | FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealHBE[i], |
514 | 0 | hSbrDec->qmfDomainInCh |
515 | 0 | ->hQmfSlotsReal[hSbrDec->hHBE->noCols - LPC_ORDER + i], |
516 | 0 | (64) * sizeof(FIXP_DBL)); |
517 | 0 | FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagHBE[i], |
518 | 0 | hSbrDec->qmfDomainInCh |
519 | 0 | ->hQmfSlotsImag[hSbrDec->hHBE->noCols - LPC_ORDER + i], |
520 | 0 | (64) * sizeof(FIXP_DBL)); |
521 | 0 | } |
522 | 0 | } |
523 | 0 | { |
524 | 0 | hSbrDec->prev_frame_lSbr = 1; |
525 | 0 | hSbrDec->prev_frame_hbeSbr = 0; |
526 | 0 | } |
527 | |
|
528 | 0 | lppTransposer( |
529 | 0 | &hSbrDec->LppTrans, &hSbrDec->qmfDomainInCh->scaling, pLowBandReal, |
530 | 0 | degreeAlias, // only used if useLP = 1 |
531 | 0 | pLowBandImag, flags & SBRDEC_LOW_POWER, |
532 | 0 | hHeaderData->bs_info.sbr_preprocessing, |
533 | 0 | hHeaderData->freqBandData.v_k_master[0], hHeaderData->timeStep, |
534 | 0 | borders[0], lastSlotOffs, hHeaderData->freqBandData.nInvfBands, |
535 | 0 | hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode); |
536 | 0 | } |
537 | | |
538 | | /* |
539 | | Adjust envelope of current frame. |
540 | | */ |
541 | |
|
542 | 0 | if ((hFrameData->sbrPatchingMode != |
543 | 0 | hSbrDec->SbrCalculateEnvelope.sbrPatchingMode)) { |
544 | 0 | ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable, |
545 | 0 | &hHeaderData->freqBandData.noLimiterBands, |
546 | 0 | hHeaderData->freqBandData.freqBandTable[0], |
547 | 0 | hHeaderData->freqBandData.nSfb[0], |
548 | 0 | hSbrDec->LppTrans.pSettings->patchParam, |
549 | 0 | hSbrDec->LppTrans.pSettings->noOfPatches, |
550 | 0 | hHeaderData->bs_data.limiterBands, |
551 | 0 | hFrameData->sbrPatchingMode, |
552 | 0 | (flags & SBRDEC_USAC_HARMONICSBR) && |
553 | 0 | (hFrameData->sbrPatchingMode == 0) |
554 | 0 | ? GetxOverBandQmfTransposer(hSbrDec->hHBE) |
555 | 0 | : NULL, |
556 | 0 | Get41SbrQmfTransposer(hSbrDec->hHBE)); |
557 | |
|
558 | 0 | hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = |
559 | 0 | hFrameData->sbrPatchingMode; |
560 | 0 | } |
561 | |
|
562 | 0 | calculateSbrEnvelope( |
563 | 0 | &hSbrDec->qmfDomainInCh->scaling, &hSbrDec->SbrCalculateEnvelope, |
564 | 0 | hHeaderData, hFrameData, &pvcDynamicData, pLowBandReal, pLowBandImag, |
565 | 0 | flags & SBRDEC_LOW_POWER, |
566 | |
|
567 | 0 | degreeAlias, flags, |
568 | 0 | (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag)); |
569 | |
|
570 | | #if (SBRDEC_MAX_HB_FADE_FRAMES > 0) |
571 | | /* Avoid hard onsets of high band */ |
572 | | if (hHeaderData->frameErrorFlag) { |
573 | | if (hSbrDec->highBandFadeCnt < SBRDEC_MAX_HB_FADE_FRAMES) { |
574 | | hSbrDec->highBandFadeCnt += 1; |
575 | | } |
576 | | } else { |
577 | | if (hSbrDec->highBandFadeCnt > |
578 | | 0) { /* Manipulate high band scale factor to get a smooth fade-in */ |
579 | | hSbrDec->qmfDomainInCh->scaling.hb_scale += hSbrDec->highBandFadeCnt; |
580 | | hSbrDec->qmfDomainInCh->scaling.hb_scale = |
581 | | fMin(hSbrDec->qmfDomainInCh->scaling.hb_scale, DFRACT_BITS - 1); |
582 | | hSbrDec->highBandFadeCnt -= 1; |
583 | | } |
584 | | } |
585 | | |
586 | | #endif |
587 | | /* |
588 | | Update hPrevFrameData (to be used in the next frame) |
589 | | */ |
590 | 0 | for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { |
591 | 0 | hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i]; |
592 | 0 | } |
593 | 0 | hPrevFrameData->coupling = hFrameData->coupling; |
594 | 0 | hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes]; |
595 | 0 | hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame; |
596 | 0 | hPrevFrameData->prevSbrPitchInBins = hFrameData->sbrPitchInBins; |
597 | | /* could be done in extractFrameInfo_pvc() but hPrevFrameData is not |
598 | | * available there */ |
599 | 0 | FDKmemcpy(&hPrevFrameData->prevFrameInfo, &hFrameData->frameInfo, |
600 | 0 | sizeof(FRAME_INFO)); |
601 | 0 | } else { |
602 | | /* rescale from lsb to nAnalysisBands in order to compensate scaling with |
603 | | * hb_scale in this area, done by synthesisFiltering*/ |
604 | 0 | int rescale; |
605 | 0 | int lsb; |
606 | 0 | int length; |
607 | | |
608 | | /* Reset hb_scale if no highband is present, because hb_scale is considered |
609 | | * in the QMF-synthesis */ |
610 | 0 | hSbrDec->qmfDomainInCh->scaling.hb_scale = saveLbScale; |
611 | |
|
612 | 0 | rescale = hSbrDec->qmfDomainInCh->scaling.hb_scale - |
613 | 0 | hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; |
614 | 0 | lsb = hSbrDec->qmfDomainOutCh->fb.lsb; |
615 | 0 | length = (hSbrDec->qmfDomainInCh->fb.no_channels - lsb); |
616 | |
|
617 | 0 | if ((rescale < 0) && (length > 0)) { |
618 | 0 | if (!(flags & SBRDEC_LOW_POWER)) { |
619 | 0 | for (i = 0; i < ov_len; i++) { |
620 | 0 | scaleValues(&pLowBandReal[i][lsb], length, rescale); |
621 | 0 | scaleValues(&pLowBandImag[i][lsb], length, rescale); |
622 | 0 | } |
623 | 0 | } else { |
624 | 0 | for (i = 0; i < ov_len; i++) { |
625 | 0 | scaleValues(&pLowBandReal[i][lsb], length, rescale); |
626 | 0 | } |
627 | 0 | } |
628 | 0 | } |
629 | 0 | } |
630 | |
|
631 | 0 | if (!(flags & SBRDEC_USAC_HARMONICSBR)) { |
632 | 0 | int length = hSbrDec->qmfDomainInCh->fb.lsb; |
633 | 0 | if (flags & SBRDEC_SYNTAX_USAC) { |
634 | 0 | length = hSbrDec->qmfDomainInCh->fb.no_channels; |
635 | 0 | } |
636 | | |
637 | | /* in case of legacy sbr saving of filter states here */ |
638 | 0 | for (i = 0; i < LPC_ORDER + ov_len; i++) { |
639 | | /* |
640 | | Store the unmodified qmf Slots values (required for LPC filtering) |
641 | | */ |
642 | 0 | if (!(flags & SBRDEC_LOW_POWER)) { |
643 | 0 | FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], |
644 | 0 | pLowBandReal[noCols - LPC_ORDER + i], |
645 | 0 | length * sizeof(FIXP_DBL)); |
646 | 0 | FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], |
647 | 0 | pLowBandImag[noCols - LPC_ORDER + i], |
648 | 0 | length * sizeof(FIXP_DBL)); |
649 | 0 | } else |
650 | 0 | FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], |
651 | 0 | pLowBandReal[noCols - LPC_ORDER + i], |
652 | 0 | length * sizeof(FIXP_DBL)); |
653 | 0 | } |
654 | 0 | } |
655 | | |
656 | | /* |
657 | | Synthesis subband filtering. |
658 | | */ |
659 | |
|
660 | 0 | if (!(flags & SBRDEC_PS_DECODED)) { |
661 | 0 | if (!(flags & SBRDEC_SKIP_QMF_SYN)) { |
662 | 0 | int outScalefactor = -(8); |
663 | |
|
664 | 0 | if (h_ps_d != NULL) { |
665 | 0 | h_ps_d->procFrameBased = 1; /* we here do frame based processing */ |
666 | 0 | } |
667 | |
|
668 | 0 | sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel, pLowBandReal, |
669 | 0 | (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag, |
670 | 0 | hSbrDec->qmfDomainOutCh->fb.no_col, &outScalefactor); |
671 | |
|
672 | 0 | qmfChangeOutScalefactor(&hSbrDec->qmfDomainOutCh->fb, outScalefactor); |
673 | |
|
674 | 0 | { |
675 | 0 | HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; |
676 | 0 | int save_usb = hSbrDec->qmfDomainOutCh->fb.usb; |
677 | |
|
678 | 0 | #if (QMF_MAX_SYNTHESIS_BANDS <= 64) |
679 | 0 | C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
680 | | #else |
681 | | C_AALLOC_STACK_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
682 | | #endif |
683 | 0 | if (hSbrDec->qmfDomainOutCh->fb.usb < hFreq->ov_highSubband) { |
684 | | /* we need to patch usb for this frame as overlap may contain higher |
685 | | frequency range if headerchange occured; fb. usb is always limited |
686 | | to maximum fb.no_channels; In case of wrongly decoded headers it |
687 | | might be that ov_highSubband is higher than the number of synthesis |
688 | | channels (fb.no_channels), which is forbidden, therefore we need to |
689 | | limit ov_highSubband with fMin function to avoid not allowed usb in |
690 | | synthesis filterbank. */ |
691 | 0 | hSbrDec->qmfDomainOutCh->fb.usb = |
692 | 0 | fMin((UINT)hFreq->ov_highSubband, |
693 | 0 | (UINT)hSbrDec->qmfDomainOutCh->fb.no_channels); |
694 | 0 | } |
695 | 0 | { |
696 | 0 | qmfSynthesisFiltering( |
697 | 0 | &hSbrDec->qmfDomainOutCh->fb, pLowBandReal, |
698 | 0 | (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag, |
699 | 0 | &hSbrDec->qmfDomainInCh->scaling, |
700 | 0 | hSbrDec->LppTrans.pSettings->overlap, timeOut, strideOut, |
701 | 0 | qmfTemp); |
702 | 0 | } |
703 | | /* restore saved value */ |
704 | 0 | hSbrDec->qmfDomainOutCh->fb.usb = save_usb; |
705 | 0 | hFreq->ov_highSubband = save_usb; |
706 | 0 | #if (QMF_MAX_SYNTHESIS_BANDS <= 64) |
707 | 0 | C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
708 | | #else |
709 | | C_AALLOC_STACK_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
710 | | #endif |
711 | 0 | } |
712 | 0 | } |
713 | |
|
714 | 0 | } else { /* (flags & SBRDEC_PS_DECODED) */ |
715 | 0 | INT sdiff; |
716 | 0 | INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov, |
717 | 0 | outScalefactor, outScalefactorR, outScalefactorL; |
718 | |
|
719 | 0 | HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb; |
720 | 0 | HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb; |
721 | | |
722 | | /* adapt scaling */ |
723 | 0 | sdiff = hSbrDec->qmfDomainInCh->scaling.lb_scale - |
724 | 0 | reserve; /* Scaling difference */ |
725 | 0 | scaleFactorHighBand = sdiff - hSbrDec->qmfDomainInCh->scaling.hb_scale; |
726 | 0 | scaleFactorLowBand_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; |
727 | 0 | scaleFactorLowBand_no_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.lb_scale; |
728 | | |
729 | | /* Scale of low band overlapping QMF data */ |
730 | 0 | scaleFactorLowBand_ov = |
731 | 0 | fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_ov)); |
732 | | /* Scale of low band current QMF data */ |
733 | 0 | scaleFactorLowBand_no_ov = fMin( |
734 | 0 | DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_no_ov)); |
735 | | /* Scale of current high band */ |
736 | 0 | scaleFactorHighBand = |
737 | 0 | fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorHighBand)); |
738 | |
|
739 | 0 | if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot |
740 | | based processing copy filter states */ |
741 | 0 | { /* procFrameBased will be unset later */ |
742 | | /* copy filter states from left to right */ |
743 | | /* was ((640)-(64))*sizeof(FIXP_QSS) |
744 | | flexible amount of synthesis bands needed for QMF based resampling |
745 | | */ |
746 | 0 | FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= |
747 | 0 | QMF_MAX_SYNTHESIS_BANDS); |
748 | 0 | synQmfRight->outScalefactor = synQmf->outScalefactor; |
749 | 0 | FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, |
750 | 0 | 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * |
751 | 0 | sizeof(FIXP_QSS)); |
752 | 0 | } |
753 | | |
754 | | /* Feed delaylines when parametric stereo is switched on. */ |
755 | 0 | PreparePsProcessing(h_ps_d, pLowBandReal, pLowBandImag, |
756 | 0 | scaleFactorLowBand_ov); |
757 | | |
758 | | /* use the same synthese qmf values for left and right channel */ |
759 | 0 | synQmfRight->no_col = synQmf->no_col; |
760 | 0 | synQmfRight->lsb = synQmf->lsb; |
761 | 0 | synQmfRight->usb = synQmf->usb; |
762 | |
|
763 | 0 | int env = 0; |
764 | |
|
765 | 0 | { |
766 | 0 | #if (QMF_MAX_SYNTHESIS_BANDS <= 64) |
767 | 0 | C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, |
768 | 0 | 2 * QMF_MAX_SYNTHESIS_BANDS); |
769 | | #else |
770 | | C_AALLOC_STACK_START(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
771 | | #endif |
772 | |
|
773 | 0 | int maxShift = 0; |
774 | |
|
775 | 0 | if (hSbrDec->sbrDrcChannel.enable != 0) { |
776 | 0 | if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) { |
777 | 0 | maxShift = hSbrDec->sbrDrcChannel.prevFact_exp; |
778 | 0 | } |
779 | 0 | if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) { |
780 | 0 | maxShift = hSbrDec->sbrDrcChannel.currFact_exp; |
781 | 0 | } |
782 | 0 | if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) { |
783 | 0 | maxShift = hSbrDec->sbrDrcChannel.nextFact_exp; |
784 | 0 | } |
785 | 0 | } |
786 | | |
787 | | /* copy DRC data to right channel (with PS both channels use the same DRC |
788 | | * gains) */ |
789 | 0 | FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, |
790 | 0 | sizeof(SBRDEC_DRC_CHANNEL)); |
791 | |
|
792 | 0 | outScalefactor = maxShift - (8); |
793 | 0 | outScalefactorL = outScalefactorR = |
794 | 0 | sbrInDataHeadroom + 1; /* +1: psDiffScale! (MPEG-PS) */ |
795 | |
|
796 | 0 | for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ |
797 | | |
798 | | /* qmf timeslot of right channel */ |
799 | 0 | FIXP_DBL *rQmfReal = pWorkBuffer; |
800 | 0 | FIXP_DBL *rQmfImag = pWorkBuffer + synQmf->no_channels; |
801 | |
|
802 | 0 | { |
803 | 0 | if (i == |
804 | 0 | h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]) { |
805 | 0 | initSlotBasedRotation(h_ps_d, env, |
806 | 0 | hHeaderData->freqBandData.highSubband); |
807 | 0 | env++; |
808 | 0 | } |
809 | |
|
810 | 0 | ApplyPsSlot( |
811 | 0 | h_ps_d, /* parametric stereo decoder handle */ |
812 | 0 | (pLowBandReal + i), /* one timeslot of left/mono channel */ |
813 | 0 | (pLowBandImag + i), /* one timeslot of left/mono channel */ |
814 | 0 | rQmfReal, /* one timeslot or right channel */ |
815 | 0 | rQmfImag, /* one timeslot or right channel */ |
816 | 0 | scaleFactorLowBand_no_ov, |
817 | 0 | (i < hSbrDec->LppTrans.pSettings->overlap) |
818 | 0 | ? scaleFactorLowBand_ov |
819 | 0 | : scaleFactorLowBand_no_ov, |
820 | 0 | scaleFactorHighBand, synQmf->lsb, synQmf->usb); |
821 | 0 | } |
822 | |
|
823 | 0 | sbrDecoder_drcApplySlot(/* right channel */ |
824 | 0 | &hSbrDecRight->sbrDrcChannel, rQmfReal, |
825 | 0 | rQmfImag, i, synQmfRight->no_col, maxShift); |
826 | |
|
827 | 0 | sbrDecoder_drcApplySlot(/* left channel */ |
828 | 0 | &hSbrDec->sbrDrcChannel, *(pLowBandReal + i), |
829 | 0 | *(pLowBandImag + i), i, synQmf->no_col, |
830 | 0 | maxShift); |
831 | |
|
832 | 0 | if (!(flags & SBRDEC_SKIP_QMF_SYN)) { |
833 | 0 | qmfChangeOutScalefactor(synQmf, outScalefactor); |
834 | 0 | qmfChangeOutScalefactor(synQmfRight, outScalefactor); |
835 | |
|
836 | 0 | qmfSynthesisFilteringSlot( |
837 | 0 | synQmfRight, rQmfReal, /* QMF real buffer */ |
838 | 0 | rQmfImag, /* QMF imag buffer */ |
839 | 0 | outScalefactorL, outScalefactorL, |
840 | 0 | timeOutRight + (i * synQmf->no_channels * strideOut), strideOut, |
841 | 0 | pWorkBuffer); |
842 | |
|
843 | 0 | qmfSynthesisFilteringSlot( |
844 | 0 | synQmf, *(pLowBandReal + i), /* QMF real buffer */ |
845 | 0 | *(pLowBandImag + i), /* QMF imag buffer */ |
846 | 0 | outScalefactorR, outScalefactorR, |
847 | 0 | timeOut + (i * synQmf->no_channels * strideOut), strideOut, |
848 | 0 | pWorkBuffer); |
849 | 0 | } |
850 | 0 | } /* no_col loop i */ |
851 | 0 | #if (QMF_MAX_SYNTHESIS_BANDS <= 64) |
852 | 0 | C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
853 | | #else |
854 | | C_AALLOC_STACK_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); |
855 | | #endif |
856 | 0 | } |
857 | 0 | } |
858 | | |
859 | 0 | sbrDecoder_drcUpdateChannel(&hSbrDec->sbrDrcChannel); |
860 | | |
861 | | /* |
862 | | Update overlap buffer |
863 | | Even bands above usb are copied to avoid outdated spectral data in case |
864 | | the stop frequency raises. |
865 | | */ |
866 | |
|
867 | 0 | if (!(flags & SBRDEC_SKIP_QMF_SYN)) { |
868 | 0 | { |
869 | 0 | FDK_QmfDomain_SaveOverlap(hSbrDec->qmfDomainInCh, 0); |
870 | 0 | FDK_ASSERT(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale == saveLbScale); |
871 | 0 | } |
872 | 0 | } |
873 | | |
874 | 0 | hSbrDec->savedStates = 0; |
875 | | |
876 | | /* Save current frame status */ |
877 | 0 | hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag; |
878 | 0 | hSbrDec->applySbrProc_old = applyProcessing; |
879 | |
|
880 | 0 | } /* sbr_dec() */ |
881 | | |
882 | | /*! |
883 | | \brief Creates sbr decoder structure |
884 | | \return errorCode, 0 if successful |
885 | | */ |
886 | | SBR_ERROR |
887 | | createSbrDec(SBR_CHANNEL *hSbrChannel, |
888 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
889 | | TRANSPOSER_SETTINGS *pSettings, |
890 | | const int downsampleFac, /*!< Downsampling factor */ |
891 | | const UINT qmfFlags, /*!< flags -> 1: HQ/LP selector, 2: CLDFB */ |
892 | | const UINT flags, const int overlap, |
893 | | int chan, /*!< Channel for which to assign buffers etc. */ |
894 | | int codecFrameSize) |
895 | | |
896 | 1.55k | { |
897 | 1.55k | SBR_ERROR err = SBRDEC_OK; |
898 | 1.55k | int timeSlots = |
899 | 1.55k | hHeaderData->numberTimeSlots; /* Number of SBR slots per frame */ |
900 | 1.55k | int noCols = |
901 | 1.55k | timeSlots * hHeaderData->timeStep; /* Number of QMF slots per frame */ |
902 | 1.55k | HANDLE_SBR_DEC hs = &(hSbrChannel->SbrDec); |
903 | | |
904 | | #if (SBRDEC_MAX_HB_FADE_FRAMES > 0) |
905 | | hs->highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES; |
906 | | |
907 | | #endif |
908 | 1.55k | hs->scale_hbe = 15; |
909 | 1.55k | hs->scale_lb = 15; |
910 | 1.55k | hs->scale_ov = 15; |
911 | | |
912 | 1.55k | hs->prev_frame_lSbr = 0; |
913 | 1.55k | hs->prev_frame_hbeSbr = 0; |
914 | | |
915 | 1.55k | hs->codecFrameSize = codecFrameSize; |
916 | | |
917 | | /* |
918 | | create envelope calculator |
919 | | */ |
920 | 1.55k | err = createSbrEnvelopeCalc(&hs->SbrCalculateEnvelope, hHeaderData, chan, |
921 | 1.55k | flags); |
922 | 1.55k | if (err != SBRDEC_OK) { |
923 | 17 | return err; |
924 | 17 | } |
925 | | |
926 | 1.54k | initSbrPrevFrameData(&hSbrChannel->prevFrameData, timeSlots); |
927 | | |
928 | | /* |
929 | | create transposer |
930 | | */ |
931 | 1.54k | err = createLppTransposer( |
932 | 1.54k | &hs->LppTrans, pSettings, hHeaderData->freqBandData.lowSubband, |
933 | 1.54k | hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, |
934 | 1.54k | hHeaderData->freqBandData.highSubband, timeSlots, noCols, |
935 | 1.54k | hHeaderData->freqBandData.freqBandTableNoise, |
936 | 1.54k | hHeaderData->freqBandData.nNfb, hHeaderData->sbrProcSmplRate, chan, |
937 | 1.54k | overlap); |
938 | 1.54k | if (err != SBRDEC_OK) { |
939 | 10 | return err; |
940 | 10 | } |
941 | | |
942 | 1.53k | if (flags & SBRDEC_USAC_HARMONICSBR) { |
943 | 49 | int noChannels, bSbr41 = flags & SBRDEC_QUAD_RATE ? 1 : 0; |
944 | | |
945 | 49 | noChannels = |
946 | 49 | QMF_SYNTH_CHANNELS / |
947 | 49 | ((bSbr41 + 1) * 2); /* 32 for (32:64 and 24:64) and 16 for 16:64 */ |
948 | | |
949 | | /* shared memory between hbeLightTimeDelayBuffer and hQmfHBESlotsReal if |
950 | | * SBRDEC_HBE_ENABLE */ |
951 | 49 | hSbrChannel->SbrDec.tmp_memory = (FIXP_DBL **)fdkCallocMatrix2D_aligned( |
952 | 49 | noCols, noChannels, sizeof(FIXP_DBL)); |
953 | 49 | if (hSbrChannel->SbrDec.tmp_memory == NULL) { |
954 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
955 | 0 | } |
956 | | |
957 | 49 | hSbrChannel->SbrDec.hQmfHBESlotsReal = hSbrChannel->SbrDec.tmp_memory; |
958 | 49 | hSbrChannel->SbrDec.hQmfHBESlotsImag = |
959 | 49 | (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, |
960 | 49 | sizeof(FIXP_DBL)); |
961 | 49 | if (hSbrChannel->SbrDec.hQmfHBESlotsImag == NULL) { |
962 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
963 | 0 | } |
964 | | |
965 | | /* buffers containing unmodified qmf data; required when switching from |
966 | | * legacy SBR to HBE */ |
967 | | /* buffer can be used as LPCFilterstates buffer because legacy SBR needs |
968 | | * exactly these values for LPC filtering */ |
969 | 49 | hSbrChannel->SbrDec.codecQMFBufferReal = |
970 | 49 | (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, |
971 | 49 | sizeof(FIXP_DBL)); |
972 | 49 | if (hSbrChannel->SbrDec.codecQMFBufferReal == NULL) { |
973 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
974 | 0 | } |
975 | | |
976 | 49 | hSbrChannel->SbrDec.codecQMFBufferImag = |
977 | 49 | (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, |
978 | 49 | sizeof(FIXP_DBL)); |
979 | 49 | if (hSbrChannel->SbrDec.codecQMFBufferImag == NULL) { |
980 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
981 | 0 | } |
982 | | |
983 | 49 | err = QmfTransposerCreate(&hs->hHBE, codecFrameSize, 0, bSbr41); |
984 | 49 | if (err != SBRDEC_OK) { |
985 | 0 | return err; |
986 | 0 | } |
987 | 49 | } |
988 | | |
989 | 1.53k | return err; |
990 | 1.53k | } |
991 | | |
992 | | /*! |
993 | | \brief Delete sbr decoder structure |
994 | | \return errorCode, 0 if successful |
995 | | */ |
996 | 1.60k | int deleteSbrDec(SBR_CHANNEL *hSbrChannel) { |
997 | 1.60k | HANDLE_SBR_DEC hs = &hSbrChannel->SbrDec; |
998 | | |
999 | 1.60k | deleteSbrEnvelopeCalc(&hs->SbrCalculateEnvelope); |
1000 | | |
1001 | 1.60k | if (hs->tmp_memory != NULL) { |
1002 | 49 | FDK_FREE_MEMORY_2D_ALIGNED(hs->tmp_memory); |
1003 | 49 | } |
1004 | | |
1005 | | /* modify here */ |
1006 | 1.60k | FDK_FREE_MEMORY_2D_ALIGNED(hs->hQmfHBESlotsImag); |
1007 | | |
1008 | 1.60k | if (hs->hHBE != NULL) QmfTransposerClose(hs->hHBE); |
1009 | | |
1010 | 1.60k | if (hs->codecQMFBufferReal != NULL) { |
1011 | 49 | FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferReal); |
1012 | 49 | } |
1013 | | |
1014 | 1.60k | if (hs->codecQMFBufferImag != NULL) { |
1015 | 49 | FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferImag); |
1016 | 49 | } |
1017 | | |
1018 | 1.60k | return 0; |
1019 | 1.60k | } |
1020 | | |
1021 | | /*! |
1022 | | \brief resets sbr decoder structure |
1023 | | \return errorCode, 0 if successful |
1024 | | */ |
1025 | | SBR_ERROR |
1026 | | resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData, |
1027 | | HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac, |
1028 | 0 | const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData) { |
1029 | 0 | SBR_ERROR sbrError = SBRDEC_OK; |
1030 | 0 | int i; |
1031 | 0 | FIXP_DBL *pLowBandReal[128]; |
1032 | 0 | FIXP_DBL *pLowBandImag[128]; |
1033 | 0 | int useLP = flags & SBRDEC_LOW_POWER; |
1034 | |
|
1035 | 0 | int old_lsb = hSbrDec->qmfDomainInCh->fb.lsb; |
1036 | 0 | int old_usb = hSbrDec->qmfDomainInCh->fb.usb; |
1037 | 0 | int new_lsb = hHeaderData->freqBandData.lowSubband; |
1038 | | /* int new_usb = hHeaderData->freqBandData.highSubband; */ |
1039 | 0 | int l, startBand, stopBand, startSlot, size; |
1040 | |
|
1041 | 0 | FIXP_DBL **OverlapBufferReal = hSbrDec->qmfDomainInCh->hQmfSlotsReal; |
1042 | 0 | FIXP_DBL **OverlapBufferImag = hSbrDec->qmfDomainInCh->hQmfSlotsImag; |
1043 | | |
1044 | | /* in case the previous frame was not active in terms of SBR processing, the |
1045 | | full band from 0 to no_channels was rescaled and not overwritten. Thats why |
1046 | | the scaling factor lb_scale can be seen as assigned to all bands from 0 to |
1047 | | no_channels in the previous frame. The same states for the current frame if |
1048 | | the current frame is not active in terms of SBR processing |
1049 | | */ |
1050 | 0 | int applySbrProc = (hHeaderData->syncState == SBR_ACTIVE || |
1051 | 0 | (hHeaderData->frameErrorFlag == 0 && |
1052 | 0 | hHeaderData->syncState == SBR_HEADER)); |
1053 | 0 | int applySbrProc_old = hSbrDec->applySbrProc_old; |
1054 | |
|
1055 | 0 | if (!applySbrProc) { |
1056 | 0 | new_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels; |
1057 | 0 | } |
1058 | 0 | if (!applySbrProc_old) { |
1059 | 0 | old_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels; |
1060 | 0 | old_usb = old_lsb; |
1061 | 0 | } |
1062 | |
|
1063 | 0 | resetSbrEnvelopeCalc(&hSbrDec->SbrCalculateEnvelope); |
1064 | | |
1065 | | /* Change lsb and usb */ |
1066 | | /* Synthesis */ |
1067 | 0 | FDK_ASSERT(hSbrDec->qmfDomainOutCh != NULL); |
1068 | 0 | hSbrDec->qmfDomainOutCh->fb.lsb = |
1069 | 0 | fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels, |
1070 | 0 | (INT)hHeaderData->freqBandData.lowSubband); |
1071 | 0 | hSbrDec->qmfDomainOutCh->fb.usb = |
1072 | 0 | fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels, |
1073 | 0 | (INT)hHeaderData->freqBandData.highSubband); |
1074 | | /* Analysis */ |
1075 | 0 | FDK_ASSERT(hSbrDec->qmfDomainInCh != NULL); |
1076 | 0 | hSbrDec->qmfDomainInCh->fb.lsb = hSbrDec->qmfDomainOutCh->fb.lsb; |
1077 | 0 | hSbrDec->qmfDomainInCh->fb.usb = hSbrDec->qmfDomainOutCh->fb.usb; |
1078 | | |
1079 | | /* |
1080 | | The following initialization of spectral data in the overlap buffer |
1081 | | is required for dynamic x-over or a change of the start-freq for 2 reasons: |
1082 | | |
1083 | | 1. If the lowband gets _wider_, unadjusted data would remain |
1084 | | |
1085 | | 2. If the lowband becomes _smaller_, the highest bands of the old lowband |
1086 | | must be cleared because the whitening would be affected |
1087 | | */ |
1088 | 0 | startBand = old_lsb; |
1089 | 0 | stopBand = new_lsb; |
1090 | 0 | startSlot = fMax(0, hHeaderData->timeStep * (hPrevFrameData->stopPos - |
1091 | 0 | hHeaderData->numberTimeSlots)); |
1092 | 0 | size = fMax(0, stopBand - startBand); |
1093 | | |
1094 | | /* in case of USAC we don't want to zero out the memory, as this can lead to |
1095 | | holes in the spectrum; fix shall only be applied for USAC not for MPEG-4 |
1096 | | SBR, in this case setting zero remains */ |
1097 | 0 | if (!(flags & SBRDEC_SYNTAX_USAC)) { |
1098 | | /* keep already adjusted data in the x-over-area */ |
1099 | 0 | if (!useLP) { |
1100 | 0 | for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { |
1101 | 0 | FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL)); |
1102 | 0 | FDKmemclear(&OverlapBufferImag[l][startBand], size * sizeof(FIXP_DBL)); |
1103 | 0 | } |
1104 | 0 | } else { |
1105 | 0 | for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { |
1106 | 0 | FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL)); |
1107 | 0 | } |
1108 | 0 | } |
1109 | | |
1110 | | /* |
1111 | | reset LPC filter states |
1112 | | */ |
1113 | 0 | startBand = fixMin(old_lsb, new_lsb); |
1114 | 0 | stopBand = fixMax(old_lsb, new_lsb); |
1115 | 0 | size = fixMax(0, stopBand - startBand); |
1116 | |
|
1117 | 0 | FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[0][startBand], |
1118 | 0 | size * sizeof(FIXP_DBL)); |
1119 | 0 | FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[1][startBand], |
1120 | 0 | size * sizeof(FIXP_DBL)); |
1121 | 0 | if (!useLP) { |
1122 | 0 | FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[0][startBand], |
1123 | 0 | size * sizeof(FIXP_DBL)); |
1124 | 0 | FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[1][startBand], |
1125 | 0 | size * sizeof(FIXP_DBL)); |
1126 | 0 | } |
1127 | 0 | } |
1128 | |
|
1129 | 0 | if (startSlot != 0) { |
1130 | 0 | int source_exp, target_exp, delta_exp, target_lsb, target_usb, reserve; |
1131 | 0 | FIXP_DBL maxVal; |
1132 | | |
1133 | | /* |
1134 | | Rescale already processed spectral data between old and new x-over |
1135 | | frequency. This must be done because of the separate scalefactors for |
1136 | | lowband and highband. |
1137 | | */ |
1138 | | |
1139 | | /* We have four relevant transitions to cover: |
1140 | | 1. old_usb is lower than new_lsb; old SBR area is completely below new SBR |
1141 | | area. |
1142 | | -> entire old area was highband and belongs to lowband now |
1143 | | and has to be rescaled. |
1144 | | 2. old_lsb is higher than new_usb; new SBR area is completely below old SBR |
1145 | | area. |
1146 | | -> old area between new_lsb and old_lsb was lowband and belongs to |
1147 | | highband now and has to be rescaled to match new highband scale. |
1148 | | 3. old_lsb is lower and old_usb is higher than new_lsb; old and new SBR |
1149 | | areas overlap. |
1150 | | -> old area between old_lsb and new_lsb was highband and belongs to |
1151 | | lowband now and has to be rescaled to match new lowband scale. |
1152 | | 4. new_lsb is lower and new_usb_is higher than old_lsb; old and new SBR |
1153 | | areas overlap. |
1154 | | -> old area between new_lsb and old_usb was lowband and belongs to |
1155 | | highband now and has to be rescaled to match new highband scale. |
1156 | | */ |
1157 | |
|
1158 | 0 | if (new_lsb > old_lsb) { |
1159 | | /* case 1 and 3 */ |
1160 | 0 | source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale); |
1161 | 0 | target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale); |
1162 | |
|
1163 | 0 | startBand = old_lsb; |
1164 | |
|
1165 | 0 | if (new_lsb >= old_usb) { |
1166 | | /* case 1 */ |
1167 | 0 | stopBand = old_usb; |
1168 | 0 | } else { |
1169 | | /* case 3 */ |
1170 | 0 | stopBand = new_lsb; |
1171 | 0 | } |
1172 | |
|
1173 | 0 | target_lsb = 0; |
1174 | 0 | target_usb = old_lsb; |
1175 | 0 | } else { |
1176 | | /* case 2 and 4 */ |
1177 | 0 | source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale); |
1178 | 0 | target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale); |
1179 | |
|
1180 | 0 | startBand = new_lsb; |
1181 | 0 | stopBand = old_lsb; |
1182 | |
|
1183 | 0 | target_lsb = old_lsb; |
1184 | 0 | target_usb = old_usb; |
1185 | 0 | } |
1186 | |
|
1187 | 0 | maxVal = |
1188 | 0 | maxSubbandSample(OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, |
1189 | 0 | startBand, stopBand, 0, startSlot); |
1190 | |
|
1191 | 0 | reserve = ((LONG)maxVal != 0 ? CntLeadingZeros(maxVal) - 1 : 0); |
1192 | 0 | reserve = fixMin( |
1193 | 0 | reserve, |
1194 | 0 | DFRACT_BITS - 1 - |
1195 | 0 | EXP2SCALE( |
1196 | 0 | source_exp)); /* what is this line for, why do we need it? */ |
1197 | | |
1198 | | /* process only if x-over-area is not dominant after rescale; |
1199 | | otherwise I'm not sure if all buffers are scaled correctly; |
1200 | | */ |
1201 | 0 | if (target_exp - (source_exp - reserve) >= 0) { |
1202 | 0 | rescaleSubbandSamples(OverlapBufferReal, |
1203 | 0 | (useLP) ? NULL : OverlapBufferImag, startBand, |
1204 | 0 | stopBand, 0, startSlot, reserve); |
1205 | 0 | source_exp -= reserve; |
1206 | 0 | } |
1207 | |
|
1208 | 0 | delta_exp = target_exp - source_exp; |
1209 | |
|
1210 | 0 | if (delta_exp < 0) { /* x-over-area is dominant */ |
1211 | 0 | startBand = target_lsb; |
1212 | 0 | stopBand = target_usb; |
1213 | 0 | delta_exp = -delta_exp; |
1214 | |
|
1215 | 0 | if (new_lsb > old_lsb) { |
1216 | | /* The lowband has to be rescaled */ |
1217 | 0 | hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = EXP2SCALE(source_exp); |
1218 | 0 | } else { |
1219 | | /* The highband has to be rescaled */ |
1220 | 0 | hSbrDec->qmfDomainInCh->scaling.ov_hb_scale = EXP2SCALE(source_exp); |
1221 | 0 | } |
1222 | 0 | } |
1223 | |
|
1224 | 0 | FDK_ASSERT(startBand <= stopBand); |
1225 | | |
1226 | 0 | if (!useLP) { |
1227 | 0 | for (l = 0; l < startSlot; l++) { |
1228 | 0 | scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, |
1229 | 0 | -delta_exp); |
1230 | 0 | scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand, |
1231 | 0 | -delta_exp); |
1232 | 0 | } |
1233 | 0 | } else |
1234 | 0 | for (l = 0; l < startSlot; l++) { |
1235 | 0 | scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, |
1236 | 0 | -delta_exp); |
1237 | 0 | } |
1238 | 0 | } /* startSlot != 0 */ |
1239 | | |
1240 | | /* |
1241 | | Initialize transposer and limiter |
1242 | | */ |
1243 | 0 | sbrError = resetLppTransposer( |
1244 | 0 | &hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband, |
1245 | 0 | hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, |
1246 | 0 | hHeaderData->freqBandData.freqBandTableNoise, |
1247 | 0 | hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband, |
1248 | 0 | hHeaderData->sbrProcSmplRate); |
1249 | 0 | if (sbrError != SBRDEC_OK) return sbrError; |
1250 | | |
1251 | 0 | hSbrDec->savedStates = 0; |
1252 | |
|
1253 | 0 | if ((flags & SBRDEC_USAC_HARMONICSBR) && applySbrProc) { |
1254 | 0 | sbrError = QmfTransposerReInit(hSbrDec->hHBE, |
1255 | 0 | hHeaderData->freqBandData.freqBandTable, |
1256 | 0 | hHeaderData->freqBandData.nSfb); |
1257 | 0 | if (sbrError != SBRDEC_OK) return sbrError; |
1258 | | |
1259 | | /* copy saved states from previous frame to legacy SBR lpc filterstate |
1260 | | * buffer */ |
1261 | 0 | for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) { |
1262 | 0 | FDKmemcpy( |
1263 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], |
1264 | 0 | hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - LPC_ORDER - |
1265 | 0 | hSbrDec->LppTrans.pSettings->overlap + i], |
1266 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
1267 | 0 | FDKmemcpy( |
1268 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], |
1269 | 0 | hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - LPC_ORDER - |
1270 | 0 | hSbrDec->LppTrans.pSettings->overlap + i], |
1271 | 0 | hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); |
1272 | 0 | } |
1273 | 0 | hSbrDec->savedStates = 1; |
1274 | |
|
1275 | 0 | { |
1276 | | /* map QMF buffer to pointer array (Overlap + Frame)*/ |
1277 | 0 | for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) { |
1278 | 0 | pLowBandReal[i] = hSbrDec->LppTrans.lpcFilterStatesRealHBE[i]; |
1279 | 0 | pLowBandImag[i] = hSbrDec->LppTrans.lpcFilterStatesImagHBE[i]; |
1280 | 0 | } |
1281 | | |
1282 | | /* map QMF buffer to pointer array (Overlap + Frame)*/ |
1283 | 0 | for (i = 0; i < hSbrDec->hHBE->noCols; i++) { |
1284 | 0 | pLowBandReal[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1285 | 0 | hSbrDec->codecQMFBufferReal[i]; |
1286 | 0 | pLowBandImag[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1287 | 0 | hSbrDec->codecQMFBufferImag[i]; |
1288 | 0 | } |
1289 | |
|
1290 | 0 | if (flags & SBRDEC_QUAD_RATE) { |
1291 | 0 | if (hFrameData->sbrPatchingMode == 0) { |
1292 | 0 | int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE); |
1293 | | |
1294 | | /* in case of harmonic SBR and no HBE_LP map additional buffer for |
1295 | | one more frame to pointer arry */ |
1296 | 0 | for (i = 0; i < hSbrDec->hHBE->noCols / 2; i++) { |
1297 | 0 | pLowBandReal[i + hSbrDec->hHBE->noCols + |
1298 | 0 | hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1299 | 0 | hSbrDec->hQmfHBESlotsReal[i]; |
1300 | 0 | pLowBandImag[i + hSbrDec->hHBE->noCols + |
1301 | 0 | hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1302 | 0 | hSbrDec->hQmfHBESlotsImag[i]; |
1303 | 0 | } |
1304 | |
|
1305 | 0 | QmfTransposerApply( |
1306 | 0 | hSbrDec->hHBE, |
1307 | 0 | pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + |
1308 | 0 | hSbrDec->hHBE->noCols / 2 + LPC_ORDER, |
1309 | 0 | pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + |
1310 | 0 | hSbrDec->hHBE->noCols / 2 + LPC_ORDER, |
1311 | 0 | hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, |
1312 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealHBE, |
1313 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagHBE, |
1314 | 0 | hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb, |
1315 | 0 | hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale, |
1316 | 0 | hHeaderData->timeStep, hFrameData->frameInfo.borders[0], |
1317 | 0 | hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); |
1318 | |
|
1319 | 0 | copyHarmonicSpectrum( |
1320 | 0 | xOverQmf, pLowBandReal, pLowBandImag, hSbrDec->hHBE->noCols, |
1321 | 0 | hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); |
1322 | 0 | } |
1323 | 0 | } else { |
1324 | | /* in case of harmonic SBR and no HBE_LP map additional buffer for |
1325 | | one more frame to pointer arry */ |
1326 | 0 | for (i = 0; i < hSbrDec->hHBE->noCols; i++) { |
1327 | 0 | pLowBandReal[i + hSbrDec->hHBE->noCols + |
1328 | 0 | hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1329 | 0 | hSbrDec->hQmfHBESlotsReal[i]; |
1330 | 0 | pLowBandImag[i + hSbrDec->hHBE->noCols + |
1331 | 0 | hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = |
1332 | 0 | hSbrDec->hQmfHBESlotsImag[i]; |
1333 | 0 | } |
1334 | |
|
1335 | 0 | if (hFrameData->sbrPatchingMode == 0) { |
1336 | 0 | QmfTransposerApply( |
1337 | 0 | hSbrDec->hHBE, |
1338 | 0 | pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER, |
1339 | 0 | pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER, |
1340 | 0 | hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, |
1341 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealHBE, |
1342 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagHBE, |
1343 | 0 | 0 /* not required for keeping states updated in this frame*/, |
1344 | 0 | hSbrDec->scale_lb, hSbrDec->scale_lb, |
1345 | 0 | &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep, |
1346 | 0 | hFrameData->frameInfo.borders[0], |
1347 | 0 | hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_NOOUT); |
1348 | 0 | } |
1349 | |
|
1350 | 0 | QmfTransposerApply( |
1351 | 0 | hSbrDec->hHBE, |
1352 | 0 | pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + |
1353 | 0 | hSbrDec->hHBE->noCols + LPC_ORDER, |
1354 | 0 | pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + |
1355 | 0 | hSbrDec->hHBE->noCols + LPC_ORDER, |
1356 | 0 | hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, |
1357 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealHBE, |
1358 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagHBE, |
1359 | 0 | hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb, |
1360 | 0 | hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale, |
1361 | 0 | hHeaderData->timeStep, hFrameData->frameInfo.borders[0], |
1362 | 0 | hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); |
1363 | 0 | } |
1364 | |
|
1365 | 0 | if (hFrameData->sbrPatchingMode == 0) { |
1366 | 0 | for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { |
1367 | | /* |
1368 | | Store the unmodified qmf Slots values for upper part of spectrum |
1369 | | (required for LPC filtering) required if next frame is a HBE frame |
1370 | | */ |
1371 | 0 | FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsReal[i], |
1372 | 0 | hSbrDec->LppTrans.lpcFilterStatesRealHBE[i + LPC_ORDER], |
1373 | 0 | (64) * sizeof(FIXP_DBL)); |
1374 | 0 | FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsImag[i], |
1375 | 0 | hSbrDec->LppTrans.lpcFilterStatesImagHBE[i + LPC_ORDER], |
1376 | 0 | (64) * sizeof(FIXP_DBL)); |
1377 | 0 | } |
1378 | |
|
1379 | 0 | for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { |
1380 | | /* |
1381 | | Store the unmodified qmf Slots values for upper part of spectrum |
1382 | | (required for LPC filtering) required if next frame is a HBE frame |
1383 | | */ |
1384 | 0 | FDKmemcpy( |
1385 | 0 | hSbrDec->qmfDomainInCh->hQmfSlotsReal[i], |
1386 | 0 | hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - |
1387 | 0 | hSbrDec->LppTrans.pSettings->overlap + |
1388 | 0 | i], |
1389 | 0 | new_lsb * sizeof(FIXP_DBL)); |
1390 | 0 | FDKmemcpy( |
1391 | 0 | hSbrDec->qmfDomainInCh->hQmfSlotsImag[i], |
1392 | 0 | hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - |
1393 | 0 | hSbrDec->LppTrans.pSettings->overlap + |
1394 | 0 | i], |
1395 | 0 | new_lsb * sizeof(FIXP_DBL)); |
1396 | 0 | } |
1397 | 0 | } |
1398 | 0 | } |
1399 | 0 | } |
1400 | | |
1401 | 0 | { |
1402 | 0 | int adapt_lb = 0, diff = 0, |
1403 | 0 | new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; |
1404 | |
|
1405 | 0 | if ((hSbrDec->qmfDomainInCh->scaling.ov_lb_scale != |
1406 | 0 | hSbrDec->qmfDomainInCh->scaling.lb_scale) && |
1407 | 0 | startSlot != 0) { |
1408 | | /* we need to adapt spectrum to have equal scale factor, always larger |
1409 | | * than zero */ |
1410 | 0 | diff = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale) - |
1411 | 0 | SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale); |
1412 | |
|
1413 | 0 | if (diff > 0) { |
1414 | 0 | adapt_lb = 1; |
1415 | 0 | diff = -diff; |
1416 | 0 | new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; |
1417 | 0 | } |
1418 | |
|
1419 | 0 | stopBand = new_lsb; |
1420 | 0 | } |
1421 | |
|
1422 | 0 | if (hFrameData->sbrPatchingMode == 1) { |
1423 | | /* scale states from LegSBR filterstates buffer */ |
1424 | 0 | for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) { |
1425 | 0 | scaleValues(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], new_lsb, |
1426 | 0 | diff); |
1427 | 0 | if (!useLP) { |
1428 | 0 | scaleValues(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], new_lsb, |
1429 | 0 | diff); |
1430 | 0 | } |
1431 | 0 | } |
1432 | |
|
1433 | 0 | if (flags & SBRDEC_SYNTAX_USAC) { |
1434 | | /* get missing states between old and new x_over from LegSBR |
1435 | | * filterstates buffer */ |
1436 | | /* in case of legacy SBR we leave these values zeroed out */ |
1437 | 0 | for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { |
1438 | 0 | FDKmemcpy(&OverlapBufferReal[i][old_lsb], |
1439 | 0 | &hSbrDec->LppTrans |
1440 | 0 | .lpcFilterStatesRealLegSBR[LPC_ORDER + i][old_lsb], |
1441 | 0 | fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL)); |
1442 | 0 | if (!useLP) { |
1443 | 0 | FDKmemcpy(&OverlapBufferImag[i][old_lsb], |
1444 | 0 | &hSbrDec->LppTrans |
1445 | 0 | .lpcFilterStatesImagLegSBR[LPC_ORDER + i][old_lsb], |
1446 | 0 | fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL)); |
1447 | 0 | } |
1448 | 0 | } |
1449 | 0 | } |
1450 | |
|
1451 | 0 | if (new_lsb > old_lsb) { |
1452 | 0 | stopBand = old_lsb; |
1453 | 0 | } |
1454 | 0 | } |
1455 | 0 | if ((adapt_lb == 1) && (stopBand > startBand)) { |
1456 | 0 | for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { |
1457 | 0 | scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, |
1458 | 0 | diff); |
1459 | 0 | if (!useLP) { |
1460 | 0 | scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand, |
1461 | 0 | diff); |
1462 | 0 | } |
1463 | 0 | } |
1464 | 0 | } |
1465 | 0 | hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = new_scale; |
1466 | 0 | } |
1467 | |
|
1468 | 0 | sbrError = ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable, |
1469 | 0 | &hHeaderData->freqBandData.noLimiterBands, |
1470 | 0 | hHeaderData->freqBandData.freqBandTable[0], |
1471 | 0 | hHeaderData->freqBandData.nSfb[0], |
1472 | 0 | hSbrDec->LppTrans.pSettings->patchParam, |
1473 | 0 | hSbrDec->LppTrans.pSettings->noOfPatches, |
1474 | 0 | hHeaderData->bs_data.limiterBands, |
1475 | 0 | hFrameData->sbrPatchingMode, |
1476 | 0 | GetxOverBandQmfTransposer(hSbrDec->hHBE), |
1477 | 0 | Get41SbrQmfTransposer(hSbrDec->hHBE)); |
1478 | |
|
1479 | 0 | hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = hFrameData->sbrPatchingMode; |
1480 | |
|
1481 | 0 | return sbrError; |
1482 | 0 | } |