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 1013343 : 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 1013343 : IF( tmp_tcx_mode > 0 )
75 : {
76 675562 : tcx_mode = tmp_tcx_mode; /*Q0*/
77 675562 : move16();
78 :
79 675562 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
80 : {
81 337781 : L_frameTCX = L_frame; /*Q0*/
82 337781 : move16();
83 : }
84 : ELSE
85 : {
86 337781 : L_frameTCX = shr( L_frame, 1 ); /*Q0*/
87 337781 : move16();
88 : }
89 : }
90 : ELSE
91 : {
92 : /*transition frame*/
93 337781 : L_frameTCX = add( L_frame, shr( L_frame, 2 ) ); /*Q0*/
94 337781 : tcx_mode = TCX_20_CORE;
95 337781 : move16();
96 : }
97 :
98 : /* select table */
99 1013343 : IF( EQ_16( L_frame, L_FRAME48k ) )
100 : {
101 605256 : sfbParam.steBands = mdctStereoBands_32000_640;
102 :
103 605256 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
104 : {
105 403504 : cnt = sfbParam.steBands->bdnCnt_TCX20[0]; /*Q0*/
106 403504 : move16();
107 : }
108 : ELSE
109 : {
110 201752 : cnt = sfbParam.steBands->bndCnt_TCX10[0]; /*Q0*/
111 201752 : move16();
112 : }
113 :
114 605256 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
115 : {
116 403504 : sfbWidths = sfbParam.steBands->bandLengthsTCX20; /*Q0*/
117 403504 : move16();
118 : }
119 : ELSE
120 : {
121 201752 : sfbWidths = sfbParam.steBands->bandLengthsTCX10; /*Q0*/
122 201752 : move16();
123 : }
124 : }
125 : ELSE
126 : {
127 408087 : IF( LT_32( element_brate, IVAS_96k ) )
128 : {
129 258810 : sfbParam.steBands = mdctStereoBands_32000_640;
130 :
131 258810 : SWITCH( L_frame )
132 : {
133 226341 : case L_FRAME32k:
134 226341 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
135 : {
136 150894 : cnt = sfbParam.steBands->bdnCnt_TCX20[1]; /*Q0*/
137 150894 : move16();
138 : }
139 : ELSE
140 : {
141 75447 : cnt = sfbParam.steBands->bndCnt_TCX10[1]; /*Q0*/
142 75447 : move16();
143 : }
144 226341 : 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 32469 : case L_FRAME16k:
158 32469 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
159 : {
160 21646 : cnt = sfbParam.steBands->bdnCnt_TCX20[3]; /*Q0*/
161 21646 : move16();
162 : }
163 : ELSE
164 : {
165 10823 : cnt = sfbParam.steBands->bndCnt_TCX10[3]; /*Q0*/
166 10823 : move16();
167 : }
168 32469 : move16();
169 32469 : BREAK;
170 0 : default:
171 0 : assert( !"Subband division not defined for this frame size" );
172 : return;
173 : }
174 :
175 258810 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
176 : {
177 172540 : sfbWidths = sfbParam.steBands->bandLengthsTCX20; /*Q0*/
178 172540 : move16();
179 : }
180 : ELSE
181 : {
182 86270 : sfbWidths = sfbParam.steBands->bandLengthsTCX10; /*Q0*/
183 86270 : move16();
184 : }
185 : }
186 : ELSE
187 : {
188 149277 : SWITCH( L_frame )
189 : {
190 103710 : case L_FRAME48k:
191 : case L_FRAME32k:
192 103710 : sfbParam.lpcBndsParam = sw32000Hz;
193 103710 : BREAK;
194 0 : case L_FRAME25_6k:
195 0 : sfbParam.lpcBndsParam = sw25600Hz;
196 0 : BREAK;
197 45567 : case L_FRAME16k:
198 45567 : sfbParam.lpcBndsParam = sw16000Hz;
199 45567 : BREAK;
200 0 : default:
201 0 : assert( !"Subband division not defined for this frame size" );
202 : return;
203 : }
204 :
205 149277 : IF( EQ_16( tcx_mode, TCX_20_CORE ) )
206 : {
207 99518 : sfbWidths = sfbParam.lpcBndsParam->bandLengthsTCX20; /*Q0*/
208 99518 : move16();
209 : }
210 : ELSE
211 : {
212 49759 : sfbWidths = sfbParam.lpcBndsParam->bandLengthsTCX10; /*Q0*/
213 49759 : move16();
214 : }
215 149277 : cnt = 64;
216 149277 : move16();
217 : }
218 : }
219 :
220 : /* calc sfb offsets */
221 1013343 : specStartOffset = 0;
222 1013343 : move16();
223 :
224 44176228 : FOR( i = 0; i < cnt; i++ )
225 : {
226 43162885 : sfbOffset[i] = s_min( specStartOffset, L_frameTCX ); /*Q0*/
227 43162885 : move16();
228 43162885 : specStartOffset = add( specStartOffset, sfbWidths[i] ); /*Q0*/
229 :
230 43162885 : IF( GE_16( sfbOffset[i], L_frameTCX ) )
231 : {
232 0 : BREAK;
233 : }
234 : }
235 :
236 1013343 : *sfbCnt = i;
237 1013343 : move16();
238 1013343 : sfbOffset[*sfbCnt] = s_min( specStartOffset, L_frameTCX ); /*Q0*/
239 1013343 : move16();
240 :
241 1013343 : IF( igf )
242 : {
243 639684 : Word16 sfbOldCnt = *sfbCnt;
244 : Word16 igfSfbStep;
245 639684 : IF( hIgfGrid->infoIsRefined )
246 : {
247 268803 : igfSfbStep = 2;
248 268803 : move16();
249 : }
250 : ELSE
251 : {
252 370881 : igfSfbStep = 1;
253 370881 : move16();
254 : }
255 : Word16 k;
256 639684 : move16();
257 639684 : move16();
258 :
259 : /* modify sfb bands according to igf grid */
260 639684 : assert( hIgfGrid != NULL );
261 :
262 : /* find sfb where IGF starts */
263 21776996 : FOR( i = 0; i <= *sfbCnt; i++ )
264 : {
265 21776996 : IF( GE_16( sfbOffset[i], hIgfGrid->startLine ) )
266 : {
267 : /* set band border to igf start line */
268 639684 : sfbOffset[i] = hIgfGrid->startLine; /*Q0*/
269 639684 : move16();
270 639684 : *sfbCnt = i;
271 639684 : move16();
272 639684 : BREAK;
273 : }
274 : }
275 : /* change bands above the igf start line to match igf bands */
276 4008732 : FOR( ( i = 1, k = igfSfbStep ); i < hIgfGrid->swb_offset_len; ( i++, k += igfSfbStep ) )
277 : {
278 3369048 : sfbOffset[( *sfbCnt + i )] = hIgfGrid->swb_offset[k]; /*Q0*/
279 3369048 : move16();
280 : }
281 :
282 639684 : *sfbCnt = add( *sfbCnt, sub( hIgfGrid->swb_offset_len, 1 ) ); /*Q0*/
283 639684 : move16();
284 :
285 : /* better save than sorry, overwrite anything that is left above */
286 1774772 : FOR( i = ( *sfbCnt + 1 ); i < ( sfbOldCnt + 1 ); i++ )
287 : {
288 1135088 : sfbOffset[i] = 0;
289 1135088 : move16();
290 : }
291 : }
292 : ELSE
293 : {
294 373659 : IF( LT_16( sfbOffset[*sfbCnt], L_frameTCX ) )
295 : {
296 135376 : Word16 nMissingBins = sub( L_frameTCX, sfbOffset[*sfbCnt] ); /*Q0*/
297 135376 : IF( LT_16( shr( sfbWidths[i], 1 ), nMissingBins ) )
298 : {
299 124553 : *sfbCnt = add( *sfbCnt, 1 );
300 124553 : move16();
301 : }
302 135376 : sfbOffset[*sfbCnt] = L_frameTCX; /*Q0*/
303 135376 : move16();
304 : }
305 : }
306 1013343 : 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 818464 : 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 818464 : bitRateIndex = IGF_MapBitRateToIndex( element_brate, bwidth, IVAS_CPE_MDCT, 0 ); /*Q0*/
326 818464 : swb_offset = &swb_offset_LB_new[bitRateIndex][1];
327 818464 : igfStartLine = IGF_ApplyTransFac( swb_offset[0], transFac ); /*Q0*/
328 :
329 27721029 : FOR( i = 0; i < stbParams->sfbCnt; i++ )
330 : {
331 27721029 : IF( EQ_16( igfStartLine, stbParams->sfbOffset[i] ) )
332 : {
333 818464 : stbParams->sfbIgfStart = i;
334 818464 : move16();
335 818464 : BREAK;
336 : }
337 : }
338 :
339 818464 : stbParams->nBandsStereoCore = stbParams->sfbIgfStart; /*Q0*/
340 818464 : move16();
341 :
342 :
343 818464 : return;
344 : }
|