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 <math.h>
36 : #include "options.h"
37 : #include "ivas_cnst.h"
38 : #include "prot_fx.h"
39 : #include "rom_com.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 :
44 : /*-------------------------------------------------------------------*
45 : * Local function prototypes
46 : *-------------------------------------------------------------------*/
47 :
48 : static void inverseBwMS_fx( const Word16 startLine, const Word16 stopLine, Word32 x0[], Word32 x1[], const Word32 norm_fac );
49 :
50 :
51 : #define NF_RED_FAC_FIXED 1610612736 // Q31
52 : #define SQRT2_OVER_2_FIXED 1518500250 // Q31
53 : #define POINT_8_FIXED 1717986918 // Q31
54 : #define POINT_2_FIXED 429496730 // Q31
55 : #define ONE_POINT_3_FIXED 87241523 // Q26
56 : #define POINT_9_FIXED 60397978 // Q26
57 :
58 : /*-------------------------------------------------------------------*
59 : * parse_stereo_from_bitstream
60 : *
61 : *
62 : *-------------------------------------------------------------------*/
63 :
64 169717 : void parse_stereo_from_bitstream(
65 : STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */
66 : Decoder_State **sts, /* i/o: decoder state structure */
67 : const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/
68 : const Word16 isSBAStereoMode, /* i : flag core coding for SBA Q0*/
69 : Decoder_State *st0, /* i/o: decoder state structure for Bstr */
70 : Word16 ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask Q0*/
71 : )
72 : {
73 : Word16 i, k, nSubframes, mdct_stereo_mode;
74 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
75 :
76 169717 : IF( !isSBAStereoMode )
77 : {
78 : // nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) ? NB_DIV : 1;
79 130891 : test();
80 130891 : IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
81 : {
82 3329 : nSubframes = NB_DIV; /* Q0 */
83 3329 : move16();
84 : }
85 : ELSE
86 : {
87 127562 : nSubframes = 1; /* Q0 */
88 127562 : move16();
89 : }
90 130891 : move16();
91 : // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
92 130891 : IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
93 : {
94 127754 : sfbConf = &hStereoMdct->stbParamsTCX20;
95 : }
96 : ELSE
97 : {
98 3137 : sfbConf = &hStereoMdct->stbParamsTCX10;
99 : }
100 130891 : if ( sts[0]->last_core_from_bs == ACELP_CORE )
101 : {
102 620 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
103 : }
104 :
105 130891 : IF( hStereoMdct->use_itd )
106 : {
107 : Word16 I;
108 :
109 11587 : hStereoMdct->itd_mode = extract_l( get_next_indice_fx( st0, STEREO_DFT_ITD_MODE_NBITS ) ); /* Q0 */
110 : /*(*nb_bits) += STEREO_DFT_ITD_MODE_NBITS;*/ /*ITD mode flag: 1bit*/
111 :
112 11587 : hStereoMdct->itd_fx = 0;
113 11587 : move32();
114 11587 : IF( hStereoMdct->itd_mode )
115 : {
116 3503 : /*(*nb_bits) += */ read_itd( st0, &I );
117 3503 : stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
118 : }
119 : }
120 :
121 265111 : FOR( k = 0; k < nSubframes; k++ )
122 : {
123 134220 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
124 134220 : IF( mdct_stereo_mode )
125 : {
126 130501 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
127 : }
128 134220 : SWITCH( mdct_stereo_mode )
129 : {
130 3719 : case 0:
131 3719 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
132 3719 : move16();
133 3719 : BREAK;
134 82193 : case 1:
135 82193 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
136 82193 : move16();
137 82193 : BREAK;
138 48308 : case 2:
139 48308 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
140 48308 : move16();
141 48308 : BREAK;
142 0 : default:
143 0 : assert( !"Not supported stereo mode\n" );
144 : }
145 :
146 134220 : IF( !mct_on )
147 : {
148 43208 : test();
149 43208 : IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
150 : {
151 42947 : hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
152 42947 : move16();
153 42947 : assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
154 : }
155 : ELSE
156 : {
157 261 : hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
158 261 : move16();
159 : }
160 : }
161 :
162 : // set16_fx( ms_mask[k], ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sfbConf->nBandsStereoCore );
163 134220 : IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
164 : {
165 82193 : set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
166 : }
167 : ELSE
168 : {
169 52027 : set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
170 : }
171 :
172 134220 : IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
173 : {
174 2011027 : FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
175 : {
176 1962719 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
177 1962719 : move16();
178 : }
179 : }
180 :
181 134220 : IF( st0->igf )
182 : {
183 88664 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
184 88664 : IF( mdct_stereo_mode )
185 : {
186 53963 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
187 : }
188 :
189 88664 : SWITCH( mdct_stereo_mode )
190 : {
191 34701 : case 0:
192 34701 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
193 34701 : move16();
194 34701 : BREAK;
195 39953 : case 1:
196 39953 : hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
197 39953 : move16();
198 39953 : BREAK;
199 14010 : case 2:
200 14010 : hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
201 14010 : move16();
202 14010 : BREAK;
203 0 : default:
204 0 : assert( !"Not supported stereo mode\n" );
205 : }
206 :
207 : // set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
208 88664 : IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
209 : {
210 39953 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
211 : }
212 : ELSE
213 : {
214 48711 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
215 : }
216 :
217 88664 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
218 : {
219 88433 : FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
220 : {
221 74423 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
222 74423 : move16();
223 : }
224 : }
225 : }
226 : ELSE
227 : {
228 45556 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
229 45556 : move16();
230 : }
231 : }
232 : }
233 :
234 169717 : IF( !mct_on )
235 : {
236 80649 : hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels Q0*/
237 80649 : move16();
238 80649 : hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
239 :
240 80649 : assert( GT_16( hStereoMdct->split_ratio, 0 ) );
241 : }
242 :
243 :
244 169717 : return;
245 : }
246 :
247 :
248 : /*-------------------------------------------------------------------*
249 : * inverseBwMS()
250 : *
251 : * Band-wise M/S stereo processing
252 : *-------------------------------------------------------------------*/
253 1406246 : static void inverseBwMS_fx(
254 : const Word16 startLine, /* i : start line of sfb Q0*/
255 : const Word16 stopLine, /* i : stop line of sfb Q0*/
256 : Word32 x0[], /* i/o: mid/left channel coefficients Qx*/
257 : Word32 x1[], /* i/o: side/right channel coefficients Qx*/
258 : const Word32 norm_fac /* i : normalization factor Q31*/
259 : )
260 : {
261 : Word16 j;
262 : Word32 tmpValue;
263 :
264 77184936 : FOR( j = startLine; j < stopLine; j++ )
265 : {
266 75778690 : tmpValue = x0[j];
267 75778690 : move32();
268 75778690 : x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
269 75778690 : move32();
270 75778690 : x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
271 75778690 : move32();
272 : }
273 :
274 1406246 : return;
275 : }
276 :
277 :
278 : /*-------------------------------------------------------------------*
279 : * inverseMS()
280 : *
281 : * M/S stereo processing
282 : *-------------------------------------------------------------------*/
283 167940 : void inverseMS_fx(
284 : const Word16 L_frame, /* i : frame length Q0*/
285 : Word32 x0[], /* i/o: mid/left channel coefficients Qx*/
286 : Word32 x1[], /* i/o: side/right channel coefficients Qx*/
287 : const Word32 norm_fac /* i : normalization factor Q31*/
288 : )
289 : {
290 167940 : inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
291 :
292 167940 : return;
293 : }
294 :
295 :
296 : /*-------------------------------------------------------------------*
297 : * stereo_decoder_tcx()
298 : *
299 : * apply stereo processing (inverse MS and global ILD)
300 : *-------------------------------------------------------------------*/
301 131655 : void stereo_decoder_tcx_fx(
302 : STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */
303 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/
304 : Word32 *spec_r_0[NB_DIV], /* i/o: spectrum right channel Qx*/
305 : Word32 *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] Qx*/
306 : Word32 *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] Qx*/
307 : const Word16 mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono Q0*/
308 : const Word16 core_l, /* i : core for left channel (TCX20/TCX10) Q0*/
309 : const Word16 core_r, /* i : core for right channel (TCX20/TCX10) Q0*/
310 : const Word16 igf, /* i : flag for IGF activity Q0*/
311 : const Word16 L_frameTCX_l, /* i : TCX frame length of left channel Q0*/
312 : const Word16 L_frameTCX_r, /* i : TCX frame length of right channel Q0*/
313 : const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/
314 : const Word16 last_core_l, /* i : last core for left channel Q0*/
315 : const Word16 last_core_r, /* i : last core for right channel Q0*/
316 : const Word16 tmp_plc_upmix /* i : indicates temp upmix for PLC decision Q0*/
317 : )
318 : {
319 : Word16 i, k, sfb, nSubframes;
320 131655 : STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
321 : Word32 nrgRatio, inv_nrgRatio, tmp_32;
322 : Word16 tmp_e, shift;
323 :
324 131655 : nSubframes = 2;
325 131655 : move16();
326 131655 : test();
327 131655 : test();
328 131655 : if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
329 : {
330 128321 : nSubframes = 1; /* Q0 */
331 128321 : move16();
332 : }
333 :
334 266644 : FOR( k = 0; k < nSubframes; k++ )
335 : {
336 : // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
337 134989 : IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
338 : {
339 128706 : sfbConf = &hStereoMdct->stbParamsTCX20;
340 : }
341 : ELSE
342 : {
343 6283 : sfbConf = &hStereoMdct->stbParamsTCX10;
344 : }
345 :
346 134989 : test();
347 134989 : if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
348 : {
349 630 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
350 : }
351 :
352 134989 : IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
353 : {
354 45130871 : FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
355 : {
356 45048316 : IF( EQ_32( spec_r_0[k][i], 0 ) )
357 : {
358 12320425 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
359 12320425 : move32();
360 : }
361 : }
362 82555 : inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
363 : }
364 52434 : ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
365 : {
366 2025627 : FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
367 : {
368 1976955 : IF( ms_mask[k][sfb] )
369 : {
370 17164018 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
371 : {
372 15965280 : IF( EQ_32( spec_r_0[k][i], 0 ) )
373 : {
374 4496455 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
375 4496455 : move32();
376 : }
377 : }
378 1198738 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
379 : }
380 : }
381 : }
382 :
383 134989 : IF( igf )
384 : {
385 89072 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
386 : {
387 12144590 : FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
388 : {
389 12104538 : IF( EQ_32( spec_r_0[k][i], 0 ) )
390 : {
391 3755101 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
392 3755101 : move32();
393 : }
394 : }
395 40052 : inverseMS_fx( sub( sfbConf->sfbOffset[sfbConf->sfbCnt], sfbConf->sfbOffset[sfbConf->nBandsStereoCore] ), &spec_l[k][sfbConf->sfbOffset[sfbConf->nBandsStereoCore]], &spec_r[k][sfbConf->sfbOffset[sfbConf->nBandsStereoCore]], SQRT2_OVER_2_FIXED );
396 : }
397 49020 : ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
398 : {
399 88748 : FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
400 : {
401 74696 : IF( ms_mask[k][sfb] )
402 : {
403 1972014 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
404 : {
405 1932446 : IF( EQ_32( spec_r_0[k][i], 0 ) )
406 : {
407 679173 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
408 679173 : move32();
409 : }
410 : }
411 39568 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
412 : }
413 : }
414 : }
415 : }
416 :
417 134989 : IF( !mct_on )
418 : {
419 43977 : tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
420 43977 : tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
421 43977 : nrgRatio = L_sub( tmp_32, ONE_IN_Q26 ); // Q26
422 :
423 43977 : hStereoMdct->smooth_ratio_fx = W_extract_h( W_mac_32_32( W_mult_32_32( POINT_8_FIXED, hStereoMdct->smooth_ratio_fx ), POINT_2_FIXED, nrgRatio ) ); // Q26
424 43977 : move32();
425 : /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
426 43977 : IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FIXED ) )
427 : {
428 16467 : hStereoMdct->reverse_dmx = 1; /* Q0 */
429 16467 : move16();
430 : }
431 27510 : ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FIXED ) )
432 : {
433 7877 : hStereoMdct->reverse_dmx = 0; /* Q0 */
434 7877 : move16();
435 : }
436 :
437 43977 : Word16 tmp1, tmp2 = 0;
438 :
439 43977 : IF( EQ_16( core_r, TCX_10_CORE ) )
440 : {
441 2645 : tmp1 = NB_DIV;
442 2645 : move16();
443 : }
444 : ELSE
445 : {
446 41332 : tmp1 = 1;
447 41332 : move16();
448 : }
449 :
450 43977 : IF( EQ_16( core_l, TCX_10_CORE ) )
451 : {
452 2395 : tmp2 = NB_DIV;
453 2395 : move16();
454 : }
455 : ELSE
456 : {
457 41582 : tmp2 = 1;
458 41582 : move16();
459 : }
460 :
461 43977 : test();
462 43977 : test();
463 43977 : IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
464 : {
465 21508 : shift = norm_l( nrgRatio );
466 21508 : nrgRatio = L_shl( nrgRatio, shift ); /* Q26 + shift */
467 21508 : v_multc_fixed( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
468 21508 : Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) ); /* Qx */
469 : }
470 22469 : ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
471 : {
472 9310 : inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
473 9310 : shift = sub( 5, tmp_e );
474 9310 : v_multc_fixed( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
475 9310 : Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) ); /* Qx */
476 : }
477 : }
478 : } /* for k */
479 :
480 131655 : return;
481 : }
482 :
483 :
484 : /*-------------------------------------------------------------------*
485 : * initMdctStereoDecData()
486 : *
487 : * Initialize MDCT stereo decoder configuration
488 : *-------------------------------------------------------------------*/
489 :
490 288370 : void initMdctStereoDecData_fx(
491 : STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */
492 : const Word16 igf, /* i : flag indicating IGF activity Q0*/
493 : const H_IGF_GRID igfGrid, /* i : IGF grid configuration Q0*/
494 : const Word32 element_brate, /* i : element bitrate Q0*/
495 : const Word16 bwidth /* i : audio bandwidth Q0*/
496 : )
497 : {
498 : Word16 tcx_coded_lines;
499 :
500 288370 : tcx_coded_lines = getNumTcxCodedLines( bwidth );
501 :
502 : /*Initialize sfb parameteres for TCX20 */
503 288370 : stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_20_CORE, element_brate, igf, &igfGrid[IGF_GRID_LB_NORM], &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
504 :
505 : /*Initialize sfb parameteres for TCX10 */
506 288370 : stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_10_CORE, element_brate, igf, &igfGrid[IGF_GRID_LB_SHORT], &hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
507 :
508 : /*Initialize sfb parameteres for transition frames */
509 288370 : stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, &igfGrid[IGF_GRID_LB_TRAN], &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
510 :
511 288370 : IF( igf )
512 : {
513 : /* calculate the igf start band from the igf start line */
514 159342 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
515 159342 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
516 159342 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
517 : }
518 : ELSE
519 : {
520 129028 : hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
521 129028 : move16();
522 129028 : hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
523 129028 : move16();
524 129028 : hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
525 129028 : move16();
526 129028 : hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
527 129028 : move16();
528 129028 : hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
529 129028 : move16();
530 129028 : hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
531 129028 : move16();
532 : }
533 :
534 288370 : return;
535 : }
536 :
537 :
538 : /*-------------------------------------------------------------------*
539 : * initMdctStereoDtxData()
540 : *
541 : * Allocate and initialize structures for MDCT-Stereo DTX operation
542 : *-------------------------------------------------------------------*/
543 :
544 31 : ivas_error initMdctStereoDtxData_fx(
545 : CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
546 : )
547 : {
548 : Word16 ch;
549 : ivas_error error;
550 :
551 31 : error = IVAS_ERR_OK;
552 31 : move16();
553 :
554 93 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
555 : {
556 62 : DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
557 :
558 62 : IF( st->hFdCngDec == NULL )
559 : {
560 : /* Create FD_CNG instance */
561 0 : IF( NE_32( ( error = createFdCngDec_fx( &st->hFdCngDec ) ), IVAS_ERR_OK ) )
562 : {
563 0 : return error;
564 : }
565 :
566 : /* Init FD-CNG */
567 0 : initFdCngDec_ivas_fx( st, st->cldfbSyn->scale );
568 : }
569 :
570 62 : IF( st->first_CNG == 0 )
571 : {
572 58 : test();
573 58 : IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
574 : {
575 17 : st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
576 17 : move16();
577 : }
578 : }
579 :
580 62 : IF( st->cldfbAna == NULL )
581 : {
582 : /* open analysis for max. sampling rate 48kHz */
583 50 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
584 : {
585 0 : return error;
586 : }
587 : }
588 :
589 62 : IF( st->cldfbBPF == NULL )
590 : {
591 : /* open analysis BPF for max. internal sampling rate 16kHz */
592 50 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
593 : {
594 0 : return error;
595 : }
596 : }
597 : }
598 :
599 31 : return error;
600 : }
601 :
602 :
603 : /*-------------------------------------------------------------------*
604 : * synchonize_channels_mdct_sid()
605 : *
606 : * Synchronize channels in SID frame in MDCT stereo
607 : *-------------------------------------------------------------------*/
608 :
609 1066221 : void synchonize_channels_mdct_sid_fx(
610 : Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure */
611 : const Word16 n /* i : channel number Q0*/
612 : )
613 : {
614 : Decoder_State *st;
615 :
616 1066221 : st = sts[n];
617 :
618 1066221 : test();
619 1066221 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
620 : {
621 912 : IF( EQ_16( n, 1 ) )
622 : {
623 : /* synchronize channels */
624 456 : sts[1]->L_frame = sts[0]->L_frame;
625 456 : move16();
626 456 : sts[1]->cng_type = sts[0]->cng_type;
627 456 : move16();
628 456 : sts[1]->bwidth = sts[0]->bwidth;
629 456 : move16();
630 456 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
631 456 : move16();
632 456 : sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
633 456 : move16();
634 :
635 : /* configure when there is a switching from DFT CNG to MDCT CNG */
636 456 : test();
637 456 : IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
638 : {
639 0 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
640 : }
641 : }
642 :
643 912 : IF( sts[0]->first_CNG == 0 )
644 : {
645 : /* configure CNG after reading first side info from SID to get correct values for L_frame and bwidth if first SID is also first valid frame */
646 58 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
647 : }
648 : }
649 :
650 1066221 : return;
651 : }
652 :
653 :
654 : /*-------------------------------------------------------------------*
655 : * updateBuffersForDmxMdctStereo()
656 : *
657 : * synch buffers between channels for mono output and
658 : * apply passive downmix to certain buffers to enable smooth transitions
659 : * between active/inactive coding in MDCT-Stereo DTX
660 : *-------------------------------------------------------------------*/
661 :
662 : // helper function
663 : static void update_exp( Word16 *a_exp, Word16 *b_exp, Word16 *buff_a, Word16 *buff_b, Word16 legth );
664 :
665 3273 : static void update_exp(
666 : Word16 *a_exp,
667 : Word16 *b_exp,
668 : Word16 *buff_a, /* exp(a_exp) */
669 : Word16 *buff_b, /* exp(b_exp) */
670 : Word16 legth /* Q0 */
671 : )
672 : {
673 3273 : Word16 diff = 0;
674 3273 : move16();
675 3273 : IF( GT_16( *a_exp, *b_exp ) )
676 : {
677 1036 : diff = sub( *a_exp, *b_exp );
678 988012 : FOR( Word16 j = 0; j < legth; j++ )
679 : {
680 986976 : buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
681 986976 : move16();
682 : }
683 1036 : *b_exp = *a_exp;
684 1036 : move16();
685 : }
686 2237 : ELSE IF( LT_16( *a_exp, *b_exp ) )
687 : {
688 34 : diff = sub( *b_exp, *a_exp );
689 :
690 18454 : FOR( Word16 j = 0; j < legth; j++ )
691 : {
692 18420 : buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
693 18420 : move16();
694 : }
695 34 : *a_exp = *b_exp;
696 34 : move16();
697 : }
698 3273 : return;
699 : }
700 :
701 1129 : void updateBuffersForDmxMdctStereo_fx(
702 : CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */
703 : const Word16 output_frame, /* i : output frame length Q0*/
704 : Word32 output0_fx[], /* Qx */
705 : Word32 output1_fx[], /* Qx */
706 : Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis qsynth*/
707 : )
708 : {
709 : Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
710 : Decoder_State *sts[CPE_CHANNELS];
711 :
712 1129 : sts[0] = hCPE->hCoreCoder[0];
713 1129 : sts[1] = hCPE->hCoreCoder[1];
714 :
715 : /* synch buffers for inactive frames, but not for transition frames */
716 1129 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
717 : {
718 1091 : Copy32( output0_fx, output1_fx, output_frame );
719 1091 : Copy( synth_fx[0], synth_fx[1], output_frame );
720 : }
721 :
722 1129 : Word32 Var1 = 0;
723 1129 : move16();
724 1129 : Word16 diff_sidNoiseEst = 0;
725 1129 : move16();
726 1129 : Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
727 1129 : move16();
728 1129 : Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
729 1129 : move16();
730 1129 : IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
731 : {
732 14 : diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
733 350 : FOR( Word32 j = 0; j < NPART; j++ )
734 : {
735 336 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
736 336 : move16();
737 : }
738 14 : exp_sidNoiseEst1 = exp_sidNoiseEst0;
739 14 : move16();
740 : }
741 1115 : ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
742 : {
743 9 : diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
744 225 : FOR( Word32 j = 0; j < NPART; j++ )
745 : {
746 216 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
747 216 : move16();
748 : }
749 9 : exp_sidNoiseEst0 = exp_sidNoiseEst1;
750 9 : move16();
751 : }
752 1129 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
753 1129 : move16();
754 1129 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
755 1129 : move16();
756 1129 : test();
757 1129 : test();
758 1129 : IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
759 : {
760 : /* in the first SID frame after an active frame, create mid noise shape here, in SID frames that follow inactive frames, it is done directly in the SID decoding since the mid shape is being used in CNG then */
761 923 : FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
762 : {
763 885 : Var1 = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); // exp_sidNoiseEst0 - 1
764 885 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 ); // 31 - exp_sidNoiseEst0 - 1 + 31 - 31
765 885 : move32();
766 : }
767 : }
768 :
769 : /* for transition of active->inactive frame, apply passive downmix on buffers */
770 1129 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
771 : {
772 1091 : delta = 1;
773 1091 : move16();
774 1091 : IF( EQ_16( output_frame, L_FRAME16k ) )
775 : {
776 350 : delta = 2;
777 350 : move16();
778 : }
779 741 : ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
780 : {
781 358 : delta = 4;
782 358 : move16();
783 : }
784 383 : ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
785 : {
786 383 : delta = 6;
787 383 : move16();
788 : }
789 :
790 1091 : delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP ); /* Q0 */
791 1091 : tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
792 1091 : move16();
793 :
794 1091 : assert( delay_buf_out_len > tcxltp_mem_in_len );
795 :
796 1091 : Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
797 1091 : move16();
798 1091 : move16();
799 1091 : move16();
800 1091 : move16();
801 :
802 1091 : Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, -11 ); // Q0
803 1091 : Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_in_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, -11 ); // Q0
804 :
805 1091 : Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
806 1091 : Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
807 :
808 1091 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
809 1091 : move16();
810 1091 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
811 1091 : move16();
812 :
813 1091 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
814 1091 : move16();
815 1091 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
816 1091 : move16();
817 :
818 :
819 1091 : Scale_sig( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
820 1091 : Scale_sig( &sts[1]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, sub( 15, sts[1]->hTcxLtpDec->exp_tcxltp_mem_in ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
821 :
822 1091 : Scale_sig( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], TCXLTP_MAX_DELAY, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_out)
823 1091 : Scale_sig( &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], TCXLTP_MAX_DELAY, sub( 15, sts[1]->hTcxLtpDec->exp_tcxltp_mem_out ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
824 :
825 :
826 1091 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
827 1091 : sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
828 :
829 1091 : update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
830 1091 : sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
831 :
832 1091 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
833 1091 : sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
834 :
835 9951 : FOR( i = 0; i < tcxltp_mem_in_len; i++ )
836 : {
837 8860 : sum_tcx_ltp = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_in[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_in[i], 1 ) ); // exp_tcxltp_mem_in + 1
838 8860 : sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp ); // exp_tcxltp_mem_in + 1
839 8860 : move16();
840 :
841 8860 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
842 8860 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
843 8860 : move16();
844 :
845 8860 : sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); // exp_old_out + 1
846 8860 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
847 8860 : move16();
848 :
849 8860 : sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
850 8860 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
851 8860 : move16();
852 : }
853 :
854 :
855 36531 : FOR( ; i < delay_buf_out_len; i++ )
856 : {
857 35440 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
858 35440 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
859 35440 : move16();
860 :
861 35440 : sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); /* exp_old_out + 1 */
862 35440 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); /* exp_old_out + 1 */
863 35440 : move16();
864 :
865 35440 : sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
866 35440 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
867 35440 : move16();
868 : }
869 :
870 665591 : FOR( ; i < output_frame; i++ )
871 : {
872 664500 : sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); // exp_old_out + 1
873 664500 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
874 664500 : move16();
875 :
876 664500 : sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
877 664500 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
878 664500 : move16();
879 : }
880 1091 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
881 1091 : move16();
882 1091 : sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
883 1091 : move16();
884 1091 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
885 1091 : move16();
886 1091 : Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11
887 1091 : Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11
888 : }
889 :
890 1129 : return;
891 : }
892 :
893 :
894 : /*-------------------------------------------------------------------*
895 : * applyDmxMdctStereo()
896 : *
897 : * apply passive downmix to certain buffers to enable smooth transitions
898 : * between active/inactive coding in MDCT-Stereo DTX
899 : *-------------------------------------------------------------------*/
900 :
901 5909 : void applyDmxMdctStereo_fx(
902 : const CPE_DEC_HANDLE hCPE, /* i : CPE handle */
903 : Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output q_out*/
904 : const Word16 output_frame /* i : output frame length Q0*/
905 : )
906 : {
907 : Word16 crossfade_len, i;
908 : Word16 dmx_len;
909 : Word32 fade_fx, step_fx;
910 :
911 5909 : step_fx = ONE_IN_Q31; /* Q31 */
912 5909 : move32();
913 5909 : fade_fx = ONE_IN_Q31; /* Q31 */
914 5909 : move32();
915 5909 : dmx_len = output_frame; /* Q0 */
916 5909 : move16();
917 :
918 5909 : test();
919 5909 : test();
920 5909 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
921 : {
922 34 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
923 34 : move16();
924 34 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
925 : {
926 14 : case 48000:
927 14 : step_fx = 22369622; /* 0.0104 in Q31 */
928 14 : move32();
929 14 : BREAK;
930 12 : case 32000:
931 12 : step_fx = 33554432; /* 0.0156 in Q31 */
932 12 : move32();
933 12 : BREAK;
934 8 : case 16000:
935 8 : step_fx = 67108864; /* 0.0312 in Q31 */
936 8 : move32();
937 8 : BREAK;
938 0 : default:
939 0 : assert( 0 );
940 : BREAK;
941 : }
942 : }
943 : /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
944 5875 : ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
945 : {
946 38 : crossfade_len = shr( output_frame, 2 ); /* Q0 */
947 38 : SWITCH( output_frame )
948 : {
949 16 : case 960:
950 16 : step_fx = -8947849; /* -0.0041 in Q31 */
951 16 : move32();
952 16 : BREAK;
953 13 : case 640:
954 13 : step_fx = -13421773; /* -0.00625 in Q31 */
955 13 : move32();
956 13 : BREAK;
957 9 : case 320:
958 9 : step_fx = -26843546; /* -0.0125 in Q31 */
959 9 : move32();
960 9 : BREAK;
961 : }
962 38 : fade_fx = 0;
963 38 : move32();
964 38 : dmx_len = crossfade_len; /* Q0 */
965 38 : move16();
966 : }
967 5837 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
968 : {
969 15 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
970 15 : move16();
971 15 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
972 : {
973 15 : case 48000:
974 15 : step_fx = 35791396; /* 0.0166 in Q31 */
975 15 : move32();
976 15 : BREAK;
977 0 : case 32000:
978 0 : step_fx = 53687092; /* 0.025 in Q31 */
979 0 : move32();
980 0 : BREAK;
981 0 : case 16000:
982 0 : step_fx = 107374184; /* 0.05 in Q31 */
983 0 : move32();
984 0 : BREAK;
985 0 : default:
986 0 : assert( 0 );
987 : BREAK;
988 : }
989 : }
990 : ELSE
991 : {
992 5822 : crossfade_len = 0;
993 5822 : move16();
994 : }
995 :
996 : /* apply crossfade */
997 15817 : FOR( i = 0; i < crossfade_len; i++ )
998 : {
999 9908 : Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx ); /* q_out */
1000 9908 : Word32 temp_2 = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), Mpy_32_32( INV_SQRT2_FX, L_sub_sat( ONE_IN_Q31, fade_fx ) ) ); /* q_out */
1001 9908 : output_fx[0][i] = L_add( temp_1, temp_2 ); /* q_out */
1002 9908 : move32();
1003 9908 : fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
1004 : }
1005 :
1006 : /* apply passive downmix on all-active-frame part */
1007 4595281 : FOR( ; i < dmx_len; i++ )
1008 : {
1009 4589372 : output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
1010 4589372 : move32();
1011 : }
1012 :
1013 5909 : return;
1014 : }
|