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 168748 : 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 168748 : 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 130844 : test();
80 130844 : IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
81 : {
82 3331 : nSubframes = NB_DIV; /* Q0 */
83 3331 : move16();
84 : }
85 : ELSE
86 : {
87 127513 : nSubframes = 1; /* Q0 */
88 127513 : move16();
89 : }
90 130844 : move16();
91 : // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
92 130844 : IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
93 : {
94 127705 : sfbConf = &hStereoMdct->stbParamsTCX20;
95 : }
96 : ELSE
97 : {
98 3139 : sfbConf = &hStereoMdct->stbParamsTCX10;
99 : }
100 130844 : if ( sts[0]->last_core_from_bs == ACELP_CORE )
101 : {
102 625 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
103 : }
104 :
105 130844 : IF( hStereoMdct->use_itd )
106 : {
107 : Word16 I;
108 :
109 11591 : 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 11591 : hStereoMdct->itd_fx = 0;
113 11591 : move32();
114 11591 : IF( hStereoMdct->itd_mode )
115 : {
116 3481 : /*(*nb_bits) += */ read_itd( st0, &I );
117 3481 : stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
118 : }
119 : }
120 :
121 265019 : FOR( k = 0; k < nSubframes; k++ )
122 : {
123 134175 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
124 134175 : IF( mdct_stereo_mode )
125 : {
126 130438 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
127 : }
128 134175 : SWITCH( mdct_stereo_mode )
129 : {
130 3737 : case 0:
131 3737 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
132 3737 : move16();
133 3737 : BREAK;
134 82082 : case 1:
135 82082 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
136 82082 : move16();
137 82082 : BREAK;
138 48356 : case 2:
139 48356 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
140 48356 : move16();
141 48356 : BREAK;
142 0 : default:
143 0 : assert( !"Not supported stereo mode\n" );
144 : }
145 :
146 134175 : IF( !mct_on )
147 : {
148 43215 : test();
149 43215 : IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
150 : {
151 42954 : hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
152 42954 : move16();
153 42954 : 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 134175 : IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
164 : {
165 82082 : set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
166 : }
167 : ELSE
168 : {
169 52093 : set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
170 : }
171 :
172 134175 : IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
173 : {
174 2013479 : FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
175 : {
176 1965123 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
177 1965123 : move16();
178 : }
179 : }
180 :
181 134175 : IF( st0->igf )
182 : {
183 88640 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
184 88640 : IF( mdct_stereo_mode )
185 : {
186 53933 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
187 : }
188 :
189 88640 : SWITCH( mdct_stereo_mode )
190 : {
191 34707 : case 0:
192 34707 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
193 34707 : move16();
194 34707 : BREAK;
195 40035 : case 1:
196 40035 : hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
197 40035 : move16();
198 40035 : BREAK;
199 13898 : case 2:
200 13898 : hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
201 13898 : move16();
202 13898 : 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 88640 : IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
209 : {
210 40035 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
211 : }
212 : ELSE
213 : {
214 48605 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
215 : }
216 :
217 88640 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
218 : {
219 87505 : FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
220 : {
221 73607 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
222 73607 : move16();
223 : }
224 : }
225 : }
226 : ELSE
227 : {
228 45535 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
229 45535 : move16();
230 : }
231 : }
232 : }
233 :
234 168748 : IF( !mct_on )
235 : {
236 79731 : hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels Q0*/
237 79731 : move16();
238 79731 : hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
239 :
240 79731 : assert( GT_16( hStereoMdct->split_ratio, 0 ) );
241 : }
242 :
243 :
244 168748 : return;
245 : }
246 :
247 :
248 : /*-------------------------------------------------------------------*
249 : * inverseBwMS()
250 : *
251 : * Band-wise M/S stereo processing
252 : *-------------------------------------------------------------------*/
253 1405820 : 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 77153054 : FOR( j = startLine; j < stopLine; j++ )
265 : {
266 75747234 : tmpValue = x0[j];
267 75747234 : move32();
268 75747234 : x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
269 75747234 : move32();
270 75747234 : x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
271 75747234 : move32();
272 : }
273 :
274 1405820 : return;
275 : }
276 :
277 :
278 : /*-------------------------------------------------------------------*
279 : * inverseMS()
280 : *
281 : * M/S stereo processing
282 : *-------------------------------------------------------------------*/
283 167034 : 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 167034 : inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
291 :
292 167034 : return;
293 : }
294 :
295 :
296 : /*-------------------------------------------------------------------*
297 : * stereo_decoder_tcx()
298 : *
299 : * apply stereo processing (inverse MS and global ILD)
300 : *-------------------------------------------------------------------*/
301 131608 : 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 131608 : STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
321 : Word32 nrgRatio, inv_nrgRatio, tmp_32;
322 : Word16 tmp_e, shift;
323 :
324 131608 : nSubframes = 2;
325 131608 : move16();
326 131608 : test();
327 131608 : test();
328 131608 : if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
329 : {
330 128272 : nSubframes = 1; /* Q0 */
331 128272 : move16();
332 : }
333 :
334 266552 : FOR( k = 0; k < nSubframes; k++ )
335 : {
336 : // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
337 134944 : IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
338 : {
339 128653 : sfbConf = &hStereoMdct->stbParamsTCX20;
340 : }
341 : ELSE
342 : {
343 6291 : sfbConf = &hStereoMdct->stbParamsTCX10;
344 : }
345 :
346 134944 : test();
347 134944 : if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
348 : {
349 635 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
350 : }
351 :
352 134944 : IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
353 : {
354 45102201 : FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
355 : {
356 45019760 : IF( EQ_32( spec_r_0[k][i], 0 ) )
357 : {
358 12326271 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
359 12326271 : move32();
360 : }
361 : }
362 82441 : inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
363 : }
364 52503 : ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
365 : {
366 2027979 : FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
367 : {
368 1979260 : IF( ms_mask[k][sfb] )
369 : {
370 17165711 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
371 : {
372 15966112 : IF( EQ_32( spec_r_0[k][i], 0 ) )
373 : {
374 4496776 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
375 4496776 : move32();
376 : }
377 : }
378 1199599 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
379 : }
380 : }
381 : }
382 :
383 134944 : IF( igf )
384 : {
385 89052 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
386 : {
387 12175620 : FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
388 : {
389 12135486 : IF( EQ_32( spec_r_0[k][i], 0 ) )
390 : {
391 3781347 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
392 3781347 : move32();
393 : }
394 : }
395 40134 : 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 48918 : ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
398 : {
399 87829 : FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
400 : {
401 73888 : IF( ms_mask[k][sfb] )
402 : {
403 1950937 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
404 : {
405 1911750 : IF( EQ_32( spec_r_0[k][i], 0 ) )
406 : {
407 665831 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
408 665831 : move32();
409 : }
410 : }
411 39187 : 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 134944 : IF( !mct_on )
418 : {
419 43984 : tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
420 43984 : tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
421 43984 : nrgRatio = L_sub( tmp_32, ONE_IN_Q26 ); // Q26
422 :
423 43984 : 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 43984 : move32();
425 : /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
426 43984 : IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FIXED ) )
427 : {
428 16482 : hStereoMdct->reverse_dmx = 1; /* Q0 */
429 16482 : move16();
430 : }
431 27502 : ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FIXED ) )
432 : {
433 7883 : hStereoMdct->reverse_dmx = 0; /* Q0 */
434 7883 : move16();
435 : }
436 :
437 43984 : Word16 tmp1, tmp2 = 0;
438 :
439 43984 : IF( EQ_16( core_r, TCX_10_CORE ) )
440 : {
441 2651 : tmp1 = NB_DIV;
442 2651 : move16();
443 : }
444 : ELSE
445 : {
446 41333 : tmp1 = 1;
447 41333 : move16();
448 : }
449 :
450 43984 : IF( EQ_16( core_l, TCX_10_CORE ) )
451 : {
452 2401 : tmp2 = NB_DIV;
453 2401 : move16();
454 : }
455 : ELSE
456 : {
457 41583 : tmp2 = 1;
458 41583 : move16();
459 : }
460 :
461 43984 : test();
462 43984 : test();
463 43984 : IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
464 : {
465 21523 : shift = norm_l( nrgRatio );
466 21523 : nrgRatio = L_shl( nrgRatio, shift ); /* Q26 + shift */
467 21523 : v_multc_fixed( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
468 21523 : Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) ); /* Qx */
469 : }
470 22461 : 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 131608 : return;
481 : }
482 :
483 :
484 : /*-------------------------------------------------------------------*
485 : * initMdctStereoDecData()
486 : *
487 : * Initialize MDCT stereo decoder configuration
488 : *-------------------------------------------------------------------*/
489 :
490 287407 : 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 287407 : tcx_coded_lines = getNumTcxCodedLines( bwidth );
501 :
502 : /*Initialize sfb parameteres for TCX20 */
503 287407 : 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 287407 : 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 287407 : 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 287407 : IF( igf )
512 : {
513 : /* calculate the igf start band from the igf start line */
514 158374 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
515 158374 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
516 158374 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
517 : }
518 : ELSE
519 : {
520 129033 : hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
521 129033 : move16();
522 129033 : hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
523 129033 : move16();
524 129033 : hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
525 129033 : move16();
526 129033 : hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
527 129033 : move16();
528 129033 : hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
529 129033 : move16();
530 129033 : hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
531 129033 : move16();
532 : }
533 :
534 287407 : return;
535 : }
536 :
537 :
538 : /*-------------------------------------------------------------------*
539 : * initMdctStereoDtxData()
540 : *
541 : * Allocate and initialize structures for MDCT-Stereo DTX operation
542 : *-------------------------------------------------------------------*/
543 :
544 36 : ivas_error initMdctStereoDtxData_fx(
545 : CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
546 : )
547 : {
548 : Word16 ch;
549 : ivas_error error;
550 :
551 36 : error = IVAS_ERR_OK;
552 36 : move16();
553 :
554 108 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
555 : {
556 72 : DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
557 :
558 72 : 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 72 : IF( st->first_CNG == 0 )
571 : {
572 66 : test();
573 66 : IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
574 : {
575 18 : st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
576 18 : move16();
577 : }
578 : }
579 :
580 72 : IF( st->cldfbAna == NULL )
581 : {
582 : /* open analysis for max. sampling rate 48kHz */
583 58 : 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 72 : IF( st->cldfbBPF == NULL )
590 : {
591 : /* open analysis BPF for max. internal sampling rate 16kHz */
592 58 : 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 36 : return error;
600 : }
601 :
602 :
603 : /*-------------------------------------------------------------------*
604 : * synchonize_channels_mdct_sid()
605 : *
606 : * Synchronize channels in SID frame in MDCT stereo
607 : *-------------------------------------------------------------------*/
608 :
609 1066218 : 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 1066218 : st = sts[n];
617 :
618 1066218 : test();
619 1066218 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
620 : {
621 1154 : IF( EQ_16( n, 1 ) )
622 : {
623 : /* synchronize channels */
624 577 : sts[1]->L_frame = sts[0]->L_frame;
625 577 : move16();
626 577 : sts[1]->cng_type = sts[0]->cng_type;
627 577 : move16();
628 577 : sts[1]->bwidth = sts[0]->bwidth;
629 577 : move16();
630 577 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
631 577 : move16();
632 577 : sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
633 577 : move16();
634 :
635 : /* configure when there is a switching from DFT CNG to MDCT CNG */
636 577 : test();
637 577 : 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 1154 : 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 60 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
647 : }
648 : }
649 :
650 1066218 : 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 3270 : 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 3270 : Word16 diff = 0;
674 3270 : move16();
675 3270 : IF( GT_16( *a_exp, *b_exp ) )
676 : {
677 1040 : diff = sub( *a_exp, *b_exp );
678 991856 : FOR( Word16 j = 0; j < legth; j++ )
679 : {
680 990816 : buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
681 990816 : move16();
682 : }
683 1040 : *b_exp = *a_exp;
684 1040 : move16();
685 : }
686 2230 : ELSE IF( LT_16( *a_exp, *b_exp ) )
687 : {
688 30 : diff = sub( *b_exp, *a_exp );
689 :
690 14610 : FOR( Word16 j = 0; j < legth; j++ )
691 : {
692 14580 : buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
693 14580 : move16();
694 : }
695 30 : *a_exp = *b_exp;
696 30 : move16();
697 : }
698 3270 : return;
699 : }
700 :
701 1128 : 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 1128 : sts[0] = hCPE->hCoreCoder[0];
713 1128 : sts[1] = hCPE->hCoreCoder[1];
714 :
715 : /* synch buffers for inactive frames, but not for transition frames */
716 1128 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
717 : {
718 1090 : Copy32( output0_fx, output1_fx, output_frame );
719 1090 : Copy( synth_fx[0], synth_fx[1], output_frame );
720 : }
721 :
722 1128 : Word32 Var1 = 0;
723 1128 : move16();
724 1128 : Word16 diff_sidNoiseEst = 0;
725 1128 : move16();
726 1128 : Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
727 1128 : move16();
728 1128 : Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
729 1128 : move16();
730 1128 : IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
731 : {
732 10 : diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
733 250 : FOR( Word32 j = 0; j < NPART; j++ )
734 : {
735 240 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
736 240 : move16();
737 : }
738 10 : exp_sidNoiseEst1 = exp_sidNoiseEst0;
739 10 : move16();
740 : }
741 1118 : ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
742 : {
743 10 : diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
744 250 : FOR( Word32 j = 0; j < NPART; j++ )
745 : {
746 240 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
747 240 : move16();
748 : }
749 10 : exp_sidNoiseEst0 = exp_sidNoiseEst1;
750 10 : move16();
751 : }
752 1128 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
753 1128 : move16();
754 1128 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
755 1128 : move16();
756 1128 : test();
757 1128 : test();
758 1128 : 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 1128 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
771 : {
772 1090 : delta = 1;
773 1090 : move16();
774 1090 : IF( EQ_16( output_frame, L_FRAME16k ) )
775 : {
776 349 : delta = 2;
777 349 : 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 1090 : delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP ); /* Q0 */
791 1090 : tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
792 1090 : move16();
793 :
794 1090 : assert( delay_buf_out_len > tcxltp_mem_in_len );
795 :
796 1090 : Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
797 1090 : move16();
798 1090 : move16();
799 1090 : move16();
800 1090 : move16();
801 :
802 1090 : 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 1090 : 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 1090 : 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 1090 : 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 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
809 1090 : move16();
810 1090 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
811 1090 : move16();
812 :
813 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
814 1090 : move16();
815 1090 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
816 1090 : move16();
817 :
818 :
819 1090 : 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 1090 : 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 1090 : 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 1090 : 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 1090 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
827 1090 : sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
828 :
829 1090 : update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
830 1090 : sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
831 :
832 1090 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
833 1090 : sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
834 :
835 9946 : FOR( i = 0; i < tcxltp_mem_in_len; i++ )
836 : {
837 8856 : 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 8856 : sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp ); // exp_tcxltp_mem_in + 1
839 8856 : move16();
840 :
841 8856 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
842 8856 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
843 8856 : move16();
844 :
845 8856 : 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 8856 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
847 8856 : move16();
848 :
849 8856 : 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 8856 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
851 8856 : move16();
852 : }
853 :
854 :
855 36514 : FOR( ; i < delay_buf_out_len; i++ )
856 : {
857 35424 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
858 35424 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
859 35424 : move16();
860 :
861 35424 : 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 35424 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); /* exp_old_out + 1 */
863 35424 : move16();
864 :
865 35424 : 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 35424 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
867 35424 : move16();
868 : }
869 :
870 665290 : FOR( ; i < output_frame; i++ )
871 : {
872 664200 : 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 664200 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
874 664200 : move16();
875 :
876 664200 : 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 664200 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
878 664200 : move16();
879 : }
880 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
881 1090 : move16();
882 1090 : sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
883 1090 : move16();
884 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
885 1090 : move16();
886 1090 : 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 1090 : 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 1128 : 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 5910 : 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 5910 : step_fx = ONE_IN_Q31; /* Q31 */
912 5910 : move32();
913 5910 : fade_fx = ONE_IN_Q31; /* Q31 */
914 5910 : move32();
915 5910 : dmx_len = output_frame; /* Q0 */
916 5910 : move16();
917 :
918 5910 : test();
919 5910 : test();
920 5910 : 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 5876 : 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 5838 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
968 : {
969 16 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
970 16 : move16();
971 16 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
972 : {
973 16 : case 48000:
974 16 : step_fx = 35791396; /* 0.0166 in Q31 */
975 16 : move32();
976 16 : 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 15878 : FOR( i = 0; i < crossfade_len; i++ )
998 : {
999 9968 : Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx ); /* q_out */
1000 9968 : 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 9968 : output_fx[0][i] = L_add( temp_1, temp_2 ); /* q_out */
1002 9968 : move32();
1003 9968 : fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
1004 : }
1005 :
1006 : /* apply passive downmix on all-active-frame part */
1007 4595542 : FOR( ; i < dmx_len; i++ )
1008 : {
1009 4589632 : output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
1010 4589632 : move32();
1011 : }
1012 :
1013 5910 : return;
1014 : }
|