/src/fdk-aac/libSBRenc/src/sbr_encoder.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** SBR encoder library ****************************** |
96 | | |
97 | | Author(s): Andreas Ehret, Tobias Chalupka |
98 | | |
99 | | Description: SBR encoder top level processing. |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "sbr_encoder.h" |
104 | | |
105 | | #include "sbrenc_ram.h" |
106 | | #include "sbrenc_rom.h" |
107 | | #include "sbrenc_freq_sca.h" |
108 | | #include "env_bit.h" |
109 | | #include "cmondata.h" |
110 | | #include "sbr_misc.h" |
111 | | #include "sbr.h" |
112 | | #include "qmf.h" |
113 | | |
114 | | #include "ps_main.h" |
115 | | |
116 | | #define SBRENCODER_LIB_VL0 4 |
117 | | #define SBRENCODER_LIB_VL1 0 |
118 | | #define SBRENCODER_LIB_VL2 0 |
119 | | |
120 | | /***************************************************************************/ |
121 | | /* |
122 | | * SBR Delay balancing definitions. |
123 | | */ |
124 | | |
125 | | /* |
126 | | input buffer (1ch) |
127 | | |
128 | | |------------ 1537 -------------|-----|---------- 2048 -------------| |
129 | | (core2sbr delay ) ds (read, core and ds area) |
130 | | */ |
131 | | |
132 | | #define SFB(dwnsmp) \ |
133 | 0 | (32 << (dwnsmp - \ |
134 | 0 | 1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */ |
135 | | #define STS(fl) \ |
136 | 0 | (((fl) == 1024) ? 32 \ |
137 | 0 | : 30) /* SBR Time Slots: 32 for core frame length 1024, 30 \ |
138 | | for core frame length 960 */ |
139 | | |
140 | | #define DELAY_QMF_ANA(dwnsmp) \ |
141 | 0 | ((320 << ((dwnsmp)-1)) - (32 << ((dwnsmp)-1))) /* Full bandwidth */ |
142 | 0 | #define DELAY_HYB_ANA (10 * 64) /* + 0.5 */ /* */ |
143 | 0 | #define DELAY_HYB_SYN (6 * 64 - 32) /* */ |
144 | | #define DELAY_QMF_POSTPROC(dwnsmp) \ |
145 | 0 | (32 * (dwnsmp)) /* QMF postprocessing delay */ |
146 | 0 | #define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp)) /* Decoder QMF overlap */ |
147 | | #define DELAY_QMF_SYN(dwnsmp) \ |
148 | 0 | (1 << (dwnsmp - \ |
149 | 0 | 1)) /* QMF_NO_POLY/2=2.5, rounded down to 2, half for single-rate */ |
150 | 0 | #define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */ |
151 | | |
152 | | /* Delay in QMF paths */ |
153 | | #define DELAY_SBR(fl, dwnsmp) \ |
154 | 0 | (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_QMF_SYN(dwnsmp)) |
155 | | #define DELAY_PS(fl, dwnsmp) \ |
156 | 0 | (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + \ |
157 | 0 | (SFB(dwnsmp) * STS(fl) - 1) + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp)) |
158 | | #define DELAY_ELDSBR(fl, dwnsmp) \ |
159 | 0 | ((((fl) / 2) * (dwnsmp)) - 1 + DELAY_QMF_POSTPROC(dwnsmp)) |
160 | | #define DELAY_ELDv2SBR(fl, dwnsmp) \ |
161 | 0 | ((((fl) / 2) * (dwnsmp)) - 1 + 80 * (dwnsmp)) /* 80 is the delay caused \ |
162 | | by the sum of the CLD \ |
163 | | analysis and the MPSLD \ |
164 | | synthesis filterbank */ |
165 | | |
166 | | /* Delay in core path (core and downsampler not taken into account) */ |
167 | | #define DELAY_COREPATH_SBR(fl, dwnsmp) \ |
168 | 0 | ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN(dwnsmp))) |
169 | 0 | #define DELAY_COREPATH_ELDSBR(fl, dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp))) |
170 | 0 | #define DELAY_COREPATH_ELDv2SBR(fl, dwnsmp) (128 * (dwnsmp)) /* 4 slots */ |
171 | | #define DELAY_COREPATH_PS(fl, dwnsmp) \ |
172 | 0 | ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + \ |
173 | 0 | /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + \ |
174 | 0 | DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))) /* 2048 - 463*2 */ |
175 | | |
176 | | /* Delay differences between SBR- and downsampled path for SBR and SBR+PS */ |
177 | | #define DELAY_AAC2SBR(fl, dwnsmp) \ |
178 | 0 | ((DELAY_COREPATH_SBR(fl, dwnsmp)) - DELAY_SBR((fl), (dwnsmp))) |
179 | | #define DELAY_ELD2SBR(fl, dwnsmp) \ |
180 | | ((DELAY_COREPATH_ELDSBR(fl, dwnsmp)) - DELAY_ELDSBR(fl, dwnsmp)) |
181 | | #define DELAY_AAC2PS(fl, dwnsmp) \ |
182 | | ((DELAY_COREPATH_PS(fl, dwnsmp)) - DELAY_PS(fl, dwnsmp)) /* 2048 - 463*2 */ |
183 | | |
184 | | /* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller |
185 | | * than the sample delay implied by DELAY_AAC2SBR */ |
186 | | #define MAX_DS_FILTER_DELAY \ |
187 | 0 | (5) /* the additional max downsampler filter delay (source fs) */ |
188 | | #define MAX_SAMPLE_DELAY \ |
189 | 0 | (DELAY_AAC2SBR(1024, 2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame \ |
190 | | length of 1024 and \ |
191 | | dual-rate sbr */ |
192 | | |
193 | | /***************************************************************************/ |
194 | | |
195 | | /*************** Delay parameters for sbrEncoder_Init_delay() **************/ |
196 | | typedef struct { |
197 | | int dsDelay; /* the delay of the (time-domain) downsampler itself */ |
198 | | int delay; /* overall delay / samples */ |
199 | | int sbrDecDelay; /* SBR decoder's delay */ |
200 | | int corePathOffset; /* core path offset / samples; added by |
201 | | sbrEncoder_Init_delay() */ |
202 | | int sbrPathOffset; /* SBR path offset / samples; added by |
203 | | sbrEncoder_Init_delay() */ |
204 | | int bitstrDelay; /* bitstream delay / frames; added by sbrEncoder_Init_delay() |
205 | | */ |
206 | | int delayInput2Core; /* delay of the input to the core / samples */ |
207 | | } DELAY_PARAM; |
208 | | /***************************************************************************/ |
209 | | |
210 | 0 | #define INVALID_TABLE_IDX -1 |
211 | | |
212 | | /***************************************************************************/ |
213 | | /*! |
214 | | |
215 | | \brief Selects the SBR tuning settings to use dependent on number of |
216 | | channels, bitrate, sample rate and core coder |
217 | | |
218 | | \return Index to the appropriate table |
219 | | |
220 | | ****************************************************************************/ |
221 | 0 | #define DISTANCE_CEIL_VALUE 5000000 |
222 | | static INT getSbrTuningTableIndex( |
223 | | UINT bitrate, /*! the total bitrate in bits/sec */ |
224 | | UINT numChannels, /*! the number of channels for the core coder */ |
225 | | UINT sampleRate, /*! the sampling rate of the core coder */ |
226 | 0 | AUDIO_OBJECT_TYPE core, UINT *pBitRateClosest) { |
227 | 0 | int i, bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1, |
228 | 0 | found = 0; |
229 | 0 | UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; |
230 | |
|
231 | 0 | #define isForThisCore(i) \ |
232 | 0 | ((sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD) || \ |
233 | 0 | (sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD)) |
234 | |
|
235 | 0 | for (i = 0; i < sbrTuningTableSize; i++) { |
236 | 0 | if (isForThisCore(i)) /* tuning table is for this core codec */ |
237 | 0 | { |
238 | 0 | if (numChannels == sbrTuningTable[i].numChannels && |
239 | 0 | sampleRate == sbrTuningTable[i].sampleRate) { |
240 | 0 | found = 1; |
241 | 0 | if ((bitrate >= sbrTuningTable[i].bitrateFrom) && |
242 | 0 | (bitrate < sbrTuningTable[i].bitrateTo)) { |
243 | 0 | return i; |
244 | 0 | } else { |
245 | 0 | if (sbrTuningTable[i].bitrateFrom > bitrate) { |
246 | 0 | if (sbrTuningTable[i].bitrateFrom < bitRateClosestLower) { |
247 | 0 | bitRateClosestLower = sbrTuningTable[i].bitrateFrom; |
248 | 0 | bitRateClosestLowerIndex = i; |
249 | 0 | } |
250 | 0 | } |
251 | 0 | if (sbrTuningTable[i].bitrateTo <= bitrate) { |
252 | 0 | if (sbrTuningTable[i].bitrateTo > bitRateClosestUpper) { |
253 | 0 | bitRateClosestUpper = sbrTuningTable[i].bitrateTo - 1; |
254 | 0 | bitRateClosestUpperIndex = i; |
255 | 0 | } |
256 | 0 | } |
257 | 0 | } |
258 | 0 | } |
259 | 0 | } |
260 | 0 | } |
261 | | |
262 | 0 | if (bitRateClosestUpperIndex >= 0) { |
263 | 0 | return bitRateClosestUpperIndex; |
264 | 0 | } |
265 | | |
266 | 0 | if (pBitRateClosest != NULL) { |
267 | | /* If there was at least one matching tuning entry pick the least distance |
268 | | * bit rate */ |
269 | 0 | if (found) { |
270 | 0 | int distanceUpper = DISTANCE_CEIL_VALUE, |
271 | 0 | distanceLower = DISTANCE_CEIL_VALUE; |
272 | 0 | if (bitRateClosestLowerIndex >= 0) { |
273 | 0 | distanceLower = |
274 | 0 | sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; |
275 | 0 | } |
276 | 0 | if (bitRateClosestUpperIndex >= 0) { |
277 | 0 | distanceUpper = |
278 | 0 | bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; |
279 | 0 | } |
280 | 0 | if (distanceUpper < distanceLower) { |
281 | 0 | *pBitRateClosest = bitRateClosestUpper; |
282 | 0 | } else { |
283 | 0 | *pBitRateClosest = bitRateClosestLower; |
284 | 0 | } |
285 | 0 | } else { |
286 | 0 | *pBitRateClosest = 0; |
287 | 0 | } |
288 | 0 | } |
289 | |
|
290 | 0 | return INVALID_TABLE_IDX; |
291 | 0 | } |
292 | | |
293 | | /***************************************************************************/ |
294 | | /*! |
295 | | |
296 | | \brief Selects the PS tuning settings to use dependent on bitrate |
297 | | and core coder |
298 | | |
299 | | \return Index to the appropriate table |
300 | | |
301 | | ****************************************************************************/ |
302 | 0 | static INT getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest) { |
303 | 0 | INT i, paramSets = sizeof(psTuningTable) / sizeof(psTuningTable[0]); |
304 | 0 | int bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1; |
305 | 0 | UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; |
306 | |
|
307 | 0 | for (i = 0; i < paramSets; i++) { |
308 | 0 | if ((bitrate >= psTuningTable[i].bitrateFrom) && |
309 | 0 | (bitrate < psTuningTable[i].bitrateTo)) { |
310 | 0 | return i; |
311 | 0 | } else { |
312 | 0 | if (psTuningTable[i].bitrateFrom > bitrate) { |
313 | 0 | if (psTuningTable[i].bitrateFrom < bitRateClosestLower) { |
314 | 0 | bitRateClosestLower = psTuningTable[i].bitrateFrom; |
315 | 0 | bitRateClosestLowerIndex = i; |
316 | 0 | } |
317 | 0 | } |
318 | 0 | if (psTuningTable[i].bitrateTo <= bitrate) { |
319 | 0 | if (psTuningTable[i].bitrateTo > bitRateClosestUpper) { |
320 | 0 | bitRateClosestUpper = psTuningTable[i].bitrateTo - 1; |
321 | 0 | bitRateClosestUpperIndex = i; |
322 | 0 | } |
323 | 0 | } |
324 | 0 | } |
325 | 0 | } |
326 | | |
327 | 0 | if (bitRateClosestUpperIndex >= 0) { |
328 | 0 | return bitRateClosestUpperIndex; |
329 | 0 | } |
330 | | |
331 | 0 | if (pBitRateClosest != NULL) { |
332 | 0 | int distanceUpper = DISTANCE_CEIL_VALUE, |
333 | 0 | distanceLower = DISTANCE_CEIL_VALUE; |
334 | 0 | if (bitRateClosestLowerIndex >= 0) { |
335 | 0 | distanceLower = |
336 | 0 | sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; |
337 | 0 | } |
338 | 0 | if (bitRateClosestUpperIndex >= 0) { |
339 | 0 | distanceUpper = |
340 | 0 | bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; |
341 | 0 | } |
342 | 0 | if (distanceUpper < distanceLower) { |
343 | 0 | *pBitRateClosest = bitRateClosestUpper; |
344 | 0 | } else { |
345 | 0 | *pBitRateClosest = bitRateClosestLower; |
346 | 0 | } |
347 | 0 | } |
348 | |
|
349 | 0 | return INVALID_TABLE_IDX; |
350 | 0 | } |
351 | | |
352 | | /***************************************************************************/ |
353 | | /*! |
354 | | |
355 | | \brief In case of downsampled SBR we may need to lower the stop freq |
356 | | of a tuning setting to fit into the lower half of the |
357 | | spectrum ( which is sampleRate/4 ) |
358 | | |
359 | | \return the adapted stop frequency index (-1 -> error) |
360 | | |
361 | | \ingroup SbrEncCfg |
362 | | |
363 | | ****************************************************************************/ |
364 | | static INT FDKsbrEnc_GetDownsampledStopFreq(const INT sampleRateCore, |
365 | | const INT startFreq, INT stopFreq, |
366 | 0 | const INT downSampleFactor) { |
367 | 0 | INT maxStopFreqRaw = sampleRateCore / 2; |
368 | 0 | INT startBand, stopBand; |
369 | 0 | HANDLE_ERROR_INFO err; |
370 | |
|
371 | 0 | while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > |
372 | 0 | maxStopFreqRaw) { |
373 | 0 | stopFreq--; |
374 | 0 | } |
375 | |
|
376 | 0 | if (FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) |
377 | 0 | return -1; |
378 | | |
379 | 0 | err = FDKsbrEnc_FindStartAndStopBand( |
380 | 0 | sampleRateCore << (downSampleFactor - 1), sampleRateCore, |
381 | 0 | 32 << (downSampleFactor - 1), startFreq, stopFreq, &startBand, &stopBand); |
382 | 0 | if (err) return -1; |
383 | | |
384 | 0 | return stopFreq; |
385 | 0 | } |
386 | | |
387 | | /***************************************************************************/ |
388 | | /*! |
389 | | |
390 | | \brief tells us, if for the given coreCoder, bitrate, number of channels |
391 | | and input sampling rate an SBR setting is available. If yes, it |
392 | | tells us also the core sampling rate we would need to run with |
393 | | |
394 | | \return a flag indicating success: yes (1) or no (0) |
395 | | |
396 | | ****************************************************************************/ |
397 | | static UINT FDKsbrEnc_IsSbrSettingAvail( |
398 | | UINT bitrate, /*! the total bitrate in bits/sec */ |
399 | | UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ |
400 | | UINT numOutputChannels, /*! the number of channels for the core coder */ |
401 | | UINT sampleRateInput, /*! the input sample rate [in Hz] */ |
402 | | UINT sampleRateCore, /*! the core's sampling rate */ |
403 | 0 | AUDIO_OBJECT_TYPE core) { |
404 | 0 | INT idx = INVALID_TABLE_IDX; |
405 | |
|
406 | 0 | if (sampleRateInput < 16000) return 0; |
407 | | |
408 | 0 | if (bitrate == 0) { |
409 | | /* map vbr quality to bitrate */ |
410 | 0 | if (vbrMode < 30) |
411 | 0 | bitrate = 24000; |
412 | 0 | else if (vbrMode < 40) |
413 | 0 | bitrate = 28000; |
414 | 0 | else if (vbrMode < 60) |
415 | 0 | bitrate = 32000; |
416 | 0 | else if (vbrMode < 75) |
417 | 0 | bitrate = 40000; |
418 | 0 | else |
419 | 0 | bitrate = 48000; |
420 | 0 | bitrate *= numOutputChannels; |
421 | 0 | } |
422 | |
|
423 | 0 | idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, |
424 | 0 | NULL); |
425 | |
|
426 | 0 | return (idx == INVALID_TABLE_IDX ? 0 : 1); |
427 | 0 | } |
428 | | |
429 | | /***************************************************************************/ |
430 | | /*! |
431 | | |
432 | | \brief Adjusts the SBR settings according to the chosen core coder |
433 | | settings which are accessible via config->codecSettings |
434 | | |
435 | | \return A flag indicating success: yes (1) or no (0) |
436 | | |
437 | | ****************************************************************************/ |
438 | | static UINT FDKsbrEnc_AdjustSbrSettings( |
439 | | const sbrConfigurationPtr config, /*! output, modified */ |
440 | | UINT bitRate, /*! the total bitrate in bits/sec */ |
441 | | UINT numChannels, /*! the core coder number of channels */ |
442 | | UINT sampleRateCore, /*! the core coder sampling rate in Hz */ |
443 | | UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */ |
444 | | UINT transFac, /*! the short block to long block ratio */ |
445 | | UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ |
446 | | UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ |
447 | | UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */ |
448 | | UINT lcsMode, /*! the low complexity stereo mode */ |
449 | | UINT bParametricStereo, /*!< use parametric stereo */ |
450 | | AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ |
451 | 0 | { |
452 | 0 | INT idx = INVALID_TABLE_IDX; |
453 | | /* set the core codec settings */ |
454 | 0 | config->codecSettings.bitRate = bitRate; |
455 | 0 | config->codecSettings.nChannels = numChannels; |
456 | 0 | config->codecSettings.sampleFreq = sampleRateCore; |
457 | 0 | config->codecSettings.transFac = transFac; |
458 | 0 | config->codecSettings.standardBitrate = standardBitrate; |
459 | |
|
460 | 0 | if (bitRate < 28000) { |
461 | 0 | config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL; |
462 | 0 | config->threshold_AmpRes_FF_e = 7; |
463 | 0 | } else if (bitRate >= 28000 && bitRate <= 48000) { |
464 | | /* The float threshold is 75 |
465 | | 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore |
466 | | tonality are scaled by this 2/3 is because the original implementation |
467 | | divides the tonality values by 3, here it's divided by 2 128 compensates |
468 | | the necessary shiftfactor of 7 */ |
469 | 0 | config->threshold_AmpRes_FF_m = |
470 | 0 | FL2FXCONST_DBL(75.0f * 0.524288f / (2.0f / 3.0f) / 128.0f); |
471 | 0 | config->threshold_AmpRes_FF_e = 7; |
472 | 0 | } else if (bitRate > 48000) { |
473 | 0 | config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0); |
474 | 0 | config->threshold_AmpRes_FF_e = 0; |
475 | 0 | } |
476 | |
|
477 | 0 | if (bitRate == 0) { |
478 | | /* map vbr quality to bitrate */ |
479 | 0 | if (vbrMode < 30) |
480 | 0 | bitRate = 24000; |
481 | 0 | else if (vbrMode < 40) |
482 | 0 | bitRate = 28000; |
483 | 0 | else if (vbrMode < 60) |
484 | 0 | bitRate = 32000; |
485 | 0 | else if (vbrMode < 75) |
486 | 0 | bitRate = 40000; |
487 | 0 | else |
488 | 0 | bitRate = 48000; |
489 | 0 | bitRate *= numChannels; |
490 | | /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ |
491 | 0 | if (numChannels == 1) { |
492 | 0 | if (sampleRateSbr == 44100 || sampleRateSbr == 48000) { |
493 | 0 | if (vbrMode < 40) bitRate = 32000; |
494 | 0 | } |
495 | 0 | } |
496 | 0 | } |
497 | |
|
498 | 0 | idx = |
499 | 0 | getSbrTuningTableIndex(bitRate, numChannels, sampleRateCore, core, NULL); |
500 | |
|
501 | 0 | if (idx != INVALID_TABLE_IDX) { |
502 | 0 | config->startFreq = sbrTuningTable[idx].startFreq; |
503 | 0 | config->stopFreq = sbrTuningTable[idx].stopFreq; |
504 | 0 | if (useSpeechConfig) { |
505 | 0 | config->startFreq = sbrTuningTable[idx].startFreqSpeech; |
506 | 0 | config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; |
507 | 0 | } |
508 | | |
509 | | /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */ |
510 | 0 | if (1 == config->downSampleFactor) { |
511 | 0 | INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq( |
512 | 0 | sampleRateCore, config->startFreq, config->stopFreq, |
513 | 0 | config->downSampleFactor); |
514 | 0 | if (dsStopFreq < 0) { |
515 | 0 | return 0; |
516 | 0 | } |
517 | | |
518 | 0 | config->stopFreq = dsStopFreq; |
519 | 0 | } |
520 | | |
521 | 0 | config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands; |
522 | 0 | if (core == AOT_ER_AAC_ELD) config->init_amp_res_FF = SBR_AMP_RES_1_5; |
523 | 0 | config->noiseFloorOffset = sbrTuningTable[idx].noiseFloorOffset; |
524 | |
|
525 | 0 | config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel; |
526 | 0 | config->stereoMode = sbrTuningTable[idx].stereoMode; |
527 | 0 | config->freqScale = sbrTuningTable[idx].freqScale; |
528 | |
|
529 | 0 | if (numChannels == 1) { |
530 | | /* stereo case */ |
531 | 0 | switch (core) { |
532 | 0 | case AOT_AAC_LC: |
533 | 0 | if (bitRate <= (useSpeechConfig ? 24000U : 20000U)) { |
534 | 0 | config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency |
535 | | resolution for |
536 | | non-split frames */ |
537 | 0 | config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency |
538 | | resolution for split |
539 | | frames */ |
540 | 0 | } |
541 | 0 | break; |
542 | 0 | case AOT_ER_AAC_ELD: |
543 | 0 | if (bitRate < 36000) |
544 | 0 | config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency |
545 | | resolution for split |
546 | | frames */ |
547 | 0 | if (bitRate < 26000) { |
548 | 0 | config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency |
549 | | resolution for |
550 | | non-split frames */ |
551 | 0 | config->fResTransIsLow = |
552 | 0 | 1; /* for transient frames, set low frequency resolution */ |
553 | 0 | } |
554 | 0 | break; |
555 | 0 | default: |
556 | 0 | break; |
557 | 0 | } |
558 | 0 | } else { |
559 | | /* stereo case */ |
560 | 0 | switch (core) { |
561 | 0 | case AOT_AAC_LC: |
562 | 0 | if (bitRate <= 28000) { |
563 | 0 | config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency |
564 | | resolution for |
565 | | non-split frames */ |
566 | 0 | config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency |
567 | | resolution for split |
568 | | frames */ |
569 | 0 | } |
570 | 0 | break; |
571 | 0 | case AOT_ER_AAC_ELD: |
572 | 0 | if (bitRate < 72000) { |
573 | 0 | config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency |
574 | | resolution for split |
575 | | frames */ |
576 | 0 | } |
577 | 0 | if (bitRate < 52000) { |
578 | 0 | config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency |
579 | | resolution for |
580 | | non-split frames */ |
581 | 0 | config->fResTransIsLow = |
582 | 0 | 1; /* for transient frames, set low frequency resolution */ |
583 | 0 | } |
584 | 0 | break; |
585 | 0 | default: |
586 | 0 | break; |
587 | 0 | } |
588 | 0 | if (bitRate <= 28000) { |
589 | | /* |
590 | | additionally restrict frequency resolution in FIXFIX frames |
591 | | to further reduce SBR payload size */ |
592 | 0 | config->freq_res_fixfix[0] = FREQ_RES_LOW; |
593 | 0 | config->freq_res_fixfix[1] = FREQ_RES_LOW; |
594 | 0 | } |
595 | 0 | } |
596 | | |
597 | | /* adjust usage of parametric coding dependent on bitrate and speech config |
598 | | * flag */ |
599 | 0 | if (useSpeechConfig) config->parametricCoding = 0; |
600 | |
|
601 | 0 | if (core == AOT_ER_AAC_ELD) { |
602 | 0 | if (bitRate < 28000) config->init_amp_res_FF = SBR_AMP_RES_3_0; |
603 | 0 | config->SendHeaderDataTime = -1; |
604 | 0 | } |
605 | |
|
606 | 0 | if (numChannels == 1) { |
607 | 0 | if (bitRate < 16000) { |
608 | 0 | config->parametricCoding = 0; |
609 | 0 | } |
610 | 0 | } else { |
611 | 0 | if (bitRate < 20000) { |
612 | 0 | config->parametricCoding = 0; |
613 | 0 | } |
614 | 0 | } |
615 | |
|
616 | 0 | config->useSpeechConfig = useSpeechConfig; |
617 | | |
618 | | /* PS settings */ |
619 | 0 | config->bParametricStereo = bParametricStereo; |
620 | |
|
621 | 0 | return 1; |
622 | 0 | } else { |
623 | 0 | return 0; |
624 | 0 | } |
625 | 0 | } |
626 | | |
627 | | /***************************************************************************** |
628 | | |
629 | | functionname: FDKsbrEnc_InitializeSbrDefaults |
630 | | description: initializes the SBR configuration |
631 | | returns: error status |
632 | | input: - core codec type, |
633 | | - factor of SBR to core frame length, |
634 | | - core frame length |
635 | | output: initialized SBR configuration |
636 | | |
637 | | *****************************************************************************/ |
638 | | static UINT FDKsbrEnc_InitializeSbrDefaults(sbrConfigurationPtr config, |
639 | | INT downSampleFactor, |
640 | | UINT codecGranuleLen, |
641 | 0 | const INT isLowDelay) { |
642 | 0 | if ((downSampleFactor < 1 || downSampleFactor > 2) || |
643 | 0 | (codecGranuleLen * downSampleFactor > 64 * 32)) |
644 | 0 | return (0); /* error */ |
645 | | |
646 | 0 | config->SendHeaderDataTime = 1000; |
647 | 0 | config->useWaveCoding = 0; |
648 | 0 | config->crcSbr = 0; |
649 | 0 | config->dynBwSupported = 1; |
650 | 0 | if (isLowDelay) |
651 | 0 | config->tran_thr = 6000; |
652 | 0 | else |
653 | 0 | config->tran_thr = 13000; |
654 | |
|
655 | 0 | config->parametricCoding = 1; |
656 | |
|
657 | 0 | config->sbrFrameSize = codecGranuleLen * downSampleFactor; |
658 | 0 | config->downSampleFactor = downSampleFactor; |
659 | | |
660 | | /* sbr default parameters */ |
661 | 0 | config->sbr_data_extra = 0; |
662 | 0 | config->amp_res = SBR_AMP_RES_3_0; |
663 | 0 | config->tran_fc = 0; |
664 | 0 | config->tran_det_mode = 1; |
665 | 0 | config->spread = 1; |
666 | 0 | config->stat = 0; |
667 | 0 | config->e = 1; |
668 | 0 | config->deltaTAcrossFrames = 1; |
669 | 0 | config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f); |
670 | 0 | config->dF_edge_incr = FL2FXCONST_DBL(0.3f); |
671 | |
|
672 | 0 | config->sbr_invf_mode = INVF_SWITCHED; |
673 | 0 | config->sbr_xpos_mode = XPOS_LC; |
674 | 0 | config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT; |
675 | 0 | config->sbr_xpos_level = 0; |
676 | 0 | config->useSaPan = 0; |
677 | 0 | config->dynBwEnabled = 0; |
678 | | |
679 | | /* the following parameters are overwritten by the |
680 | | FDKsbrEnc_AdjustSbrSettings() function since they are included in the |
681 | | tuning table */ |
682 | 0 | config->stereoMode = SBR_SWITCH_LRC; |
683 | 0 | config->ana_max_level = 6; |
684 | 0 | config->noiseFloorOffset = 0; |
685 | 0 | config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ |
686 | 0 | config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ |
687 | 0 | config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */ |
688 | 0 | config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */ |
689 | 0 | config->fResTransIsLow = 0; /* for transient frames, set variable frequency |
690 | | resolution according to freqResTable */ |
691 | | |
692 | | /* header_extra_1 */ |
693 | 0 | config->freqScale = SBR_FREQ_SCALE_DEFAULT; |
694 | 0 | config->alterScale = SBR_ALTER_SCALE_DEFAULT; |
695 | 0 | config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT; |
696 | | |
697 | | /* header_extra_2 */ |
698 | 0 | config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT; |
699 | 0 | config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT; |
700 | 0 | config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; |
701 | 0 | config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT; |
702 | |
|
703 | 0 | return 1; |
704 | 0 | } |
705 | | |
706 | | /***************************************************************************** |
707 | | |
708 | | functionname: DeleteEnvChannel |
709 | | description: frees memory of one SBR channel |
710 | | returns: - |
711 | | input: handle of channel |
712 | | output: released handle |
713 | | |
714 | | *****************************************************************************/ |
715 | 0 | static void deleteEnvChannel(HANDLE_ENV_CHANNEL hEnvCut) { |
716 | 0 | if (hEnvCut) { |
717 | 0 | FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr); |
718 | |
|
719 | 0 | FDKsbrEnc_deleteExtractSbrEnvelope(&hEnvCut->sbrExtractEnvelope); |
720 | 0 | } |
721 | 0 | } |
722 | | |
723 | | /***************************************************************************** |
724 | | |
725 | | functionname: sbrEncoder_ChannelClose |
726 | | description: close the channel coding handle |
727 | | returns: |
728 | | input: phSbrChannel |
729 | | output: |
730 | | |
731 | | *****************************************************************************/ |
732 | 0 | static void sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) { |
733 | 0 | if (hSbrChannel != NULL) { |
734 | 0 | deleteEnvChannel(&hSbrChannel->hEnvChannel); |
735 | 0 | } |
736 | 0 | } |
737 | | |
738 | | /***************************************************************************** |
739 | | |
740 | | functionname: sbrEncoder_ElementClose |
741 | | description: close the channel coding handle |
742 | | returns: |
743 | | input: phSbrChannel |
744 | | output: |
745 | | |
746 | | *****************************************************************************/ |
747 | 0 | static void sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) { |
748 | 0 | HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement; |
749 | |
|
750 | 0 | if (hSbrElement != NULL) { |
751 | 0 | if (hSbrElement->sbrConfigData.v_k_master) |
752 | 0 | FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master); |
753 | 0 | if (hSbrElement->sbrConfigData.freqBandTable[LO]) |
754 | 0 | FreeRam_Sbr_freqBandTableLO( |
755 | 0 | &hSbrElement->sbrConfigData.freqBandTable[LO]); |
756 | 0 | if (hSbrElement->sbrConfigData.freqBandTable[HI]) |
757 | 0 | FreeRam_Sbr_freqBandTableHI( |
758 | 0 | &hSbrElement->sbrConfigData.freqBandTable[HI]); |
759 | |
|
760 | 0 | FreeRam_SbrElement(phSbrElement); |
761 | 0 | } |
762 | 0 | return; |
763 | 0 | } |
764 | | |
765 | 0 | void sbrEncoder_Close(HANDLE_SBR_ENCODER *phSbrEncoder) { |
766 | 0 | HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder; |
767 | |
|
768 | 0 | if (hSbrEncoder != NULL) { |
769 | 0 | int el, ch; |
770 | |
|
771 | 0 | for (el = 0; el < (8); el++) { |
772 | 0 | if (hSbrEncoder->sbrElement[el] != NULL) { |
773 | 0 | sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]); |
774 | 0 | } |
775 | 0 | } |
776 | | |
777 | | /* Close sbr Channels */ |
778 | 0 | for (ch = 0; ch < (8); ch++) { |
779 | 0 | if (hSbrEncoder->pSbrChannel[ch]) { |
780 | 0 | sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]); |
781 | 0 | FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]); |
782 | 0 | } |
783 | |
|
784 | 0 | if (hSbrEncoder->QmfAnalysis[ch].FilterStates) |
785 | 0 | FreeRam_Sbr_QmfStatesAnalysis( |
786 | 0 | (FIXP_QAS **)&hSbrEncoder->QmfAnalysis[ch].FilterStates); |
787 | 0 | } |
788 | |
|
789 | 0 | if (hSbrEncoder->hParametricStereo) |
790 | 0 | PSEnc_Destroy(&hSbrEncoder->hParametricStereo); |
791 | 0 | if (hSbrEncoder->qmfSynthesisPS.FilterStates) |
792 | 0 | FreeRam_PsQmfStatesSynthesis( |
793 | 0 | (FIXP_DBL **)&hSbrEncoder->qmfSynthesisPS.FilterStates); |
794 | | |
795 | | /* Release Overlay */ |
796 | 0 | if (hSbrEncoder->pSBRdynamic_RAM) |
797 | 0 | FreeRam_SbrDynamic_RAM((FIXP_DBL **)&hSbrEncoder->pSBRdynamic_RAM); |
798 | |
|
799 | 0 | FreeRam_SbrEncoder(phSbrEncoder); |
800 | 0 | } |
801 | 0 | } |
802 | | |
803 | | /***************************************************************************** |
804 | | |
805 | | functionname: updateFreqBandTable |
806 | | description: updates vk_master |
807 | | returns: - |
808 | | input: config handle |
809 | | output: error info |
810 | | |
811 | | *****************************************************************************/ |
812 | | static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData, |
813 | | HANDLE_SBR_HEADER_DATA sbrHeaderData, |
814 | 0 | const INT downSampleFactor) { |
815 | 0 | INT k0, k2; |
816 | |
|
817 | 0 | if (FDKsbrEnc_FindStartAndStopBand( |
818 | 0 | sbrConfigData->sampleFreq, |
819 | 0 | sbrConfigData->sampleFreq >> (downSampleFactor - 1), |
820 | 0 | sbrConfigData->noQmfBands, sbrHeaderData->sbr_start_frequency, |
821 | 0 | sbrHeaderData->sbr_stop_frequency, &k0, &k2)) |
822 | 0 | return (1); |
823 | | |
824 | 0 | if (FDKsbrEnc_UpdateFreqScale( |
825 | 0 | sbrConfigData->v_k_master, &sbrConfigData->num_Master, k0, k2, |
826 | 0 | sbrHeaderData->freqScale, sbrHeaderData->alterScale)) |
827 | 0 | return (1); |
828 | | |
829 | 0 | sbrHeaderData->sbr_xover_band = 0; |
830 | |
|
831 | 0 | if (FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI], |
832 | 0 | &sbrConfigData->nSfb[HI], sbrConfigData->v_k_master, |
833 | 0 | sbrConfigData->num_Master, |
834 | 0 | &sbrHeaderData->sbr_xover_band)) |
835 | 0 | return (1); |
836 | | |
837 | 0 | FDKsbrEnc_UpdateLoRes( |
838 | 0 | sbrConfigData->freqBandTable[LO], &sbrConfigData->nSfb[LO], |
839 | 0 | sbrConfigData->freqBandTable[HI], sbrConfigData->nSfb[HI]); |
840 | |
|
841 | 0 | sbrConfigData->xOverFreq = |
842 | 0 | (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / |
843 | 0 | sbrConfigData->noQmfBands + |
844 | 0 | 1) >> |
845 | 0 | 1; |
846 | |
|
847 | 0 | return (0); |
848 | 0 | } |
849 | | |
850 | | /***************************************************************************** |
851 | | |
852 | | functionname: resetEnvChannel |
853 | | description: resets parameters and allocates memory |
854 | | returns: error status |
855 | | input: |
856 | | output: hEnv |
857 | | |
858 | | *****************************************************************************/ |
859 | | static INT resetEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, |
860 | | HANDLE_SBR_HEADER_DATA sbrHeaderData, |
861 | 0 | HANDLE_ENV_CHANNEL hEnv) { |
862 | | /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function |
863 | | * FDKsbrEnc_extractSbrEnvelope !!!*/ |
864 | 0 | hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = |
865 | 0 | sbrHeaderData->sbr_noise_bands; |
866 | |
|
867 | 0 | if (FDKsbrEnc_ResetTonCorrParamExtr( |
868 | 0 | &hEnv->TonCorr, sbrConfigData->xposCtrlSwitch, |
869 | 0 | sbrConfigData->freqBandTable[HI][0], sbrConfigData->v_k_master, |
870 | 0 | sbrConfigData->num_Master, sbrConfigData->sampleFreq, |
871 | 0 | sbrConfigData->freqBandTable, sbrConfigData->nSfb, |
872 | 0 | sbrConfigData->noQmfBands)) |
873 | 0 | return (1); |
874 | | |
875 | 0 | hEnv->sbrCodeNoiseFloor.nSfb[LO] = |
876 | 0 | hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; |
877 | 0 | hEnv->sbrCodeNoiseFloor.nSfb[HI] = |
878 | 0 | hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; |
879 | |
|
880 | 0 | hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO]; |
881 | 0 | hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI]; |
882 | |
|
883 | 0 | hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; |
884 | |
|
885 | 0 | hEnv->sbrCodeEnvelope.upDate = 0; |
886 | 0 | hEnv->sbrCodeNoiseFloor.upDate = 0; |
887 | |
|
888 | 0 | return (0); |
889 | 0 | } |
890 | | |
891 | | /* ****************************** FDKsbrEnc_SbrGetXOverFreq |
892 | | * ******************************/ |
893 | | /** |
894 | | * @fn |
895 | | * @brief calculates the closest possible crossover frequency |
896 | | * @return the crossover frequency SBR accepts |
897 | | * |
898 | | */ |
899 | | static INT FDKsbrEnc_SbrGetXOverFreq( |
900 | | HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */ |
901 | | INT xoverFreq) /*!< from core coder suggested crossover frequency */ |
902 | 0 | { |
903 | 0 | INT band; |
904 | 0 | INT lastDiff, newDiff; |
905 | 0 | INT cutoffSb; |
906 | |
|
907 | 0 | UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master; |
908 | | |
909 | | /* Check if there is a matching cutoff frequency in the master table */ |
910 | 0 | cutoffSb = (4 * xoverFreq * hEnv->sbrConfigData.noQmfBands / |
911 | 0 | hEnv->sbrConfigData.sampleFreq + |
912 | 0 | 1) >> |
913 | 0 | 1; |
914 | 0 | lastDiff = cutoffSb; |
915 | 0 | for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) { |
916 | 0 | newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb); |
917 | |
|
918 | 0 | if (newDiff >= lastDiff) { |
919 | 0 | band--; |
920 | 0 | break; |
921 | 0 | } |
922 | | |
923 | 0 | lastDiff = newDiff; |
924 | 0 | } |
925 | |
|
926 | 0 | return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq / |
927 | 0 | hEnv->sbrConfigData.noQmfBands + |
928 | 0 | 1) >> |
929 | 0 | 1); |
930 | 0 | } |
931 | | |
932 | | /***************************************************************************** |
933 | | |
934 | | functionname: FDKsbrEnc_EnvEncodeFrame |
935 | | description: performs the sbr envelope calculation for one element |
936 | | returns: |
937 | | input: |
938 | | output: |
939 | | |
940 | | *****************************************************************************/ |
941 | | INT FDKsbrEnc_EnvEncodeFrame( |
942 | | HANDLE_SBR_ENCODER hEnvEncoder, int iElement, |
943 | | INT_PCM *samples, /*!< time samples, always deinterleaved */ |
944 | | UINT samplesBufSize, /*!< time buffer channel stride */ |
945 | | UINT *sbrDataBits, /*!< Size of SBR payload */ |
946 | | UCHAR *sbrData, /*!< SBR payload */ |
947 | | int clearOutput /*!< Do not consider any input signal */ |
948 | 0 | ) { |
949 | 0 | HANDLE_SBR_ELEMENT hSbrElement = NULL; |
950 | 0 | FDK_CRCINFO crcInfo; |
951 | 0 | INT crcReg; |
952 | 0 | INT ch; |
953 | 0 | INT band; |
954 | 0 | INT cutoffSb; |
955 | 0 | INT newXOver; |
956 | |
|
957 | 0 | if (hEnvEncoder == NULL) return -1; |
958 | | |
959 | 0 | hSbrElement = hEnvEncoder->sbrElement[iElement]; |
960 | |
|
961 | 0 | if (hSbrElement == NULL) return -1; |
962 | | |
963 | | /* header bitstream handling */ |
964 | 0 | HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData; |
965 | |
|
966 | 0 | INT psHeaderActive = 0; |
967 | 0 | sbrBitstreamData->HeaderActive = 0; |
968 | | |
969 | | /* Anticipate PS header because of internal PS bitstream delay in order to be |
970 | | * in sync with SBR header. */ |
971 | 0 | if (sbrBitstreamData->CountSendHeaderData == |
972 | 0 | (sbrBitstreamData->NrSendHeaderData - 1)) { |
973 | 0 | psHeaderActive = 1; |
974 | 0 | } |
975 | | |
976 | | /* Signal SBR header to be written into bitstream */ |
977 | 0 | if (sbrBitstreamData->CountSendHeaderData == 0) { |
978 | 0 | sbrBitstreamData->HeaderActive = 1; |
979 | 0 | } |
980 | | |
981 | | /* Increment header interval counter */ |
982 | 0 | if (sbrBitstreamData->NrSendHeaderData == 0) { |
983 | 0 | sbrBitstreamData->CountSendHeaderData = 1; |
984 | 0 | } else { |
985 | 0 | if (sbrBitstreamData->CountSendHeaderData >= 0) { |
986 | 0 | sbrBitstreamData->CountSendHeaderData++; |
987 | 0 | sbrBitstreamData->CountSendHeaderData %= |
988 | 0 | sbrBitstreamData->NrSendHeaderData; |
989 | 0 | } |
990 | 0 | } |
991 | |
|
992 | 0 | if (hSbrElement->CmonData.dynBwEnabled) { |
993 | 0 | INT i; |
994 | 0 | for (i = 4; i > 0; i--) |
995 | 0 | hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i - 1]; |
996 | |
|
997 | 0 | hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc; |
998 | 0 | if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2]) |
999 | 0 | newXOver = hSbrElement->dynXOverFreqDelay[2]; |
1000 | 0 | else |
1001 | 0 | newXOver = hSbrElement->dynXOverFreqDelay[1]; |
1002 | | |
1003 | | /* has the crossover frequency changed? */ |
1004 | 0 | if (hSbrElement->sbrConfigData.dynXOverFreq != newXOver) { |
1005 | | /* get corresponding master band */ |
1006 | 0 | cutoffSb = ((4 * newXOver * hSbrElement->sbrConfigData.noQmfBands / |
1007 | 0 | hSbrElement->sbrConfigData.sampleFreq) + |
1008 | 0 | 1) >> |
1009 | 0 | 1; |
1010 | |
|
1011 | 0 | for (band = 0; band < hSbrElement->sbrConfigData.num_Master; band++) { |
1012 | 0 | if (cutoffSb == hSbrElement->sbrConfigData.v_k_master[band]) break; |
1013 | 0 | } |
1014 | 0 | FDK_ASSERT(band < hSbrElement->sbrConfigData.num_Master); |
1015 | | |
1016 | 0 | hSbrElement->sbrConfigData.dynXOverFreq = newXOver; |
1017 | 0 | hSbrElement->sbrHeaderData.sbr_xover_band = band; |
1018 | 0 | hSbrElement->sbrBitstreamData.HeaderActive = 1; |
1019 | 0 | psHeaderActive = 1; /* ps header is one frame delayed */ |
1020 | | |
1021 | | /* |
1022 | | update vk_master table |
1023 | | */ |
1024 | 0 | if (updateFreqBandTable(&hSbrElement->sbrConfigData, |
1025 | 0 | &hSbrElement->sbrHeaderData, |
1026 | 0 | hEnvEncoder->downSampleFactor)) |
1027 | 0 | return (1); |
1028 | | |
1029 | | /* reset SBR channels */ |
1030 | 0 | INT nEnvCh = hSbrElement->sbrConfigData.nChannels; |
1031 | 0 | for (ch = 0; ch < nEnvCh; ch++) { |
1032 | 0 | if (resetEnvChannel(&hSbrElement->sbrConfigData, |
1033 | 0 | &hSbrElement->sbrHeaderData, |
1034 | 0 | &hSbrElement->sbrChannel[ch]->hEnvChannel)) |
1035 | 0 | return (1); |
1036 | 0 | } |
1037 | 0 | } |
1038 | 0 | } |
1039 | | |
1040 | | /* |
1041 | | allocate space for dummy header and crc |
1042 | | */ |
1043 | 0 | crcReg = FDKsbrEnc_InitSbrBitstream( |
1044 | 0 | &hSbrElement->CmonData, |
1045 | 0 | hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay], |
1046 | 0 | MAX_PAYLOAD_SIZE * sizeof(UCHAR), &crcInfo, |
1047 | 0 | hSbrElement->sbrConfigData.sbrSyntaxFlags); |
1048 | | |
1049 | | /* Temporal Envelope Data */ |
1050 | 0 | SBR_FRAME_TEMP_DATA _fData; |
1051 | 0 | SBR_FRAME_TEMP_DATA *fData = &_fData; |
1052 | 0 | SBR_ENV_TEMP_DATA eData[MAX_NUM_CHANNELS]; |
1053 | | |
1054 | | /* Init Temporal Envelope Data */ |
1055 | 0 | { |
1056 | 0 | int i; |
1057 | |
|
1058 | 0 | FDKmemclear(&eData[0], sizeof(SBR_ENV_TEMP_DATA)); |
1059 | 0 | FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA)); |
1060 | 0 | FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA)); |
1061 | |
|
1062 | 0 | for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) fData->res[i] = FREQ_RES_HIGH; |
1063 | 0 | } |
1064 | |
|
1065 | 0 | if (!clearOutput) { |
1066 | | /* |
1067 | | * Transform audio data into QMF domain |
1068 | | */ |
1069 | 0 | for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { |
1070 | 0 | HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel; |
1071 | 0 | HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope; |
1072 | |
|
1073 | 0 | if (hSbrElement->elInfo.fParametricStereo == 0) { |
1074 | 0 | QMF_SCALE_FACTOR tmpScale; |
1075 | 0 | FIXP_DBL **pQmfReal, **pQmfImag; |
1076 | 0 | C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, 64 * 2) |
1077 | | |
1078 | | /* Obtain pointers to QMF buffers. */ |
1079 | 0 | pQmfReal = sbrExtrEnv->rBuffer; |
1080 | 0 | pQmfImag = sbrExtrEnv->iBuffer; |
1081 | |
|
1082 | 0 | qmfAnalysisFiltering( |
1083 | 0 | hSbrElement->hQmfAnalysis[ch], pQmfReal, pQmfImag, &tmpScale, |
1084 | 0 | samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, 0, |
1085 | 0 | 1, qmfWorkBuffer); |
1086 | |
|
1087 | 0 | h_envChan->qmfScale = tmpScale.lb_scale + 7; |
1088 | |
|
1089 | 0 | C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, 64 * 2) |
1090 | |
|
1091 | 0 | } /* fParametricStereo == 0 */ |
1092 | | |
1093 | | /* |
1094 | | Parametric Stereo processing |
1095 | | */ |
1096 | 0 | if (hSbrElement->elInfo.fParametricStereo) { |
1097 | 0 | INT error = noError; |
1098 | | |
1099 | | /* Limit Parametric Stereo to one instance */ |
1100 | 0 | FDK_ASSERT(ch == 0); |
1101 | | |
1102 | 0 | if (error == noError) { |
1103 | | /* parametric stereo processing: |
1104 | | - input: |
1105 | | o left and right time domain samples |
1106 | | - processing: |
1107 | | o stereo qmf analysis |
1108 | | o stereo hybrid analysis |
1109 | | o ps parameter extraction |
1110 | | o downmix + hybrid synthesis |
1111 | | - output: |
1112 | | o downmixed qmf data is written to sbrExtrEnv->rBuffer and |
1113 | | sbrExtrEnv->iBuffer |
1114 | | */ |
1115 | 0 | SCHAR qmfScale; |
1116 | 0 | INT_PCM *pSamples[2] = { |
1117 | 0 | samples + hSbrElement->elInfo.ChannelIndex[0] * samplesBufSize, |
1118 | 0 | samples + hSbrElement->elInfo.ChannelIndex[1] * samplesBufSize}; |
1119 | 0 | error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( |
1120 | 0 | hEnvEncoder->hParametricStereo, pSamples, samplesBufSize, |
1121 | 0 | hSbrElement->hQmfAnalysis, sbrExtrEnv->rBuffer, |
1122 | 0 | sbrExtrEnv->iBuffer, |
1123 | 0 | samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, |
1124 | 0 | &hEnvEncoder->qmfSynthesisPS, &qmfScale, psHeaderActive); |
1125 | 0 | h_envChan->qmfScale = (int)qmfScale; |
1126 | 0 | } |
1127 | |
|
1128 | 0 | } /* if (hEnvEncoder->hParametricStereo) */ |
1129 | | |
1130 | | /* |
1131 | | |
1132 | | Extract Envelope relevant things from QMF data |
1133 | | |
1134 | | */ |
1135 | 0 | FDKsbrEnc_extractSbrEnvelope1(&hSbrElement->sbrConfigData, |
1136 | 0 | &hSbrElement->sbrHeaderData, |
1137 | 0 | &hSbrElement->sbrBitstreamData, h_envChan, |
1138 | 0 | &hSbrElement->CmonData, &eData[ch], fData); |
1139 | |
|
1140 | 0 | } /* hEnvEncoder->sbrConfigData.nChannels */ |
1141 | 0 | } |
1142 | | |
1143 | | /* |
1144 | | Process Envelope relevant things and calculate envelope data and write |
1145 | | payload |
1146 | | */ |
1147 | 0 | FDKsbrEnc_extractSbrEnvelope2( |
1148 | 0 | &hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, |
1149 | 0 | (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo |
1150 | 0 | : NULL, |
1151 | 0 | &hSbrElement->sbrBitstreamData, &hSbrElement->sbrChannel[0]->hEnvChannel, |
1152 | 0 | (hSbrElement->sbrConfigData.stereoMode != SBR_MONO) |
1153 | 0 | ? &hSbrElement->sbrChannel[1]->hEnvChannel |
1154 | 0 | : NULL, |
1155 | 0 | &hSbrElement->CmonData, eData, fData, clearOutput); |
1156 | |
|
1157 | 0 | hSbrElement->sbrBitstreamData.rightBorderFIX = 0; |
1158 | | |
1159 | | /* |
1160 | | format payload, calculate crc |
1161 | | */ |
1162 | 0 | FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, |
1163 | 0 | hSbrElement->sbrConfigData.sbrSyntaxFlags); |
1164 | | |
1165 | | /* |
1166 | | save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE |
1167 | | */ |
1168 | 0 | hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = |
1169 | 0 | FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf); |
1170 | |
|
1171 | 0 | if (hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > |
1172 | 0 | (MAX_PAYLOAD_SIZE << 3)) |
1173 | 0 | hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = 0; |
1174 | | |
1175 | | /* While filling the Delay lines, sbrData is NULL */ |
1176 | 0 | if (sbrData) { |
1177 | 0 | *sbrDataBits = hSbrElement->payloadDelayLineSize[0]; |
1178 | 0 | FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], |
1179 | 0 | (hSbrElement->payloadDelayLineSize[0] + 7) >> 3); |
1180 | 0 | } |
1181 | | |
1182 | | /* delay header active flag */ |
1183 | 0 | if (hSbrElement->sbrBitstreamData.HeaderActive == 1) { |
1184 | 0 | hSbrElement->sbrBitstreamData.HeaderActiveDelay = |
1185 | 0 | 1 + hEnvEncoder->nBitstrDelay; |
1186 | 0 | } else { |
1187 | 0 | if (hSbrElement->sbrBitstreamData.HeaderActiveDelay > 0) { |
1188 | 0 | hSbrElement->sbrBitstreamData.HeaderActiveDelay--; |
1189 | 0 | } |
1190 | 0 | } |
1191 | |
|
1192 | 0 | return (0); |
1193 | 0 | } |
1194 | | |
1195 | | /***************************************************************************** |
1196 | | |
1197 | | functionname: FDKsbrEnc_Downsample |
1198 | | description: performs downsampling and delay compensation of the core path |
1199 | | returns: |
1200 | | input: |
1201 | | output: |
1202 | | |
1203 | | *****************************************************************************/ |
1204 | | INT FDKsbrEnc_Downsample( |
1205 | | HANDLE_SBR_ENCODER hSbrEncoder, |
1206 | | INT_PCM *samples, /*!< time samples, always deinterleaved */ |
1207 | | UINT samplesBufSize, /*!< time buffer size per channel */ |
1208 | | UINT numChannels, /*!< number of channels */ |
1209 | | UINT *sbrDataBits, /*!< Size of SBR payload */ |
1210 | | UCHAR *sbrData, /*!< SBR payload */ |
1211 | | int clearOutput /*!< Do not consider any input signal */ |
1212 | 0 | ) { |
1213 | 0 | HANDLE_SBR_ELEMENT hSbrElement = NULL; |
1214 | 0 | INT nOutSamples; |
1215 | 0 | int el; |
1216 | 0 | if (hSbrEncoder->downSampleFactor > 1) { |
1217 | | /* Do downsampling */ |
1218 | | |
1219 | | /* Loop over elements (LFE is handled later) */ |
1220 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
1221 | 0 | hSbrElement = hSbrEncoder->sbrElement[el]; |
1222 | 0 | if (hSbrEncoder->sbrElement[el] != NULL) { |
1223 | 0 | if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { |
1224 | 0 | int ch; |
1225 | 0 | int nChannels = hSbrElement->sbrConfigData.nChannels; |
1226 | |
|
1227 | 0 | for (ch = 0; ch < nChannels; ch++) { |
1228 | 0 | FDKaacEnc_Downsample( |
1229 | 0 | &hSbrElement->sbrChannel[ch]->downSampler, |
1230 | 0 | samples + |
1231 | 0 | hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize + |
1232 | 0 | hSbrEncoder->bufferOffset / numChannels, |
1233 | 0 | hSbrElement->sbrConfigData.frameSize, |
1234 | 0 | samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, |
1235 | 0 | &nOutSamples); |
1236 | 0 | } |
1237 | 0 | } |
1238 | 0 | } |
1239 | 0 | } |
1240 | | |
1241 | | /* Handle LFE (if existing) */ |
1242 | 0 | if (hSbrEncoder->lfeChIdx != -1) { /* lfe downsampler */ |
1243 | 0 | FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, |
1244 | 0 | samples + hSbrEncoder->lfeChIdx * samplesBufSize + |
1245 | 0 | hSbrEncoder->bufferOffset / numChannels, |
1246 | 0 | hSbrEncoder->frameSize, |
1247 | 0 | samples + hSbrEncoder->lfeChIdx * samplesBufSize, |
1248 | 0 | &nOutSamples); |
1249 | 0 | } |
1250 | 0 | } else { |
1251 | | /* No downsampling. Still, some buffer shifting for correct delay */ |
1252 | 0 | int samples2Copy = hSbrEncoder->frameSize; |
1253 | 0 | if (hSbrEncoder->bufferOffset / (int)numChannels < samples2Copy) { |
1254 | 0 | for (int c = 0; c < (int)numChannels; c++) { |
1255 | | /* Do memmove while taking care of overlapping memory areas. (memcpy |
1256 | | does not necessarily take care) Distinguish between oeverlapping and |
1257 | | non overlapping version due to reasons of complexity. */ |
1258 | 0 | FDKmemmove(samples + c * samplesBufSize, |
1259 | 0 | samples + c * samplesBufSize + |
1260 | 0 | hSbrEncoder->bufferOffset / numChannels, |
1261 | 0 | samples2Copy * sizeof(INT_PCM)); |
1262 | 0 | } |
1263 | 0 | } else { |
1264 | 0 | for (int c = 0; c < (int)numChannels; c++) { |
1265 | | /* Simple memcpy since the memory areas are not overlapping */ |
1266 | 0 | FDKmemcpy(samples + c * samplesBufSize, |
1267 | 0 | samples + c * samplesBufSize + |
1268 | 0 | hSbrEncoder->bufferOffset / numChannels, |
1269 | 0 | samples2Copy * sizeof(INT_PCM)); |
1270 | 0 | } |
1271 | 0 | } |
1272 | 0 | } |
1273 | |
|
1274 | 0 | return 0; |
1275 | 0 | } |
1276 | | |
1277 | | /***************************************************************************** |
1278 | | |
1279 | | functionname: createEnvChannel |
1280 | | description: initializes parameters and allocates memory |
1281 | | returns: error status |
1282 | | input: |
1283 | | output: hEnv |
1284 | | |
1285 | | *****************************************************************************/ |
1286 | | |
1287 | | static INT createEnvChannel(HANDLE_ENV_CHANNEL hEnv, INT channel, |
1288 | 0 | UCHAR *dynamic_RAM) { |
1289 | 0 | FDKmemclear(hEnv, sizeof(struct ENV_CHANNEL)); |
1290 | |
|
1291 | 0 | if (FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, channel)) { |
1292 | 0 | return (1); |
1293 | 0 | } |
1294 | | |
1295 | 0 | if (FDKsbrEnc_CreateExtractSbrEnvelope(&hEnv->sbrExtractEnvelope, channel, |
1296 | 0 | /*chan*/ 0, dynamic_RAM)) { |
1297 | 0 | return (1); |
1298 | 0 | } |
1299 | | |
1300 | 0 | return 0; |
1301 | 0 | } |
1302 | | |
1303 | | /***************************************************************************** |
1304 | | |
1305 | | functionname: initEnvChannel |
1306 | | description: initializes parameters |
1307 | | returns: error status |
1308 | | input: |
1309 | | output: |
1310 | | |
1311 | | *****************************************************************************/ |
1312 | | static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, |
1313 | | HANDLE_SBR_HEADER_DATA sbrHeaderData, |
1314 | | HANDLE_ENV_CHANNEL hEnv, sbrConfigurationPtr params, |
1315 | | ULONG statesInitFlag, INT chanInEl, |
1316 | 0 | UCHAR *dynamic_RAM) { |
1317 | 0 | int frameShift, tran_off = 0; |
1318 | 0 | INT e; |
1319 | 0 | INT tran_fc; |
1320 | 0 | INT timeSlots, timeStep, startIndex; |
1321 | 0 | INT noiseBands[2] = {3, 3}; |
1322 | |
|
1323 | 0 | e = 1 << params->e; |
1324 | |
|
1325 | 0 | FDK_ASSERT(params->e >= 0); |
1326 | | |
1327 | 0 | hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0]; |
1328 | 0 | hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1]; |
1329 | 0 | hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow; |
1330 | |
|
1331 | 0 | hEnv->fLevelProtect = 0; |
1332 | |
|
1333 | 0 | hEnv->encEnvData.ldGrid = |
1334 | 0 | (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; |
1335 | |
|
1336 | 0 | hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode; |
1337 | |
|
1338 | 0 | if (hEnv->encEnvData.sbr_xpos_mode == XPOS_SWITCHED) { |
1339 | | /* |
1340 | | no other type than XPOS_MDCT or XPOS_SPEECH allowed, |
1341 | | but enable switching |
1342 | | */ |
1343 | 0 | sbrConfigData->switchTransposers = TRUE; |
1344 | 0 | hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT; |
1345 | 0 | } else { |
1346 | 0 | sbrConfigData->switchTransposers = FALSE; |
1347 | 0 | } |
1348 | |
|
1349 | 0 | hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl; |
1350 | | |
1351 | | /* extended data */ |
1352 | 0 | if (params->parametricCoding) { |
1353 | 0 | hEnv->encEnvData.extended_data = 1; |
1354 | 0 | } else { |
1355 | 0 | hEnv->encEnvData.extended_data = 0; |
1356 | 0 | } |
1357 | |
|
1358 | 0 | hEnv->encEnvData.extension_size = 0; |
1359 | |
|
1360 | 0 | startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands; |
1361 | |
|
1362 | 0 | switch (params->sbrFrameSize) { |
1363 | 0 | case 2304: |
1364 | 0 | timeSlots = 18; |
1365 | 0 | break; |
1366 | 0 | case 2048: |
1367 | 0 | case 1024: |
1368 | 0 | case 512: |
1369 | 0 | timeSlots = 16; |
1370 | 0 | break; |
1371 | 0 | case 1920: |
1372 | 0 | case 960: |
1373 | 0 | case 480: |
1374 | 0 | timeSlots = 15; |
1375 | 0 | break; |
1376 | 0 | case 1152: |
1377 | 0 | timeSlots = 9; |
1378 | 0 | break; |
1379 | 0 | default: |
1380 | 0 | return (1); /* Illegal frame size */ |
1381 | 0 | } |
1382 | | |
1383 | 0 | timeStep = sbrConfigData->noQmfSlots / timeSlots; |
1384 | |
|
1385 | 0 | if (FDKsbrEnc_InitTonCorrParamExtr( |
1386 | 0 | params->sbrFrameSize, &hEnv->TonCorr, sbrConfigData, timeSlots, |
1387 | 0 | params->sbr_xpos_ctrl, params->ana_max_level, |
1388 | 0 | sbrHeaderData->sbr_noise_bands, params->noiseFloorOffset, |
1389 | 0 | params->useSpeechConfig)) |
1390 | 0 | return (1); |
1391 | | |
1392 | 0 | hEnv->encEnvData.noOfnoisebands = |
1393 | 0 | hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; |
1394 | |
|
1395 | 0 | noiseBands[0] = hEnv->encEnvData.noOfnoisebands; |
1396 | 0 | noiseBands[1] = hEnv->encEnvData.noOfnoisebands; |
1397 | |
|
1398 | 0 | hEnv->encEnvData.sbr_invf_mode = (INVF_MODE)params->sbr_invf_mode; |
1399 | |
|
1400 | 0 | if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) { |
1401 | 0 | hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL; |
1402 | 0 | hEnv->TonCorr.switchInverseFilt = TRUE; |
1403 | 0 | } else { |
1404 | 0 | hEnv->TonCorr.switchInverseFilt = FALSE; |
1405 | 0 | } |
1406 | |
|
1407 | 0 | tran_fc = params->tran_fc; |
1408 | |
|
1409 | 0 | if (tran_fc == 0) { |
1410 | 0 | tran_fc = fixMin( |
1411 | 0 | 5000, FDKsbrEnc_getSbrStartFreqRAW(sbrHeaderData->sbr_start_frequency, |
1412 | 0 | params->codecSettings.sampleFreq)); |
1413 | 0 | } |
1414 | |
|
1415 | 0 | tran_fc = |
1416 | 0 | (tran_fc * 4 * sbrConfigData->noQmfBands / sbrConfigData->sampleFreq + |
1417 | 0 | 1) >> |
1418 | 0 | 1; |
1419 | |
|
1420 | 0 | if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { |
1421 | 0 | frameShift = LD_PRETRAN_OFF; |
1422 | 0 | tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD * timeStep; |
1423 | 0 | } else { |
1424 | 0 | frameShift = 0; |
1425 | 0 | switch (timeSlots) { |
1426 | | /* The factor of 2 is by definition. */ |
1427 | 0 | case NUMBER_TIME_SLOTS_2048: |
1428 | 0 | tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; |
1429 | 0 | break; |
1430 | 0 | case NUMBER_TIME_SLOTS_1920: |
1431 | 0 | tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; |
1432 | 0 | break; |
1433 | 0 | default: |
1434 | 0 | return 1; |
1435 | 0 | } |
1436 | 0 | } |
1437 | 0 | if (FDKsbrEnc_InitExtractSbrEnvelope( |
1438 | 0 | &hEnv->sbrExtractEnvelope, sbrConfigData->noQmfSlots, |
1439 | 0 | sbrConfigData->noQmfBands, startIndex, timeSlots, timeStep, tran_off, |
1440 | 0 | statesInitFlag, chanInEl, dynamic_RAM, sbrConfigData->sbrSyntaxFlags)) |
1441 | 0 | return (1); |
1442 | | |
1443 | 0 | if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeEnvelope, sbrConfigData->nSfb, |
1444 | 0 | params->deltaTAcrossFrames, |
1445 | 0 | params->dF_edge_1stEnv, |
1446 | 0 | params->dF_edge_incr)) |
1447 | 0 | return (1); |
1448 | | |
1449 | 0 | if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeNoiseFloor, noiseBands, |
1450 | 0 | params->deltaTAcrossFrames, 0, 0)) |
1451 | 0 | return (1); |
1452 | | |
1453 | 0 | if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope, |
1454 | 0 | &hEnv->sbrCodeNoiseFloor, |
1455 | 0 | sbrHeaderData->sbr_amp_res)) |
1456 | 0 | return (1); |
1457 | | |
1458 | 0 | FDKsbrEnc_initFrameInfoGenerator( |
1459 | 0 | &hEnv->SbrEnvFrame, params->spread, e, params->stat, timeSlots, |
1460 | 0 | hEnv->encEnvData.freq_res_fixfix, hEnv->encEnvData.fResTransIsLow, |
1461 | 0 | hEnv->encEnvData.ldGrid); |
1462 | |
|
1463 | 0 | if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) |
1464 | | |
1465 | 0 | { |
1466 | 0 | INT bandwidth_qmf_slot = |
1467 | 0 | (sbrConfigData->sampleFreq >> 1) / (sbrConfigData->noQmfBands); |
1468 | 0 | if (FDKsbrEnc_InitSbrFastTransientDetector( |
1469 | 0 | &hEnv->sbrFastTransientDetector, sbrConfigData->noQmfSlots, |
1470 | 0 | bandwidth_qmf_slot, sbrConfigData->noQmfBands, |
1471 | 0 | sbrConfigData->freqBandTable[0][0])) |
1472 | 0 | return (1); |
1473 | 0 | } |
1474 | | |
1475 | | /* The transient detector has to be initialized also if the fast transient |
1476 | | detector was active, because the values from the transient detector |
1477 | | structure are used. */ |
1478 | 0 | if (FDKsbrEnc_InitSbrTransientDetector( |
1479 | 0 | &hEnv->sbrTransientDetector, sbrConfigData->sbrSyntaxFlags, |
1480 | 0 | sbrConfigData->frameSize, sbrConfigData->sampleFreq, params, tran_fc, |
1481 | 0 | sbrConfigData->noQmfSlots, sbrConfigData->noQmfBands, |
1482 | 0 | hEnv->sbrExtractEnvelope.YBufferWriteOffset, |
1483 | 0 | hEnv->sbrExtractEnvelope.YBufferSzShift, frameShift, tran_off)) |
1484 | 0 | return (1); |
1485 | | |
1486 | 0 | sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl; |
1487 | |
|
1488 | 0 | hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; |
1489 | 0 | hEnv->encEnvData.addHarmonicFlag = 0; |
1490 | |
|
1491 | 0 | return (0); |
1492 | 0 | } |
1493 | | |
1494 | | INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements, |
1495 | 0 | INT nChannels, INT supportPS) { |
1496 | 0 | INT i; |
1497 | 0 | INT errorStatus = 1; |
1498 | 0 | HANDLE_SBR_ENCODER hSbrEncoder = NULL; |
1499 | |
|
1500 | 0 | if (phSbrEncoder == NULL) { |
1501 | 0 | goto bail; |
1502 | 0 | } |
1503 | | |
1504 | 0 | hSbrEncoder = GetRam_SbrEncoder(); |
1505 | 0 | if (hSbrEncoder == NULL) { |
1506 | 0 | goto bail; |
1507 | 0 | } |
1508 | 0 | FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER)); |
1509 | |
|
1510 | 0 | if (NULL == |
1511 | 0 | (hSbrEncoder->pSBRdynamic_RAM = (UCHAR *)GetRam_SbrDynamic_RAM())) { |
1512 | 0 | goto bail; |
1513 | 0 | } |
1514 | 0 | hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; |
1515 | | |
1516 | | /* Create SBR elements */ |
1517 | 0 | for (i = 0; i < nElements; i++) { |
1518 | 0 | hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i); |
1519 | 0 | if (hSbrEncoder->sbrElement[i] == NULL) { |
1520 | 0 | goto bail; |
1521 | 0 | } |
1522 | 0 | FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT)); |
1523 | 0 | hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = |
1524 | 0 | GetRam_Sbr_freqBandTableLO(i); |
1525 | 0 | hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = |
1526 | 0 | GetRam_Sbr_freqBandTableHI(i); |
1527 | 0 | hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = |
1528 | 0 | GetRam_Sbr_v_k_master(i); |
1529 | 0 | if ((hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] == NULL) || |
1530 | 0 | (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] == NULL) || |
1531 | 0 | (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master == NULL)) { |
1532 | 0 | goto bail; |
1533 | 0 | } |
1534 | 0 | } |
1535 | | |
1536 | | /* Create SBR channels */ |
1537 | 0 | for (i = 0; i < nChannels; i++) { |
1538 | 0 | hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i); |
1539 | 0 | if (hSbrEncoder->pSbrChannel[i] == NULL) { |
1540 | 0 | goto bail; |
1541 | 0 | } |
1542 | | |
1543 | 0 | if (createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, i, |
1544 | 0 | hSbrEncoder->dynamicRam)) { |
1545 | 0 | goto bail; |
1546 | 0 | } |
1547 | 0 | } |
1548 | | |
1549 | | /* Create QMF States */ |
1550 | 0 | for (i = 0; i < fixMax(nChannels, (supportPS) ? 2 : 0); i++) { |
1551 | 0 | hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i); |
1552 | 0 | if (hSbrEncoder->QmfAnalysis[i].FilterStates == NULL) { |
1553 | 0 | goto bail; |
1554 | 0 | } |
1555 | 0 | } |
1556 | | |
1557 | | /* Create Parametric Stereo handle */ |
1558 | 0 | if (supportPS) { |
1559 | 0 | if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) { |
1560 | 0 | goto bail; |
1561 | 0 | } |
1562 | | |
1563 | 0 | hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis(); |
1564 | 0 | if (hSbrEncoder->qmfSynthesisPS.FilterStates == NULL) { |
1565 | 0 | goto bail; |
1566 | 0 | } |
1567 | 0 | } /* supportPS */ |
1568 | | |
1569 | 0 | *phSbrEncoder = hSbrEncoder; |
1570 | |
|
1571 | 0 | errorStatus = 0; |
1572 | 0 | return errorStatus; |
1573 | | |
1574 | 0 | bail: |
1575 | | /* Close SBR encoder instance */ |
1576 | 0 | sbrEncoder_Close(&hSbrEncoder); |
1577 | 0 | return errorStatus; |
1578 | 0 | } |
1579 | | |
1580 | | static INT FDKsbrEnc_Reallocate(HANDLE_SBR_ENCODER hSbrEncoder, |
1581 | | SBR_ELEMENT_INFO elInfo[(8)], |
1582 | 0 | const INT noElements) { |
1583 | 0 | INT totalCh = 0; |
1584 | 0 | INT totalQmf = 0; |
1585 | 0 | INT coreEl; |
1586 | 0 | INT el = -1; |
1587 | |
|
1588 | 0 | hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */ |
1589 | |
|
1590 | 0 | for (coreEl = 0; coreEl < noElements; coreEl++) { |
1591 | | /* SBR only handles SCE and CPE's */ |
1592 | 0 | if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { |
1593 | 0 | el++; |
1594 | 0 | } else { |
1595 | 0 | if (elInfo[coreEl].elType == ID_LFE) { |
1596 | 0 | hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0]; |
1597 | 0 | } |
1598 | 0 | continue; |
1599 | 0 | } |
1600 | | |
1601 | 0 | SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl]; |
1602 | 0 | HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el]; |
1603 | |
|
1604 | 0 | int ch; |
1605 | 0 | for (ch = 0; ch < pelInfo->nChannelsInEl; ch++) { |
1606 | 0 | hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh]; |
1607 | 0 | totalCh++; |
1608 | 0 | } |
1609 | | /* analysis QMF */ |
1610 | 0 | for (ch = 0; |
1611 | 0 | ch < ((pelInfo->fParametricStereo) ? 2 : pelInfo->nChannelsInEl); |
1612 | 0 | ch++) { |
1613 | 0 | hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch]; |
1614 | 0 | hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++]; |
1615 | 0 | } |
1616 | | |
1617 | | /* Copy Element info */ |
1618 | 0 | hSbrElement->elInfo.elType = pelInfo->elType; |
1619 | 0 | hSbrElement->elInfo.instanceTag = pelInfo->instanceTag; |
1620 | 0 | hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl; |
1621 | 0 | hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo; |
1622 | 0 | hSbrElement->elInfo.fDualMono = pelInfo->fDualMono; |
1623 | 0 | } /* coreEl */ |
1624 | |
|
1625 | 0 | return 0; |
1626 | 0 | } |
1627 | | |
1628 | | /***************************************************************************** |
1629 | | |
1630 | | functionname: FDKsbrEnc_bsBufInit |
1631 | | description: initializes bitstream buffer |
1632 | | returns: initialized bitstream buffer in env encoder |
1633 | | input: |
1634 | | output: hEnv |
1635 | | |
1636 | | *****************************************************************************/ |
1637 | | static INT FDKsbrEnc_bsBufInit(HANDLE_SBR_ELEMENT hSbrElement, |
1638 | 0 | int nBitstrDelay) { |
1639 | 0 | UCHAR *bitstreamBuffer; |
1640 | | |
1641 | | /* initialize the bitstream buffer */ |
1642 | 0 | bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay]; |
1643 | 0 | FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, |
1644 | 0 | MAX_PAYLOAD_SIZE * sizeof(UCHAR), 0, BS_WRITER); |
1645 | |
|
1646 | 0 | return (0); |
1647 | 0 | } |
1648 | | |
1649 | | /***************************************************************************** |
1650 | | |
1651 | | functionname: FDKsbrEnc_EnvInit |
1652 | | description: initializes parameters |
1653 | | returns: error status |
1654 | | input: |
1655 | | output: hEnv |
1656 | | |
1657 | | *****************************************************************************/ |
1658 | | static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement, |
1659 | | sbrConfigurationPtr params, INT *coreBandWith, |
1660 | | AUDIO_OBJECT_TYPE aot, int nElement, |
1661 | | const int headerPeriod, ULONG statesInitFlag, |
1662 | | const SBRENC_DS_TYPE downsamplingMethod, |
1663 | 0 | UCHAR *dynamic_RAM) { |
1664 | 0 | int ch, i; |
1665 | |
|
1666 | 0 | if ((params->codecSettings.nChannels < 1) || |
1667 | 0 | (params->codecSettings.nChannels > MAX_NUM_CHANNELS)) { |
1668 | 0 | return (1); |
1669 | 0 | } |
1670 | | |
1671 | | /* init and set syntax flags */ |
1672 | 0 | hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; |
1673 | |
|
1674 | 0 | switch (aot) { |
1675 | 0 | case AOT_ER_AAC_ELD: |
1676 | 0 | hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; |
1677 | 0 | break; |
1678 | 0 | default: |
1679 | 0 | break; |
1680 | 0 | } |
1681 | 0 | if (params->crcSbr) { |
1682 | 0 | hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; |
1683 | 0 | } |
1684 | |
|
1685 | 0 | hSbrElement->sbrConfigData.noQmfBands = 64 >> (2 - params->downSampleFactor); |
1686 | 0 | switch (hSbrElement->sbrConfigData.noQmfBands) { |
1687 | 0 | case 64: |
1688 | 0 | hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; |
1689 | 0 | break; |
1690 | 0 | case 32: |
1691 | 0 | hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 5; |
1692 | 0 | break; |
1693 | 0 | default: |
1694 | 0 | hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; |
1695 | 0 | return (2); |
1696 | 0 | } |
1697 | | |
1698 | | /* |
1699 | | now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData, |
1700 | | */ |
1701 | 0 | hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels; |
1702 | |
|
1703 | 0 | if (params->codecSettings.nChannels == 2) { |
1704 | 0 | if ((hSbrElement->elInfo.elType == ID_CPE) && |
1705 | 0 | ((hSbrElement->elInfo.fDualMono == 1))) { |
1706 | 0 | hSbrElement->sbrConfigData.stereoMode = SBR_LEFT_RIGHT; |
1707 | 0 | } else { |
1708 | 0 | hSbrElement->sbrConfigData.stereoMode = params->stereoMode; |
1709 | 0 | } |
1710 | 0 | } else { |
1711 | 0 | hSbrElement->sbrConfigData.stereoMode = SBR_MONO; |
1712 | 0 | } |
1713 | |
|
1714 | 0 | hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; |
1715 | |
|
1716 | 0 | hSbrElement->sbrConfigData.sampleFreq = |
1717 | 0 | params->downSampleFactor * params->codecSettings.sampleFreq; |
1718 | |
|
1719 | 0 | hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; |
1720 | 0 | if (params->SendHeaderDataTime > 0) { |
1721 | 0 | if (headerPeriod == -1) { |
1722 | 0 | hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)( |
1723 | 0 | params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq / |
1724 | 0 | (1000 * hSbrElement->sbrConfigData.frameSize)); |
1725 | 0 | hSbrElement->sbrBitstreamData.NrSendHeaderData = |
1726 | 0 | fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData, 1); |
1727 | 0 | } else { |
1728 | | /* assure header period at least once per second */ |
1729 | 0 | hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin( |
1730 | 0 | fixMax(headerPeriod, 1), (hSbrElement->sbrConfigData.sampleFreq / |
1731 | 0 | hSbrElement->sbrConfigData.frameSize)); |
1732 | 0 | } |
1733 | 0 | } else { |
1734 | 0 | hSbrElement->sbrBitstreamData.NrSendHeaderData = 0; |
1735 | 0 | } |
1736 | |
|
1737 | 0 | hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra; |
1738 | 0 | hSbrElement->sbrBitstreamData.HeaderActive = 0; |
1739 | 0 | hSbrElement->sbrBitstreamData.rightBorderFIX = 0; |
1740 | 0 | hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq; |
1741 | 0 | hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq; |
1742 | 0 | hSbrElement->sbrHeaderData.sbr_xover_band = 0; |
1743 | 0 | hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0; |
1744 | | |
1745 | | /* data_extra */ |
1746 | 0 | if (params->sbr_xpos_ctrl != SBR_XPOS_CTRL_DEFAULT) |
1747 | 0 | hSbrElement->sbrHeaderData.sbr_data_extra = 1; |
1748 | |
|
1749 | 0 | hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res; |
1750 | 0 | hSbrElement->sbrConfigData.initAmpResFF = params->init_amp_res_FF; |
1751 | | |
1752 | | /* header_extra_1 */ |
1753 | 0 | hSbrElement->sbrHeaderData.freqScale = params->freqScale; |
1754 | 0 | hSbrElement->sbrHeaderData.alterScale = params->alterScale; |
1755 | 0 | hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands; |
1756 | 0 | hSbrElement->sbrHeaderData.header_extra_1 = 0; |
1757 | |
|
1758 | 0 | if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) || |
1759 | 0 | (params->alterScale != SBR_ALTER_SCALE_DEFAULT) || |
1760 | 0 | (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) { |
1761 | 0 | hSbrElement->sbrHeaderData.header_extra_1 = 1; |
1762 | 0 | } |
1763 | | |
1764 | | /* header_extra_2 */ |
1765 | 0 | hSbrElement->sbrHeaderData.sbr_limiter_bands = params->sbr_limiter_bands; |
1766 | 0 | hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains; |
1767 | |
|
1768 | 0 | if ((hSbrElement->sbrConfigData.sampleFreq > 48000) && |
1769 | 0 | (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) { |
1770 | 0 | hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE; |
1771 | 0 | } |
1772 | |
|
1773 | 0 | hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq; |
1774 | 0 | hSbrElement->sbrHeaderData.sbr_smoothing_length = |
1775 | 0 | params->sbr_smoothing_length; |
1776 | 0 | hSbrElement->sbrHeaderData.header_extra_2 = 0; |
1777 | |
|
1778 | 0 | if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) || |
1779 | 0 | (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) || |
1780 | 0 | (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) || |
1781 | 0 | (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) { |
1782 | 0 | hSbrElement->sbrHeaderData.header_extra_2 = 1; |
1783 | 0 | } |
1784 | | |
1785 | | /* other switches */ |
1786 | 0 | hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; |
1787 | 0 | hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; |
1788 | 0 | hSbrElement->sbrConfigData.thresholdAmpResFF_m = |
1789 | 0 | params->threshold_AmpRes_FF_m; |
1790 | 0 | hSbrElement->sbrConfigData.thresholdAmpResFF_e = |
1791 | 0 | params->threshold_AmpRes_FF_e; |
1792 | | |
1793 | | /* init freq band table */ |
1794 | 0 | if (updateFreqBandTable(&hSbrElement->sbrConfigData, |
1795 | 0 | &hSbrElement->sbrHeaderData, |
1796 | 0 | params->downSampleFactor)) { |
1797 | 0 | return (1); |
1798 | 0 | } |
1799 | | |
1800 | | /* now create envelope ext and QMF for each available channel */ |
1801 | 0 | for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { |
1802 | 0 | if (initEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, |
1803 | 0 | &hSbrElement->sbrChannel[ch]->hEnvChannel, params, |
1804 | 0 | statesInitFlag, ch, dynamic_RAM)) { |
1805 | 0 | return (1); |
1806 | 0 | } |
1807 | |
|
1808 | 0 | } /* nChannels */ |
1809 | | |
1810 | | /* reset and intialize analysis qmf */ |
1811 | 0 | for (ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo) |
1812 | 0 | ? 2 |
1813 | 0 | : hSbrElement->sbrConfigData.nChannels); |
1814 | 0 | ch++) { |
1815 | 0 | int err; |
1816 | 0 | UINT qmfFlags = |
1817 | 0 | (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) |
1818 | 0 | ? QMF_FLAG_CLDFB |
1819 | 0 | : 0; |
1820 | 0 | if (statesInitFlag) |
1821 | 0 | qmfFlags &= ~QMF_FLAG_KEEP_STATES; |
1822 | 0 | else |
1823 | 0 | qmfFlags |= QMF_FLAG_KEEP_STATES; |
1824 | |
|
1825 | 0 | err = qmfInitAnalysisFilterBank( |
1826 | 0 | hSbrElement->hQmfAnalysis[ch], |
1827 | 0 | (FIXP_QAS *)hSbrElement->hQmfAnalysis[ch]->FilterStates, |
1828 | 0 | hSbrElement->sbrConfigData.noQmfSlots, |
1829 | 0 | hSbrElement->sbrConfigData.noQmfBands, |
1830 | 0 | hSbrElement->sbrConfigData.noQmfBands, |
1831 | 0 | hSbrElement->sbrConfigData.noQmfBands, qmfFlags); |
1832 | 0 | if (0 != err) { |
1833 | 0 | return err; |
1834 | 0 | } |
1835 | 0 | } |
1836 | | |
1837 | | /* */ |
1838 | 0 | hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq; |
1839 | 0 | hSbrElement->CmonData.dynBwEnabled = |
1840 | 0 | (params->dynBwSupported && params->dynBwEnabled); |
1841 | 0 | hSbrElement->CmonData.dynXOverFreqEnc = |
1842 | 0 | FDKsbrEnc_SbrGetXOverFreq(hSbrElement, hSbrElement->CmonData.xOverFreq); |
1843 | 0 | for (i = 0; i < 5; i++) |
1844 | 0 | hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc; |
1845 | 0 | hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels; |
1846 | 0 | hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq; |
1847 | | |
1848 | | /* Update Bandwith to be passed to the core encoder */ |
1849 | 0 | *coreBandWith = hSbrElement->CmonData.xOverFreq; |
1850 | |
|
1851 | 0 | return (0); |
1852 | 0 | } |
1853 | | |
1854 | 0 | INT sbrEncoder_GetInBufferSize(int noChannels) { |
1855 | 0 | INT temp; |
1856 | |
|
1857 | 0 | temp = (2048); |
1858 | 0 | temp += 1024 + MAX_SAMPLE_DELAY; |
1859 | 0 | temp *= noChannels; |
1860 | 0 | temp *= sizeof(INT_PCM); |
1861 | 0 | return temp; |
1862 | 0 | } |
1863 | | |
1864 | | /* |
1865 | | * Encode Dummy SBR payload frames to fill the delay lines. |
1866 | | */ |
1867 | | static INT FDKsbrEnc_DelayCompensation(HANDLE_SBR_ENCODER hEnvEnc, |
1868 | | INT_PCM *timeBuffer, |
1869 | 0 | UINT timeBufferBufSize) { |
1870 | 0 | int n, el; |
1871 | |
|
1872 | 0 | for (n = hEnvEnc->nBitstrDelay; n > 0; n--) { |
1873 | 0 | for (el = 0; el < hEnvEnc->noElements; el++) { |
1874 | 0 | if (FDKsbrEnc_EnvEncodeFrame( |
1875 | 0 | hEnvEnc, el, |
1876 | 0 | timeBuffer + hEnvEnc->downsampledOffset / hEnvEnc->nChannels, |
1877 | 0 | timeBufferBufSize, NULL, NULL, 1)) |
1878 | 0 | return -1; |
1879 | 0 | } |
1880 | 0 | sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer, timeBufferBufSize); |
1881 | 0 | } |
1882 | 0 | return 0; |
1883 | 0 | } |
1884 | | |
1885 | | UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, |
1886 | 0 | UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) { |
1887 | 0 | UINT newBitRate = bitRate; |
1888 | 0 | INT index; |
1889 | |
|
1890 | 0 | FDK_ASSERT(numChannels > 0 && numChannels <= 2); |
1891 | 0 | if (aot == AOT_PS) { |
1892 | 0 | if (numChannels == 1) { |
1893 | 0 | index = getPsTuningTableIndex(bitRate, &newBitRate); |
1894 | 0 | if (index == INVALID_TABLE_IDX) { |
1895 | 0 | bitRate = newBitRate; |
1896 | 0 | } |
1897 | 0 | } else { |
1898 | 0 | return 0; |
1899 | 0 | } |
1900 | 0 | } |
1901 | 0 | index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, |
1902 | 0 | &newBitRate); |
1903 | 0 | if (index != INVALID_TABLE_IDX) { |
1904 | 0 | newBitRate = bitRate; |
1905 | 0 | } |
1906 | |
|
1907 | 0 | return newBitRate; |
1908 | 0 | } |
1909 | | |
1910 | 0 | UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) { |
1911 | 0 | UINT isPossible = (AOT_PS == aot) ? 0 : 1; |
1912 | 0 | return isPossible; |
1913 | 0 | } |
1914 | | |
1915 | | /*****************************************************************************/ |
1916 | | /* */ |
1917 | | /*functionname: sbrEncoder_Init_delay */ |
1918 | | /*description: Determine Delay balancing and new encoder delay */ |
1919 | | /* */ |
1920 | | /*returns: - error status */ |
1921 | | /*input: - frame length of the core (i.e. e.g. AAC) */ |
1922 | | /* - number of channels */ |
1923 | | /* - downsample factor (1 for downsampled, 2 for dual-rate SBR) */ |
1924 | | /* - low delay presence */ |
1925 | | /* - ps presence */ |
1926 | | /* - downsampling method: QMF-, time domain or no downsampling */ |
1927 | | /* - various delay values (see DELAY_PARAM struct description) */ |
1928 | | /* */ |
1929 | | /*Example: Delay balancing for a HE-AACv1 encoder (time-domain downsampling) */ |
1930 | | /*========================================================================== */ |
1931 | | /* */ |
1932 | | /* +--------+ +--------+ +--------+ +--------+ +--------+ */ |
1933 | | /* |core | |ds 2:1 | |AAC | |QMF | |QMF | */ |
1934 | | /* +-+path +------------+ +-+core +-+analysis+-+overlap +-+ */ |
1935 | | /* | |offset | | | | | |32 bands| | | | */ |
1936 | | /* | +--------+ +--------+ +--------+ +--------+ +--------+ | */ |
1937 | | /* | core path +-------++ */ |
1938 | | /* | |QMF | */ |
1939 | | /*->+ +synth. +-> */ |
1940 | | /* | |64 bands| */ |
1941 | | /* | +-------++ */ |
1942 | | /* | +--------+ +--------+ +--------+ +--------+ | */ |
1943 | | /* | |SBR path| |QMF | |subband | |bs delay| | */ |
1944 | | /* +-+offset +-+analysis+-+sample +-+(full +-----------------------+ */ |
1945 | | /* | | |64 bands| |buffer | | frames)| */ |
1946 | | /* +--------+ +--------+ +--------+ +--------+ */ |
1947 | | /* SBR path */ |
1948 | | /* */ |
1949 | | /*****************************************************************************/ |
1950 | | static INT sbrEncoder_Init_delay( |
1951 | | const int coreFrameLength, /* input */ |
1952 | | const int numChannels, /* input */ |
1953 | | const int downSampleFactor, /* input */ |
1954 | | const int lowDelay, /* input */ |
1955 | | const int usePs, /* input */ |
1956 | | const int is212, /* input */ |
1957 | | const SBRENC_DS_TYPE downsamplingMethod, /* input */ |
1958 | | DELAY_PARAM *hDelayParam /* input/output */ |
1959 | 0 | ) { |
1960 | 0 | int delayCorePath = 0; /* delay in core path */ |
1961 | 0 | int delaySbrPath = 0; /* delay difference in QMF aka SBR path */ |
1962 | 0 | int delayInput2Core = 0; /* delay from the input to the core */ |
1963 | 0 | int delaySbrDec = 0; /* delay of the decoder's SBR module */ |
1964 | |
|
1965 | 0 | int delayCore = hDelayParam->delay; /* delay of the core */ |
1966 | | |
1967 | | /* Added delay by the SBR delay initialization */ |
1968 | 0 | int corePathOffset = 0; /* core path */ |
1969 | 0 | int sbrPathOffset = 0; /* sbr path */ |
1970 | 0 | int bitstreamDelay = 0; /* sbr path, framewise */ |
1971 | |
|
1972 | 0 | int flCore = coreFrameLength; /* core frame length */ |
1973 | |
|
1974 | 0 | int returnValue = 0; /* return value - 0 means: no error */ |
1975 | | |
1976 | | /* 1) Calculate actual delay for core and SBR path */ |
1977 | 0 | if (is212) { |
1978 | 0 | delayCorePath = DELAY_COREPATH_ELDv2SBR(flCore, downSampleFactor); |
1979 | 0 | delaySbrPath = DELAY_ELDv2SBR(flCore, downSampleFactor); |
1980 | 0 | delaySbrDec = ((flCore) / 2) * (downSampleFactor); |
1981 | 0 | } else if (lowDelay) { |
1982 | 0 | delayCorePath = DELAY_COREPATH_ELDSBR(flCore, downSampleFactor); |
1983 | 0 | delaySbrPath = DELAY_ELDSBR(flCore, downSampleFactor); |
1984 | 0 | delaySbrDec = DELAY_QMF_POSTPROC(downSampleFactor); |
1985 | 0 | } else if (usePs) { |
1986 | 0 | delayCorePath = DELAY_COREPATH_PS(flCore, downSampleFactor); |
1987 | 0 | delaySbrPath = DELAY_PS(flCore, downSampleFactor); |
1988 | 0 | delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); |
1989 | 0 | } else { |
1990 | 0 | delayCorePath = DELAY_COREPATH_SBR(flCore, downSampleFactor); |
1991 | 0 | delaySbrPath = DELAY_SBR(flCore, downSampleFactor); |
1992 | 0 | delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); |
1993 | 0 | } |
1994 | 0 | delayCorePath += delayCore * downSampleFactor; |
1995 | 0 | delayCorePath += |
1996 | 0 | (downsamplingMethod == SBRENC_DS_TIME) ? hDelayParam->dsDelay : 0; |
1997 | | |
1998 | | /* 2) Manage coupling of paths */ |
1999 | 0 | if (downsamplingMethod == SBRENC_DS_QMF && delayCorePath > delaySbrPath) { |
2000 | | /* In case of QMF downsampling, both paths are coupled, i.e. the SBR path |
2001 | | offset would be added to both the SBR path and to the core path |
2002 | | as well, thus making it impossible to achieve delay balancing. |
2003 | | To overcome that problem, a framewise delay is added to the SBR path |
2004 | | first, until the overall delay of the core path is shorter than |
2005 | | the delay of the SBR path. When this is achieved, the missing delay |
2006 | | difference can be added as downsampled offset to the core path. |
2007 | | */ |
2008 | 0 | while (delayCorePath > delaySbrPath) { |
2009 | | /* Add one frame delay to SBR path */ |
2010 | 0 | delaySbrPath += flCore * downSampleFactor; |
2011 | 0 | bitstreamDelay += 1; |
2012 | 0 | } |
2013 | 0 | } |
2014 | | |
2015 | | /* 3) Calculate necessary additional delay to balance the paths */ |
2016 | 0 | if (delayCorePath > delaySbrPath) { |
2017 | | /* Delay QMF input */ |
2018 | 0 | while (delayCorePath > delaySbrPath + (int)flCore * (int)downSampleFactor) { |
2019 | | /* Do bitstream frame-wise delay balancing if there are |
2020 | | more than SBR framelength samples delay difference */ |
2021 | 0 | delaySbrPath += flCore * downSampleFactor; |
2022 | 0 | bitstreamDelay += 1; |
2023 | 0 | } |
2024 | | /* Multiply input offset by input channels */ |
2025 | 0 | corePathOffset = 0; |
2026 | 0 | sbrPathOffset = (delayCorePath - delaySbrPath) * numChannels; |
2027 | 0 | } else { |
2028 | | /* Delay AAC data */ |
2029 | | /* Multiply downsampled offset by AAC core channels. Divide by 2 because of |
2030 | | half samplerate of downsampled data. */ |
2031 | 0 | corePathOffset = ((delaySbrPath - delayCorePath) * numChannels) >> |
2032 | 0 | (downSampleFactor - 1); |
2033 | 0 | sbrPathOffset = 0; |
2034 | 0 | } |
2035 | | |
2036 | | /* 4) Calculate delay from input to core */ |
2037 | 0 | if (usePs) { |
2038 | 0 | delayInput2Core = |
2039 | 0 | (DELAY_QMF_ANA(downSampleFactor) + DELAY_QMF_DS + DELAY_HYB_SYN) + |
2040 | 0 | (downSampleFactor * corePathOffset) + 1; |
2041 | 0 | } else if (downsamplingMethod == SBRENC_DS_TIME) { |
2042 | 0 | delayInput2Core = corePathOffset + hDelayParam->dsDelay; |
2043 | 0 | } else { |
2044 | 0 | delayInput2Core = corePathOffset; |
2045 | 0 | } |
2046 | | |
2047 | | /* 6) Set output parameters */ |
2048 | 0 | hDelayParam->delay = FDKmax(delayCorePath, delaySbrPath); /* overall delay */ |
2049 | 0 | hDelayParam->sbrDecDelay = delaySbrDec; /* SBR decoder delay */ |
2050 | 0 | hDelayParam->delayInput2Core = delayInput2Core; /* delay input - core */ |
2051 | 0 | hDelayParam->bitstrDelay = bitstreamDelay; /* bitstream delay, in frames */ |
2052 | 0 | hDelayParam->corePathOffset = corePathOffset; /* offset added to core path */ |
2053 | 0 | hDelayParam->sbrPathOffset = sbrPathOffset; /* offset added to SBR path */ |
2054 | |
|
2055 | 0 | return returnValue; |
2056 | 0 | } |
2057 | | |
2058 | | /***************************************************************************** |
2059 | | |
2060 | | functionname: sbrEncoder_Init |
2061 | | description: initializes the SBR encoder |
2062 | | returns: error status |
2063 | | |
2064 | | *****************************************************************************/ |
2065 | | INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder, |
2066 | | SBR_ELEMENT_INFO elInfo[(8)], int noElements, |
2067 | | INT_PCM *inputBuffer, UINT inputBufferBufSize, |
2068 | | INT *coreBandwidth, INT *inputBufferOffset, |
2069 | | INT *numChannels, const UINT syntaxFlags, |
2070 | | INT *coreSampleRate, UINT *downSampleFactor, |
2071 | | INT *frameLength, AUDIO_OBJECT_TYPE aot, int *delay, |
2072 | | int transformFactor, const int headerPeriod, |
2073 | 0 | ULONG statesInitFlag) { |
2074 | 0 | HANDLE_ERROR_INFO errorInfo = noError; |
2075 | 0 | sbrConfiguration sbrConfig[(8)]; |
2076 | 0 | INT error = 0; |
2077 | 0 | INT lowestBandwidth; |
2078 | | /* Save input parameters */ |
2079 | 0 | INT inputSampleRate = *coreSampleRate; |
2080 | 0 | int coreFrameLength = *frameLength; |
2081 | 0 | int inputBandWidth = *coreBandwidth; |
2082 | 0 | int inputChannels = *numChannels; |
2083 | |
|
2084 | 0 | SBRENC_DS_TYPE downsamplingMethod = SBRENC_DS_NONE; |
2085 | 0 | int highestSbrStartFreq, highestSbrStopFreq; |
2086 | 0 | int lowDelay = 0; |
2087 | 0 | int usePs = 0; |
2088 | 0 | int is212 = 0; |
2089 | |
|
2090 | 0 | DELAY_PARAM delayParam; |
2091 | | |
2092 | | /* check whether SBR setting is available for the current encoder |
2093 | | * configuration (bitrate, samplerate) */ |
2094 | 0 | if (!sbrEncoder_IsSingleRatePossible(aot)) { |
2095 | 0 | *downSampleFactor = 2; |
2096 | 0 | } |
2097 | |
|
2098 | 0 | if (aot == AOT_PS) { |
2099 | 0 | usePs = 1; |
2100 | 0 | } |
2101 | 0 | if (aot == AOT_ER_AAC_ELD) { |
2102 | 0 | lowDelay = 1; |
2103 | 0 | } else if (aot == AOT_ER_AAC_LD) { |
2104 | 0 | error = 1; |
2105 | 0 | goto bail; |
2106 | 0 | } |
2107 | | |
2108 | | /* Parametric Stereo */ |
2109 | 0 | if (usePs) { |
2110 | 0 | if (*numChannels == 2 && noElements == 1) { |
2111 | | /* Override Element type in case of Parametric stereo */ |
2112 | 0 | elInfo[0].elType = ID_SCE; |
2113 | 0 | elInfo[0].fParametricStereo = 1; |
2114 | 0 | elInfo[0].nChannelsInEl = 1; |
2115 | | /* core encoder gets downmixed mono signal */ |
2116 | 0 | *numChannels = 1; |
2117 | 0 | } else { |
2118 | 0 | error = 1; |
2119 | 0 | goto bail; |
2120 | 0 | } |
2121 | 0 | } /* usePs */ |
2122 | | |
2123 | | /* set the core's sample rate */ |
2124 | 0 | switch (*downSampleFactor) { |
2125 | 0 | case 1: |
2126 | 0 | *coreSampleRate = inputSampleRate; |
2127 | 0 | downsamplingMethod = SBRENC_DS_NONE; |
2128 | 0 | break; |
2129 | 0 | case 2: |
2130 | 0 | *coreSampleRate = inputSampleRate >> 1; |
2131 | 0 | downsamplingMethod = usePs ? SBRENC_DS_QMF : SBRENC_DS_TIME; |
2132 | 0 | break; |
2133 | 0 | default: |
2134 | 0 | *coreSampleRate = inputSampleRate >> 1; |
2135 | 0 | return 0; /* return error */ |
2136 | 0 | } |
2137 | | |
2138 | | /* check whether SBR setting is available for the current encoder |
2139 | | * configuration (bitrate, coreSampleRate) */ |
2140 | 0 | { |
2141 | 0 | int el, coreEl; |
2142 | | |
2143 | | /* Check if every element config is feasible */ |
2144 | 0 | for (coreEl = 0; coreEl < noElements; coreEl++) { |
2145 | | /* SBR only handles SCE and CPE's */ |
2146 | 0 | if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) { |
2147 | 0 | continue; |
2148 | 0 | } |
2149 | | /* check if desired configuration is available */ |
2150 | 0 | if (!FDKsbrEnc_IsSbrSettingAvail(elInfo[coreEl].bitRate, 0, |
2151 | 0 | elInfo[coreEl].nChannelsInEl, |
2152 | 0 | inputSampleRate, *coreSampleRate, aot)) { |
2153 | 0 | error = 1; |
2154 | 0 | goto bail; |
2155 | 0 | } |
2156 | 0 | } |
2157 | | |
2158 | 0 | hSbrEncoder->nChannels = *numChannels; |
2159 | 0 | hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor; |
2160 | 0 | hSbrEncoder->downsamplingMethod = downsamplingMethod; |
2161 | 0 | hSbrEncoder->downSampleFactor = *downSampleFactor; |
2162 | 0 | hSbrEncoder->estimateBitrate = 0; |
2163 | 0 | hSbrEncoder->inputDataDelay = 0; |
2164 | 0 | is212 = ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS)) ? 1 : 0; |
2165 | | |
2166 | | /* Open SBR elements */ |
2167 | 0 | el = -1; |
2168 | 0 | highestSbrStartFreq = highestSbrStopFreq = 0; |
2169 | 0 | lowestBandwidth = 99999; |
2170 | | |
2171 | | /* Loop through each core encoder element and get a matching SBR element |
2172 | | * config */ |
2173 | 0 | for (coreEl = 0; coreEl < noElements; coreEl++) { |
2174 | | /* SBR only handles SCE and CPE's */ |
2175 | 0 | if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { |
2176 | 0 | el++; |
2177 | 0 | } else { |
2178 | 0 | continue; |
2179 | 0 | } |
2180 | | |
2181 | | /* Set parametric Stereo Flag. */ |
2182 | 0 | if (usePs) { |
2183 | 0 | elInfo[coreEl].fParametricStereo = 1; |
2184 | 0 | } else { |
2185 | 0 | elInfo[coreEl].fParametricStereo = 0; |
2186 | 0 | } |
2187 | | |
2188 | | /* |
2189 | | * Init sbrConfig structure |
2190 | | */ |
2191 | 0 | if (!FDKsbrEnc_InitializeSbrDefaults(&sbrConfig[el], *downSampleFactor, |
2192 | 0 | coreFrameLength, IS_LOWDELAY(aot))) { |
2193 | 0 | error = 1; |
2194 | 0 | goto bail; |
2195 | 0 | } |
2196 | | |
2197 | | /* |
2198 | | * Modify sbrConfig structure according to Element parameters |
2199 | | */ |
2200 | 0 | if (!FDKsbrEnc_AdjustSbrSettings( |
2201 | 0 | &sbrConfig[el], elInfo[coreEl].bitRate, |
2202 | 0 | elInfo[coreEl].nChannelsInEl, *coreSampleRate, inputSampleRate, |
2203 | 0 | transformFactor, 24000, 0, 0, /* useSpeechConfig */ |
2204 | 0 | 0, /* lcsMode */ |
2205 | 0 | usePs, /* bParametricStereo */ |
2206 | 0 | aot)) { |
2207 | 0 | error = 1; |
2208 | 0 | goto bail; |
2209 | 0 | } |
2210 | | |
2211 | | /* Find common frequency border for all SBR elements */ |
2212 | 0 | highestSbrStartFreq = |
2213 | 0 | fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); |
2214 | 0 | highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); |
2215 | |
|
2216 | 0 | } /* first element loop */ |
2217 | | |
2218 | | /* Set element count (can be less than core encoder element count) */ |
2219 | 0 | hSbrEncoder->noElements = el + 1; |
2220 | |
|
2221 | 0 | FDKsbrEnc_Reallocate(hSbrEncoder, elInfo, noElements); |
2222 | |
|
2223 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2224 | 0 | int bandwidth = *coreBandwidth; |
2225 | | |
2226 | | /* Use lowest common bandwidth */ |
2227 | 0 | sbrConfig[el].startFreq = highestSbrStartFreq; |
2228 | 0 | sbrConfig[el].stopFreq = highestSbrStopFreq; |
2229 | | |
2230 | | /* initialize SBR element, and get core bandwidth */ |
2231 | 0 | error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], &sbrConfig[el], |
2232 | 0 | &bandwidth, aot, el, headerPeriod, |
2233 | 0 | statesInitFlag, hSbrEncoder->downsamplingMethod, |
2234 | 0 | hSbrEncoder->dynamicRam); |
2235 | |
|
2236 | 0 | if (error != 0) { |
2237 | 0 | error = 2; |
2238 | 0 | goto bail; |
2239 | 0 | } |
2240 | | |
2241 | | /* Get lowest core encoder bandwidth to be returned later. */ |
2242 | 0 | lowestBandwidth = fixMin(lowestBandwidth, bandwidth); |
2243 | |
|
2244 | 0 | } /* second element loop */ |
2245 | | |
2246 | | /* Initialize a downsampler for each channel in each SBR element */ |
2247 | 0 | if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { |
2248 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2249 | 0 | HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el]; |
2250 | 0 | INT Wc, ch; |
2251 | |
|
2252 | 0 | Wc = 500; /* Cutoff frequency with full bandwidth */ |
2253 | |
|
2254 | 0 | for (ch = 0; ch < hSbrEl->elInfo.nChannelsInEl; ch++) { |
2255 | 0 | FDKaacEnc_InitDownsampler(&hSbrEl->sbrChannel[ch]->downSampler, Wc, |
2256 | 0 | *downSampleFactor); |
2257 | 0 | FDK_ASSERT(hSbrEl->sbrChannel[ch]->downSampler.delay <= |
2258 | 0 | MAX_DS_FILTER_DELAY); |
2259 | 0 | } |
2260 | 0 | } /* third element loop */ |
2261 | | |
2262 | | /* lfe */ |
2263 | 0 | FDKaacEnc_InitDownsampler(&hSbrEncoder->lfeDownSampler, 0, |
2264 | 0 | *downSampleFactor); |
2265 | 0 | } |
2266 | | |
2267 | | /* Get delay information */ |
2268 | 0 | delayParam.dsDelay = |
2269 | 0 | hSbrEncoder->sbrElement[0]->sbrChannel[0]->downSampler.delay; |
2270 | 0 | delayParam.delay = *delay; |
2271 | |
|
2272 | 0 | error = sbrEncoder_Init_delay(coreFrameLength, *numChannels, |
2273 | 0 | *downSampleFactor, lowDelay, usePs, is212, |
2274 | 0 | downsamplingMethod, &delayParam); |
2275 | |
|
2276 | 0 | if (error != 0) { |
2277 | 0 | error = 3; |
2278 | 0 | goto bail; |
2279 | 0 | } |
2280 | | |
2281 | 0 | hSbrEncoder->nBitstrDelay = delayParam.bitstrDelay; |
2282 | 0 | hSbrEncoder->sbrDecDelay = delayParam.sbrDecDelay; |
2283 | 0 | hSbrEncoder->inputDataDelay = delayParam.delayInput2Core; |
2284 | | |
2285 | | /* Assign core encoder Bandwidth */ |
2286 | 0 | *coreBandwidth = lowestBandwidth; |
2287 | | |
2288 | | /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */ |
2289 | 0 | hSbrEncoder->estimateBitrate += 2500 * (*numChannels); |
2290 | | |
2291 | | /* Initialize bitstream buffer for each element */ |
2292 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2293 | 0 | FDKsbrEnc_bsBufInit(hSbrEncoder->sbrElement[el], delayParam.bitstrDelay); |
2294 | 0 | } |
2295 | | |
2296 | | /* initialize parametric stereo */ |
2297 | 0 | if (usePs) { |
2298 | 0 | PSENC_CONFIG psEncConfig; |
2299 | 0 | FDK_ASSERT(hSbrEncoder->noElements == 1); |
2300 | 0 | INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); |
2301 | |
|
2302 | 0 | psEncConfig.frameSize = coreFrameLength; // sbrConfig.sbrFrameSize; |
2303 | 0 | psEncConfig.qmfFilterMode = 0; |
2304 | 0 | psEncConfig.sbrPsDelay = 0; |
2305 | | |
2306 | | /* tuning parameters */ |
2307 | 0 | if (psTuningTableIdx != INVALID_TABLE_IDX) { |
2308 | 0 | psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands; |
2309 | 0 | psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes; |
2310 | 0 | psEncConfig.iidQuantErrorThreshold = |
2311 | 0 | (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold; |
2312 | | |
2313 | | /* calculation is not quite linear, increased number of envelopes causes |
2314 | | * more bits */ |
2315 | | /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope |
2316 | | * configuration */ |
2317 | 0 | hSbrEncoder->estimateBitrate += |
2318 | 0 | ((((*coreSampleRate) * 5 * psEncConfig.nStereoBands * |
2319 | 0 | psEncConfig.maxEnvelopes) / |
2320 | 0 | hSbrEncoder->frameSize)); |
2321 | |
|
2322 | 0 | } else { |
2323 | 0 | error = ERROR(CDI, "Invalid ps tuning table index."); |
2324 | 0 | goto bail; |
2325 | 0 | } |
2326 | | |
2327 | 0 | qmfInitSynthesisFilterBank( |
2328 | 0 | &hSbrEncoder->qmfSynthesisPS, |
2329 | 0 | (FIXP_DBL *)hSbrEncoder->qmfSynthesisPS.FilterStates, |
2330 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, |
2331 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, |
2332 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, |
2333 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, |
2334 | 0 | (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES); |
2335 | |
|
2336 | 0 | if (errorInfo == noError) { |
2337 | | /* update delay */ |
2338 | 0 | psEncConfig.sbrPsDelay = |
2339 | 0 | FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0] |
2340 | 0 | ->sbrChannel[0] |
2341 | 0 | ->hEnvChannel.sbrExtractEnvelope); |
2342 | |
|
2343 | 0 | errorInfo = |
2344 | 0 | PSEnc_Init(hSbrEncoder->hParametricStereo, &psEncConfig, |
2345 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, |
2346 | 0 | hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands, |
2347 | 0 | hSbrEncoder->dynamicRam); |
2348 | 0 | } |
2349 | 0 | } |
2350 | | |
2351 | 0 | hSbrEncoder->downsampledOffset = delayParam.corePathOffset; |
2352 | 0 | hSbrEncoder->bufferOffset = delayParam.sbrPathOffset; |
2353 | 0 | *delay = delayParam.delay; |
2354 | |
|
2355 | 0 | { hSbrEncoder->downmixSize = coreFrameLength * (*numChannels); } |
2356 | | |
2357 | | /* Delay Compensation: fill bitstream delay buffer with zero input signal */ |
2358 | 0 | if (hSbrEncoder->nBitstrDelay > 0) { |
2359 | 0 | error = FDKsbrEnc_DelayCompensation(hSbrEncoder, inputBuffer, |
2360 | 0 | inputBufferBufSize); |
2361 | 0 | if (error != 0) goto bail; |
2362 | 0 | } |
2363 | | |
2364 | | /* Set Output frame length */ |
2365 | 0 | *frameLength = coreFrameLength * *downSampleFactor; |
2366 | | /* Input buffer offset */ |
2367 | 0 | *inputBufferOffset = |
2368 | 0 | fixMax(delayParam.sbrPathOffset, delayParam.corePathOffset); |
2369 | 0 | } |
2370 | | |
2371 | 0 | return error; |
2372 | | |
2373 | 0 | bail: |
2374 | | /* Restore input settings */ |
2375 | 0 | *coreSampleRate = inputSampleRate; |
2376 | 0 | *frameLength = coreFrameLength; |
2377 | 0 | *numChannels = inputChannels; |
2378 | 0 | *coreBandwidth = inputBandWidth; |
2379 | |
|
2380 | 0 | return error; |
2381 | 0 | } |
2382 | | |
2383 | | INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hSbrEncoder, INT_PCM *samples, |
2384 | | UINT samplesBufSize, UINT sbrDataBits[(8)], |
2385 | 0 | UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]) { |
2386 | 0 | INT error; |
2387 | 0 | int el; |
2388 | |
|
2389 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2390 | 0 | if (hSbrEncoder->sbrElement[el] != NULL) { |
2391 | 0 | error = FDKsbrEnc_EnvEncodeFrame( |
2392 | 0 | hSbrEncoder, el, |
2393 | 0 | samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, |
2394 | 0 | samplesBufSize, &sbrDataBits[el], sbrData[el], 0); |
2395 | 0 | if (error) return error; |
2396 | 0 | } |
2397 | 0 | } |
2398 | | |
2399 | 0 | error = FDKsbrEnc_Downsample( |
2400 | 0 | hSbrEncoder, |
2401 | 0 | samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, |
2402 | 0 | samplesBufSize, hSbrEncoder->nChannels, &sbrDataBits[el], sbrData[el], 0); |
2403 | 0 | if (error) return error; |
2404 | | |
2405 | 0 | return 0; |
2406 | 0 | } |
2407 | | |
2408 | | INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hSbrEncoder, |
2409 | 0 | INT_PCM *timeBuffer, UINT timeBufferBufSize) { |
2410 | 0 | if (hSbrEncoder->downsampledOffset > 0) { |
2411 | 0 | int c; |
2412 | 0 | int nd = hSbrEncoder->downmixSize / hSbrEncoder->nChannels; |
2413 | |
|
2414 | 0 | for (c = 0; c < hSbrEncoder->nChannels; c++) { |
2415 | | /* Move delayed downsampled data */ |
2416 | 0 | FDKmemcpy(timeBuffer + timeBufferBufSize * c, |
2417 | 0 | timeBuffer + timeBufferBufSize * c + nd, |
2418 | 0 | sizeof(INT_PCM) * |
2419 | 0 | (hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels)); |
2420 | 0 | } |
2421 | 0 | } else { |
2422 | 0 | int c; |
2423 | |
|
2424 | 0 | for (c = 0; c < hSbrEncoder->nChannels; c++) { |
2425 | | /* Move delayed input data */ |
2426 | 0 | FDKmemcpy( |
2427 | 0 | timeBuffer + timeBufferBufSize * c, |
2428 | 0 | timeBuffer + timeBufferBufSize * c + hSbrEncoder->frameSize, |
2429 | 0 | sizeof(INT_PCM) * hSbrEncoder->bufferOffset / hSbrEncoder->nChannels); |
2430 | 0 | } |
2431 | 0 | } |
2432 | 0 | if (hSbrEncoder->nBitstrDelay > 0) { |
2433 | 0 | int el; |
2434 | |
|
2435 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2436 | 0 | FDKmemmove( |
2437 | 0 | hSbrEncoder->sbrElement[el]->payloadDelayLine[0], |
2438 | 0 | hSbrEncoder->sbrElement[el]->payloadDelayLine[1], |
2439 | 0 | sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay * MAX_PAYLOAD_SIZE)); |
2440 | |
|
2441 | 0 | FDKmemmove(&hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0], |
2442 | 0 | &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1], |
2443 | 0 | sizeof(UINT) * (hSbrEncoder->nBitstrDelay)); |
2444 | 0 | } |
2445 | 0 | } |
2446 | 0 | return 0; |
2447 | 0 | } |
2448 | | |
2449 | 0 | INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder) { |
2450 | 0 | INT error = -1; |
2451 | 0 | if (hSbrEncoder) { |
2452 | 0 | int el; |
2453 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2454 | 0 | if ((hSbrEncoder->noElements == 1) && |
2455 | 0 | (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { |
2456 | 0 | hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = |
2457 | 0 | hSbrEncoder->sbrElement[el]->sbrBitstreamData.NrSendHeaderData - 1; |
2458 | 0 | } else { |
2459 | 0 | hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = 0; |
2460 | 0 | } |
2461 | 0 | } |
2462 | 0 | error = 0; |
2463 | 0 | } |
2464 | 0 | return error; |
2465 | 0 | } |
2466 | | |
2467 | 0 | INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder) { |
2468 | 0 | INT sbrHeader = 1; |
2469 | 0 | if (hSbrEncoder) { |
2470 | 0 | int el; |
2471 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2472 | 0 | sbrHeader &= |
2473 | 0 | (hSbrEncoder->sbrElement[el]->sbrBitstreamData.HeaderActiveDelay == 1) |
2474 | 0 | ? 1 |
2475 | 0 | : 0; |
2476 | 0 | } |
2477 | 0 | } |
2478 | 0 | return sbrHeader; |
2479 | 0 | } |
2480 | | |
2481 | 0 | INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder) { |
2482 | 0 | INT delay = -1; |
2483 | |
|
2484 | 0 | if (hSbrEncoder) { |
2485 | 0 | if ((hSbrEncoder->noElements == 1) && |
2486 | 0 | (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { |
2487 | 0 | delay = hSbrEncoder->nBitstrDelay + 1; |
2488 | 0 | } else { |
2489 | 0 | delay = hSbrEncoder->nBitstrDelay; |
2490 | 0 | } |
2491 | 0 | } |
2492 | 0 | return delay; |
2493 | 0 | } |
2494 | 0 | INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder) { |
2495 | 0 | INT delay = -1; |
2496 | |
|
2497 | 0 | if (hSbrEncoder) { |
2498 | 0 | delay = hSbrEncoder->nBitstrDelay; |
2499 | 0 | } |
2500 | 0 | return delay; |
2501 | 0 | } |
2502 | | |
2503 | 0 | INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder) { |
2504 | 0 | INT error = -1; |
2505 | 0 | if (hSbrEncoder) { |
2506 | 0 | int el; |
2507 | 0 | for (el = 0; el < hSbrEncoder->noElements; el++) { |
2508 | 0 | hSbrEncoder->sbrElement[el]->sbrBitstreamData.rightBorderFIX = 1; |
2509 | 0 | } |
2510 | 0 | error = 0; |
2511 | 0 | } |
2512 | 0 | return error; |
2513 | 0 | } |
2514 | | |
2515 | 0 | INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) { |
2516 | 0 | INT estimateBitrate = 0; |
2517 | |
|
2518 | 0 | if (hSbrEncoder) { |
2519 | 0 | estimateBitrate += hSbrEncoder->estimateBitrate; |
2520 | 0 | } |
2521 | |
|
2522 | 0 | return estimateBitrate; |
2523 | 0 | } |
2524 | | |
2525 | 0 | INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) { |
2526 | 0 | INT delay = -1; |
2527 | |
|
2528 | 0 | if (hSbrEncoder) { |
2529 | 0 | delay = hSbrEncoder->inputDataDelay; |
2530 | 0 | } |
2531 | 0 | return delay; |
2532 | 0 | } |
2533 | | |
2534 | 0 | INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder) { |
2535 | 0 | INT delay = -1; |
2536 | |
|
2537 | 0 | if (hSbrEncoder) { |
2538 | 0 | delay = hSbrEncoder->sbrDecDelay; |
2539 | 0 | } |
2540 | 0 | return delay; |
2541 | 0 | } |
2542 | | |
2543 | 0 | INT sbrEncoder_GetLibInfo(LIB_INFO *info) { |
2544 | 0 | int i; |
2545 | |
|
2546 | 0 | if (info == NULL) { |
2547 | 0 | return -1; |
2548 | 0 | } |
2549 | | /* search for next free tab */ |
2550 | 0 | for (i = 0; i < FDK_MODULE_LAST; i++) { |
2551 | 0 | if (info[i].module_id == FDK_NONE) break; |
2552 | 0 | } |
2553 | 0 | if (i == FDK_MODULE_LAST) { |
2554 | 0 | return -1; |
2555 | 0 | } |
2556 | 0 | info += i; |
2557 | |
|
2558 | 0 | info->module_id = FDK_SBRENC; |
2559 | 0 | info->version = |
2560 | 0 | LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); |
2561 | 0 | LIB_VERSION_STRING(info); |
2562 | | #ifdef SUPPRESS_BUILD_DATE_INFO |
2563 | | info->build_date = ""; |
2564 | | info->build_time = ""; |
2565 | | #else |
2566 | 0 | info->build_date = __DATE__; |
2567 | 0 | info->build_time = __TIME__; |
2568 | 0 | #endif |
2569 | 0 | info->title = "SBR Encoder"; |
2570 | | |
2571 | | /* Set flags */ |
2572 | 0 | info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_PS_MPEG; |
2573 | | /* End of flags */ |
2574 | |
|
2575 | 0 | return 0; |
2576 | 0 | } |