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