Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include "ivas_cnst.h"
37 : #include "ivas_rom_com.h"
38 : #include "rom_com.h"
39 : #include "prot_fx.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 : /*-------------------------------------------------------------------*
44 : * Local union
45 : *-------------------------------------------------------------------*/
46 :
47 : typedef union
48 : {
49 : MDCTStereoBands_config const *steBands;
50 : SpectrumWarping const *lpcBndsParam;
51 : } SBPARAMS;
52 :
53 :
54 : /*-------------------------------------------------------------------*
55 : * stereo_mdct_init_bands()
56 : *
57 : * initialize stereo band tables for MDCT stereo
58 : *-------------------------------------------------------------------*/
59 :
60 791991 : void stereo_mdct_init_bands_fx(
61 : const Word16 L_frame, /* i : frame length Q0*/
62 : const Word16 tmp_tcx_mode, /* i : tcx mode (TCX10, TCX 20), -1 if transition frame Q0*/
63 : const Word32 element_brate, /* i : element bitrate Q0*/
64 : const Word16 igf, /* i : flag indicating if IGF is used Q0*/
65 : const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */
66 : Word16 *sfbOffset, /* o : sfb offset table Q0*/
67 : Word16 *sfbCnt /* o : number of sfbs Q0*/
68 : )
69 : {
70 : SBPARAMS sfbParam;
71 : Word16 i, cnt, specStartOffset, L_frameTCX, tcx_mode;
72 : const UWord8 *sfbWidths;
73 :
74 791991 : IF( tmp_tcx_mode > 0 )
75 : {
76 527994 : tcx_mode = tmp_tcx_mode; /*Q0*/
77 527994 : move16();
78 :
79 527994 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
80 : {
81 263997 : L_frameTCX = L_frame; /*Q0*/
82 263997 : move16();
83 : }
84 : ELSE
85 : {
86 263997 : L_frameTCX = shr( L_frame, 1 ); /*Q0*/
87 263997 : move16();
88 : }
89 : }
90 : ELSE
91 : {
92 : /*transition frame*/
93 263997 : L_frameTCX = add( L_frame, shr( L_frame, 2 ) ); /*Q0*/
94 263997 : tcx_mode = TCX_20_CORE;
95 263997 : move16();
96 : }
97 :
98 : /* select table */
99 791991 : IF( EQ_16( L_frame, L_FRAME48k ) )
100 : {
101 487008 : sfbParam.steBands = mdctStereoBands_32000_640;
102 :
103 487008 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
104 : {
105 324672 : cnt = sfbParam.steBands->bdnCnt_TCX20[0]; /*Q0*/
106 324672 : move16();
107 : }
108 : ELSE
109 : {
110 162336 : cnt = sfbParam.steBands->bndCnt_TCX10[0]; /*Q0*/
111 162336 : move16();
112 : }
113 :
114 487008 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
115 : {
116 324672 : sfbWidths = sfbParam.steBands->bandLengthsTCX20; /*Q0*/
117 324672 : move16();
118 : }
119 : ELSE
120 : {
121 162336 : sfbWidths = sfbParam.steBands->bandLengthsTCX10; /*Q0*/
122 162336 : move16();
123 : }
124 : }
125 : ELSE
126 : {
127 304983 : IF( LT_32( element_brate, IVAS_96k ) )
128 : {
129 162306 : sfbParam.steBands = mdctStereoBands_32000_640;
130 :
131 162306 : SWITCH( L_frame )
132 : {
133 130152 : case L_FRAME32k:
134 130152 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
135 : {
136 86768 : cnt = sfbParam.steBands->bdnCnt_TCX20[1]; /*Q0*/
137 86768 : move16();
138 : }
139 : ELSE
140 : {
141 43384 : cnt = sfbParam.steBands->bndCnt_TCX10[1]; /*Q0*/
142 43384 : move16();
143 : }
144 130152 : BREAK;
145 0 : case L_FRAME25_6k:
146 0 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
147 : {
148 0 : cnt = sfbParam.steBands->bdnCnt_TCX20[2]; /*Q0*/
149 0 : move16();
150 : }
151 : ELSE
152 : {
153 0 : cnt = sfbParam.steBands->bndCnt_TCX10[2]; /*Q0*/
154 0 : move16();
155 : }
156 0 : BREAK;
157 32154 : case L_FRAME16k:
158 32154 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
159 : {
160 21436 : cnt = sfbParam.steBands->bdnCnt_TCX20[3]; /*Q0*/
161 21436 : move16();
162 : }
163 : ELSE
164 : {
165 10718 : cnt = sfbParam.steBands->bndCnt_TCX10[3]; /*Q0*/
166 10718 : move16();
167 : }
168 32154 : move16();
169 32154 : BREAK;
170 0 : default:
171 0 : assert( !"Subband division not defined for this frame size" );
172 : return;
173 : }
174 :
175 162306 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
176 : {
177 108204 : sfbWidths = sfbParam.steBands->bandLengthsTCX20; /*Q0*/
178 108204 : move16();
179 : }
180 : ELSE
181 : {
182 54102 : sfbWidths = sfbParam.steBands->bandLengthsTCX10; /*Q0*/
183 54102 : move16();
184 : }
185 : }
186 : ELSE
187 : {
188 142677 : SWITCH( L_frame )
189 : {
190 97479 : case L_FRAME48k:
191 : case L_FRAME32k:
192 97479 : sfbParam.lpcBndsParam = sw32000Hz;
193 97479 : BREAK;
194 0 : case L_FRAME25_6k:
195 0 : sfbParam.lpcBndsParam = sw25600Hz;
196 0 : BREAK;
197 45198 : case L_FRAME16k:
198 45198 : sfbParam.lpcBndsParam = sw16000Hz;
199 45198 : BREAK;
200 0 : default:
201 0 : assert( !"Subband division not defined for this frame size" );
202 : return;
203 : }
204 :
205 142677 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
206 : {
207 95118 : sfbWidths = sfbParam.lpcBndsParam->bandLengthsTCX20; /*Q0*/
208 95118 : move16();
209 : }
210 : ELSE
211 : {
212 47559 : sfbWidths = sfbParam.lpcBndsParam->bandLengthsTCX10; /*Q0*/
213 47559 : move16();
214 : }
215 142677 : cnt = 64;
216 142677 : move16();
217 : }
218 : }
219 :
220 : /* calc sfb offsets */
221 791991 : specStartOffset = 0;
222 791991 : move16();
223 :
224 35196167 : FOR( i = 0; i < cnt; i++ )
225 : {
226 34404176 : sfbOffset[i] = s_min( specStartOffset, L_frameTCX ); /*Q0*/
227 34404176 : move16();
228 34404176 : specStartOffset = add( specStartOffset, sfbWidths[i] ); /*Q0*/
229 :
230 34404176 : IF( GE_16( sfbOffset[i], L_frameTCX ) )
231 : {
232 0 : BREAK;
233 : }
234 : }
235 :
236 791991 : *sfbCnt = i;
237 791991 : move16();
238 791991 : sfbOffset[*sfbCnt] = s_min( specStartOffset, L_frameTCX ); /*Q0*/
239 791991 : move16();
240 :
241 791991 : IF( igf )
242 : {
243 435162 : Word16 sfbOldCnt = *sfbCnt;
244 : Word16 igfSfbStep;
245 435162 : IF( hIgfGrid->infoIsRefined )
246 : {
247 268803 : igfSfbStep = 2;
248 268803 : move16();
249 : }
250 : ELSE
251 : {
252 166359 : igfSfbStep = 1;
253 166359 : move16();
254 : }
255 : Word16 k;
256 435162 : move16();
257 435162 : move16();
258 :
259 : /* modify sfb bands according to igf grid */
260 435162 : assert( hIgfGrid != NULL );
261 :
262 : /* find sfb where IGF starts */
263 15082658 : FOR( i = 0; i <= *sfbCnt; i++ )
264 : {
265 15082658 : IF( GE_16( sfbOffset[i], hIgfGrid->startLine ) )
266 : {
267 : /* set band border to igf start line */
268 435162 : sfbOffset[i] = hIgfGrid->startLine; /*Q0*/
269 435162 : move16();
270 435162 : *sfbCnt = i;
271 435162 : move16();
272 435162 : BREAK;
273 : }
274 : }
275 : /* change bands above the igf start line to match igf bands */
276 2571934 : FOR( ( i = 1, k = igfSfbStep ); i < hIgfGrid->swb_offset_len; ( i++, k += igfSfbStep ) )
277 : {
278 2136772 : sfbOffset[( *sfbCnt + i )] = hIgfGrid->swb_offset[k]; /*Q0*/
279 2136772 : move16();
280 : }
281 :
282 435162 : *sfbCnt = add( *sfbCnt, sub( hIgfGrid->swb_offset_len, 1 ) ); /*Q0*/
283 435162 : move16();
284 :
285 : /* better save than sorry, overwrite anything that is left above */
286 1133893 : FOR( i = ( *sfbCnt + 1 ); i < ( sfbOldCnt + 1 ); i++ )
287 : {
288 698731 : sfbOffset[i] = 0;
289 698731 : move16();
290 : }
291 : }
292 : ELSE
293 : {
294 356829 : IF( LT_16( sfbOffset[*sfbCnt], L_frameTCX ) )
295 : {
296 129661 : Word16 nMissingBins = sub( L_frameTCX, sfbOffset[*sfbCnt] ); /*Q0*/
297 129661 : IF( LT_16( shr( sfbWidths[i], 1 ), nMissingBins ) )
298 : {
299 118943 : *sfbCnt = add( *sfbCnt, 1 );
300 118943 : move16();
301 : }
302 129661 : sfbOffset[*sfbCnt] = L_frameTCX; /*Q0*/
303 129661 : move16();
304 : }
305 : }
306 791991 : return;
307 : }
308 :
309 : /*-------------------------------------------------------------------*
310 : * stereo_mdct_init_igf_start_band()
311 : *
312 : * initialize start band of the IGF in MDCT stereo
313 : *-------------------------------------------------------------------*/
314 :
315 435162 : void stereo_mdct_init_igf_start_band_fx(
316 : STEREO_MDCT_BAND_PARAMETERS *stbParams, /* i/o: stereo frequency band parameters */
317 : const Word16 transFac, /* i : transform factor Q14*/
318 : const Word16 bwidth, /* i : audio bandwidth Q0*/
319 : const Word32 element_brate /* i : element bitrate Q0*/
320 : )
321 : {
322 : Word16 i, bitRateIndex, igfStartLine;
323 : const Word16 *swb_offset;
324 :
325 435162 : bitRateIndex = IGF_MapBitRateToIndex( element_brate, bwidth, IVAS_CPE_MDCT, 0 ); /*Q0*/
326 435162 : swb_offset = &swb_offset_LB_new[bitRateIndex][1];
327 435162 : igfStartLine = IGF_ApplyTransFac( swb_offset[0], transFac ); /*Q0*/
328 :
329 15082658 : FOR( i = 0; i < stbParams->sfbCnt; i++ )
330 : {
331 15082658 : IF( EQ_16( igfStartLine, stbParams->sfbOffset[i] ) )
332 : {
333 435162 : stbParams->sfbIgfStart = i;
334 435162 : move16();
335 435162 : BREAK;
336 : }
337 : }
338 :
339 435162 : stbParams->nBandsStereoCore = stbParams->sfbIgfStart; /*Q0*/
340 435162 : move16();
341 :
342 :
343 435162 : return;
344 : }
|