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 158607 : 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 158607 : 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 121867 : test();
80 121867 : IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
81 : {
82 2989 : nSubframes = NB_DIV; /* Q0 */
83 2989 : move16();
84 : }
85 : ELSE
86 : {
87 118878 : nSubframes = 1; /* Q0 */
88 118878 : move16();
89 : }
90 121867 : move16();
91 : // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
92 121867 : IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
93 : {
94 119056 : sfbConf = &hStereoMdct->stbParamsTCX20;
95 : }
96 : ELSE
97 : {
98 2811 : sfbConf = &hStereoMdct->stbParamsTCX10;
99 : }
100 121867 : if ( sts[0]->last_core_from_bs == ACELP_CORE )
101 : {
102 596 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
103 : }
104 :
105 121867 : IF( hStereoMdct->use_itd )
106 : {
107 : Word16 I;
108 :
109 11381 : 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 11381 : hStereoMdct->itd_fx = 0;
113 11381 : move32();
114 11381 : IF( hStereoMdct->itd_mode )
115 : {
116 3388 : /*(*nb_bits) += */ read_itd( st0, &I );
117 3388 : stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
118 : }
119 : }
120 :
121 246723 : FOR( k = 0; k < nSubframes; k++ )
122 : {
123 124856 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
124 124856 : IF( mdct_stereo_mode )
125 : {
126 121272 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
127 : }
128 124856 : SWITCH( mdct_stereo_mode )
129 : {
130 3584 : case 0:
131 3584 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
132 3584 : move16();
133 3584 : BREAK;
134 76707 : case 1:
135 76707 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
136 76707 : move16();
137 76707 : BREAK;
138 44565 : case 2:
139 44565 : hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
140 44565 : move16();
141 44565 : BREAK;
142 0 : default:
143 0 : assert( !"Not supported stereo mode\n" );
144 : }
145 :
146 124856 : IF( !mct_on )
147 : {
148 40996 : test();
149 40996 : IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
150 : {
151 40754 : hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
152 40754 : move16();
153 40754 : assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
154 : }
155 : ELSE
156 : {
157 242 : hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
158 242 : 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 124856 : IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
164 : {
165 76707 : set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
166 : }
167 : ELSE
168 : {
169 48149 : set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
170 : }
171 :
172 124856 : IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
173 : {
174 1854167 : FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
175 : {
176 1809602 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
177 1809602 : move16();
178 : }
179 : }
180 :
181 124856 : IF( st0->igf )
182 : {
183 82885 : mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
184 82885 : IF( mdct_stereo_mode )
185 : {
186 50929 : mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
187 : }
188 :
189 82885 : SWITCH( mdct_stereo_mode )
190 : {
191 31956 : case 0:
192 31956 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
193 31956 : move16();
194 31956 : BREAK;
195 37724 : case 1:
196 37724 : hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
197 37724 : move16();
198 37724 : BREAK;
199 13205 : case 2:
200 13205 : hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
201 13205 : move16();
202 13205 : 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 82885 : IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
209 : {
210 37724 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
211 : }
212 : ELSE
213 : {
214 45161 : set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
215 : }
216 :
217 82885 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
218 : {
219 81967 : FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
220 : {
221 68762 : ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
222 68762 : move16();
223 : }
224 : }
225 : }
226 : ELSE
227 : {
228 41971 : hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
229 41971 : move16();
230 : }
231 : }
232 : }
233 :
234 158607 : IF( !mct_on )
235 : {
236 76446 : hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels Q0*/
237 76446 : move16();
238 76446 : hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
239 :
240 76446 : assert( GT_16( hStereoMdct->split_ratio, 0 ) );
241 : }
242 :
243 :
244 158607 : return;
245 : }
246 :
247 :
248 : /*-------------------------------------------------------------------*
249 : * inverseBwMS()
250 : *
251 : * Band-wise M/S stereo processing
252 : *-------------------------------------------------------------------*/
253 1301115 : 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 71736965 : FOR( j = startLine; j < stopLine; j++ )
265 : {
266 70435850 : tmpValue = x0[j];
267 70435850 : move32();
268 70435850 : x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
269 70435850 : move32();
270 70435850 : x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
271 70435850 : move32();
272 : }
273 :
274 1301115 : return;
275 : }
276 :
277 :
278 : /*-------------------------------------------------------------------*
279 : * inverseMS()
280 : *
281 : * M/S stereo processing
282 : *-------------------------------------------------------------------*/
283 157330 : 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 157330 : inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
291 :
292 157330 : return;
293 : }
294 :
295 :
296 : /*-------------------------------------------------------------------*
297 : * stereo_decoder_tcx()
298 : *
299 : * apply stereo processing (inverse MS and global ILD)
300 : *-------------------------------------------------------------------*/
301 122627 : 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 : Word16 *q_x_ch2,
318 : Word16 *q_x_ch1 )
319 : {
320 : Word16 i, k, sfb, nSubframes;
321 122627 : STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
322 : Word32 nrgRatio, inv_nrgRatio, tmp_32;
323 : Word16 tmp_e, shift;
324 :
325 122627 : nSubframes = 2;
326 122627 : move16();
327 122627 : test();
328 122627 : test();
329 122627 : if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
330 : {
331 119633 : nSubframes = 1; /* Q0 */
332 119633 : move16();
333 : }
334 :
335 248248 : FOR( k = 0; k < nSubframes; k++ )
336 : {
337 : // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
338 125621 : IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
339 : {
340 119986 : sfbConf = &hStereoMdct->stbParamsTCX20;
341 : }
342 : ELSE
343 : {
344 5635 : sfbConf = &hStereoMdct->stbParamsTCX10;
345 : }
346 :
347 125621 : test();
348 125621 : if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
349 : {
350 606 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
351 : }
352 :
353 125621 : IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
354 : {
355 42007472 : FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
356 : {
357 41930408 : IF( EQ_32( spec_r_0[k][i], 0 ) )
358 : {
359 11526093 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
360 11526093 : move32();
361 : }
362 : }
363 77064 : inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
364 77064 : *q_x_ch2 = *q_x_ch2;
365 77064 : move16();
366 77064 : *q_x_ch1 = *q_x_ch1;
367 77064 : move16();
368 : }
369 48557 : ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
370 : {
371 1868599 : FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
372 : {
373 1823673 : IF( ms_mask[k][sfb] )
374 : {
375 15794351 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
376 : {
377 14687034 : IF( EQ_32( spec_r_0[k][i], 0 ) )
378 : {
379 4247497 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
380 4247497 : move32();
381 : }
382 : }
383 1107317 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
384 1107317 : *q_x_ch2 = *q_x_ch2;
385 1107317 : move16();
386 1107317 : *q_x_ch1 = *q_x_ch1;
387 1107317 : move16();
388 : }
389 : }
390 : }
391 :
392 125621 : IF( igf )
393 : {
394 83294 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
395 : {
396 11380043 : FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
397 : {
398 11342222 : IF( EQ_32( spec_r_0[k][i], 0 ) )
399 : {
400 3409895 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
401 3409895 : move32();
402 : }
403 : }
404 37821 : 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 );
405 37821 : *q_x_ch2 = *q_x_ch2;
406 37821 : move16();
407 37821 : *q_x_ch1 = *q_x_ch1;
408 37821 : move16();
409 : }
410 45473 : ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
411 : {
412 82281 : FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
413 : {
414 69034 : IF( ms_mask[k][sfb] )
415 : {
416 1830752 : FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
417 : {
418 1794284 : IF( EQ_32( spec_r_0[k][i], 0 ) )
419 : {
420 611740 : spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
421 611740 : move32();
422 : }
423 : }
424 36468 : inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
425 36468 : *q_x_ch2 = *q_x_ch2;
426 36468 : move16();
427 36468 : *q_x_ch1 = *q_x_ch1;
428 36468 : move16();
429 : }
430 : }
431 : }
432 : }
433 :
434 125621 : IF( !mct_on )
435 : {
436 41761 : tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
437 41761 : tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
438 41761 : nrgRatio = L_sub( tmp_32, ONE_IN_Q26 ); // Q26
439 :
440 41761 : 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
441 41761 : move32();
442 : /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
443 41761 : IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FIXED ) )
444 : {
445 15684 : hStereoMdct->reverse_dmx = 1; /* Q0 */
446 15684 : move16();
447 : }
448 26077 : ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FIXED ) )
449 : {
450 7548 : hStereoMdct->reverse_dmx = 0; /* Q0 */
451 7548 : move16();
452 : }
453 :
454 41761 : Word16 tmp1, tmp2 = 0;
455 :
456 41761 : IF( EQ_16( core_r, TCX_10_CORE ) )
457 : {
458 2465 : tmp1 = NB_DIV;
459 2465 : move16();
460 : }
461 : ELSE
462 : {
463 39296 : tmp1 = 1;
464 39296 : move16();
465 : }
466 :
467 41761 : IF( EQ_16( core_l, TCX_10_CORE ) )
468 : {
469 2233 : tmp2 = NB_DIV;
470 2233 : move16();
471 : }
472 : ELSE
473 : {
474 39528 : tmp2 = 1;
475 39528 : move16();
476 : }
477 :
478 41761 : test();
479 41761 : test();
480 41761 : IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
481 : {
482 20428 : shift = norm_l( nrgRatio );
483 20428 : nrgRatio = L_shl( nrgRatio, shift ); /* Q26 + shift */
484 20428 : v_multc_fixed( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
485 20428 : Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) ); /* Qx */
486 20428 : *q_x_ch2 = *q_x_ch2;
487 20428 : move16();
488 : }
489 21333 : ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
490 : {
491 8875 : inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
492 8875 : shift = sub( 5, tmp_e );
493 8875 : v_multc_fixed( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
494 8875 : Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) ); /* Qx */
495 8875 : *q_x_ch1 = *q_x_ch1;
496 8875 : move16();
497 : }
498 : }
499 : } /* for k */
500 :
501 122627 : return;
502 : }
503 :
504 :
505 : /*-------------------------------------------------------------------*
506 : * initMdctStereoDecData()
507 : *
508 : * Initialize MDCT stereo decoder configuration
509 : *-------------------------------------------------------------------*/
510 :
511 263997 : void initMdctStereoDecData_fx(
512 : STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */
513 : const Word16 igf, /* i : flag indicating IGF activity Q0*/
514 : const H_IGF_GRID igfGrid, /* i : IGF grid configuration Q0*/
515 : const Word32 element_brate, /* i : element bitrate Q0*/
516 : const Word16 bwidth /* i : audio bandwidth Q0*/
517 : )
518 : {
519 : Word16 tcx_coded_lines;
520 :
521 263997 : tcx_coded_lines = getNumTcxCodedLines( bwidth );
522 :
523 : /*Initialize sfb parameteres for TCX20 */
524 263997 : 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 );
525 :
526 : /*Initialize sfb parameteres for TCX10 */
527 263997 : 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 );
528 :
529 : /*Initialize sfb parameteres for transition frames */
530 263997 : stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, &igfGrid[IGF_GRID_LB_TRAN], &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
531 :
532 263997 : IF( igf )
533 : {
534 : /* calculate the igf start band from the igf start line */
535 145054 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
536 145054 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
537 145054 : stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
538 : }
539 : ELSE
540 : {
541 118943 : hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
542 118943 : move16();
543 118943 : hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
544 118943 : move16();
545 118943 : hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
546 118943 : move16();
547 118943 : hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
548 118943 : move16();
549 118943 : hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
550 118943 : move16();
551 118943 : hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
552 118943 : move16();
553 : }
554 :
555 263997 : return;
556 : }
557 :
558 :
559 : /*-------------------------------------------------------------------*
560 : * initMdctStereoDtxData()
561 : *
562 : * Allocate and initialize structures for MDCT-Stereo DTX operation
563 : *-------------------------------------------------------------------*/
564 :
565 36 : ivas_error initMdctStereoDtxData_fx(
566 : CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
567 : )
568 : {
569 : Word16 ch;
570 : ivas_error error;
571 :
572 36 : error = IVAS_ERR_OK;
573 36 : move16();
574 :
575 108 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
576 : {
577 72 : DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
578 :
579 72 : IF( st->hFdCngDec == NULL )
580 : {
581 : /* Create FD_CNG instance */
582 0 : IF( NE_32( ( error = createFdCngDec_fx( &st->hFdCngDec ) ), IVAS_ERR_OK ) )
583 : {
584 0 : return error;
585 : }
586 :
587 : /* Init FD-CNG */
588 0 : initFdCngDec_ivas_fx( st, st->cldfbSyn->scale );
589 : }
590 :
591 72 : IF( st->first_CNG == 0 )
592 : {
593 66 : test();
594 66 : IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
595 : {
596 18 : st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
597 18 : move16();
598 : }
599 : }
600 :
601 72 : IF( st->cldfbAna == NULL )
602 : {
603 : /* open analysis for max. sampling rate 48kHz */
604 58 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
605 : {
606 0 : return error;
607 : }
608 : }
609 :
610 72 : IF( st->cldfbBPF == NULL )
611 : {
612 : /* open analysis BPF for max. internal sampling rate 16kHz */
613 58 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
614 : {
615 0 : return error;
616 : }
617 : }
618 : }
619 :
620 36 : return error;
621 : }
622 :
623 :
624 : /*-------------------------------------------------------------------*
625 : * synchonize_channels_mdct_sid()
626 : *
627 : * Synchronize channels in SID frame in MDCT stereo
628 : *-------------------------------------------------------------------*/
629 :
630 1012562 : void synchonize_channels_mdct_sid_fx(
631 : Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure */
632 : const Word16 n /* i : channel number Q0*/
633 : )
634 : {
635 : Decoder_State *st;
636 :
637 1012562 : st = sts[n];
638 :
639 1012562 : test();
640 1012562 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
641 : {
642 1154 : IF( EQ_16( n, 1 ) )
643 : {
644 : /* synchronize channels */
645 577 : sts[1]->L_frame = sts[0]->L_frame;
646 577 : move16();
647 577 : sts[1]->cng_type = sts[0]->cng_type;
648 577 : move16();
649 577 : sts[1]->bwidth = sts[0]->bwidth;
650 577 : move16();
651 577 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
652 577 : move16();
653 577 : sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
654 577 : move16();
655 :
656 : /* configure when there is a switching from DFT CNG to MDCT CNG */
657 577 : test();
658 577 : IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
659 : {
660 0 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
661 : }
662 : }
663 :
664 1154 : IF( sts[0]->first_CNG == 0 )
665 : {
666 : /* 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 */
667 60 : configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
668 : }
669 : }
670 :
671 1012562 : return;
672 : }
673 :
674 :
675 : /*-------------------------------------------------------------------*
676 : * updateBuffersForDmxMdctStereo()
677 : *
678 : * synch buffers between channels for mono output and
679 : * apply passive downmix to certain buffers to enable smooth transitions
680 : * between active/inactive coding in MDCT-Stereo DTX
681 : *-------------------------------------------------------------------*/
682 :
683 : // helper function
684 : static void update_exp( Word16 *a_exp, Word16 *b_exp, Word16 *buff_a, Word16 *buff_b, Word16 legth );
685 :
686 3270 : static void update_exp(
687 : Word16 *a_exp,
688 : Word16 *b_exp,
689 : Word16 *buff_a, /* exp(a_exp) */
690 : Word16 *buff_b, /* exp(b_exp) */
691 : Word16 legth /* Q0 */
692 : )
693 : {
694 3270 : Word16 diff = 0;
695 3270 : move16();
696 3270 : IF( GT_16( *a_exp, *b_exp ) )
697 : {
698 1036 : diff = sub( *a_exp, *b_exp );
699 987064 : FOR( Word16 j = 0; j < legth; j++ )
700 : {
701 986028 : buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
702 986028 : move16();
703 : }
704 1036 : *b_exp = *a_exp;
705 1036 : move16();
706 : }
707 2234 : ELSE IF( LT_16( *a_exp, *b_exp ) )
708 : {
709 32 : diff = sub( *b_exp, *a_exp );
710 :
711 17480 : FOR( Word16 j = 0; j < legth; j++ )
712 : {
713 17448 : buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
714 17448 : move16();
715 : }
716 32 : *a_exp = *b_exp;
717 32 : move16();
718 : }
719 3270 : return;
720 : }
721 :
722 1128 : void updateBuffersForDmxMdctStereo_fx(
723 : CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */
724 : const Word16 output_frame, /* i : output frame length Q0*/
725 : Word32 output0_fx[], /* Qx */
726 : Word32 output1_fx[], /* Qx */
727 : Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis qsynth*/
728 : )
729 : {
730 : Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
731 : Decoder_State *sts[CPE_CHANNELS];
732 :
733 1128 : sts[0] = hCPE->hCoreCoder[0];
734 1128 : sts[1] = hCPE->hCoreCoder[1];
735 :
736 : /* synch buffers for inactive frames, but not for transition frames */
737 1128 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
738 : {
739 1090 : Copy32( output0_fx, output1_fx, output_frame );
740 1090 : Copy( synth_fx[0], synth_fx[1], output_frame );
741 : }
742 :
743 1128 : Word32 Var1 = 0;
744 1128 : move16();
745 1128 : Word16 diff_sidNoiseEst = 0;
746 1128 : move16();
747 1128 : Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
748 1128 : move16();
749 1128 : Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
750 1128 : move16();
751 1128 : IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
752 : {
753 10 : diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
754 250 : FOR( Word32 j = 0; j < NPART; j++ )
755 : {
756 240 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
757 240 : move16();
758 : }
759 10 : exp_sidNoiseEst1 = exp_sidNoiseEst0;
760 10 : move16();
761 : }
762 1118 : ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
763 : {
764 10 : diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
765 250 : FOR( Word32 j = 0; j < NPART; j++ )
766 : {
767 240 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
768 240 : move16();
769 : }
770 10 : exp_sidNoiseEst0 = exp_sidNoiseEst1;
771 10 : move16();
772 : }
773 1128 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
774 1128 : move16();
775 1128 : sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
776 1128 : move16();
777 1128 : test();
778 1128 : test();
779 1128 : IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
780 : {
781 : /* 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 */
782 923 : FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
783 : {
784 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
785 885 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 ); // 31 - exp_sidNoiseEst0 - 1 + 31 - 31
786 885 : move32();
787 : }
788 : }
789 :
790 : /* for transition of active->inactive frame, apply passive downmix on buffers */
791 1128 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
792 : {
793 1090 : delta = 1;
794 1090 : move16();
795 1090 : IF( EQ_16( output_frame, L_FRAME16k ) )
796 : {
797 349 : delta = 2;
798 349 : move16();
799 : }
800 741 : ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
801 : {
802 358 : delta = 4;
803 358 : move16();
804 : }
805 383 : ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
806 : {
807 383 : delta = 6;
808 383 : move16();
809 : }
810 :
811 1090 : delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP ); /* Q0 */
812 1090 : tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
813 1090 : move16();
814 :
815 1090 : assert( delay_buf_out_len > tcxltp_mem_in_len );
816 :
817 1090 : Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
818 1090 : move16();
819 1090 : move16();
820 1090 : move16();
821 1090 : move16();
822 :
823 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
824 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
825 :
826 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
827 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
828 :
829 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
830 1090 : move16();
831 1090 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
832 1090 : move16();
833 :
834 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
835 1090 : move16();
836 1090 : sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
837 1090 : move16();
838 :
839 :
840 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)
841 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)
842 :
843 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)
844 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)
845 :
846 :
847 1090 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
848 1090 : sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
849 :
850 1090 : update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
851 1090 : sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
852 :
853 1090 : update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
854 1090 : sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
855 :
856 9946 : FOR( i = 0; i < tcxltp_mem_in_len; i++ )
857 : {
858 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
859 8856 : sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp ); // exp_tcxltp_mem_in + 1
860 8856 : move16();
861 :
862 8856 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
863 8856 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
864 8856 : move16();
865 :
866 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
867 8856 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
868 8856 : move16();
869 :
870 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
871 8856 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
872 8856 : move16();
873 : }
874 :
875 :
876 36514 : FOR( ; i < delay_buf_out_len; i++ )
877 : {
878 35424 : sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
879 35424 : sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf ); // Q0
880 35424 : move16();
881 :
882 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 */
883 35424 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); /* exp_old_out + 1 */
884 35424 : move16();
885 :
886 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
887 35424 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
888 35424 : move16();
889 : }
890 :
891 665290 : FOR( ; i < output_frame; i++ )
892 : {
893 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
894 664200 : sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out ); // exp_old_out + 1
895 664200 : move16();
896 :
897 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
898 664200 : sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out ); // exp_tcxltp_mem_out + 1
899 664200 : move16();
900 : }
901 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
902 1090 : move16();
903 1090 : sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
904 1090 : move16();
905 1090 : sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
906 1090 : move16();
907 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
908 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
909 : }
910 :
911 1128 : return;
912 : }
913 :
914 :
915 : /*-------------------------------------------------------------------*
916 : * applyDmxMdctStereo()
917 : *
918 : * apply passive downmix to certain buffers to enable smooth transitions
919 : * between active/inactive coding in MDCT-Stereo DTX
920 : *-------------------------------------------------------------------*/
921 :
922 5910 : void applyDmxMdctStereo_fx(
923 : const CPE_DEC_HANDLE hCPE, /* i : CPE handle */
924 : Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output q_out*/
925 : const Word16 output_frame /* i : output frame length Q0*/
926 : )
927 : {
928 : Word16 crossfade_len, i;
929 : Word16 dmx_len;
930 : Word32 fade_fx, step_fx;
931 :
932 5910 : step_fx = ONE_IN_Q31; /* Q31 */
933 5910 : move32();
934 5910 : fade_fx = ONE_IN_Q31; /* Q31 */
935 5910 : move32();
936 5910 : dmx_len = output_frame; /* Q0 */
937 5910 : move16();
938 :
939 5910 : test();
940 5910 : test();
941 5910 : IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
942 : {
943 34 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
944 34 : move16();
945 34 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
946 : {
947 14 : case 48000:
948 14 : step_fx = 22369622; /* 0.0104 in Q31 */
949 14 : move32();
950 14 : BREAK;
951 12 : case 32000:
952 12 : step_fx = 33554432; /* 0.0156 in Q31 */
953 12 : move32();
954 12 : BREAK;
955 8 : case 16000:
956 8 : step_fx = 67108864; /* 0.0312 in Q31 */
957 8 : move32();
958 8 : BREAK;
959 0 : default:
960 0 : assert( 0 );
961 : BREAK;
962 : }
963 : }
964 : /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
965 5876 : ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
966 : {
967 38 : crossfade_len = shr( output_frame, 2 ); /* Q0 */
968 38 : SWITCH( output_frame )
969 : {
970 16 : case 960:
971 16 : step_fx = -8947849; /* -0.0041 in Q31 */
972 16 : move32();
973 16 : BREAK;
974 13 : case 640:
975 13 : step_fx = -13421773; /* -0.00625 in Q31 */
976 13 : move32();
977 13 : BREAK;
978 9 : case 320:
979 9 : step_fx = -26843546; /* -0.0125 in Q31 */
980 9 : move32();
981 9 : BREAK;
982 : }
983 38 : fade_fx = 0;
984 38 : move32();
985 38 : dmx_len = crossfade_len; /* Q0 */
986 38 : move16();
987 : }
988 5838 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
989 : {
990 15 : crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
991 15 : move16();
992 15 : SWITCH( hCPE->hCoreCoder[0]->output_Fs )
993 : {
994 15 : case 48000:
995 15 : step_fx = 35791396; /* 0.0166 in Q31 */
996 15 : move32();
997 15 : BREAK;
998 0 : case 32000:
999 0 : step_fx = 53687092; /* 0.025 in Q31 */
1000 0 : move32();
1001 0 : BREAK;
1002 0 : case 16000:
1003 0 : step_fx = 107374184; /* 0.05 in Q31 */
1004 0 : move32();
1005 0 : BREAK;
1006 0 : default:
1007 0 : assert( 0 );
1008 : BREAK;
1009 : }
1010 : }
1011 : ELSE
1012 : {
1013 5823 : crossfade_len = 0;
1014 5823 : move16();
1015 : }
1016 :
1017 : /* apply crossfade */
1018 15818 : FOR( i = 0; i < crossfade_len; i++ )
1019 : {
1020 9908 : Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx ); /* q_out */
1021 9908 : Word32 temp_2 = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), Mpy_32_32( INV_SQRT2_FX, L_sub_sat( ONE_IN_Q31, fade_fx ) ) ); /* q_out */
1022 9908 : output_fx[0][i] = L_add( temp_1, temp_2 ); /* q_out */
1023 9908 : move32();
1024 9908 : fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
1025 : }
1026 :
1027 : /* apply passive downmix on all-active-frame part */
1028 4595602 : FOR( ; i < dmx_len; i++ )
1029 : {
1030 4589692 : output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
1031 4589692 : move32();
1032 : }
1033 :
1034 5910 : return;
1035 : }
|