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