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 201168 : 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 201168 : 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 162170 : test();
84 162170 : IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
85 : {
86 4099 : nSubframes = NB_DIV; /* Q0 */
87 4099 : move16();
88 : }
89 : ELSE
90 : {
91 158071 : nSubframes = 1; /* Q0 */
92 158071 : move16();
93 : }
94 162170 : move16();
95 : // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
96 162170 : IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
97 : {
98 158283 : sfbConf = &hStereoMdct->stbParamsTCX20;
99 : }
100 : ELSE
101 : {
102 3887 : sfbConf = &hStereoMdct->stbParamsTCX10;
103 : }
104 162170 : if ( sts[0]->last_core_from_bs == ACELP_CORE )
105 : {
106 1342 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
107 : }
108 :
109 162170 : IF( hStereoMdct->use_itd )
110 : {
111 : Word16 I;
112 :
113 11461 : 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 11461 : hStereoMdct->itd_fx = 0;
117 11461 : move32();
118 11461 : IF( hStereoMdct->itd_mode )
119 : {
120 3467 : /*(*nb_bits) += */ read_itd( st0, &I );
121 3467 : stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
122 : }
123 : }
124 :
125 328439 : FOR( k = 0; k < nSubframes; k++ )
126 : {
127 166269 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
128 166269 : IF( mdct_stereo_mode )
129 : {
130 160580 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
131 : }
132 166269 : SWITCH( mdct_stereo_mode )
133 : {
134 5689 : case 0:
135 5689 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
136 5689 : move16();
137 5689 : BREAK;
138 96149 : case 1:
139 96149 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
140 96149 : move16();
141 96149 : BREAK;
142 64431 : case 2:
143 64431 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
144 64431 : move16();
145 64431 : BREAK;
146 0 : default:
147 0 : assert( !"Not supported stereo mode\n" );
148 : }
149 :
150 166269 : IF( !mct_on )
151 : {
152 72685 : test();
153 72685 : IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
154 : {
155 72365 : hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
156 72365 : move16();
157 72365 : assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
158 : }
159 : ELSE
160 : {
161 320 : hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
162 320 : 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 166269 : IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
168 : {
169 96149 : set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
170 : }
171 : ELSE
172 : {
173 70120 : set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
174 : }
175 :
176 166269 : IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
177 : {
178 2666845 : FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
179 : {
180 2602414 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
181 2602414 : move16();
182 : }
183 : }
184 :
185 166269 : IF( st0->igf )
186 : {
187 108462 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
188 108462 : IF( mdct_stereo_mode )
189 : {
190 60336 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
191 : }
192 :
193 108462 : SWITCH( mdct_stereo_mode )
194 : {
195 48126 : case 0:
196 48126 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
197 48126 : move16();
198 48126 : BREAK;
199 45050 : case 1:
200 45050 : hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
201 45050 : move16();
202 45050 : BREAK;
203 15286 : case 2:
204 15286 : hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
205 15286 : move16();
206 15286 : 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 108462 : IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
213 : {
214 45050 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
215 : }
216 : ELSE
217 : {
218 63412 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
219 : }
220 :
221 108462 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
222 : {
223 97365 : FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
224 : {
225 82079 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
226 82079 : move16();
227 : }
228 : }
229 : }
230 : ELSE
231 : {
232 57807 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
233 57807 : move16();
234 : }
235 : }
236 : }
237 :
238 201168 : IF( !mct_on )
239 : {
240 109572 : hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels Q0*/
241 109572 : move16();
242 109572 : hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
243 :
244 109572 : assert( GT_16( hStereoMdct->split_ratio, 0 ) );
245 : }
246 :
247 :
248 201168 : return;
249 : }
250 :
251 :
252 : /*-------------------------------------------------------------------*
253 : * inverseBwMS()
254 : *
255 : * Band-wise M/S stereo processing
256 : *-------------------------------------------------------------------*/
257 :
258 1841927 : 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 94737137 : FOR( j = startLine; j < stopLine; j++ )
270 : {
271 92895210 : tmpValue = x0[j];
272 92895210 : move32();
273 92895210 : x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
274 92895210 : move32();
275 92895210 : x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
276 92895210 : move32();
277 : }
278 :
279 1841927 : return;
280 : }
281 :
282 :
283 : /*-------------------------------------------------------------------*
284 : * inverseMS()
285 : *
286 : * M/S stereo processing
287 : *-------------------------------------------------------------------*/
288 :
289 194180 : 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 194180 : inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
297 :
298 194180 : return;
299 : }
300 :
301 :
302 : /*-------------------------------------------------------------------*
303 : * stereo_decoder_tcx()
304 : *
305 : * apply stereo processing (inverse MS and global ILD)
306 : *-------------------------------------------------------------------*/
307 :
308 164366 : 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 164366 : STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
328 : Word32 nrgRatio, inv_nrgRatio, tmp_32;
329 : Word16 tmp_e, shift;
330 :
331 164366 : nSubframes = 2;
332 164366 : move16();
333 164366 : test();
334 164366 : test();
335 164366 : if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
336 : {
337 160231 : nSubframes = 1; /* Q0 */
338 160231 : move16();
339 : }
340 :
341 332867 : FOR( k = 0; k < nSubframes; k++ )
342 : {
343 : // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
344 168501 : IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
345 : {
346 160614 : sfbConf = &hStereoMdct->stbParamsTCX20;
347 : }
348 : ELSE
349 : {
350 7887 : sfbConf = &hStereoMdct->stbParamsTCX10;
351 : }
352 :
353 168501 : test();
354 168501 : if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
355 : {
356 1351 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
357 : }
358 :
359 168501 : IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
360 : {
361 54215378 : FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
362 : {
363 54118034 : IF( EQ_32( spec_r_0[k][i], 0 ) )
364 : {
365 19477141 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
366 19477141 : move32();
367 : }
368 : }
369 97344 : inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
370 : }
371 71157 : ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
372 : {
373 2702979 : FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
374 : {
375 2637616 : IF( ms_mask[k][sfb] )
376 : {
377 23554839 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
378 : {
379 21951038 : IF( EQ_32( spec_r_0[k][i], 0 ) )
380 : {
381 7844267 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
382 7844267 : move32();
383 : }
384 : }
385 1603801 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
386 : }
387 : }
388 : }
389 :
390 168501 : IF( igf )
391 : {
392 109812 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
393 : {
394 13922471 : FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
395 : {
396 13877028 : IF( EQ_32( spec_r_0[k][i], 0 ) )
397 : {
398 5458077 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
399 5458077 : move32();
400 : }
401 : }
402 45443 : 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 64369 : ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
405 : {
406 97983 : FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
407 : {
408 82617 : IF( ms_mask[k][sfb] )
409 : {
410 2168124 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
411 : {
412 2124178 : IF( EQ_32( spec_r_0[k][i], 0 ) )
413 : {
414 834035 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
415 834035 : move32();
416 : }
417 : }
418 43946 : 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 168501 : IF( !mct_on )
425 : {
426 74917 : tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
427 74917 : tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
428 74917 : nrgRatio = L_sub( tmp_32, ONE_IN_Q26 ); // Q26
429 :
430 74917 : 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 74917 : move32();
432 : /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
433 74917 : IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FX ) )
434 : {
435 16839 : hStereoMdct->reverse_dmx = 1; /* Q0 */
436 16839 : move16();
437 : }
438 58078 : ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FX ) )
439 : {
440 12435 : hStereoMdct->reverse_dmx = 0; /* Q0 */
441 12435 : move16();
442 : }
443 :
444 74917 : Word16 tmp1, tmp2 = 0;
445 :
446 74917 : IF( EQ_16( core_r, TCX_10_CORE ) )
447 : {
448 4110 : tmp1 = NB_DIV;
449 4110 : move16();
450 : }
451 : ELSE
452 : {
453 70807 : tmp1 = 1;
454 70807 : move16();
455 : }
456 :
457 74917 : IF( EQ_16( core_l, TCX_10_CORE ) )
458 : {
459 3900 : tmp2 = NB_DIV;
460 3900 : move16();
461 : }
462 : ELSE
463 : {
464 71017 : tmp2 = 1;
465 71017 : move16();
466 : }
467 :
468 74917 : test();
469 74917 : test();
470 74917 : IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
471 : {
472 25703 : shift = norm_l( nrgRatio );
473 25703 : nrgRatio = L_shl( nrgRatio, shift ); /* Q26 + shift */
474 25703 : v_multc_fx( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
475 25703 : Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) ); /* Qx */
476 : }
477 49214 : ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
478 : {
479 15760 : inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
480 15760 : shift = sub( 5, tmp_e );
481 15760 : v_multc_fx( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
482 15760 : Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) ); /* Qx */
483 : }
484 : }
485 : } /* for k */
486 :
487 164366 : return;
488 : }
489 :
490 :
491 : /*-------------------------------------------------------------------*
492 : * initMdctStereoDecData()
493 : *
494 : * Initialize MDCT stereo decoder configuration
495 : *-------------------------------------------------------------------*/
496 :
497 327873 : 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 327873 : tcx_coded_lines = getNumTcxCodedLines( bwidth );
508 :
509 : /*Initialize sfb parameteres for TCX20 */
510 327873 : 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 327873 : 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 327873 : 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 327873 : IF( igf )
519 : {
520 : /* calculate the igf start band from the igf start line */
521 185638 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
522 185638 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
523 185638 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
524 : }
525 : ELSE
526 : {
527 142235 : hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
528 142235 : move16();
529 142235 : hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
530 142235 : move16();
531 142235 : hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
532 142235 : move16();
533 142235 : hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
534 142235 : move16();
535 142235 : hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
536 142235 : move16();
537 142235 : hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
538 142235 : move16();
539 : }
540 :
541 327873 : return;
542 : }
543 :
544 :
545 : /*-------------------------------------------------------------------*
546 : * initMdctStereoDtxData()
547 : *
548 : * Allocate and initialize structures for MDCT-Stereo DTX operation
549 : *-------------------------------------------------------------------*/
550 :
551 27 : ivas_error initMdctStereoDtxData_fx(
552 : CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
553 : )
554 : {
555 : Word16 ch;
556 : ivas_error error;
557 :
558 27 : error = IVAS_ERR_OK;
559 27 : move16();
560 :
561 81 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
562 : {
563 54 : DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
564 :
565 54 : 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 54 : IF( st->first_CNG == 0 )
578 : {
579 54 : test();
580 54 : IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
581 : {
582 15 : st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
583 15 : move16();
584 : }
585 : }
586 :
587 54 : IF( st->cldfbAna == NULL )
588 : {
589 : /* open analysis for max. sampling rate 48kHz */
590 46 : 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 54 : IF( st->cldfbBPF == NULL )
597 : {
598 : /* open analysis BPF for max. internal sampling rate 16kHz */
599 46 : 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 27 : return error;
607 : }
608 :
609 :
610 : /*-------------------------------------------------------------------*
611 : * synchonize_channels_mdct_sid()
612 : *
613 : * Synchronize channels in SID frame in MDCT stereo
614 : *-------------------------------------------------------------------*/
615 :
616 1242887 : 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 1242887 : st = sts[n];
624 :
625 1242887 : test();
626 1242887 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
627 : {
628 978 : IF( EQ_16( n, 1 ) )
629 : {
630 : /* synchronize channels */
631 489 : sts[1]->L_frame = sts[0]->L_frame;
632 489 : move16();
633 489 : sts[1]->cng_type = sts[0]->cng_type;
634 489 : move16();
635 489 : sts[1]->bwidth = sts[0]->bwidth;
636 489 : move16();
637 : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
638 489 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx[0] = sts[1]->hFdCngDec->hFdCngCom->coherence_fx[0]; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
639 : #else
640 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
641 : #endif
642 489 : move16();
643 489 : sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
644 489 : move16();
645 :
646 : /* configure when there is a switching from DFT CNG to MDCT CNG */
647 489 : test();
648 489 : IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
649 : {
650 0 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
651 : }
652 : }
653 :
654 978 : IF( sts[0]->first_CNG == 0 )
655 : {
656 : /* 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 */
657 54 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
658 : }
659 : }
660 :
661 1242887 : return;
662 : }
663 :
664 :
665 : /*-------------------------------------------------------------------*
666 : * updateBuffersForDmxMdctStereo()
667 : *
668 : * synch buffers between channels for mono output and
669 : * apply passive downmix to certain buffers to enable smooth transitions
670 : * between active/inactive coding in MDCT-Stereo DTX
671 : *-------------------------------------------------------------------*/
672 :
673 3234 : static void update_exp(
674 : Word16 *a_exp,
675 : Word16 *b_exp,
676 : Word16 *buff_a, /* exp(a_exp) */
677 : Word16 *buff_b, /* exp(b_exp) */
678 : const Word16 legth /* Q0 */
679 : )
680 : {
681 3234 : Word16 diff = 0;
682 3234 : move16();
683 3234 : IF( GT_16( *a_exp, *b_exp ) )
684 : {
685 1027 : diff = sub( *a_exp, *b_exp );
686 983155 : FOR( Word16 j = 0; j < legth; j++ )
687 : {
688 982128 : buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
689 982128 : move16();
690 : }
691 1027 : *b_exp = *a_exp;
692 1027 : move16();
693 : }
694 2207 : ELSE IF( LT_16( *a_exp, *b_exp ) )
695 : {
696 32 : diff = sub( *b_exp, *a_exp );
697 :
698 18428 : FOR( Word16 j = 0; j < legth; j++ )
699 : {
700 18396 : buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
701 18396 : move16();
702 : }
703 32 : *a_exp = *b_exp;
704 32 : move16();
705 : }
706 3234 : return;
707 : }
708 :
709 1114 : void updateBuffersForDmxMdctStereo_fx(
710 : CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */
711 : const Word16 output_frame, /* i : output frame length Q0*/
712 : Word32 output0_fx[], /* Qx */
713 : Word32 output1_fx[], /* Qx */
714 : Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis qsynth*/
715 : )
716 : {
717 : Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
718 : Decoder_State *sts[CPE_CHANNELS];
719 :
720 1114 : sts[0] = hCPE->hCoreCoder[0];
721 1114 : sts[1] = hCPE->hCoreCoder[1];
722 :
723 : /* synch buffers for inactive frames, but not for transition frames */
724 1114 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
725 : {
726 1078 : Copy32( output0_fx, output1_fx, output_frame );
727 1078 : Copy( synth_fx[0], synth_fx[1], output_frame );
728 : }
729 :
730 1114 : Word32 Var1 = 0;
731 1114 : move16();
732 1114 : Word16 diff_sidNoiseEst = 0;
733 1114 : move16();
734 1114 : Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
735 1114 : move16();
736 1114 : Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
737 1114 : move16();
738 1114 : IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
739 : {
740 14 : diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
741 350 : FOR( Word32 j = 0; j < NPART; j++ )
742 : {
743 336 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
744 336 : move16();
745 : }
746 14 : exp_sidNoiseEst1 = exp_sidNoiseEst0;
747 14 : move16();
748 : }
749 1100 : ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
750 : {
751 12 : diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
752 300 : FOR( Word32 j = 0; j < NPART; j++ )
753 : {
754 288 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
755 288 : move16();
756 : }
757 12 : exp_sidNoiseEst0 = exp_sidNoiseEst1;
758 12 : move16();
759 : }
760 1114 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
761 1114 : move16();
762 1114 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
763 1114 : move16();
764 1114 : test();
765 1114 : test();
766 1114 : IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
767 : {
768 : /* 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 */
769 873 : FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
770 : {
771 837 : Var1 = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); // exp_sidNoiseEst0 - 1
772 837 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 ); // 31 - exp_sidNoiseEst0 - 1 + 31 - 31
773 837 : move32();
774 : }
775 : }
776 :
777 : /* for transition of active->inactive frame, apply passive downmix on buffers */
778 1114 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
779 : {
780 1078 : delta = 1;
781 1078 : move16();
782 1078 : IF( EQ_16( output_frame, L_FRAME16k ) )
783 : {
784 348 : delta = 2;
785 348 : move16();
786 : }
787 730 : ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
788 : {
789 356 : delta = 4;
790 356 : move16();
791 : }
792 374 : ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
793 : {
794 374 : delta = 6;
795 374 : move16();
796 : }
797 :
798 1078 : delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP ); /* Q0 */
799 1078 : tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
800 1078 : move16();
801 :
802 1078 : assert( delay_buf_out_len > tcxltp_mem_in_len );
803 :
804 1078 : Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
805 1078 : move16();
806 1078 : move16();
807 1078 : move16();
808 1078 : move16();
809 :
810 1078 : 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
811 1078 : 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
812 :
813 1078 : Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
814 1078 : Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
815 :
816 1078 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
817 1078 : move16();
818 1078 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
819 1078 : move16();
820 :
821 1078 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
822 1078 : move16();
823 1078 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
824 1078 : move16();
825 :
826 :
827 1078 : 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)
828 1078 : 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)
829 :
830 1078 : 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)
831 1078 : 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)
832 :
833 :
834 1078 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
835 1078 : sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
836 :
837 1078 : update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
838 1078 : sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
839 :
840 1078 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
841 1078 : sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
842 :
843 9806 : FOR( i = 0; i < tcxltp_mem_in_len; i++ )
844 : {
845 8728 : 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
846 8728 : sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp ); // exp_tcxltp_mem_in + 1
847 8728 : move16();
848 :
849 8728 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
850 8728 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
851 8728 : move16();
852 :
853 8728 : 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
854 8728 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
855 8728 : move16();
856 :
857 8728 : 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
858 8728 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
859 8728 : move16();
860 : }
861 :
862 :
863 35990 : FOR( ; i < delay_buf_out_len; i++ )
864 : {
865 34912 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
866 34912 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
867 34912 : move16();
868 :
869 34912 : 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 */
870 34912 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); /* exp_old_out + 1 */
871 34912 : move16();
872 :
873 34912 : 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
874 34912 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
875 34912 : move16();
876 : }
877 :
878 655678 : FOR( ; i < output_frame; i++ )
879 : {
880 654600 : 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
881 654600 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
882 654600 : move16();
883 :
884 654600 : 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
885 654600 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
886 654600 : move16();
887 : }
888 1078 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
889 1078 : move16();
890 1078 : sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
891 1078 : move16();
892 1078 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
893 1078 : move16();
894 1078 : 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
895 1078 : 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
896 : }
897 :
898 1114 : return;
899 : }
900 :
901 :
902 : /*-------------------------------------------------------------------*
903 : * applyDmxMdctStereo()
904 : *
905 : * apply passive downmix to certain buffers to enable smooth transitions
906 : * between active/inactive coding in MDCT-Stereo DTX
907 : *-------------------------------------------------------------------*/
908 :
909 5920 : void applyDmxMdctStereo_fx(
910 : const CPE_DEC_HANDLE hCPE, /* i : CPE handle */
911 : Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output q_out*/
912 : const Word16 output_frame /* i : output frame length Q0*/
913 : )
914 : {
915 : Word16 crossfade_len, i;
916 : Word16 dmx_len;
917 : Word32 fade_fx, step_fx;
918 :
919 5920 : step_fx = ONE_IN_Q31; /* Q31 */
920 5920 : move32();
921 5920 : fade_fx = ONE_IN_Q31; /* Q31 */
922 5920 : move32();
923 5920 : dmx_len = output_frame; /* Q0 */
924 5920 : move16();
925 :
926 5920 : test();
927 5920 : test();
928 5920 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
929 : {
930 32 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
931 32 : move16();
932 32 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
933 : {
934 15 : case 48000:
935 15 : step_fx = 22369622; /* 0.0104 in Q31 */
936 15 : move32();
937 15 : BREAK;
938 9 : case 32000:
939 9 : step_fx = 33554432; /* 0.0156 in Q31 */
940 9 : move32();
941 9 : BREAK;
942 8 : case 16000:
943 8 : step_fx = 67108864; /* 0.0312 in Q31 */
944 8 : move32();
945 8 : BREAK;
946 0 : default:
947 0 : assert( 0 );
948 : BREAK;
949 : }
950 : }
951 : /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
952 5888 : ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
953 : {
954 36 : crossfade_len = shr( output_frame, 2 ); /* Q0 */
955 36 : SWITCH( output_frame )
956 : {
957 17 : case 960:
958 17 : step_fx = -8947849; /* -0.0041 in Q31 */
959 17 : move32();
960 17 : BREAK;
961 10 : case 640:
962 10 : step_fx = -13421773; /* -0.00625 in Q31 */
963 10 : move32();
964 10 : BREAK;
965 9 : case 320:
966 9 : step_fx = -26843546; /* -0.0125 in Q31 */
967 9 : move32();
968 9 : BREAK;
969 : }
970 36 : fade_fx = 0;
971 36 : move32();
972 36 : dmx_len = crossfade_len; /* Q0 */
973 36 : move16();
974 : }
975 5852 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
976 : {
977 15 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
978 15 : move16();
979 15 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
980 : {
981 15 : case 48000:
982 15 : step_fx = 35791396; /* 0.0166 in Q31 */
983 15 : move32();
984 15 : BREAK;
985 0 : case 32000:
986 0 : step_fx = 53687092; /* 0.025 in Q31 */
987 0 : move32();
988 0 : BREAK;
989 0 : case 16000:
990 0 : step_fx = 107374184; /* 0.05 in Q31 */
991 0 : move32();
992 0 : BREAK;
993 0 : default:
994 0 : assert( 0 );
995 : BREAK;
996 : }
997 : }
998 : ELSE
999 : {
1000 5837 : crossfade_len = 0;
1001 5837 : move16();
1002 : }
1003 :
1004 : /* apply crossfade */
1005 15492 : FOR( i = 0; i < crossfade_len; i++ )
1006 : {
1007 9572 : Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx ); /* q_out */
1008 9572 : 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 */
1009 9572 : output_fx[0][i] = L_add( temp_1, temp_2 ); /* q_out */
1010 9572 : move32();
1011 9572 : fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
1012 : }
1013 :
1014 : /* apply passive downmix on all-active-frame part */
1015 4605628 : FOR( ; i < dmx_len; i++ )
1016 : {
1017 4599708 : output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
1018 4599708 : move32();
1019 : }
1020 :
1021 5920 : return;
1022 : }
|