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