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 "options.h"
36 : #include <math.h>
37 : #include "ivas_cnst.h"
38 : #include "ivas_prot_fx.h"
39 : #include "prot_fx.h"
40 : #include "prot_fx_enc.h"
41 : #include "ivas_rom_com.h"
42 : #include "ivas_rom_com_fx.h"
43 : #include "ivas_rom_enc.h"
44 : #include "wmc_auto.h"
45 : #include "stat_enc.h"
46 :
47 :
48 : /*-------------------------------------------------------------------*
49 : * Local constants
50 : *-------------------------------------------------------------------*/
51 :
52 : #define OFFSET_BITS_TCX20 126
53 : #define OFFSET_BITS_TCX10 222
54 :
55 :
56 : /*-------------------------------------------------------------------*
57 : * Local function prototypes
58 : *-------------------------------------------------------------------*/
59 :
60 : static void convertToBwMS_fx( const Word16 startLine, const Word16 stopLine, Word32 x0[], Word32 x1[], const Word32 norm_fac );
61 :
62 : void convertToMS_fx( const Word16 L_frame, Word32 x0_fx[], Word32 x1_fx[], const Word32 norm_fac );
63 :
64 : static Word16 GetChannelEnergyRatio_fx( Encoder_State **st, const Word16 iFirstSubframe, const Word16 iLastSubframe, const UWord8 ratioInRmsDomain );
65 :
66 : static void MsStereoDecision_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, Word32 *specL_fx, Word32 *specR_fx, Word32 *specM_fx, Word32 *specS_fx, Word16 q_spec, Word16 *mdct_stereo_mode, Word16 *msMask, const Word16 nBitsAvailable );
67 :
68 :
69 : /*-------------------------------------------------------------------*
70 : * dft_ana_init()
71 : *
72 : * Initialization function for dft analysis handle within
73 : * MDCT-stereo
74 : *-------------------------------------------------------------------*/
75 :
76 151 : static void dft_ana_init_fx(
77 : DFT_ANA_HANDLE hDft_ana, /*i : DFT analysis handle */
78 : const Word32 input_Fs /*i : Input sampling frequency Q0*/
79 : )
80 : {
81 151 : hDft_ana->N = extract_l( Mpy_32_16_1( input_Fs, 656 /* STEREO_DFT_HOP_MAX_ENC / 48000 in Q15 */ ) );
82 151 : move16();
83 151 : hDft_ana->NFFT = extract_l( Mpy_32_16_1( input_Fs, 1311 /* STEREO_DFT_N_MAX_ENC / 48000 in Q15 */ ) );
84 151 : move16();
85 151 : hDft_ana->dft_ovl = extract_l( Mpy_32_16_1( input_Fs, 287 /* STEREO_DFT_OVL_MAX / 48000 in Q15 */ ) );
86 151 : move16();
87 151 : hDft_ana->dft_zp = extract_l( Mpy_32_16_1( input_Fs, 185 /* STEREO_DFT_ZP_MAX_ENC / 48000 in Q15 */ ) );
88 151 : move16();
89 :
90 151 : hDft_ana->dft_trigo_32k_fx = dft_trigo_32k_fx; /* Q15 */
91 :
92 151 : IF( EQ_32( input_Fs, 16000 ) )
93 : {
94 5 : hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */
95 5 : hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP;
96 5 : move16();
97 5 : hDft_ana->win_ana_fx = win_ana_16k_fx; /* Q15 */
98 : }
99 146 : ELSE IF( EQ_32( input_Fs, 32000 ) )
100 : {
101 59 : hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */
102 59 : hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_32k_STEP;
103 59 : move16();
104 59 : hDft_ana->win_ana_fx = win_ana_32k_fx; /* Q15 */
105 : }
106 : ELSE
107 : {
108 87 : assert( input_Fs == 48000 );
109 87 : hDft_ana->dft_trigo_fx = dft_trigo_48k_fx; /* Q15 */
110 87 : hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_48k_STEP;
111 87 : move16();
112 87 : hDft_ana->win_ana_fx = win_ana_48k_fx; /* Q15 */
113 : }
114 :
115 151 : return;
116 : }
117 :
118 :
119 : /*-------------------------------------------------------------------*
120 : * write_itd_data()
121 : *
122 : * Bitstream writing of ITDs
123 : *-------------------------------------------------------------------*/
124 :
125 11750 : static void write_itd_data_fx(
126 : ITD_DATA_HANDLE hItd, /* i : ITD data handle */
127 : BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */
128 : )
129 : {
130 : Word16 k_offset;
131 : Word16 itd;
132 :
133 11750 : k_offset = 1;
134 11750 : move16();
135 :
136 11750 : push_next_indice( hBstr, ( hItd->itd_fx[k_offset] != 0 ), STEREO_DFT_ITD_MODE_NBITS );
137 :
138 11750 : IF( hItd->itd_fx[k_offset] != 0 )
139 : {
140 3549 : itd = hItd->itd_index[k_offset]; /* Q0 */
141 3549 : IF( GT_16( itd, 255 ) )
142 : {
143 2391 : itd = sub( itd, 256 );
144 :
145 2391 : IF( LT_16( itd, 20 ) )
146 : {
147 1620 : push_next_indice( hBstr, 1, 1 ); /* use Huffman*/
148 1620 : push_next_indice( hBstr, 1, 1 ); /* negative */
149 1620 : push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] );
150 : }
151 : ELSE
152 : {
153 771 : push_next_indice( hBstr, 0, 1 ); /* don't use Huffman */
154 771 : push_next_indice( hBstr, 1, 1 ); /* negative */
155 771 : push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS - 1 );
156 : }
157 : }
158 : ELSE
159 : {
160 1158 : IF( LT_16( itd, 20 ) )
161 : {
162 886 : push_next_indice( hBstr, 1, 1 ); /* use Huffman*/
163 886 : push_next_indice( hBstr, 0, 1 ); /* positive */
164 886 : push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] );
165 : }
166 : ELSE
167 : {
168 : /* don't use Huffman and positive*/
169 272 : push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS + 1 );
170 : }
171 : }
172 : }
173 11750 : return;
174 : }
175 :
176 : /*-------------------------------------------------------------------*
177 : * stereo_coder_tcx()
178 : *
179 : *
180 : *-------------------------------------------------------------------*/
181 :
182 139819 : void stereo_coder_tcx_fx(
183 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */
184 : Encoder_State **sts, /* i/o: encoder state structure */
185 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/
186 : Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV],
187 : /* i/o: MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
188 : Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV],
189 : /* i/o: inverse spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
190 : Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV],
191 : /* i/o: inverse MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
192 : const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/
193 : Word16 exp_spec,
194 : Word16 exp_mdct_spec )
195 : {
196 139819 : STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
197 : Word32 nrgRatio_fx[CPE_CHANNELS];
198 : Word16 nrgRatio_e[CPE_CHANNELS];
199 : Word16 nonQNrgRatio_fx[CPE_CHANNELS]; // Q15
200 : Word16 k;
201 : Word16 nSubframes, L_frameTCX;
202 : Word16 nAvailBitsMS[NB_DIV];
203 : Word16 tmp, e_tmp;
204 139819 : push_wmops( "stereo_coder_tcx" );
205 :
206 :
207 139819 : set16_fx( nAvailBitsMS, 0, NB_DIV );
208 :
209 139819 : nSubframes = ( sts[0]->core == TCX_20_CORE && sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV;
210 139819 : L_frameTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes );
211 :
212 139819 : set16_fx( &ms_mask[0][0], 0, MAX_SFB );
213 139819 : set16_fx( &ms_mask[1][0], 0, MAX_SFB );
214 :
215 139819 : IF( !mct_on )
216 : {
217 42785 : IF( EQ_16( sts[0]->core, sts[1]->core ) )
218 : {
219 86188 : FOR( k = 0; k < nSubframes; k++ )
220 : {
221 43667 : nonQNrgRatio_fx[k] = GetChannelEnergyRatio_fx( sts, k, k, 1 ); // Q15
222 43667 : move16();
223 :
224 43667 : hStereoMdct->global_ild[k] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[k] ) ) ) );
225 43667 : move16();
226 43667 : nrgRatio_fx[k] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[k] ), hStereoMdct->global_ild[k], &nrgRatio_e[k] ) ); /* Q31-nrgRatio_e[k] */
227 43667 : move32();
228 : /*nonQNrgRatio[k] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[k] ) );
229 : nonQNrgRatio[k] = 1.0f / nonQNrgRatio[k] - 1.0f;*/
230 : // Not getting used further
231 : }
232 : }
233 : ELSE
234 : {
235 264 : nonQNrgRatio_fx[0] = nonQNrgRatio_fx[1] = GetChannelEnergyRatio_fx( sts, 0, nSubframes - 1, 1 ); /* Q15 */
236 264 : move16();
237 264 : hStereoMdct->global_ild[0] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[0] ) ) ) );
238 264 : move16();
239 264 : nrgRatio_fx[0] = nrgRatio_fx[1] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[0] ), hStereoMdct->global_ild[0], &nrgRatio_e[0] ) ); /* nrgRatio = nrg[1]/nrg[0] (Q31-nrgRatio_e[0])*/
240 264 : move32();
241 264 : nrgRatio_e[1] = nrgRatio_e[0];
242 264 : move16();
243 : /*nonQNrgRatio[0] = nonQNrgRatio[1] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[0] ) );
244 : nonQNrgRatio[0] = nonQNrgRatio[1] = 1.0f / nonQNrgRatio[0] - 1.0f;*/
245 : // Not getting used further
246 : }
247 :
248 86980 : FOR( k = 0; k < nSubframes; k++ )
249 : {
250 44195 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), 1 ) && LT_16( k, ( EQ_16( sts[1]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) )
251 : {
252 21443 : L_frameTCX = add( sts[1]->hTcxEnc->L_frameTCX, ( ( sts[1]->last_core == 0 ) ? shr( sts[1]->hTcxEnc->L_frameTCX, 2 ) : 0 ) ); /* Q0 */
253 21443 : L_frameTCX = idiv1616( L_frameTCX, ( sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV ); /* Q0 */
254 :
255 21443 : e_tmp = nrgRatio_e[k];
256 21443 : tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); /* Q15-e_tmp */
257 21443 : tmp = shl( tmp, e_tmp ); /* Q15 */
258 :
259 21443 : v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */
260 21443 : v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); /* exp: exp_mdct_spec */
261 : }
262 22752 : ELSE IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), -1 ) && LT_16( k, EQ_16( sts[0]->core, TCX_20_CORE ) ? 1 : NB_DIV ) )
263 : {
264 9564 : L_frameTCX = add( sts[0]->hTcxEnc->L_frameTCX, EQ_16( sts[0]->last_core, 0 ) ? shr( sts[0]->hTcxEnc->L_frameTCX, 2 ) : 0 ); /* Q0 */
265 9564 : L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV ); /* Q0 */
266 :
267 : /* This operation is resulting in some high MLDs in fixed point. */
268 9564 : v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */
269 9564 : v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); /* exp: exp_mdct_spec */
270 : }
271 : }
272 : }
273 :
274 : #ifdef DEBUG_FORCE_MDCT_STEREO_MODE
275 : IF( hStereoMdct->fDualMono ||
276 : ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) ) || NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) || ( NE_16( sts[0]->last_core, sts[1]->last_core ) && ( EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) ) || EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) )
277 : #else
278 139819 : IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) ) || NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) || ( NE_16( sts[0]->last_core, sts[1]->last_core ) && ( EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) ) || EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) )
279 : #endif
280 : {
281 931 : hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO;
282 931 : move16();
283 931 : hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO;
284 931 : move16();
285 :
286 :
287 931 : IF( sts[0]->igf )
288 : {
289 659 : hStereoMdct->IGFStereoMode[0] = SMDCT_DUAL_MONO;
290 659 : move16();
291 659 : hStereoMdct->IGFStereoMode[1] = SMDCT_DUAL_MONO;
292 659 : move16();
293 : }
294 931 : hStereoMdct->sw_uncorr = 1;
295 931 : move16();
296 :
297 931 : pop_wmops();
298 931 : return;
299 : }
300 : #ifdef DEBUG_FORCE_MDCT_STEREO_MODE
301 : else if ( hStereoMdct->fMSstereo )
302 : {
303 : hStereoMdct->mdct_stereo_mode[0] = SMDCT_MS_FULL;
304 : hStereoMdct->mdct_stereo_mode[1] = SMDCT_MS_FULL;
305 :
306 : if ( sts[0]->igf )
307 : {
308 : hStereoMdct->IGFStereoMode[0] = SMDCT_MS_FULL;
309 : hStereoMdct->IGFStereoMode[1] = SMDCT_MS_FULL;
310 : }
311 : for ( k = 0; k < nSubframes; k++ )
312 : {
313 : convertToMS_fx( L_frameTCX, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], SQRT2_OVER_2_FIXED );
314 :
315 : /* Make sure that the MDST is processed in the correct way also */
316 : set_s( &ms_mask[k][0], 1, MAX_SFB );
317 : }
318 :
319 : pop_wmops();
320 : return;
321 : }
322 : #endif
323 : ELSE /* decide based on signal */
324 : {
325 280939 : FOR( k = 0; k < nSubframes; k++ )
326 : {
327 142051 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
328 : {
329 135725 : sfbConf = &hStereoMdct->stbParamsTCX20;
330 : }
331 : ELSE
332 : {
333 6326 : sfbConf = &hStereoMdct->stbParamsTCX10;
334 : }
335 142051 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
336 : {
337 0 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
338 : }
339 :
340 142051 : IF( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && !mct_on ) /* band-wise HF ILD alignment to increase channel compaction */
341 : {
342 25293 : Word16 sfb = 1;
343 25293 : move16();
344 :
345 25293 : test();
346 417805 : WHILE( LT_16( sfb, sfbConf->nBandsStereoCore ) && LT_16( sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ), 12 ) )
347 : {
348 392512 : test();
349 392512 : sfb = add( sfb, 1 ); /* find start offset */
350 : }
351 :
352 420649 : FOR( sfb--; sfb < sfbConf->nBandsStereoCore; sfb++ ) /* start one SFB early for the fade-in */
353 : {
354 395356 : const Word16 startLine = sfbConf->sfbOffset[sfb]; /* Q0 */
355 395356 : move16();
356 395356 : const Word16 endLine = sfbConf->sfbOffset[sfb + 1]; /* Q0 */
357 395356 : move16();
358 395356 : const Word16 sfbWidth = sub( endLine, startLine );
359 :
360 395356 : nrgRatio_e[0] = nrgRatio_e[1] = exp_spec;
361 395356 : move16();
362 395356 : move16();
363 :
364 395356 : nrgRatio_fx[0] = sum2_32_fx( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
365 395356 : move32();
366 395356 : nrgRatio_fx[1] = sum2_32_fx( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
367 395356 : move32();
368 :
369 395356 : test();
370 395356 : IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] ) /* no TNS in either ch */
371 : {
372 : Word32 tmp_fx;
373 : Word16 tmp_e;
374 331885 : tmp_e = exp_mdct_spec;
375 331885 : move16();
376 331885 : tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */
377 331885 : nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
378 331885 : tmp_e = exp_mdct_spec;
379 331885 : move16();
380 331885 : tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */
381 331885 : nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
382 : }
383 395356 : IF( ( nrgRatio_fx[0] > 0 ) && ( nrgRatio_fx[1] > 0 ) && BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1] ) )
384 : {
385 : Word16 fTemp_e, tmp_e;
386 395026 : Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); /* Q31-fTemp_e */
387 395026 : fTemp_e = sub( fTemp_e, 1 );
388 395026 : nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[0], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[0] */
389 395026 : move32();
390 395026 : nrgRatio_e[0] = add( tmp_e, sub( fTemp_e, nrgRatio_e[0] ) );
391 395026 : move16();
392 395026 : nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
393 395026 : move32();
394 :
395 395026 : nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[1], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[1] */
396 395026 : move32();
397 395026 : nrgRatio_e[1] = add( tmp_e, sub( fTemp_e, nrgRatio_e[1] ) );
398 395026 : move16();
399 395026 : nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
400 395026 : move32();
401 :
402 395026 : nrgRatio_fx[0] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[0], sub( nrgRatio_e[0], 2 ) ) ); // max( 0.25f, min( 4.f, nrgRatio[0] ) );
403 395026 : move32();
404 395026 : nrgRatio_fx[1] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[1], sub( nrgRatio_e[1], 2 ) ) ); // Q29
405 395026 : move32();
406 395026 : nrgRatio_e[0] = Q2;
407 395026 : move16();
408 395026 : nrgRatio_e[1] = Q2;
409 395026 : move16();
410 :
411 395026 : IF( ( LT_16( sfbWidth, 12 ) && LT_16( add( sfb, 1 ), sfbConf->nBandsStereoCore ) ) || GT_32( sts[0]->element_brate, IVAS_48k ) ) /* attenuate ILD alignment in the first SFB or at 64k */
412 : {
413 208803 : nrgRatio_fx[0] = BASOP_Util_fPow( nrgRatio_fx[0], nrgRatio_e[0], ONE_IN_Q29, 0, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
414 208803 : move32();
415 208803 : nrgRatio_fx[1] = BASOP_Util_fPow( nrgRatio_fx[1], nrgRatio_e[1], ONE_IN_Q29, 0, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
416 208803 : move32();
417 : }
418 : ELSE
419 : {
420 186223 : nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
421 186223 : move32();
422 186223 : nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
423 186223 : move32();
424 : }
425 :
426 395026 : nrgRatio_fx[0] = L_shl( nrgRatio_fx[0], sub( nrgRatio_e[0], 1 ) ); // Q30
427 395026 : move32();
428 395026 : nrgRatio_fx[1] = L_shl( nrgRatio_fx[1], sub( nrgRatio_e[1], 1 ) ); // Q30
429 395026 : move32();
430 :
431 :
432 395026 : v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */
433 395026 : v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); /* exp: exp_mdct_spec+1 */
434 395026 : scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // exp: exp_spec
435 395026 : scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // exp: exp_mdct_spec
436 :
437 395026 : v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */
438 395026 : v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); /* exp: exp_mdct_spec+1 */
439 395026 : scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // exp: exp_spec
440 395026 : scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // exp: exp_mdct_spec
441 : }
442 : }
443 : }
444 :
445 : /* set mask to zero */
446 142051 : set16_fx( &ms_mask[k][0], 0, MAX_SFB );
447 142051 : IF( mct_on )
448 : {
449 99057 : nAvailBitsMS[k] = shl( sts[0]->bits_frame_channel, 1 ); /* Q0 */
450 99057 : move16();
451 : }
452 : ELSE
453 : {
454 42994 : nAvailBitsMS[k] = sts[0]->bits_frame_nominal; /* Q0 */
455 42994 : move16();
456 : }
457 :
458 142051 : nAvailBitsMS[k] = sub( nAvailBitsMS[k], add( sts[0]->side_bits_frame_channel, sts[1]->side_bits_frame_channel ) ); /* Q0 */
459 142051 : move16();
460 :
461 142051 : IF( EQ_16( nSubframes, 2 ) )
462 : {
463 6326 : nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX10 ); /* Q0 */
464 6326 : move16();
465 : }
466 : ELSE
467 : {
468 135725 : nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX20 ); /* Q0 */
469 135725 : move16();
470 : }
471 :
472 142051 : nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); /* Q0 */
473 142051 : move16();
474 :
475 142051 : test();
476 142051 : IF( mct_on && LE_16( nAvailBitsMS[k], 0 ) ) /*Force M/S when bit-budget is low for MCT*/
477 : {
478 0 : hStereoMdct->mdct_stereo_mode[k] = 1;
479 0 : move16();
480 0 : hStereoMdct->IGFStereoMode[k] = 1;
481 0 : move16();
482 0 : set16_fx( ms_mask[k], 1, sfbConf->sfbCnt );
483 : }
484 : ELSE
485 : {
486 142051 : MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sub( Q31, exp_spec ), &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] );
487 :
488 142051 : IF( sts[0]->igf )
489 : {
490 92740 : IGFEncStereoEncoder_fx( sfbConf, sts[0]->hIGFEnc, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sub( Q31, exp_spec ), &ms_mask[k][0],
491 92740 : &hStereoMdct->IGFStereoMode[k], hStereoMdct->mdct_stereo_mode[k], (Word16) EQ_16( sts[0]->core, TCX_20_CORE ), (Word16) EQ_16( sts[0]->last_core, ACELP_CORE ) );
492 : }
493 : ELSE
494 : {
495 49311 : hStereoMdct->IGFStereoMode[k] = hStereoMdct->mdct_stereo_mode[k];
496 49311 : move16();
497 : }
498 : }
499 :
500 142051 : IF( NE_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) || NE_16( hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) )
501 : {
502 :
503 134652 : ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sfbConf->sfbCnt );
504 :
505 134652 : ms_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sfbConf->sfbCnt );
506 :
507 134652 : IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] )
508 : {
509 111833 : sts[0]->hTcxEnc->tns_ms_flag[k] = 1;
510 111833 : move16();
511 111833 : sts[1]->hTcxEnc->tns_ms_flag[k] = 1;
512 111833 : move16();
513 111833 : ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], inv_mdst_spectrum_fx[0][k], inv_mdst_spectrum_fx[1][k], -1 );
514 :
515 111833 : ms_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], sfbConf->sfbCnt );
516 : }
517 : }
518 : } /* for k */
519 : }
520 : /* for bitrate switching determine correlation depending on m/s decision */
521 : {
522 : Word16 ms_bands[2];
523 : Word16 sw_uncorr[2], sw_uncorr_mean;
524 280939 : FOR( k = 0; k < nSubframes; k++ )
525 : {
526 142051 : sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
527 142051 : ms_bands[k] = sum_s( ms_mask[k], sfbConf->nBandsStereoCore ); /* Q0 */
528 142051 : move16();
529 142051 : sw_uncorr[k] = sub( 32767 /*Q15*/, div_s( ms_bands[k], sfbConf->nBandsStereoCore ) ); /* Q15 */
530 142051 : move16();
531 : }
532 138888 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
533 : {
534 135725 : sw_uncorr_mean = sw_uncorr[0]; /* Q15 */
535 135725 : move16();
536 : }
537 : ELSE
538 : {
539 3163 : sw_uncorr_mean = add( shr( sw_uncorr[0], 1 ), shr( sw_uncorr[1], 1 ) ); /* Q15 */
540 : }
541 138888 : hStereoMdct->sw_uncorr = extract_l( GT_16( sw_uncorr_mean, 19661 /*0.6 in Q15*/ ) );
542 138888 : move16();
543 : }
544 :
545 138888 : pop_wmops();
546 138888 : return;
547 : }
548 :
549 : /*-------------------------------------------------------------------*
550 : * ms_processing()
551 : *
552 : *
553 : *-------------------------------------------------------------------*/
554 :
555 246485 : void ms_processing_fx(
556 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */
557 : Encoder_State **sts, /* i/o: Encoder state structure */
558 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/
559 : const Word16 iSubframe, /* i : subframe number Q0*/
560 : Word32 x_0_fx[],
561 : /* i/o: spectrum 1 */ // Q( q_x )
562 : Word32 x_1_fx[],
563 : /* i/o: spectrum 1 */ // Q( q_x )
564 : Word16 maxSfb /* i : number of stereo frequency bands Q0*/
565 : )
566 : {
567 : Word16 sfb;
568 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
569 :
570 246485 : sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
571 :
572 246485 : IF( sts[0]->last_core == ACELP_CORE )
573 : {
574 0 : assert( EQ_16( sts[1]->last_core, ACELP_CORE ) );
575 0 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
576 : }
577 :
578 246485 : if ( EQ_16( maxSfb, -1 ) )
579 : {
580 0 : maxSfb = sfbConf->sfbCnt; /* Q0 */
581 0 : move16();
582 : }
583 :
584 10841495 : FOR( sfb = 0; sfb < maxSfb; sfb++ )
585 : {
586 10595010 : IF( NE_16( ms_mask[iSubframe][sfb], 0 ) )
587 : {
588 8698441 : convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_0_fx, x_1_fx, SQRT2_OVER_2_FIXED );
589 : }
590 : }
591 :
592 246485 : return;
593 : }
594 :
595 : /*-------------------------------------------------------------------*
596 : * ms_inv_mask_processing()
597 : *
598 : *
599 : *-------------------------------------------------------------------*/
600 :
601 246485 : void ms_inv_mask_processing_fx(
602 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */
603 : Encoder_State **sts, /* i/o: Encoder state structure */
604 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/
605 : const Word16 iSubframe, /* i : subframe number Q0*/
606 : const Word32 x_0_fx[],
607 : /* i : spectrum 1 */ // Q( q_x )
608 : const Word32 x_1_fx[],
609 : /* i : spectrum 2 */ // Q( q_x )
610 : Word32 x_inv_0_fx[],
611 : /* o : inverse spectrum 1 */ // Q( q_x )
612 : Word32 x_inv_1_fx[],
613 : /* o : inverse spectrum 2 */ // Q( q_x )
614 : Word16 maxSfb /* i : number of stereo frequency bands Q0*/
615 : )
616 : {
617 : Word16 sfb;
618 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
619 : Word16 nSubframes, L_subframeTCX;
620 :
621 246485 : nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
622 246485 : L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */
623 246485 : sfbConf = ( sts[0]->core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
624 :
625 246485 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
626 : {
627 0 : assert( EQ_16( sts[1]->last_core, ACELP_CORE ) );
628 0 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
629 : }
630 :
631 246485 : IF( EQ_16( maxSfb, -1 ) )
632 : {
633 111833 : maxSfb = sfbConf->sfbCnt; /* Q0 */
634 111833 : move16();
635 : }
636 :
637 10841495 : FOR( sfb = 0; sfb < maxSfb; sfb++ )
638 : {
639 10595010 : Copy32( &x_0_fx[sfbConf->sfbOffset[sfb]], &x_inv_0_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */
640 10595010 : Copy32( &x_1_fx[sfbConf->sfbOffset[sfb]], &x_inv_1_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */
641 :
642 10595010 : IF( EQ_16( ms_mask[iSubframe][sfb], 0 ) )
643 : {
644 1896569 : convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_inv_0_fx, x_inv_1_fx, SQRT2_OVER_2_FIXED );
645 : }
646 : }
647 :
648 : /* set rest of inverse spectrum to zero */
649 246485 : IF( GT_16( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) )
650 : {
651 146728 : set_zero_fx( &x_inv_0_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) );
652 146728 : set_zero_fx( &x_inv_1_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) );
653 : }
654 :
655 246485 : return;
656 : }
657 :
658 :
659 : /*-------------------------------------------------------------------*
660 : * write_stereo_to_bitstream()
661 : *
662 : *
663 : *-------------------------------------------------------------------*/
664 :
665 134951 : Word16 write_stereo_to_bitstream_fx(
666 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */
667 : Encoder_State **sts, /* i/o: Encoder state structure */
668 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/
669 : const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/
670 : BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */
671 : )
672 : {
673 : Word16 i, k, nSubframes;
674 : UWord16 mdct_stereo_mode, stereo_mode_bits;
675 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
676 134951 : Word16 start_bits = hBstr->nb_bits_tot;
677 134951 : move16();
678 :
679 134951 : if ( !mct_on )
680 : {
681 42785 : assert( ( EQ_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && EQ_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || ( EQ_16( hStereoMdct->mdct_stereo_mode[0], SMDCT_DUAL_MONO ) && EQ_16( hStereoMdct->mdct_stereo_mode[1], SMDCT_DUAL_MONO ) ) );
682 : }
683 :
684 134951 : nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || NE_16( sts[0]->core, sts[1]->core ) ) ? NB_DIV : 1;
685 134951 : move16();
686 134951 : sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
687 134951 : move16();
688 :
689 134951 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
690 : {
691 651 : assert( EQ_16( sts[1]->ini_frame, 0 ) || EQ_16( sts[1]->last_core, ACELP_CORE ) );
692 651 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
693 : }
694 :
695 134951 : IF( hStereoMdct->hItd != NULL )
696 : {
697 11750 : write_itd_data_fx( hStereoMdct->hItd, hBstr );
698 : }
699 :
700 273320 : FOR( k = 0; k < nSubframes; k++ )
701 : {
702 138369 : mdct_stereo_mode = 0;
703 138369 : move16();
704 138369 : stereo_mode_bits = 1;
705 138369 : move16();
706 :
707 138369 : SWITCH( hStereoMdct->mdct_stereo_mode[k] )
708 : {
709 3788 : case SMDCT_DUAL_MONO:
710 3788 : mdct_stereo_mode = 0;
711 3788 : move16();
712 3788 : stereo_mode_bits = 1;
713 3788 : move16();
714 3788 : BREAK;
715 83549 : case SMDCT_MS_FULL:
716 83549 : mdct_stereo_mode = 2;
717 83549 : move16();
718 83549 : stereo_mode_bits = 2;
719 83549 : move16();
720 83549 : BREAK;
721 51032 : case SMDCT_BW_MS:
722 51032 : mdct_stereo_mode = 3;
723 51032 : move16();
724 51032 : stereo_mode_bits = 2;
725 51032 : move16();
726 51032 : BREAK;
727 0 : default:
728 0 : assert( !"Not supported MDCT stereo mode\n" );
729 : }
730 :
731 138369 : push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits );
732 :
733 138369 : IF( !mct_on )
734 : {
735 44195 : IF( EQ_16( sts[0]->core, sts[1]->core ) || ( k == 0 ) )
736 : {
737 43931 : push_next_indice( hBstr, hStereoMdct->global_ild[k], SMDCT_GLOBAL_ILD_BITS );
738 : }
739 : }
740 :
741 138369 : IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
742 : {
743 2117442 : FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
744 : {
745 2066410 : push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 );
746 : }
747 : }
748 :
749 138369 : IF( sts[0]->igf )
750 : {
751 92107 : mdct_stereo_mode = 0;
752 92107 : move16();
753 92107 : stereo_mode_bits = 1;
754 92107 : move16();
755 92107 : SWITCH( hStereoMdct->IGFStereoMode[k] )
756 : {
757 37337 : case SMDCT_DUAL_MONO:
758 37337 : mdct_stereo_mode = 0;
759 37337 : move16();
760 37337 : stereo_mode_bits = 1;
761 37337 : move16();
762 37337 : BREAK;
763 40413 : case SMDCT_MS_FULL:
764 40413 : mdct_stereo_mode = 2;
765 40413 : move16();
766 40413 : stereo_mode_bits = 2;
767 40413 : move16();
768 40413 : BREAK;
769 14357 : case SMDCT_BW_MS:
770 14357 : mdct_stereo_mode = 3;
771 14357 : move16();
772 14357 : stereo_mode_bits = 2;
773 14357 : move16();
774 14357 : BREAK;
775 0 : default:
776 0 : assert( !"Not supported MDCT stereo mode\n" );
777 : }
778 :
779 92107 : push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits );
780 :
781 :
782 92107 : IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
783 : {
784 90936 : FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
785 : {
786 76579 : push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 );
787 : }
788 : }
789 : }
790 : }
791 :
792 134951 : return sub( hBstr->nb_bits_tot, start_bits );
793 : }
794 :
795 : /*-------------------------------------------------------------------*
796 : * Band-wise M/S stereo processing
797 : *
798 : *
799 : *-------------------------------------------------------------------*/
800 :
801 10689090 : static void convertToBwMS_fx(
802 : const Word16 startLine, /* i : start line of sfb Q0*/
803 : const Word16 stopLine, /* i : stop line of sfb Q0*/
804 : Word32 x0[],
805 : /* i/o: mid/left channel coefficients */ /* Q_x */
806 : Word32 x1[],
807 : /* i/o: side/right channel coefficients */ /* Q_x */
808 : const Word32 norm_fac /* i : normalization factor */ /* Q31 */
809 : )
810 : {
811 : Word16 j;
812 : Word32 tmpValue_fx;
813 :
814 198213652 : FOR( j = startLine; j < stopLine; j++ )
815 : {
816 187524562 : tmpValue_fx = x0[j]; /*Q_x*/
817 187524562 : move32();
818 187524562 : x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Q_x */
819 187524562 : move32();
820 187524562 : x1[j] = Mpy_32_32( L_sub( tmpValue_fx, x1[j] ), norm_fac ); /* Q_x */
821 187524562 : move32();
822 : }
823 :
824 10689090 : return;
825 : }
826 :
827 : /*-------------------------------------------------------------------*
828 : * convertToMS()
829 : *
830 : *
831 : *-------------------------------------------------------------------*/
832 :
833 94080 : void convertToMS_fx(
834 : const Word16 L_frame, /* i : frame length Q0*/
835 : Word32 x0[], /* i/o: mid/left channel coefficients Q(q_x)*/
836 : Word32 x1[], /* i/o: side/right channel coefficients Q(q_x)*/
837 : const Word32 norm_fac /* i : normalization factor Q31*/
838 : )
839 : {
840 94080 : convertToBwMS_fx( 0, L_frame, x0, x1, norm_fac );
841 :
842 94080 : return;
843 : }
844 :
845 : /*-------------------------------------------------------------------*
846 : * SQ_gain_estimate_stereo()
847 : *
848 : *
849 : *-------------------------------------------------------------------*/
850 :
851 : /*! r: SQ gain */
852 142051 : static Word32 SQ_gain_estimate_stereo_fx( // e_res
853 : const Word32 xL_fx[], /* i : L vector to quantize Q31-e_xL*/
854 : const Word16 e_xL,
855 : const Word32 xR_fx[], /* i : R vector to quantize Q31-e_xR*/
856 : const Word16 e_xR,
857 : const Word16 nbitsSQ, /* i : number of bits targeted Q0*/
858 : const Word16 lg, /* i : vector size (2048 max) Q0*/
859 : Word16 *e_res )
860 : {
861 : Word16 i, q, iter, e_ener, e_xL_2, e_xR_2, s;
862 : Word32 ener_fx, tmp_32, target_fx, fac_fx, offset_fx;
863 : Word32 en_fx[N_MAX / 2]; // Q25
864 : Word16 lg2, lg_4, lg2_4;
865 : Word64 W_tmp, _0_01;
866 :
867 142051 : lg_4 = shr( lg, 2 ); /* Q0 */
868 142051 : lg2_4 = shl( lg_4, 1 ); /* Q0 */
869 142051 : lg2 = shl( lg2_4, 2 ); /* Q0 */
870 142051 : i = 0;
871 142051 : move16();
872 142051 : e_xL_2 = shl( e_xL, 1 );
873 142051 : e_xR_2 = shl( e_xR, 1 );
874 142051 : _0_01 = W_shr( 21474836 /* 0.01 in Q31 */, sub( e_xL_2, 32 ) ); // 0.01 in 2*(Q of specL/R) + 1
875 :
876 142051 : set32_fx( en_fx, 335544 /* 0.01 in Q25 */, ( N_MAX / 2 ) );
877 :
878 : /* energy of quadruples with 9dB offset */
879 : /* ignore that we may take no all lines into account, max. 3 lines at the upper end of the spectrum can be missed (if lg is not a multiple of 4, happens also in SQGain()*/
880 :
881 20311967 : FOR( q = 0; q < lg_4; q++ )
882 : {
883 20169916 : W_tmp = W_mac_32_32( _0_01, xL_fx[i], xL_fx[i] ); // 2 * e_xL
884 20169916 : W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 1], xL_fx[i + 1] ); // 2 * e_xL
885 20169916 : W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 2], xL_fx[i + 2] ); // 2 * e_xL
886 20169916 : W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 3], xL_fx[i + 3] ); // 2 * e_xL
887 :
888 20169916 : s = W_norm( W_tmp );
889 20169916 : ener_fx = W_extract_h( W_shl( W_tmp, s ) );
890 20169916 : e_ener = sub( e_xL_2, s );
891 :
892 20169916 : en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */
893 20169916 : move32();
894 20169916 : en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25)
895 20169916 : move32();
896 20169916 : i += 4;
897 : }
898 142051 : i = 0;
899 142051 : move16();
900 20311967 : FOR( ; q < lg2_4; q++ )
901 : {
902 20169916 : W_tmp = W_mac_32_32( _0_01, xR_fx[i], xR_fx[i] ); // 2 * e_xR
903 20169916 : W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 1], xR_fx[i + 1] ); // 2 * e_xR
904 20169916 : W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 2], xR_fx[i + 2] ); // 2 * e_xR
905 20169916 : W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 3], xR_fx[i + 3] ); // 2 * e_xR
906 :
907 20169916 : s = W_norm( W_tmp );
908 20169916 : ener_fx = W_extract_h( W_shl( W_tmp, s ) );
909 20169916 : e_ener = sub( e_xR_2, s );
910 :
911 20169916 : en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */
912 20169916 : move32();
913 20169916 : en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25)
914 20169916 : move32();
915 20169916 : i += 4;
916 : }
917 :
918 : /* SQ scale: 4 bits / 6 dB per quadruple */
919 142051 : target_fx = L_mult( 19660 /* 0.15 in Q17 */, sub( nbitsSQ, shr( lg2, 4 ) ) ); // Q(18)
920 142051 : fac_fx = 429496729; /* 12.8 in Q25 */
921 142051 : move32();
922 142051 : offset_fx = fac_fx; /* Q25 */
923 142051 : move32();
924 :
925 142051 : Word64 target_64_fx = W_shl( target_fx, 7 ); // Q25
926 : /* find offset (0 to 128 dB with step of 0.125dB) */
927 1562561 : FOR( iter = 0; iter < 10; iter++ )
928 : {
929 1420510 : fac_fx = L_shr( fac_fx, 1 ); /* Q25 */
930 1420510 : offset_fx = L_sub( offset_fx, fac_fx ); /* Q25 */
931 1420510 : W_tmp = 0;
932 1420510 : move64();
933 :
934 366372737 : FOR( i = 0; i < lg2_4; i++ )
935 : {
936 365534700 : tmp_32 = L_sub( en_fx[i], offset_fx ); /* Q25 */
937 :
938 : /* avoid SV with 1 bin of amp < 0.5f */
939 365534700 : if ( GT_32( tmp_32, 10066329 /*0.3 Q25*/ ) )
940 : {
941 202080105 : W_tmp = W_add( W_tmp, tmp_32 ); /* Q25 */
942 : }
943 : /* if ener is above target -> break and increase offset */
944 365534700 : IF( GT_64( W_tmp, target_64_fx ) )
945 : {
946 582473 : offset_fx = L_add( offset_fx, fac_fx ); /* Q25 */
947 582473 : BREAK;
948 : }
949 : }
950 : }
951 :
952 : /* return gain */
953 142051 : tmp_32 = L_add( 12539858, Mpy_32_16_1( offset_fx, 13606 ) ); // Q23
954 :
955 142051 : return BASOP_util_Pow2( tmp_32, Q8, e_res ); /* Q31-e_res */
956 : }
957 :
958 : /*-------------------------------------------------------------------*
959 : * QuantSpecEstimateBits()
960 : *
961 : *
962 : *-------------------------------------------------------------------*/
963 :
964 568204 : static Word16 QuantSpecEstimateBits_fx(
965 : Word32 *spec_fx, /* Q15-spec_e */
966 : Word16 spec_e,
967 : Word16 G_fx, /* Q15-G_e */
968 : Word16 G_e,
969 : const Word16 length, /* Q0 */
970 : const Word16 nBitsAvailable, /* Q0 */
971 : Word16 sqQ[] /* Q0 */ )
972 : {
973 : Word16 stop, sqBits, nEncoded;
974 : Word16 lastnz;
975 :
976 568204 : tcx_scalar_quantization_ivas_fx( spec_fx, spec_e, sqQ, length, G_fx, G_e, 16384 /*Q15*/, NULL, 1 );
977 :
978 568204 : stop = 0;
979 568204 : move16();
980 :
981 568204 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, length, &lastnz, &nEncoded, nBitsAvailable, &stop, 0, NULL ); /*Q0*/
982 :
983 568204 : if ( stop != 0 )
984 : {
985 79531 : sqBits = stop;
986 79531 : move16();
987 : }
988 :
989 568204 : return sqBits;
990 : }
991 :
992 : /*-------------------------------------------------------------------*
993 : * context_update()
994 : *
995 : *
996 : *-------------------------------------------------------------------*/
997 :
998 11299330 : static void context_update_fx(
999 : HANDLE_RC_CONTEXT_MEM ctxSrc,
1000 : HANDLE_RC_CONTEXT_MEM ctxTarget,
1001 : const Word16 endLine /*Q0*/ )
1002 : {
1003 : Word16 last_nz;
1004 :
1005 : /* check if last_nz of target is smaller than endLine, save and update */
1006 11299330 : last_nz = s_max( ctxTarget->lastnz, endLine ); /* Q0 */
1007 :
1008 11299330 : mvc2c( (UWord8 *) ctxSrc, (UWord8 *) ctxTarget, sizeof( RC_CONTEXT_MEM ) );
1009 11299330 : ctxTarget->lastnz = last_nz;
1010 11299330 : move16();
1011 :
1012 11299330 : return;
1013 : }
1014 :
1015 : /*-------------------------------------------------------------------*
1016 : * GetChannelEnergyRatio()
1017 : *
1018 : *
1019 : *-------------------------------------------------------------------*/
1020 :
1021 127714 : static Word16 GetChannelEnergyRatio_fx( // Q15
1022 : Encoder_State **sts, /* i/o: Encoder state structure */
1023 : const Word16 iFirstSubframe,
1024 : const Word16 iLastSubframe,
1025 : const UWord8 ratioInRmsDomain /* Q0 */ )
1026 : {
1027 : Word16 ch, n, i;
1028 : Word32 nrg_fx[2];
1029 : Word16 nrg_e[2];
1030 :
1031 : /* Calculate energies per channel */
1032 383142 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
1033 : {
1034 255428 : const Encoder_State *st = sts[ch];
1035 :
1036 255428 : Word16 nSubframes = NB_DIV;
1037 255428 : move16();
1038 :
1039 255428 : if ( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
1040 : {
1041 246420 : nSubframes = 1;
1042 246420 : move16();
1043 : }
1044 :
1045 255428 : Word16 L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, sub( nSubframes, 1 ) ); /* Q0 */
1046 :
1047 255428 : if ( st->last_core == ACELP_CORE )
1048 : {
1049 2604 : L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); /* Q0 */
1050 : }
1051 255428 : assert( iFirstSubframe >= 0 && ( iFirstSubframe <= iLastSubframe ) );
1052 :
1053 255428 : nrg_fx[ch] = 0;
1054 255428 : move32();
1055 255428 : nrg_e[ch] = 0;
1056 255428 : move16();
1057 :
1058 515280 : FOR( n = iFirstSubframe; n <= s_min( nSubframes - 1, iLastSubframe ); n++ )
1059 : {
1060 196510092 : FOR( i = 0; i < L_subframeTCX; i++ )
1061 : {
1062 196250240 : nrg_fx[ch] = BASOP_Util_Add_Mant32Exp( nrg_fx[ch], nrg_e[ch], Mpy_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ), shl( st->hTcxEnc->spectrum_e[n], 1 ), &nrg_e[ch] ); /* Q31-nrg_e */
1063 196250240 : move32();
1064 : }
1065 : }
1066 255428 : IF( ratioInRmsDomain && nrg_fx[ch] )
1067 : {
1068 246431 : nrg_fx[ch] = Sqrt32( nrg_fx[ch], &nrg_e[ch] ); /* Q31-nrg_e */
1069 246431 : move32();
1070 : }
1071 : }
1072 :
1073 127714 : IF( L_add_sat( nrg_fx[0], nrg_fx[1] ) )
1074 : {
1075 127693 : nrg_fx[1] = BASOP_Util_Add_Mant32Exp( nrg_fx[0], nrg_e[0], nrg_fx[1], nrg_e[1], &nrg_e[1] ); /* Q31-nrg_e[1] */
1076 127693 : move32();
1077 :
1078 127693 : IF( NE_16( nrg_e[1], nrg_e[0] ) )
1079 : {
1080 89664 : nrg_fx[0] = L_shr( nrg_fx[0], sub( nrg_e[1], nrg_e[0] ) ); /* Q31-nrg_e[1] */
1081 89664 : move32();
1082 : }
1083 127693 : return divide3232( nrg_fx[0], nrg_fx[1] ); /* Q15 */
1084 : }
1085 :
1086 21 : return MIN_16;
1087 : }
1088 :
1089 : /*-------------------------------------------------------------------*
1090 : * FindSplitRatio()
1091 : *
1092 : *
1093 : *-------------------------------------------------------------------*/
1094 :
1095 83783 : void FindSplitRatio_fx(
1096 : CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */
1097 : Encoder_State **sts /* i/o: Encoder state structure */
1098 : )
1099 : {
1100 83783 : const UWord8 highRateMdctStereo = ( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) && sts[0]->hTcxEnc->enc_ste_pre_corr_past ? 0 : 1 );
1101 83783 : move16();
1102 : Word16 ratio_fx;
1103 :
1104 : /* Calculate split ratio and quantize it */
1105 83783 : hCPE->hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels */
1106 83783 : move16();
1107 :
1108 83783 : ratio_fx = GetChannelEnergyRatio_fx( sts, 0, 1, highRateMdctStereo ); // Q15
1109 :
1110 83783 : IF( ratio_fx >= 0 )
1111 : {
1112 83762 : hCPE->hStereoMdct->split_ratio = round_fx( L_mult( SMDCT_BITRATE_RATIO_RANGE, ratio_fx ) ); /* Q0 */
1113 83762 : move16();
1114 : /* Tuning to get closer to the optimal split ratio */
1115 83762 : IF( LT_32( L_mult0( 9, ratio_fx ), 8 * ONE_IN_Q15 ) && GT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE + ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) )
1116 : {
1117 64698 : hCPE->hStereoMdct->split_ratio = sub( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */
1118 64698 : move16();
1119 : }
1120 83762 : IF( GT_32( L_mult0( 9, ratio_fx ), 1 * ONE_IN_Q15 ) && LT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE - ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) )
1121 : {
1122 1139 : hCPE->hStereoMdct->split_ratio = add( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */
1123 1139 : move16();
1124 : }
1125 :
1126 83762 : hCPE->hStereoMdct->split_ratio = s_min( SMDCT_BITRATE_RATIO_RANGE - 1, s_max( 1, hCPE->hStereoMdct->split_ratio ) ); /* Q0 */
1127 83762 : move16();
1128 : }
1129 :
1130 83783 : return;
1131 : }
1132 :
1133 : /*-------------------------------------------------------------------*
1134 : * MsStereoDecision()
1135 : *
1136 : *
1137 : *-------------------------------------------------------------------*/
1138 :
1139 142051 : static void MsStereoDecision_fx(
1140 : STEREO_MDCT_BAND_PARAMETERS *sfbParam,
1141 : Word32 *specL_fx, /* Q( q_spec ) */
1142 : Word32 *specR_fx, /* Q( q_spec ) */
1143 : Word32 *specM_fx,
1144 : /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */
1145 : Word32 *specS_fx,
1146 : /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */
1147 : Word16 q_spec,
1148 : Word16 *mdct_stereo_mode, /* output Q0*/
1149 : Word16 *msMask, /* output Q0*/
1150 : const Word16 nBitsAvailable /*Q0*/ )
1151 : {
1152 142051 : Word16 length = sfbParam->sfbOffset[sfbParam->nBandsStereoCore]; /* Q0 */
1153 :
1154 : Word16 bitsL, bitsR, bitsM, bitsS;
1155 : Word16 bitsBW, bitsLR, bitsMS;
1156 : Word16 sfb, i;
1157 : Word16 nMSOn; /* Number of MS active bands */
1158 : Word16 quantSpecL[N_MAX];
1159 : Word16 quantSpecR[N_MAX];
1160 : Word16 quantSpecM[N_MAX];
1161 : Word16 quantSpecS[N_MAX];
1162 : RC_CONTEXT_MEM ctxMem[4];
1163 : HANDLE_RC_CONTEXT_MEM ctxL, ctxR, ctxM, ctxS;
1164 :
1165 142051 : set16_fx( quantSpecL, 0, N_MAX );
1166 142051 : set16_fx( quantSpecR, 0, N_MAX );
1167 142051 : set16_fx( quantSpecM, 0, N_MAX );
1168 142051 : set16_fx( quantSpecS, 0, N_MAX );
1169 :
1170 142051 : assert( GT_16( nBitsAvailable, 0 ) );
1171 :
1172 142051 : ctxL = &ctxMem[0];
1173 142051 : ctxR = &ctxMem[1];
1174 142051 : ctxM = &ctxMem[2];
1175 142051 : ctxS = &ctxMem[3];
1176 : Word16 specL_e, specR_e, specM_e, specS_e, G_fx, G_e;
1177 : Word16 e_GLR;
1178 : Word32 GLR_fx;
1179 :
1180 142051 : specL_e = sub( Q31, q_spec );
1181 142051 : specR_e = sub( Q31, q_spec );
1182 142051 : specM_e = sub( Q31, q_spec );
1183 142051 : specS_e = sub( Q31, q_spec );
1184 :
1185 142051 : GLR_fx = SQ_gain_estimate_stereo_fx( specL_fx, specL_e, specR_fx, specR_e, nBitsAvailable, length, &e_GLR ); /* Q31-e_GLR */
1186 :
1187 80821715 : FOR( i = 0; i < length; i++ )
1188 : {
1189 80679664 : specM_fx[i] = Mpy_32_32( L_add( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec )
1190 80679664 : move32();
1191 80679664 : specS_fx[i] = Mpy_32_32( L_sub( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec )
1192 80679664 : move32();
1193 : }
1194 :
1195 142051 : G_fx = extract_h( GLR_fx ); /* seems to be favourable to underestimate a bit Q15-e_GLR*/
1196 142051 : G_e = sub( e_GLR, 1 );
1197 :
1198 : /* do the full spectrum estimates already here, as side effect we get the quantized spectra... */
1199 142051 : bitsLR = add( QuantSpecEstimateBits_fx( specL_fx, specL_e, G_fx, G_e, length, nBitsAvailable, quantSpecL ), QuantSpecEstimateBits_fx( specR_fx, specR_e, G_fx, G_e, length, nBitsAvailable, quantSpecR ) ); /* Q0 */
1200 142051 : bitsMS = add( QuantSpecEstimateBits_fx( specM_fx, specM_e, G_fx, G_e, length, nBitsAvailable, quantSpecM ), QuantSpecEstimateBits_fx( specS_fx, specS_e, G_fx, G_e, length, nBitsAvailable, quantSpecS ) ); /* Q0 */
1201 :
1202 : /* clean-up MS scratch buffers */
1203 142051 : set32_fx( specM_fx, 0, length );
1204 142051 : set32_fx( specS_fx, 0, length );
1205 :
1206 142051 : nMSOn = 0;
1207 142051 : move16();
1208 142051 : bitsBW = 0;
1209 142051 : move16();
1210 :
1211 142051 : RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecL, length, nBitsAvailable, ctxL );
1212 142051 : RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecR, length, nBitsAvailable, ctxR );
1213 :
1214 142051 : bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecM, length, nBitsAvailable, ctxM ) ); /* Q0 */
1215 142051 : bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecS, length, nBitsAvailable, ctxS ) ); /* Q0 */
1216 :
1217 : /*find_max_lastnz(ctxL,ctxR,ctxM,ctxS);*/
1218 :
1219 5791716 : FOR( sfb = 0; sfb < sfbParam->nBandsStereoCore; sfb++ )
1220 : {
1221 5649665 : const Word16 startline = sfbParam->sfbOffset[sfb];
1222 5649665 : move16();
1223 5649665 : const Word16 endline = sfbParam->sfbOffset[sfb + 1];
1224 5649665 : move16();
1225 :
1226 5649665 : bitsL = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecL, startline, endline, ctxL );
1227 5649665 : bitsR = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecR, startline, endline, ctxR );
1228 5649665 : bitsM = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecM, startline, endline, ctxM );
1229 5649665 : bitsS = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecS, startline, endline, ctxS );
1230 :
1231 5649665 : IF( LE_16( add( bitsM, bitsS ), add( bitsL, bitsR ) ) )
1232 : {
1233 4241882 : msMask[sfb] = 1;
1234 4241882 : move16();
1235 4241882 : nMSOn = add( nMSOn, 1 );
1236 4241882 : context_update_fx( ctxM, ctxL, endline );
1237 4241882 : context_update_fx( ctxS, ctxR, endline );
1238 4241882 : bitsBW = add( bitsBW, add( bitsM, bitsS ) ); /* Q0 */
1239 : }
1240 : ELSE
1241 : {
1242 1407783 : msMask[sfb] = 0;
1243 1407783 : move16();
1244 :
1245 1407783 : context_update_fx( ctxL, ctxM, endline );
1246 1407783 : context_update_fx( ctxR, ctxS, endline );
1247 1407783 : bitsBW = add( bitsBW, add( bitsL, bitsR ) ); /* Q0 */
1248 : }
1249 : }
1250 :
1251 142051 : bitsBW = add( bitsBW, sfbParam->nBandsStereoCore ); /* Signaling bits Q0*/
1252 :
1253 142051 : IF( LT_16( bitsLR, bitsBW ) )
1254 : {
1255 8666 : nMSOn = 0;
1256 8666 : move16();
1257 8666 : set16_fx( msMask, 0, sfbParam->sfbCnt );
1258 8666 : bitsBW = bitsLR;
1259 8666 : move16();
1260 : }
1261 :
1262 142051 : IF( LT_16( bitsMS, bitsBW ) )
1263 : {
1264 83549 : nMSOn = sfbParam->nBandsStereoCore;
1265 83549 : move16();
1266 83549 : set16_fx( msMask, 1, sfbParam->sfbCnt );
1267 : }
1268 :
1269 142051 : *mdct_stereo_mode = SMDCT_BW_MS;
1270 142051 : move16();
1271 142051 : IF( EQ_16( nMSOn, sfbParam->nBandsStereoCore ) )
1272 : {
1273 83549 : *mdct_stereo_mode = SMDCT_MS_FULL;
1274 83549 : move16();
1275 : }
1276 58502 : ELSE IF( nMSOn == 0 )
1277 : {
1278 7470 : *mdct_stereo_mode = SMDCT_DUAL_MONO;
1279 7470 : move16();
1280 : }
1281 :
1282 142051 : return;
1283 : }
1284 :
1285 :
1286 : /*-----------------------------------------------------------------------*
1287 : * initMdctStereoEncData()
1288 : *
1289 : * initialize encoder mdct stereo structure
1290 : *-----------------------------------------------------------------------*/
1291 :
1292 76307 : void initMdctStereoEncData_fx(
1293 : STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */
1294 : const IVAS_FORMAT ivas_format, /* i : IVAS format */
1295 : const Word16 element_mode, /* i : element mode Q0*/
1296 : const Word32 element_brate, /* i : element bitrate Q0*/
1297 : const Word16 bwidth, /* i : bandwidth Q0*/
1298 : const Word16 igf, /* i : flag indicating IGF activity Q0*/
1299 : const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */
1300 : const Word16 mem_init /* i : initialize memory after malloc Q0*/
1301 : )
1302 : {
1303 : Word16 tcx_coded_lines;
1304 :
1305 76307 : tcx_coded_lines = getNumTcxCodedLines( bwidth ); /* Q0 */
1306 :
1307 : /*initialize mdct stereo mode*/
1308 76307 : set16_fx( hStereoMdct->mdct_stereo_mode, -1, 2 );
1309 :
1310 : /*Initialize sfb parameteres for TCX20 */
1311 76307 : stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_20_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_NORM] : NULL, &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
1312 :
1313 : /*Initialize sfb parameteres for TCX10 */
1314 76307 : stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_10_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_SHORT] : NULL,
1315 : &hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
1316 :
1317 : /*Initialize sfb parameteres for transitions */
1318 76307 : stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_TRAN] : NULL,
1319 : &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
1320 :
1321 76307 : set16_fx( hStereoMdct->IGFStereoMode, -1, 2 );
1322 :
1323 76307 : hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Q0 */
1324 76307 : move16();
1325 76307 : set16_fx( hStereoMdct->global_ild, SMDCT_ILD_RANGE >> 1, 2 );
1326 :
1327 76307 : IF( mem_init )
1328 : {
1329 3550 : hStereoMdct->hItd = NULL;
1330 3550 : hStereoMdct->hDft_ana = NULL;
1331 : }
1332 :
1333 76307 : test();
1334 76307 : test();
1335 76307 : IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && LE_32( element_brate, MAX_MDCT_ITD_BRATE ) && EQ_32( ivas_format, STEREO_FORMAT ) ) )
1336 : {
1337 25747 : IF( hStereoMdct->hDft_ana != NULL )
1338 : {
1339 25 : free( hStereoMdct->hDft_ana );
1340 25 : hStereoMdct->hDft_ana = NULL;
1341 : }
1342 :
1343 25747 : IF( hStereoMdct->hItd != NULL )
1344 : {
1345 25 : free( hStereoMdct->hItd );
1346 25 : hStereoMdct->hItd = NULL;
1347 : }
1348 : }
1349 :
1350 76307 : return;
1351 : }
1352 :
1353 :
1354 : /*-----------------------------------------------------------------------*
1355 : * initMdctItdHandling()
1356 : *
1357 : * initialize encoder mdct ITD handling structures
1358 : *-----------------------------------------------------------------------*/
1359 :
1360 151 : ivas_error initMdctItdHandling_fx(
1361 : STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */
1362 : const Word32 input_Fs /* i : input sampling rate Q0*/
1363 : )
1364 : {
1365 151 : test();
1366 151 : test();
1367 151 : IF( hStereoMdct->hItd == NULL )
1368 : {
1369 67 : IF( ( hStereoMdct->hItd = (ITD_DATA_HANDLE) malloc( sizeof( ITD_DATA ) ) ) == NULL )
1370 : {
1371 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ITD data\n" ) );
1372 : }
1373 : }
1374 :
1375 151 : test();
1376 151 : test();
1377 151 : IF( hStereoMdct->hDft_ana == NULL )
1378 : {
1379 67 : IF( ( hStereoMdct->hDft_ana = (DFT_ANA_HANDLE) malloc( sizeof( DFT_ANA ) ) ) == NULL )
1380 : {
1381 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ITD data\n" ) );
1382 : }
1383 : }
1384 :
1385 : /*Initialize ITD parameters*/
1386 151 : stereo_enc_itd_init_fx( hStereoMdct->hItd );
1387 :
1388 : /*Initialize DFT analysis parameters*/
1389 151 : dft_ana_init_fx( hStereoMdct->hDft_ana, input_Fs );
1390 :
1391 151 : return IVAS_ERR_OK;
1392 : }
1393 :
1394 : /*-------------------------------------------------------------------------
1395 : * stereo_mdct_enc_destroy()
1396 : *
1397 : * destroy MDCT stereo handle
1398 : *-------------------------------------------------------------------------*/
1399 :
1400 1123 : void stereo_mdct_enc_destroy_fx(
1401 : STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */
1402 : )
1403 : {
1404 1123 : IF( ( *hStereoMdct )->hDft_ana != NULL )
1405 : {
1406 42 : free( ( *hStereoMdct )->hDft_ana );
1407 42 : ( *hStereoMdct )->hDft_ana = NULL;
1408 : }
1409 :
1410 1123 : IF( ( *hStereoMdct )->hItd != NULL )
1411 : {
1412 42 : free( ( *hStereoMdct )->hItd );
1413 42 : ( *hStereoMdct )->hItd = NULL;
1414 : }
1415 :
1416 1123 : free( *hStereoMdct );
1417 1123 : *hStereoMdct = NULL;
1418 :
1419 1123 : return;
1420 : }
|