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 : // helper macros to convert the 64 bitt accumulators into the 48 bit float format
34 : #define CONVERT_CY( x_64, y_fx, y_e ) \
35 : { \
36 : Word16 norm; \
37 : norm = W_norm( x_64 ); \
38 : y_fx = W_extract_h( W_shl( x_64, norm ) ); \
39 : y_e = sub( sub62gb, norm ); \
40 : }
41 : #define CONVERT_DMX( x_64, y_fx, y_e ) \
42 : { \
43 : Word16 norm; \
44 : norm = W_norm( x_64 ); \
45 : y_fx = W_extract_h( W_shl( x_64, norm ) ); \
46 : y_e = sub( sub35gb, norm ); \
47 : }
48 : #include <math.h>
49 : #include <assert.h>
50 : #include "options.h"
51 : #include "cnst.h"
52 : #include "rom_enc.h"
53 : #include "ivas_rom_enc.h"
54 : #include "rom_com.h"
55 : #include "prot_fx.h"
56 : #include "ivas_prot_fx.h"
57 : #include "ivas_cnst.h"
58 : #include "ivas_rom_com.h"
59 : #include "wmc_auto.h"
60 :
61 : #include "prot_fx_enc.h"
62 :
63 : /*-------------------------------------------------------------------------
64 : * Local function prototypes
65 : *------------------------------------------------------------------------*/
66 :
67 : static void ivas_param_mc_write_bs_fx( const PARAM_MC_ENC_HANDLE hParamMC, Word16 *ILD_idx, Word16 *ICC_idx, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos );
68 :
69 : static void ivas_param_mc_dec2bin_fx( const Word16 val, const Word16 N, UWord16 bits[PARAM_MC_MAX_BITS] );
70 :
71 : static void ivas_param_mc_encode_parameter_fx( Word16 *idx_in, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, const Word16 nbands, const Word16 band_step, const Word16 map_size_wo_lfe, const Word16 map_size, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos );
72 :
73 : static void ivas_param_mc_range_encoder_fx( const Word16 *seq_in, const Word16 num_symbols, const UWord16 *cum_freq, const UWord16 *sym_freq, const UWord16 tot_shift, const Word16 max_nb_bits, UWord16 *bit_buffer, Word16 *bit_pos );
74 :
75 :
76 : #define ATTACKTHRESHOLD_E 4
77 : static void ivas_param_mc_quantize_ilds_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 freq_idx, const Word16 nchan_input, const Word16 nchan_transport, Word16 *ILD_idx_out, Word16 ILD_q[PARAM_MC_SZ_ILD_MAP] );
78 :
79 : static void ivas_param_mc_parameter_quantizer_fx( const Word32 *x, const Word16 *x_e, const Word16 L, const Word16 sz_quantizer, const Word16 *quantizer_fx, const Word16 Q_quant, Word16 *quant_idx, Word16 *y );
80 :
81 : static void ivas_param_mc_quantize_iccs_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], const Word16 freq_idx, const Word16 nchan_input, Word16 *ICC_idx_out );
82 :
83 : static void ivas_param_mc_dmx_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f_fx[], Word32 data_dmx_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport );
84 :
85 : static void ivas_param_mc_transient_detection_fx( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, Word16 *bAttackPresent, Word16 *attackIdx );
86 :
87 : static void ivas_param_mc_param_est_enc_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f[], Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport );
88 :
89 :
90 : /*-------------------------------------------------------------------------
91 : * ivas_param_mc_enc_open()
92 : *
93 : * Initialize Parametric MC encoder handle
94 : *------------------------------------------------------------------------*/
95 :
96 279 : ivas_error ivas_param_mc_enc_open_fx(
97 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
98 : )
99 : {
100 : Word16 i;
101 : IVAS_FB_CFG *fb_cfg;
102 : PARAM_MC_ENC_HANDLE hParamMC;
103 : UWord16 config_index;
104 : MC_LS_SETUP mc_input_setup;
105 : Word16 max_bwidth, nchan_inp;
106 : Word16 tmp1, tmp2;
107 : Word32 input_Fs, ivas_total_brate;
108 : ivas_error error;
109 :
110 279 : error = IVAS_ERR_OK;
111 279 : move16();
112 :
113 : /* Sanity Checks */
114 279 : IF( ( hParamMC = (PARAM_MC_ENC_HANDLE) malloc( sizeof( PARAM_MC_ENC_DATA ) ) ) == NULL )
115 : {
116 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Paramtric MC\n" ) );
117 : }
118 :
119 279 : mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
120 279 : move32();
121 279 : max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
122 279 : move16();
123 279 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
124 279 : move32();
125 279 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
126 279 : move16();
127 279 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
128 279 : move32();
129 :
130 : /* Preparing Config */
131 279 : hParamMC->lfe_index = LFE_CHANNEL;
132 279 : move16();
133 279 : st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
134 279 : move16();
135 :
136 : /* get configuration index */
137 279 : config_index = ivas_param_mc_get_configuration_index_fx( mc_input_setup, ivas_total_brate );
138 :
139 : /* set core coder dependent on the number of transport channels */
140 279 : SWITCH( st_ivas->nchan_transport )
141 : {
142 17 : case 4:
143 : case 3:
144 17 : st_ivas->nCPE = 2;
145 17 : move16();
146 17 : st_ivas->nSCE = 0;
147 17 : move16();
148 17 : st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
149 17 : move16();
150 17 : BREAK;
151 262 : case 2:
152 262 : st_ivas->nCPE = 1;
153 262 : move16();
154 262 : st_ivas->nSCE = 0;
155 262 : move16();
156 262 : st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
157 262 : move16();
158 262 : BREAK;
159 : }
160 :
161 : /* get dmx factors */
162 279 : hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
163 :
164 : /* set FB config. */
165 279 : IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, nchan_inp, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
166 : {
167 0 : return error;
168 : }
169 :
170 : /* Allocate and initialize FB mixer handle */
171 279 : IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hParamMC->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) )
172 : {
173 0 : return error;
174 : }
175 :
176 : /* open/init parameter coding */
177 279 : ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
178 :
179 : /* Band Grouping */
180 279 : IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) )
181 : {
182 3 : Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 );
183 : }
184 276 : ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
185 : {
186 135 : Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
187 : }
188 141 : ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
189 : {
190 141 : Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 );
191 : }
192 : ELSE
193 : {
194 0 : assert( 0 && "nbands must be 20, 14, or 10!" );
195 : }
196 :
197 : /* set max parameter band for abs cov */
198 279 : i = 0;
199 279 : move16();
200 2514 : WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
201 : {
202 2235 : hParamMC->max_param_band_abs_cov = i;
203 2235 : move16();
204 2235 : i = add( i, 1 );
205 : }
206 :
207 : /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
208 3918 : FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
209 : {
210 3639 : hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
211 3639 : move16();
212 : }
213 :
214 : /* set correct coded band width */
215 279 : hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
216 279 : move16();
217 279 : hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
218 279 : move16();
219 279 : ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
220 :
221 : /* initialize offset for transient detection */
222 279 : tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
223 279 : move16();
224 279 : tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
225 279 : move16();
226 279 : tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
227 279 : hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
228 279 : move16();
229 :
230 : /* Init total/dmx ener factors */
231 279 : set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
232 :
233 : /* init previous ILDs */
234 5859 : FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ )
235 : {
236 5580 : set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); // Q21
237 : }
238 :
239 279 : st_ivas->hParamMC = hParamMC;
240 :
241 279 : return error;
242 : }
243 :
244 :
245 : /*-------------------------------------------------------------------------
246 : * ivas_param_mc_enc_reconfig()
247 : *
248 : * Reconfigure Parametric MC encoder
249 : *------------------------------------------------------------------------*/
250 :
251 65 : ivas_error ivas_param_mc_enc_reconfig_fx(
252 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
253 : )
254 : {
255 : Word16 i;
256 : PARAM_MC_ENC_HANDLE hParamMC;
257 : UWord16 config_index;
258 : MC_LS_SETUP mc_input_setup;
259 : Word16 max_bwidth;
260 : Word16 tmp1, tmp2;
261 : Word32 input_Fs, ivas_total_brate;
262 : ivas_error error;
263 :
264 65 : error = IVAS_ERR_OK;
265 65 : move16();
266 :
267 65 : mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
268 65 : move32();
269 65 : max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
270 65 : move16();
271 65 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
272 65 : move32();
273 65 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
274 65 : move32();
275 65 : hParamMC = st_ivas->hParamMC;
276 :
277 : /* Preparing Config */
278 65 : st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
279 65 : move16();
280 :
281 : /* get configuration index */
282 65 : config_index = ivas_param_mc_get_configuration_index_fx( mc_input_setup, ivas_total_brate );
283 :
284 : /* set core coder dependent on the number of transport channels */
285 65 : SWITCH( st_ivas->nchan_transport )
286 : {
287 0 : case 4:
288 : case 3:
289 0 : st_ivas->nCPE = 2;
290 0 : move16();
291 0 : st_ivas->nSCE = 0;
292 0 : move16();
293 0 : st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
294 0 : move16();
295 0 : BREAK;
296 65 : case 2:
297 65 : st_ivas->nCPE = 1;
298 65 : move16();
299 65 : st_ivas->nSCE = 0;
300 65 : move16();
301 65 : st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
302 65 : move16();
303 65 : BREAK;
304 : }
305 :
306 : /* get dmx factors */
307 65 : hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
308 :
309 : /* open/init parameter coding */
310 65 : ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
311 :
312 : /* Band Grouping */
313 65 : IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) )
314 : {
315 0 : Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 );
316 : }
317 65 : ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
318 : {
319 34 : Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
320 : }
321 31 : ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
322 : {
323 31 : Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 );
324 : }
325 : ELSE
326 : {
327 0 : assert( 0 && "nbands must be 20, 14, or 10!" );
328 : }
329 :
330 : /* set max parameter band for abs cov */
331 65 : i = 0;
332 65 : move16();
333 588 : WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
334 : {
335 523 : hParamMC->max_param_band_abs_cov = i;
336 523 : move16();
337 523 : i = add( i, 1 );
338 : }
339 :
340 : /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
341 916 : FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
342 : {
343 851 : hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
344 851 : move16();
345 : }
346 :
347 : /* set correct coded band width */
348 65 : hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
349 65 : move16();
350 65 : hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
351 65 : move16();
352 65 : ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
353 :
354 : /* initialize offset for transient detection */
355 65 : tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
356 65 : move16();
357 65 : tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
358 65 : move16();
359 65 : tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
360 65 : hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
361 65 : move16();
362 :
363 : /* Init total/dmx ener factors */
364 65 : set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
365 :
366 :
367 65 : return error;
368 : }
369 :
370 :
371 : /*-------------------------------------------------------------------------
372 : * ivas_param_mc_enc_close()
373 : *
374 : * Close Parametric MC encoder handle
375 : *------------------------------------------------------------------------*/
376 :
377 1210 : void ivas_param_mc_enc_close_fx(
378 : PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */
379 : const Word32 sampling_rate )
380 : {
381 1210 : test();
382 1210 : IF( hParamMC == NULL || *hParamMC == NULL )
383 : {
384 931 : return;
385 : }
386 :
387 279 : ivas_FB_mixer_close_fx( &( *hParamMC )->hFbMixer, sampling_rate, 0 );
388 :
389 279 : free( ( *hParamMC ) );
390 279 : ( *hParamMC ) = NULL;
391 :
392 279 : return;
393 : }
394 :
395 :
396 : /*-------------------------------------------------------------------------
397 : * ivas_param_mc_enc()
398 : *
399 : * Parametric MC Encoder main encoding function
400 : *------------------------------------------------------------------------*/
401 :
402 10250 : void ivas_param_mc_enc_fx(
403 : Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */
404 : BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */
405 : Word32 *data_f_fx[], /* i/o: input/transport MC data Q11 */
406 : const Word16 input_frame /* i : input frame length */
407 : )
408 : {
409 : Word16 k;
410 : Word16 ILD_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
411 : Word16 ICC_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP];
412 : UWord16 bit_buffer[PARAM_MC_MAX_BITS];
413 : Word16 bit_pos;
414 : Word16 band_step;
415 : Word16 data_f_fx16[L_FRAME48k];
416 : Word32 data_dmx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k];
417 : Word16 data_dmx_fx16[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k];
418 : Word32 Cy_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
419 : Word16 Cy_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
420 : Word32 Cx_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
421 : Word16 Cx_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
422 : Word16 ILD_q_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP];
423 : Word16 ch;
424 : Word16 band;
425 : PARAM_MC_ENC_HANDLE hParamMC;
426 : Word16 nchan_inp;
427 :
428 10250 : push_wmops( "param_mc_enc" );
429 :
430 : /* initializations */
431 10250 : hParamMC = st_ivas->hParamMC;
432 10250 : bit_pos = 0;
433 10250 : move16();
434 10250 : band_step = 1;
435 10250 : move16();
436 10250 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
437 10250 : move16();
438 :
439 215250 : FOR( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ )
440 : {
441 3485000 : FOR( ch = 0; ch < MAX_CICP_CHANNELS; ch++ )
442 : {
443 3280000 : set32_fx( Cy_sum_fx[band][ch], 0, MAX_CICP_CHANNELS );
444 3280000 : set16_fx( Cy_sum_e[band][ch], 0, MAX_CICP_CHANNELS );
445 : }
446 820000 : FOR( ch = 0; ch < PARAM_MC_MAX_TRANSPORT_CHANS; ch++ )
447 : {
448 615000 : set32_fx( Cx_sum_fx[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
449 615000 : set16_fx( Cx_sum_e[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
450 : }
451 : }
452 :
453 10250 : set16_fx( ILD_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
454 10250 : set16_fx( ICC_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP );
455 :
456 : /* update parameter frame index */
457 10250 : hParamMC->hMetadataPMC.param_frame_idx = add( hParamMC->hMetadataPMC.param_frame_idx, 1 ) % PARAM_MC_PARAMETER_FRAMES;
458 10250 : move16();
459 :
460 : /* DMX generation*/
461 10250 : ivas_param_mc_dmx_fx( hParamMC, data_f_fx, data_dmx_fx, input_frame, nchan_inp, st_ivas->nchan_transport );
462 :
463 : /* Transient Detector */
464 10250 : SWITCH( st_ivas->nchan_transport )
465 : {
466 10250 : case 3:
467 : case 2:
468 : case 4:
469 : {
470 : Word16 q_data_dmx_fx16;
471 : Word16 bAttackPresent[PARAM_MC_MAX_TRANSPORT_CHANS];
472 : Word16 attackIdx[PARAM_MC_MAX_TRANSPORT_CHANS];
473 :
474 10250 : set16_fx( attackIdx, -1, PARAM_MC_MAX_TRANSPORT_CHANS );
475 10250 : set16_fx( bAttackPresent, 0, PARAM_MC_MAX_TRANSPORT_CHANS );
476 :
477 30860 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
478 : {
479 20610 : Word16 cpe_idx = shr( ch, 1 );
480 :
481 20610 : q_data_dmx_fx16 = sub( L_norm_arr( data_dmx_fx[ch], input_frame ), 16 );
482 20610 : Copy_Scale_sig_32_16( data_dmx_fx[ch], data_dmx_fx16[ch], input_frame, q_data_dmx_fx16 ); // Q11 -> Q(q_data_dmx_fx16 + 11)
483 20610 : q_data_dmx_fx16 = add( q_data_dmx_fx16, Q11 );
484 :
485 20610 : RunTransientDetection_ivas_fx( data_dmx_fx16[ch], input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, q_data_dmx_fx16 );
486 :
487 20610 : ivas_param_mc_transient_detection_fx( hParamMC, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, &bAttackPresent[ch], &attackIdx[ch] );
488 : }
489 :
490 : /* if more than one attack, use the earlier */
491 10250 : hParamMC->hMetadataPMC.bAttackPresent = 0;
492 10250 : move16();
493 10250 : hParamMC->hMetadataPMC.attackIndex = 16;
494 10250 : move16();
495 :
496 30860 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
497 : {
498 20610 : hParamMC->hMetadataPMC.bAttackPresent = s_max( hParamMC->hMetadataPMC.bAttackPresent, bAttackPresent[ch] );
499 20610 : move16();
500 : }
501 :
502 10250 : IF( hParamMC->hMetadataPMC.bAttackPresent )
503 : {
504 1500 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
505 : {
506 1010 : hParamMC->hMetadataPMC.attackIndex = s_min( hParamMC->hMetadataPMC.attackIndex, attackIdx[ch] );
507 1010 : move16();
508 : }
509 : }
510 : ELSE
511 : {
512 9760 : hParamMC->hMetadataPMC.attackIndex = 0;
513 9760 : move16();
514 : }
515 : }
516 10250 : BREAK;
517 : }
518 :
519 : /* Encoding */
520 : /* parameter estimation*/
521 10250 : ivas_param_mc_param_est_enc_fx( hParamMC, data_f_fx, Cy_sum_fx, Cy_sum_e, Cx_sum_fx, Cx_sum_e, input_frame, nchan_inp, st_ivas->nchan_transport );
522 :
523 10250 : IF( hParamMC->hMetadataPMC.bAttackPresent )
524 : {
525 490 : band_step = PARAM_MC_TRANSIENT_BAND_STEP;
526 490 : move16();
527 : }
528 : ELSE
529 : {
530 9760 : band_step = 1;
531 9760 : move16();
532 : }
533 :
534 :
535 : /* ILD parameter quantization */
536 142356 : FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
537 : {
538 132106 : ivas_param_mc_quantize_ilds_fx( hParamMC, Cy_sum_fx[k], Cy_sum_e[k], Cx_sum_fx[k], Cx_sum_e[k], k, nchan_inp, st_ivas->nchan_transport, ILD_idx, ILD_q_fx[k] );
539 : }
540 :
541 : /* ICC parameter quantization */
542 142356 : FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
543 : {
544 132106 : ivas_param_mc_quantize_iccs_fx( hParamMC, Cy_sum_fx[k], Cy_sum_e[k], k, nchan_inp, ICC_idx );
545 : }
546 :
547 : /* time domain DMX generation*/
548 : /* just copy data_dmx generated above, contains already the downmix */
549 30860 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
550 : {
551 20610 : Copy32( data_dmx_fx[ch], data_f_fx[ch], input_frame ); // q_data_dmx_fx16
552 : }
553 :
554 : /* we have to run the transient detector on the second channel of the last CPE if we
555 : have an odd number of transport channels */
556 10250 : IF( GT_16( st_ivas->nchan_transport, 2 ) )
557 : {
558 220 : FOR( ; ch < st_ivas->nCPE * CPE_CHANNELS; ch++ )
559 : {
560 110 : Word16 cpe_idx = shr( ch, 1 );
561 :
562 110 : set32_fx( data_f_fx[ch], 0, input_frame ); // Q11
563 110 : set16_fx( data_f_fx16, 0, input_frame ); // Q11
564 :
565 110 : RunTransientDetection_ivas_fx( data_f_fx16, input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, 0 );
566 : }
567 : }
568 :
569 : /* write Parametric MC side info bitstream into temporary buffer*/
570 10250 : ivas_param_mc_write_bs_fx( hParamMC, ILD_idx, ICC_idx, bit_buffer, &bit_pos );
571 :
572 : /* push the Parametric MC side info from the temporary buffer into the medatdata bitstream*/
573 10250 : push_next_bits( hMetaData, bit_buffer, bit_pos );
574 :
575 : /* updates */
576 10250 : hParamMC->hMetadataPMC.last_coded_bwidth = hParamMC->hMetadataPMC.coded_bwidth;
577 10250 : move16();
578 :
579 10250 : pop_wmops();
580 :
581 10250 : return;
582 : }
583 :
584 :
585 : /*****************************************************************************************/
586 : /* local functions */
587 : /*****************************************************************************************/
588 :
589 : /*-------------------------------------------------------------------------
590 : * ivas_param_mc_dmx()
591 : *
592 : * Computes the time domain down mix signal
593 : *------------------------------------------------------------------------*/
594 :
595 10250 : static void ivas_param_mc_dmx_fx(
596 : PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */
597 : Word32 *data_f_fx[], /* i : Input frame Q_x */
598 : Word32 data_dmx_fx[][L_FRAME48k], /* o : Down mixed frame Q_x - 11 */
599 : const Word16 input_frame, /* i : Input frame length */
600 : const Word16 nchan_input, /* i : number of input channels */
601 : const Word16 nchan_transport /* i : number of transport channels */
602 : )
603 : {
604 : Word16 i;
605 : const Word16 *idx;
606 : Word16 dmx_ch;
607 : Word16 inp_ch;
608 : const Word32 *p_dmx_fac_fx;
609 :
610 10250 : idx = Param_MC_index;
611 9741450 : FOR( i = 0; i < input_frame; i++ )
612 : {
613 9731200 : p_dmx_fac_fx = hParamMC->dmx_factors_fx;
614 29299200 : FOR( dmx_ch = 0; dmx_ch < nchan_transport; dmx_ch++ )
615 : {
616 19568000 : Word32 *dmx_sample_fx = &data_dmx_fx[idx[dmx_ch]][i];
617 19568000 : *dmx_sample_fx = 0;
618 19568000 : move16();
619 140412800 : FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
620 : {
621 120844800 : ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); // Q_x - 11
622 120844800 : move16();
623 : }
624 : }
625 : }
626 :
627 10250 : return;
628 : }
629 :
630 :
631 : /*-------------------------------------------------------------------------
632 : * ivas_param_mc_param_est_enc()
633 : *
634 : * run the CLDFB analysis on the input signal
635 : * estimate the input and down mix covariances
636 : *------------------------------------------------------------------------*/
637 :
638 10250 : static void ivas_param_mc_param_est_enc_fx(
639 : PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */
640 : Word32 *data_f_fx[], /* i : Input frame in the time domain Q11 */
641 : Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame Cy_sum_e*/
642 : Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame */
643 : Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame Cx_sum_e*/
644 : Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame */
645 : const Word16 input_frame, /* i : Input frame length */
646 : const Word16 nchan_input, /* i : number of input channels */
647 : const Word16 nchan_transport /* i : number of transport channels */
648 : )
649 : {
650 : Word16 i, cur_cldfb_band, cur_param_band, ch_idx1, ch_idx2, inp_ch;
651 : Word16 ts;
652 : Word16 l_ts;
653 : Word16 num_time_slots;
654 : Word16 num_parameter_bands;
655 : Word16 brange[2];
656 : Word16 band_step;
657 10250 : const Word16 *map_ls = Param_MC_index; /* Loudspeakers mapping */
658 : Word16 idx_ls;
659 : Word16 start_ts;
660 :
661 : Word32 *pcm_in_fx[MAX_CICP_CHANNELS];
662 : Word32 slot_frame_f_real_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - real part */
663 : Word32 slot_frame_f_imag_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - imag part */
664 : Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - real part */
665 : Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - imag part */
666 :
667 : Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS];
668 : Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS];
669 : Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */
670 : Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */
671 : Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
672 : Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
673 : Word16 sub62gb;
674 : Word16 sub35gb;
675 : Word32 Cx_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
676 : Word16 Cx_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
677 : Word32 real_part_fx, imag_part_fx;
678 : Word16 real_part_e, imag_part_e;
679 : const Word32 *p_dmx_fac_fx;
680 : Word32 L_tmp;
681 : Word16 tmp_e;
682 :
683 10250 : push_wmops( "param_mc_prm_est" );
684 :
685 : /* initializations */
686 10250 : l_ts = extract_l( Mpy_32_16_1( input_frame, INV_PARAM_MC_MDFT_NO_SLOTS_FX ) );
687 10250 : num_time_slots = PARAM_MC_MDFT_NO_SLOTS;
688 10250 : move16();
689 10250 : IF( hParamMC->hMetadataPMC.bAttackPresent )
690 : {
691 490 : start_ts = hParamMC->hMetadataPMC.attackIndex;
692 490 : move16();
693 : }
694 : ELSE
695 : {
696 9760 : start_ts = 0;
697 9760 : move16();
698 : }
699 10250 : num_parameter_bands = hParamMC->hMetadataPMC.nbands_coded;
700 10250 : move16();
701 10250 : band_step = 1;
702 10250 : move16();
703 215250 : FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
704 : {
705 3485000 : FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
706 : {
707 3280000 : set64_fx( Cy_sum_real_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
708 : }
709 : }
710 :
711 112750 : FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC; cur_param_band++ )
712 : {
713 1742500 : FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
714 : {
715 1640000 : set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
716 : }
717 :
718 410000 : FOR( ch_idx1 = 0; ch_idx1 < PARAM_MC_MAX_TRANSPORT_CHANS; ch_idx1++ )
719 : {
720 307500 : set32_fx( Cx_sum_imag_fx[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
721 307500 : set16_fx( Cx_sum_imag_e[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
722 : }
723 : }
724 :
725 : /* Copy current frame to memory for delay compensation */
726 73270 : FOR( i = 0; i < nchan_input; i++ )
727 : {
728 63020 : idx_ls = map_ls[i];
729 63020 : move16();
730 63020 : pcm_in_fx[i] = data_f_fx[idx_ls];
731 63020 : p_slot_frame_f_real_fx[i] = &slot_frame_f_real_fx[i][0];
732 63020 : p_slot_frame_f_imag_fx[i] = &slot_frame_f_imag_fx[i][0];
733 : }
734 :
735 11907 : FOR( ts = 0; ts < start_ts; ts++ )
736 : {
737 1657 : ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
738 12453 : FOR( i = 0; i < nchan_input; i++ )
739 : {
740 10796 : pcm_in_fx[i] += l_ts;
741 : }
742 : }
743 :
744 10250 : Word16 gb = find_guarded_bits_fx( l_ts );
745 :
746 10250 : sub35gb = sub( 32, sub( 11, find_guarded_bits_fx( l_ts ) ) ); // 31 - (((11 - gb) + 31 + norm) - 32)
747 10250 : sub62gb = sub( 63, shl( sub( 11, find_guarded_bits_fx( l_ts ) ), 1 ) ); // 31 - ((2*(11 - gb) + norm) - 32)
748 :
749 90593 : FOR( ts = start_ts; ts < num_time_slots; ts++ )
750 : {
751 80343 : ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb );
752 80343 : ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
753 :
754 : /* slot_frame_f buffer Q = 11 - gb : exponent = 20 + gb */
755 :
756 573707 : FOR( i = 0; i < nchan_input; i++ )
757 : {
758 493364 : pcm_in_fx[i] += l_ts;
759 493364 : move32();
760 : }
761 : /* Computing the downmix */
762 693761 : FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
763 : {
764 613418 : brange[0] = hParamMC->band_grouping[cur_param_band];
765 613418 : move16();
766 613418 : brange[1] = hParamMC->band_grouping[cur_param_band + 1];
767 613418 : move16();
768 :
769 2220278 : FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
770 : {
771 : /* Cx for DMX */
772 : /* Real Part */
773 1606860 : p_dmx_fac_fx = hParamMC->dmx_factors_fx;
774 :
775 4836340 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
776 : {
777 : Word64 real_64;
778 : Word64 imag_64;
779 :
780 3229480 : real_64 = 0;
781 3229480 : imag_64 = 0;
782 3229480 : move64();
783 3229480 : move64();
784 23135880 : FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
785 : {
786 19906400 : real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
787 19906400 : imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
788 19906400 : p_dmx_fac_fx++;
789 : }
790 3229480 : dmx_real_64[ch_idx1] = real_64;
791 3229480 : dmx_imag_64[ch_idx1] = imag_64;
792 3229480 : move64();
793 3229480 : move64();
794 : }
795 :
796 : /* Cx for transport channels */
797 4836340 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
798 : {
799 3229480 : CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
800 3229480 : CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
801 9735720 : FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
802 : {
803 6506240 : CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
804 6506240 : CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
805 :
806 : /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
807 6506240 : L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e );
808 13012480 : Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
809 6506240 : L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
810 6506240 : move32();
811 6506240 : L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, d_fx ), add( a_e, d_e ), L_negate( Mpy_32_32( b_fx, c_fx ) ), add( b_e, c_e ), &tmp_e );
812 13012480 : Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2],
813 6506240 : L_tmp, tmp_e, &Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2] );
814 6506240 : move32();
815 : }
816 : }
817 11474140 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
818 : {
819 9867280 : a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
820 9867280 : b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
821 9867280 : move32();
822 45444520 : FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
823 : {
824 35577240 : c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
825 35577240 : d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
826 35577240 : move32();
827 : // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
828 35577240 : Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
829 : W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
830 35577240 : move64();
831 35577240 : Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2],
832 : W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) );
833 35577240 : move64();
834 : }
835 : }
836 : }
837 : }
838 :
839 527628 : FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
840 : {
841 447285 : brange[0] = hParamMC->band_grouping[cur_param_band];
842 447285 : move16();
843 447285 : brange[1] = hParamMC->band_grouping[cur_param_band + 1];
844 447285 : move16();
845 :
846 8274025 : FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
847 : {
848 : /* Cx for DMX */
849 : /* Real Part */
850 7826740 : p_dmx_fac_fx = hParamMC->dmx_factors_fx; // Q31
851 :
852 23559020 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
853 : {
854 : Word64 real_64;
855 : Word64 imag_64;
856 :
857 15732280 : real_64 = 0;
858 15732280 : imag_64 = 0;
859 15732280 : move64();
860 15732280 : move64();
861 :
862 112773560 : FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
863 : {
864 97041280 : real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
865 97041280 : imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
866 97041280 : p_dmx_fac_fx++;
867 : }
868 15732280 : dmx_real_64[ch_idx1] = real_64;
869 15732280 : dmx_imag_64[ch_idx1] = imag_64;
870 15732280 : move64();
871 15732280 : move64();
872 : }
873 :
874 : /* Cx for transport channels */
875 23559020 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
876 : {
877 15732280 : CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
878 15732280 : CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
879 47433240 : FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
880 : {
881 31700960 : CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
882 31700960 : CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
883 :
884 : /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
885 31700960 : L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e );
886 63401920 : Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e,
887 31700960 : &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
888 31700960 : move32();
889 : }
890 : }
891 :
892 : /* Cy for input channels */
893 55917780 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
894 : {
895 48091040 : a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
896 48091040 : b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
897 48091040 : move32();
898 48091040 : move32();
899 221618480 : FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
900 : {
901 173527440 : c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
902 173527440 : d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
903 173527440 : move32();
904 173527440 : move32();
905 : // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
906 173527440 : Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
907 : W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
908 173527440 : move64();
909 : }
910 : }
911 : }
912 : }
913 : }
914 :
915 : /* make sure energy and correlation is zero above the relevant LFE bands for LFE
916 : * avoids wrong energy in case of band combining at transients */
917 10250 : IF( hParamMC->lfe_index >= 0 )
918 : {
919 78220 : FOR( cur_param_band = PARAM_MC_MAX_BAND_LFE; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
920 : {
921 486350 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
922 : {
923 418380 : Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
924 418380 : move64();
925 418380 : Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
926 418380 : move64();
927 418380 : Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
928 418380 : move64();
929 418380 : Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
930 418380 : move64();
931 : }
932 : }
933 :
934 67260 : FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
935 : {
936 408230 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
937 : {
938 351220 : Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
939 351220 : move64();
940 351220 : Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
941 351220 : move64();
942 : }
943 : }
944 : }
945 :
946 10250 : IF( !hParamMC->hMetadataPMC.bAttackPresent )
947 : {
948 : const PARAM_MC_ILD_MAPPING *h_ild_mapping;
949 : Word16 ild_attack;
950 9760 : ild_attack = 0;
951 9760 : move16();
952 9760 : h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
953 : /* create ILDs for to non transmitted parameter bands (only lower half) */
954 74573 : FOR( cur_param_band = 0; cur_param_band < hParamMC->hMetadataPMC.num_parameter_bands / 2; cur_param_band++ )
955 : {
956 : Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
957 : Word16 k;
958 : Word16 num_ilds_to_code;
959 :
960 64813 : IF( GE_16( cur_param_band, PARAM_MC_MAX_BAND_LFE ) )
961 : {
962 55053 : num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
963 55053 : move16();
964 : }
965 : ELSE
966 : {
967 9760 : num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
968 9760 : move16();
969 : }
970 64813 : IF( NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[cur_param_band] ) )
971 : {
972 : Word32 Nrg_fx[MAX_CICP_CHANNELS];
973 : Word16 Nrg_e[MAX_CICP_CHANNELS];
974 :
975 : /* get ICLDs */
976 231161 : FOR( k = 0; k < nchan_input; ++k )
977 : {
978 198792 : CONVERT_CY( Cy_sum_real_64[cur_param_band][k][k], Nrg_fx[k], Nrg_e[k] );
979 198792 : move32();
980 198792 : move16();
981 : }
982 203355 : FOR( k = 0; k < num_ilds_to_code; ++k )
983 : {
984 170986 : Word32 ref_ener_fx = 0;
985 170986 : move32();
986 170986 : Word16 ref_ener_e = 0;
987 170986 : move16();
988 : Word16 ref_channel_cnt;
989 : Word16 ref_channel_idx;
990 :
991 378816 : FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
992 : {
993 207830 : ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
994 207830 : move16();
995 207830 : ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], // ref_ener_e
996 207830 : Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e );
997 : }
998 170986 : L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
999 170986 : L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( L_tmp, EPSILLON_FX ), &tmp_e ) );
1000 :
1001 170986 : tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
1002 :
1003 : /*1342177280 = 10 in Q27*/
1004 170986 : ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q25 + Q27 - Q31 = Q21
1005 170986 : move32();
1006 :
1007 170986 : if ( GT_32( L_sub( hParamMC->prev_ilds_fx[cur_param_band][k], ILD_fx[k] ), param_mc_ild_diff_threshold_fx[cur_param_band] ) )
1008 : {
1009 313 : ild_attack = add( ild_attack, 1 );
1010 : }
1011 : }
1012 : }
1013 : }
1014 : /* check if the ILDs change too much -> go into transient mode... */
1015 9760 : if ( GT_16( ild_attack, PARAM_MC_NUM_ATTACK_ILD_THRESH ) )
1016 : {
1017 0 : hParamMC->hMetadataPMC.bAttackPresent = 1;
1018 0 : move16();
1019 : }
1020 : }
1021 :
1022 :
1023 10250 : IF( hParamMC->hMetadataPMC.bAttackPresent )
1024 : {
1025 : /* combine bands */
1026 2325 : FOR( cur_param_band = 1; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += 2 )
1027 : {
1028 5632 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
1029 : {
1030 11772 : FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
1031 : {
1032 15950 : Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2],
1033 7975 : Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
1034 7975 : &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
1035 7975 : move32();
1036 15950 : Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2],
1037 7975 : Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2],
1038 7975 : &Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] );
1039 7975 : move32();
1040 : }
1041 : }
1042 :
1043 13949 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
1044 : {
1045 60033 : FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
1046 : {
1047 47919 : Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] );
1048 47919 : move64();
1049 47919 : Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] );
1050 47919 : move64();
1051 : }
1052 : }
1053 : }
1054 :
1055 1779 : FOR( ; cur_param_band < num_parameter_bands; cur_param_band += 2 )
1056 : {
1057 1289 : IF( LT_16( cur_param_band, num_parameter_bands ) )
1058 : {
1059 3971 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
1060 : {
1061 8358 : FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
1062 : {
1063 11352 : Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2],
1064 5676 : Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
1065 5676 : &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
1066 5676 : move32();
1067 : }
1068 : }
1069 :
1070 9863 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
1071 : {
1072 42771 : FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
1073 : {
1074 34197 : Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] );
1075 : }
1076 : }
1077 : }
1078 : }
1079 :
1080 490 : band_step = 2;
1081 490 : move16();
1082 : }
1083 : {
1084 : // convert the 64 bit fixpoint back into the 48 bit float format
1085 215250 : FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
1086 : {
1087 3485000 : FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
1088 : {
1089 55760000 : FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ )
1090 : {
1091 52480000 : CONVERT_CY( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] );
1092 52480000 : move32();
1093 52480000 : move16();
1094 : }
1095 : }
1096 : }
1097 : }
1098 :
1099 : /* map complex covariances to real values */
1100 86635 : FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += band_step )
1101 : {
1102 : /* Cx for transport channels */
1103 229968 : FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ch_idx1++ )
1104 : {
1105 463188 : FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ch_idx2++ )
1106 : {
1107 309605 : real_part_fx = Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2];
1108 309605 : move32();
1109 309605 : real_part_e = Cx_sum_e[cur_param_band][ch_idx1][ch_idx2];
1110 309605 : move16();
1111 309605 : imag_part_fx = Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2];
1112 309605 : move32();
1113 309605 : imag_part_e = Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2];
1114 309605 : move16();
1115 :
1116 309605 : real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
1117 309605 : imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
1118 309605 : L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
1119 :
1120 : /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
1121 309605 : L_tmp = Sqrt32( L_tmp, &tmp_e );
1122 309605 : Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
1123 309605 : move32();
1124 309605 : Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
1125 309605 : move16();
1126 : }
1127 : }
1128 :
1129 : /* Cy for transport channels */
1130 545671 : FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ch_idx1++ )
1131 : {
1132 2162267 : FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ )
1133 : {
1134 1692981 : CONVERT_CY( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], imag_part_fx, imag_part_e );
1135 1692981 : move32();
1136 1692981 : move16();
1137 1692981 : real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2];
1138 1692981 : move32();
1139 1692981 : real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2];
1140 1692981 : move16();
1141 1692981 : real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
1142 1692981 : imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
1143 :
1144 1692981 : L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
1145 1692981 : L_tmp = Sqrt32( L_tmp, &tmp_e );
1146 :
1147 1692981 : Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
1148 1692981 : move32();
1149 1692981 : Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
1150 1692981 : move16();
1151 : }
1152 : }
1153 : }
1154 :
1155 10250 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Cy_sum_fx[0][LFE_CHANNEL][LFE_CHANNEL], Cy_sum_e[0][LFE_CHANNEL][LFE_CHANNEL], PARAM_MC_LFE_ON_THRESH_FX, 31 ), -1 ) )
1156 : {
1157 9181 : hParamMC->hMetadataPMC.lfe_on = 0;
1158 9181 : move16();
1159 : }
1160 : ELSE
1161 : {
1162 1069 : hParamMC->hMetadataPMC.lfe_on = 1;
1163 1069 : move16();
1164 : }
1165 :
1166 10250 : pop_wmops();
1167 :
1168 10250 : return;
1169 : }
1170 :
1171 : /*-------------------------------------------------------------------------
1172 : * ivas_param_mc_quantize_ilds()
1173 : *
1174 : * Quantize the ILD parameters
1175 : *------------------------------------------------------------------------*/
1176 :
1177 132106 : static void ivas_param_mc_quantize_ilds_fx(
1178 : PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */
1179 : Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i : Covariance matrix of the input */
1180 : Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i : Covariance matrix of the input */
1181 : Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* i : Covariance matrix of the dmx */
1182 : Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* i : Covariance matrix of the dmx */
1183 : const Word16 freq_idx, /* i : frequency index being processed */
1184 : const Word16 nchan_input, /* i : number of input channels */
1185 : const Word16 nchan_transport, /* i : number of transport channels */
1186 : Word16 *ILD_idx_out, /* o : ILD indices */
1187 : Word16 ILD_q[PARAM_MC_SZ_ILD_MAP] /* o : Quanzited ILD matrix */
1188 : )
1189 : {
1190 : Word16 i, k;
1191 : Word16 Ny;
1192 : Word16 num_ilds_to_code;
1193 : Word16 ild_map_size;
1194 : Word32 Nrg_fx[MAX_CICP_CHANNELS];
1195 : Word16 Nrg_e[MAX_CICP_CHANNELS];
1196 : Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
1197 : Word16 ILD_e[PARAM_MC_SZ_ILD_MAP];
1198 : const PARAM_MC_ILD_MAPPING *h_ild_mapping;
1199 : Word32 tot_ener_fx, dmx_ener_fx, ener_fac_fx, delta_fac_fx;
1200 : Word16 tot_ener_e, dmx_ener_e;
1201 : Word16 ILD_idx[PARAM_MC_SZ_ILD_MAP];
1202 : Word32 L_tmp;
1203 : Word16 tmp_e;
1204 :
1205 132106 : push_wmops( "param_mc_prm_q" );
1206 :
1207 : /* Initialization */
1208 132106 : set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
1209 132106 : set32_fx( ILD_fx, 0, PARAM_MC_SZ_ILD_MAP );
1210 :
1211 132106 : Ny = nchan_input;
1212 132106 : move16();
1213 :
1214 132106 : h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
1215 132106 : ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
1216 132106 : move16();
1217 132106 : IF( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
1218 : {
1219 121856 : num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
1220 121856 : move16();
1221 : }
1222 : ELSE
1223 : {
1224 10250 : num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
1225 10250 : move16();
1226 : }
1227 :
1228 : /* Downsampling */
1229 132106 : test();
1230 132106 : IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
1231 : {
1232 64455 : pop_wmops();
1233 :
1234 64455 : return;
1235 : }
1236 :
1237 : /* get ICLDs */
1238 484191 : FOR( k = 0; k < Ny; ++k )
1239 : {
1240 416540 : Nrg_fx[k] = Cy_fx[k][k];
1241 416540 : move32();
1242 416540 : Nrg_e[k] = Cy_e[k][k];
1243 416540 : move16();
1244 : }
1245 :
1246 : /* limit ILDs if DMX energy is lower than sum of channel energies */
1247 67651 : tot_ener_fx = 0;
1248 67651 : move32();
1249 67651 : tot_ener_e = 0;
1250 67651 : move16();
1251 67651 : dmx_ener_fx = 0;
1252 67651 : move32();
1253 67651 : dmx_ener_e = 0;
1254 67651 : move16();
1255 :
1256 484191 : FOR( k = 0; k < ild_map_size; k++ )
1257 : {
1258 416540 : test();
1259 416540 : IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
1260 : {
1261 356156 : tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
1262 : }
1263 : }
1264 :
1265 203820 : FOR( k = 0; k < nchan_transport; k++ )
1266 : {
1267 136169 : dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
1268 : }
1269 : /*ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) )*/
1270 67651 : IF( tot_ener_fx == 0 )
1271 : {
1272 0 : tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
1273 0 : tot_ener_e = -32;
1274 0 : move32();
1275 0 : move16();
1276 : }
1277 67651 : IF( dmx_ener_fx == 0 )
1278 : {
1279 0 : dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
1280 0 : dmx_ener_e = -32;
1281 0 : move32();
1282 0 : move16();
1283 : }
1284 :
1285 67651 : L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
1286 67651 : tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
1287 67651 : ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e ); // Q25
1288 : /*10 in Q21 = 1342177280*/
1289 67651 : ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
1290 :
1291 67651 : IF( GT_32( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 ) )
1292 : {
1293 17 : L_tmp = L_sub( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
1294 17 : L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 ); // Q25
1295 : /*0.3 in Q31 = 644245094*/
1296 17 : L_tmp = L_sub( L_shr( Mpy_32_32( 644245094, L_tmp ), 4 ), L_sub( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 ) );
1297 : /*0.1 in Q31 = 214748365*/
1298 17 : L_tmp = Mpy_32_32( L_tmp, 214748365 );
1299 17 : L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
1300 :
1301 : /*v_multc( Nrg, limit_fac, Nrg, num_ilds_to_code );*/
1302 118 : FOR( i = 0; i < num_ilds_to_code; i++ )
1303 : {
1304 101 : Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
1305 101 : move32();
1306 101 : Nrg_e[i] = add( tmp_e, Nrg_e[i] );
1307 101 : move16();
1308 101 : Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
1309 101 : move32();
1310 : }
1311 : }
1312 :
1313 : /* limit ILD jumps in non-tranient frames */
1314 67651 : tot_ener_fx = 0;
1315 67651 : move32();
1316 67651 : dmx_ener_fx = 0;
1317 67651 : move32();
1318 :
1319 484191 : FOR( k = 0; k < ild_map_size; k++ )
1320 : {
1321 416540 : test();
1322 416540 : IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
1323 : {
1324 356156 : tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
1325 : }
1326 : }
1327 :
1328 203820 : FOR( k = 0; k < nchan_transport; k++ )
1329 : {
1330 136169 : dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
1331 : }
1332 : /* ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) ); */
1333 67651 : IF( tot_ener_fx == 0 )
1334 : {
1335 0 : tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
1336 0 : tot_ener_e = -32;
1337 0 : move32();
1338 0 : move16();
1339 : }
1340 67651 : IF( dmx_ener_fx == 0 )
1341 : {
1342 0 : dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
1343 0 : dmx_ener_e = -32;
1344 0 : move32();
1345 0 : move16();
1346 : }
1347 :
1348 67651 : L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
1349 67651 : tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
1350 67651 : ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e ); // Q25
1351 : /*10 in Q21 = 1342177280*/
1352 67651 : ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
1353 67651 : delta_fac_fx = L_sub( ener_fac_fx, hParamMC->ener_fac_fx[freq_idx] );
1354 :
1355 67651 : test();
1356 67651 : test();
1357 67651 : IF( !hParamMC->hMetadataPMC.bAttackPresent && GT_32( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 ) && LT_32( delta_fac_fx, PARAM_MC_ENER_LIMIT_MAX_DELTA_FAC_FX_Q21 ) )
1358 : {
1359 403 : L_tmp = L_sub( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
1360 403 : L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 ); // Q25
1361 : /*0.3 in Q31 = 644245094*/
1362 403 : L_tmp = L_sub( L_shr( Mpy_32_32( 644245094, L_tmp ), 4 ), L_sub( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 ) );
1363 : /*0.1 in Q31 = 214748365*/
1364 403 : L_tmp = Mpy_32_32( L_tmp, 214748365 );
1365 403 : L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
1366 :
1367 2524 : FOR( i = 0; i < num_ilds_to_code; i++ )
1368 : {
1369 2121 : Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
1370 2121 : move32();
1371 2121 : Nrg_e[i] = add( tmp_e, Nrg_e[i] );
1372 2121 : move16();
1373 2121 : Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
1374 2121 : move32();
1375 : }
1376 :
1377 : /*10 in Q21 = 1342177280*/
1378 403 : ener_fac_fx = L_add( ener_fac_fx, Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ) );
1379 : }
1380 :
1381 67651 : hParamMC->ener_fac_fx[freq_idx] = ener_fac_fx; // Q21
1382 67651 : move32();
1383 :
1384 : /* update also combined bands ener_fac when in transient frame */
1385 67651 : test();
1386 67651 : if ( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
1387 : {
1388 3124 : hParamMC->ener_fac_fx[freq_idx + 1] = ener_fac_fx; // Q21
1389 3124 : move32();
1390 : }
1391 :
1392 421124 : FOR( k = 0; k < num_ilds_to_code; ++k )
1393 : {
1394 353473 : Word32 ref_ener_fx = 0;
1395 353473 : move32();
1396 353473 : Word16 ref_ener_e = 0;
1397 353473 : move16();
1398 : Word16 ref_channel_cnt;
1399 : Word16 ref_channel_idx;
1400 :
1401 779049 : FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
1402 : {
1403 425576 : ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
1404 425576 : move16();
1405 425576 : ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_fx[ref_channel_idx][ref_channel_idx], Cx_e[ref_channel_idx][ref_channel_idx], &ref_ener_e );
1406 : }
1407 353473 : ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
1408 353473 : L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( ref_ener_fx, EPSILLON_FX ), &tmp_e ) );
1409 353473 : tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
1410 : /*10 in Q21 = 1342177280*/
1411 353473 : ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21
1412 353473 : move32();
1413 353473 : ILD_e[k] = 31 - 21;
1414 353473 : move16();
1415 353473 : hParamMC->prev_ilds_fx[freq_idx][k] = ILD_fx[k];
1416 353473 : move32();
1417 353473 : test();
1418 353473 : IF( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
1419 : {
1420 17853 : hParamMC->prev_ilds_fx[freq_idx + 1][k] = ILD_fx[k];
1421 17853 : move32();
1422 : }
1423 : }
1424 :
1425 :
1426 : /* quantize parameters */
1427 67651 : ivas_param_mc_parameter_quantizer_fx( ILD_fx, ILD_e, num_ilds_to_code, hParamMC->hMetadataPMC.ild_coding.quantizer_size, hParamMC->hMetadataPMC.ild_coding.quantizer_fx, Q8, ILD_idx, ILD_q );
1428 :
1429 : /* Save current quantized ICLDs */
1430 67651 : Copy( ILD_idx, ILD_idx_out + freq_idx * ild_map_size, num_ilds_to_code );
1431 :
1432 67651 : pop_wmops();
1433 :
1434 67651 : return;
1435 : }
1436 :
1437 :
1438 : /*-------------------------------------------------------------------------
1439 : * ivas_param_mc_quantize_iccs()
1440 : *
1441 : * Quantize the ILD parameters
1442 : *------------------------------------------------------------------------*/
1443 :
1444 132106 : static void ivas_param_mc_quantize_iccs_fx(
1445 : PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */
1446 : Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i : Covariance matrix of the input */
1447 : Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i : Covariance matrix of the input */
1448 : const Word16 freq_idx, /* i : frequency index being processed */
1449 : const Word16 nchan_input, /* i : number of input channels */
1450 : Word16 *ICC_idx_out /* o : quantizer indices */
1451 : )
1452 : {
1453 : Word16 i, k;
1454 : Word16 Ny;
1455 : Word16 num_iccs_to_code;
1456 : Word16 icc_map_size;
1457 : Word16 tmp_map[2];
1458 : Word16 ICC_idx[PARAM_MC_SZ_ICC_MAP];
1459 :
1460 : /* Initialization */
1461 : Word32 a_fx;
1462 : Word32 Nrg_fx[MAX_CICP_CHANNELS];
1463 : Word16 Nrg_e;
1464 : Word32 ICC_vect_fx[PARAM_MC_SZ_ICC_MAP];
1465 : Word16 ICC_vect_e[PARAM_MC_SZ_ICC_MAP];
1466 : Word16 ICC_vect_q_fx[PARAM_MC_SZ_ICC_MAP];
1467 :
1468 132106 : set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
1469 132106 : set32_fx( ICC_vect_fx, 0, PARAM_MC_SZ_ICC_MAP );
1470 132106 : set16_fx( ICC_vect_q_fx, 0, PARAM_MC_SZ_ICC_MAP );
1471 :
1472 :
1473 132106 : Ny = nchan_input;
1474 132106 : move16();
1475 :
1476 : /* Downsampling */
1477 132106 : test();
1478 132106 : IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
1479 : {
1480 64455 : return;
1481 : }
1482 :
1483 67651 : icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
1484 67651 : move16();
1485 67651 : num_iccs_to_code = icc_map_size;
1486 67651 : move16();
1487 :
1488 67651 : if ( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
1489 : {
1490 62266 : num_iccs_to_code = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
1491 62266 : move16();
1492 : }
1493 :
1494 : /* Get ICC matrix from Cy */
1495 484191 : FOR( k = 0; k < Ny; ++k )
1496 : {
1497 416540 : Nrg_fx[k] = Cy_fx[k][k];
1498 416540 : move32();
1499 416540 : Nrg_e = Cy_e[k][k];
1500 416540 : move16();
1501 416540 : a_fx = ISqrt32( L_add( Nrg_fx[k], EPSILLON_FX ), &Nrg_e );
1502 :
1503 1923686 : FOR( i = k; i < Ny; ++i )
1504 : {
1505 1507146 : Cy_fx[k][i] = Mpy_32_32( Cy_fx[k][i], a_fx );
1506 1507146 : move32();
1507 1507146 : Cy_fx[k][i] = BASOP_Util_Add_Mant32Exp( Cy_fx[k][i], add( Cy_e[k][i], Nrg_e ), 0, 0, &Cy_e[k][i] );
1508 1507146 : move32();
1509 : }
1510 :
1511 1923686 : FOR( i = 0; i <= k; i++ )
1512 : {
1513 1507146 : Cy_fx[i][k] = Mpy_32_32( Cy_fx[i][k], a_fx );
1514 1507146 : move32();
1515 1507146 : Cy_fx[i][k] = BASOP_Util_Add_Mant32Exp( Cy_fx[i][k], add( Cy_e[i][k], Nrg_e ), 0, 0, &Cy_e[i][k] );
1516 1507146 : move32();
1517 : }
1518 : }
1519 :
1520 : /* set ICCs for zero channels to 1 to avoid artifacts in the decoded signal */
1521 484191 : FOR( k = 0; k < Ny; ++k )
1522 : {
1523 416540 : IF( Nrg_fx[k] == 0 )
1524 : {
1525 258920 : FOR( i = k; i < Ny; ++i )
1526 : {
1527 196632 : Cy_fx[k][i] = ONE_IN_Q31;
1528 196632 : move32();
1529 196632 : Cy_e[k][i] = 0;
1530 196632 : move16();
1531 : }
1532 :
1533 311440 : FOR( i = 0; i <= k; ++i )
1534 : {
1535 249152 : Cy_fx[i][k] = ONE_IN_Q31;
1536 249152 : move32();
1537 249152 : Cy_e[i][k] = 0;
1538 249152 : move16();
1539 : }
1540 : }
1541 : }
1542 :
1543 : /* Reduce set of parameters and quantize them */
1544 354274 : FOR( k = 0; k < num_iccs_to_code; ++k )
1545 : {
1546 286623 : tmp_map[0] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][0];
1547 286623 : move16();
1548 286623 : tmp_map[1] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][1];
1549 286623 : move16();
1550 286623 : ICC_vect_fx[k] = Cy_fx[tmp_map[0]][tmp_map[1]];
1551 286623 : move32();
1552 286623 : ICC_vect_e[k] = Cy_e[tmp_map[0]][tmp_map[1]];
1553 286623 : move16();
1554 : }
1555 :
1556 : /* Quantization */
1557 67651 : ivas_param_mc_parameter_quantizer_fx( ICC_vect_fx, ICC_vect_e, num_iccs_to_code, hParamMC->hMetadataPMC.icc_coding.quantizer_size, hParamMC->hMetadataPMC.icc_coding.quantizer_fx, Q15, ICC_idx, ICC_vect_q_fx );
1558 :
1559 : /* Save current quantized ICCs */
1560 67651 : Copy( ICC_idx, ICC_idx_out + freq_idx * icc_map_size, num_iccs_to_code );
1561 :
1562 67651 : return;
1563 : }
1564 :
1565 :
1566 : /*-------------------------------------------------------------------------
1567 : * ivas_param_mc_parameter_quantizer()
1568 : *
1569 : * Parameter Quantization
1570 : *------------------------------------------------------------------------*/
1571 :
1572 135302 : static void ivas_param_mc_parameter_quantizer_fx(
1573 : const Word32 *x, /* i : input sequence */
1574 : const Word16 *x_e, /* i : input sequence */
1575 : const Word16 L, /* i : input length */
1576 : const Word16 sz_quantizer, /* i : quantizer size */
1577 : const Word16 *quantizer_fx, /* i : quantizer table Q_quant */
1578 : const Word16 Q_quant, /* i : quantizer table */
1579 : Word16 *quant_idx, /* o : quant indices */
1580 : Word16 *y_fx /* o : output sequence Q_quant */
1581 : )
1582 : {
1583 : Word16 idx, i;
1584 : Word16 idx_min;
1585 : Word32 tmp_min_fx;
1586 : Word16 tmp_min_e;
1587 : Word32 tmp_val;
1588 : Word16 tmp_e;
1589 :
1590 135302 : set16_fx( y_fx, 0, L );
1591 135302 : idx_min = 0;
1592 135302 : move16();
1593 :
1594 775398 : FOR( idx = 0; idx < L; ++idx )
1595 : {
1596 640096 : tmp_min_fx = 1000;
1597 640096 : move32();
1598 640096 : tmp_min_e = 31;
1599 640096 : move16();
1600 :
1601 8588648 : FOR( i = 0; i < sz_quantizer; ++i )
1602 : {
1603 7948552 : tmp_val = BASOP_Util_Add_Mant32Exp( x[idx], x_e[idx], L_negate( L_deposit_h( quantizer_fx[i] ) ), sub( 15, Q_quant ), &tmp_e );
1604 7948552 : tmp_val = L_abs( tmp_val );
1605 7948552 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_val, tmp_e, tmp_min_fx, tmp_min_e ), -1 ) )
1606 : {
1607 4184865 : tmp_min_fx = tmp_val;
1608 4184865 : move32();
1609 4184865 : tmp_min_e = tmp_e;
1610 4184865 : move16();
1611 4184865 : idx_min = i;
1612 4184865 : move16();
1613 : }
1614 : }
1615 :
1616 640096 : y_fx[idx] = quantizer_fx[idx_min];
1617 640096 : move32();
1618 640096 : quant_idx[idx] = idx_min;
1619 640096 : move16();
1620 : }
1621 :
1622 135302 : return;
1623 : }
1624 :
1625 :
1626 : /*-------------------------------------------------------------------------
1627 : * ivas_param_mc_transient_detection()
1628 : *
1629 : * Detect if the current frame has a transient
1630 : *------------------------------------------------------------------------*/
1631 :
1632 20610 : static void ivas_param_mc_transient_detection_fx(
1633 : PARAM_MC_ENC_HANDLE hParamMC, /* i : Parametric MC encoder handle */
1634 : TRAN_DET_HANDLE hTranDet, /* i : Transient detector handle from core coder for a transport channel */
1635 : Word16 *pbIsAttackPresent, /* o : Flag for indicating a found transient */
1636 : Word16 *pAttackIndex /* o : Attack position (0 if no attack) */
1637 : )
1638 : {
1639 : Word16 i;
1640 : Word16 bIsAttackPresent, attackIndex;
1641 : Word32 *pSubblockNrg_fx;
1642 : Word32 *pAccSubblockNrg_fx;
1643 : Word16 attackRatioThreshold_fx;
1644 :
1645 20610 : push_wmops( "param_mc_trn_det" );
1646 :
1647 20610 : attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold;
1648 20610 : pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; // Q(-1)
1649 20610 : pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1)
1650 :
1651 20610 : bIsAttackPresent = FALSE;
1652 20610 : move16();
1653 20610 : attackIndex = 16;
1654 20610 : move16();
1655 :
1656 : /* Search for the last attack in the subblocks,
1657 : * if we had an attack very late in the last frame,
1658 : * make the current frame also a transient one... */
1659 20610 : test();
1660 20610 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ||
1661 : EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) )
1662 : {
1663 71 : bIsAttackPresent = TRUE;
1664 71 : move16();
1665 71 : attackIndex = 0;
1666 71 : move16();
1667 : }
1668 :
1669 185490 : FOR( i = 0; i < NSUBBLOCKS; i++ ){
1670 164880 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){
1671 784 : bIsAttackPresent = TRUE;
1672 784 : move16();
1673 784 : attackIndex = i;
1674 784 : move16();
1675 : }
1676 : }
1677 :
1678 : /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */
1679 20610 : *pAttackIndex = attackIndex;
1680 20610 : move16();
1681 20610 : *pbIsAttackPresent = bIsAttackPresent;
1682 20610 : move16();
1683 :
1684 20610 : pop_wmops();
1685 :
1686 20610 : return;
1687 : }
1688 :
1689 : /*-------------------------------------------------------------------------
1690 : * ivas_param_mc_entropy_encoder()
1691 : *
1692 : * Write the metadata bitstream
1693 : *------------------------------------------------------------------------*/
1694 :
1695 10250 : static void ivas_param_mc_write_bs_fx(
1696 : const PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder Handle */
1697 : Word16 *ILD_idx, /* i : ILD quantizer indices sequence */
1698 : Word16 *ICC_idx, /* i : ICC quantizer indices sequence */
1699 : UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o : Output bit buffer */
1700 : Word16 *bit_pos /* o : Number of bits used */
1701 : )
1702 : {
1703 : Word16 i, pos;
1704 : Word16 nbands;
1705 : Word16 band_step;
1706 : /*buffers are not getting used in the function*/
1707 : // Word16 seq_tmp[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
1708 : // float seq_tmp_uni[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
1709 : Word16 icc_map_size_wo_lfe;
1710 : Word16 icc_map_size;
1711 : Word16 ild_map_size_wo_lfe;
1712 : Word16 ild_map_size;
1713 :
1714 10250 : push_wmops( "param_mc_prm_enc" );
1715 :
1716 : /* Init */
1717 : /*buffers are not getting used in the function */
1718 : // set_zero( seq_tmp_uni, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
1719 : // set_s( seq_tmp, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
1720 10250 : nbands = hParamMC->hMetadataPMC.nbands_in_param_frame[hParamMC->hMetadataPMC.param_frame_idx];
1721 10250 : move16();
1722 10250 : icc_map_size_wo_lfe = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
1723 10250 : move16();
1724 10250 : icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
1725 10250 : move16();
1726 10250 : ild_map_size_wo_lfe = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
1727 10250 : move16();
1728 10250 : ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
1729 10250 : move16();
1730 :
1731 : /*-----------------------------------------------------------------*
1732 : * Signaling bits
1733 : *-----------------------------------------------------------------*/
1734 :
1735 : /* reserved bit */
1736 10250 : bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.lfe_on;
1737 10250 : move16();
1738 :
1739 : /* write coded band width */
1740 10250 : i = hParamMC->hMetadataPMC.coded_bwidth;
1741 10250 : move16();
1742 30750 : FOR( pos = 0; pos < 2; pos++ )
1743 : {
1744 20500 : bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( i, pos ), 1 );
1745 20500 : move16();
1746 : }
1747 :
1748 : /* write param frame indicator */
1749 10250 : bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.param_frame_idx;
1750 10250 : move16();
1751 :
1752 : /* write transient frame indicator */
1753 10250 : bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.bAttackPresent;
1754 10250 : move16();
1755 :
1756 10250 : band_step = 1;
1757 10250 : move16();
1758 10250 : IF( hParamMC->hMetadataPMC.bAttackPresent )
1759 : {
1760 490 : band_step = PARAM_MC_TRANSIENT_BAND_STEP;
1761 490 : move16();
1762 1960 : FOR( pos = 2; pos >= 0; --pos )
1763 : {
1764 1470 : bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( hParamMC->hMetadataPMC.attackIndex, pos ), 1 );
1765 1470 : move16();
1766 : }
1767 490 : IF( ( hParamMC->hMetadataPMC.nbands_coded % band_step ) )
1768 : {
1769 53 : nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 1 );
1770 : }
1771 : ELSE
1772 : {
1773 437 : nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 0 );
1774 : }
1775 : }
1776 :
1777 10250 : ivas_param_mc_encode_parameter_fx( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding,
1778 : nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos );
1779 :
1780 10250 : ivas_param_mc_encode_parameter_fx( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding,
1781 : nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos );
1782 10250 : pop_wmops();
1783 :
1784 10250 : return;
1785 : }
1786 :
1787 :
1788 : /*-------------------------------------------------------------------------
1789 : * ivas_param_mc_encode_parameter_fx()
1790 : *
1791 : * (entropy) encode a sequence of parameter indices
1792 : *------------------------------------------------------------------------*/
1793 :
1794 20500 : static void ivas_param_mc_encode_parameter_fx(
1795 : Word16 *quant_idx, /* i : indices sequence to encode */
1796 : HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata handle */
1797 : HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, /* i : parameter quantization and coding info */
1798 : const Word16 nbands, /* i : number of parameter bands to encode */
1799 : const Word16 band_step, /* i : parameter band step */
1800 : const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFE) */
1801 : const Word16 map_size, /* i : number of parameters per band */
1802 : UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o : Output bit buffer */
1803 : Word16 *bit_pos /* o : Number of bits used */
1804 : )
1805 : {
1806 : Word16 sz_seq;
1807 : Word16 idx_prev;
1808 : Word16 idx_offset;
1809 : Word16 bit_cnt_uni;
1810 : Word16 bit_cnt_range;
1811 : Word16 bit_cnt_range_diff;
1812 : Word16 bit_cnt_range_min;
1813 : Word16 bit_pos_tmp;
1814 : Word16 i, j;
1815 : Word16 idx;
1816 : Word16 seq_delta[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
1817 : Word16 seq[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
1818 : UWord16 tmp_bit_buffer[PARAM_MC_MAX_BITS];
1819 : UWord16 tmp_bit_buffer_diff[PARAM_MC_MAX_BITS];
1820 :
1821 : /* Inits */
1822 20500 : sz_seq = i_mult( nbands, ( map_size_wo_lfe ) );
1823 :
1824 : /* Computing Delta Sequence */
1825 20500 : idx_prev = sub( add( shr( hParameterCodingInfo->quantizer_size, 1 ), hParameterCodingInfo->quantizer_size % 2 ), 1 );
1826 20500 : idx_offset = sub( hParameterCodingInfo->quantizer_size, 1 );
1827 :
1828 115680 : FOR( j = 0; j < map_size_wo_lfe; ++j )
1829 : {
1830 95180 : Word16 coding_band = 0;
1831 95180 : move16();
1832 :
1833 1321237 : FOR( i = 0; i < hMetadataPMC->nbands_coded; i += band_step )
1834 : {
1835 1226057 : test();
1836 1226057 : IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
1837 : {
1838 629260 : idx = quant_idx[i * map_size + j];
1839 629260 : move16();
1840 629260 : seq[coding_band + j * nbands] = idx;
1841 629260 : move16();
1842 629260 : seq_delta[coding_band + j * nbands] = add( sub( idx, idx_prev ), idx_offset );
1843 629260 : move16();
1844 629260 : idx_prev = idx;
1845 629260 : move16();
1846 629260 : coding_band = add( coding_band, 1 );
1847 : }
1848 : }
1849 : }
1850 :
1851 : /* LFE */
1852 20500 : IF( hMetadataPMC->lfe_on )
1853 : {
1854 4276 : FOR( i = 0; i < PARAM_MC_MAX_BAND_LFE; i += band_step )
1855 : {
1856 2138 : test();
1857 2138 : IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
1858 : {
1859 : /* LFE ICC/ILDs are always the last ones in coding band 0 */
1860 : Word16 n_lfe_idx, k;
1861 1172 : n_lfe_idx = sub( map_size, map_size_wo_lfe );
1862 2410 : FOR( k = 0; k < n_lfe_idx; k++ )
1863 : {
1864 1238 : idx = quant_idx[( i + 1 ) * map_size - n_lfe_idx + k];
1865 1238 : move16();
1866 1238 : seq[sz_seq] = idx;
1867 1238 : move16();
1868 1238 : seq_delta[sz_seq] = add( sub( idx, idx_prev ), idx_offset );
1869 1238 : move16();
1870 1238 : idx_prev = idx;
1871 1238 : move16();
1872 1238 : sz_seq = add( sz_seq, 1 );
1873 : }
1874 : }
1875 : }
1876 : }
1877 :
1878 :
1879 20500 : bit_cnt_uni = sub( i_mult( sz_seq, hParameterCodingInfo->uni_bits ), 1 ); /* -1 for the additional diff/direct signaling bit for the range encoder*/
1880 :
1881 : /* code the direct index sequence */
1882 20500 : ivas_param_mc_range_encoder_fx( seq, sz_seq, hParameterCodingInfo->cum_freq, hParameterCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer[0], &bit_cnt_range );
1883 :
1884 : /* Coding the delta index sequence */
1885 20500 : ivas_param_mc_range_encoder_fx( seq_delta, sz_seq, hParameterCodingInfo->cum_freq_delta, hParameterCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer_diff[0], &bit_cnt_range_diff );
1886 :
1887 20500 : bit_cnt_range_min = s_min( bit_cnt_range, bit_cnt_range_diff );
1888 :
1889 : /* uniform fallback */
1890 20500 : IF( GT_16( bit_cnt_range_min, bit_cnt_uni ) )
1891 : {
1892 : /* Uniform coding is used */
1893 478 : bit_buffer[( *bit_pos )++] = 0;
1894 478 : move16();
1895 478 : bit_pos_tmp = 0;
1896 478 : move16();
1897 :
1898 12904 : FOR( i = 0; i < sz_seq; ++i )
1899 : {
1900 12426 : ivas_param_mc_dec2bin_fx( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] );
1901 12426 : bit_pos_tmp = add( bit_pos_tmp, hParameterCodingInfo->uni_bits );
1902 : }
1903 478 : *bit_pos = add( *bit_pos, bit_pos_tmp );
1904 : }
1905 : ELSE
1906 : {
1907 : /* Range Coding is used */
1908 20022 : bit_buffer[( *bit_pos )++] = 1;
1909 20022 : move16();
1910 20022 : IF( bit_cnt_range_diff < bit_cnt_range )
1911 : {
1912 19757 : bit_buffer[( *bit_pos )++] = 1;
1913 19757 : move16();
1914 1356014 : FOR( i = 0; i < bit_cnt_range_diff; i++ )
1915 : {
1916 1336257 : bit_buffer[( *bit_pos )++] = tmp_bit_buffer_diff[i];
1917 1336257 : move16();
1918 : }
1919 : }
1920 : ELSE
1921 : {
1922 265 : bit_buffer[( *bit_pos )++] = 0;
1923 265 : move16();
1924 15687 : FOR( i = 0; i < bit_cnt_range; i++ )
1925 : {
1926 15422 : bit_buffer[( *bit_pos )++] = tmp_bit_buffer[i];
1927 15422 : move16();
1928 : }
1929 : }
1930 : }
1931 :
1932 20500 : return;
1933 : }
1934 :
1935 :
1936 : /*-------------------------------------------------------------------------
1937 : * ivas_param_mc_dec2bin()
1938 : *
1939 : * Decimal to binary routine
1940 : *------------------------------------------------------------------------*/
1941 :
1942 12426 : static void ivas_param_mc_dec2bin_fx(
1943 : const Word16 val, /* i : value to encode */
1944 : const Word16 N, /* i : number of bits for encoding the value */
1945 : UWord16 bits[PARAM_MC_MAX_BITS] ) /* o : encoded bits buffer */
1946 : {
1947 : Word16 idx;
1948 :
1949 12426 : idx = 0;
1950 12426 : move16();
1951 : /* convert value to bitstream, MSB first */
1952 49704 : FOR( idx = 0; idx < N; idx++ )
1953 : {
1954 37278 : bits[idx] = (UWord16) s_and( shr( val, sub( sub( N, 1 ), idx ) ), 1 );
1955 37278 : move16();
1956 : }
1957 :
1958 12426 : return;
1959 : }
1960 :
1961 :
1962 : /*-------------------------------------------------------------------*
1963 : * ivas_param_mc_range_encoder()
1964 : *
1965 : * Parametric MC Range encoder
1966 : *-------------------------------------------------------------------*/
1967 :
1968 41000 : static void ivas_param_mc_range_encoder_fx(
1969 : const Word16 *seq_in, /* i : input sequence */
1970 : const Word16 num_symbols, /* i : Number of symbole to encode */
1971 : const UWord16 *cum_freq, /* i : cumulated frequencies */
1972 : const UWord16 *sym_freq, /* i : symbol frequencies */
1973 : const UWord16 tot_shift, /* i : max cumulative freq as power of 2 */
1974 : const Word16 max_nb_bits, /* i : Maximum number of bits allowed */
1975 : UWord16 *bit_buffer, /* o : output bit buffer */
1976 : Word16 *bit_pos /* o : number of bits used */
1977 : )
1978 : {
1979 : RangeUniEncState rc_st_enc;
1980 : Word16 rc_tot_bits; /* No. of bits returned by range coder */
1981 : Word16 i;
1982 : UWord8 k, byte;
1983 : UWord16 *bits;
1984 :
1985 : /* Initialize range encoder */
1986 41000 : rc_uni_enc_init_fx( &rc_st_enc );
1987 :
1988 : /* Main loop over the length of the sequence */
1989 1242380 : FOR( i = 0; i < num_symbols; ++i )
1990 : {
1991 1211481 : rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift );
1992 :
1993 1211481 : IF( GT_16( rc_uni_enc_virtual_finish_fx( &rc_st_enc ), max_nb_bits ) )
1994 : {
1995 : /* we alread have exceeded the maximum number of bits allowed, i.e. the uniform fallback */
1996 10101 : *bit_pos = MAX_BITS_PER_FRAME;
1997 10101 : return;
1998 : }
1999 : }
2000 :
2001 : /* Finish range encoder */
2002 30899 : rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder */
2003 :
2004 : /* Push range coded bits from byte_buffer to bitstream */
2005 :
2006 : /* 1) Push all complete bytes, one byte at a time */
2007 335966 : FOR( i = 0; i < ( rc_tot_bits >> 3 ); ++i )
2008 : {
2009 : /* use rc_st_enc.byte_buffer */
2010 305067 : bits = &bit_buffer[i << 3];
2011 :
2012 305067 : byte = rc_st_enc.byte_buffer[i];
2013 305067 : move16();
2014 :
2015 305067 : bits[0] = (UWord16) s_and( shr( (Word16) byte, 7 ), 1 );
2016 305067 : move16();
2017 305067 : bits[1] = (UWord16) s_and( shr( (Word16) byte, 6 ), 1 );
2018 305067 : move16();
2019 305067 : bits[2] = (UWord16) s_and( shr( (Word16) byte, 5 ), 1 );
2020 305067 : move16();
2021 305067 : bits[3] = (UWord16) s_and( shr( (Word16) byte, 4 ), 1 );
2022 305067 : move16();
2023 305067 : bits[4] = (UWord16) s_and( shr( (Word16) byte, 3 ), 1 );
2024 305067 : move16();
2025 305067 : bits[5] = (UWord16) s_and( shr( (Word16) byte, 2 ), 1 );
2026 305067 : move16();
2027 305067 : bits[6] = (UWord16) s_and( shr( (Word16) byte, 1 ), 1 );
2028 305067 : move16();
2029 305067 : bits[7] = (UWord16) s_and( (Word16) byte, 1 );
2030 305067 : move16();
2031 : }
2032 :
2033 : /* 2) Push remaining bits */
2034 30899 : IF( s_and( rc_tot_bits, 7 ) != 0 )
2035 : {
2036 27184 : UWord8 rem_bits = (UWord8) s_and( rc_tot_bits, 7 );
2037 :
2038 27184 : bits = &bit_buffer[( i << 3 )];
2039 27184 : byte = rc_st_enc.byte_buffer[i];
2040 27184 : move16();
2041 :
2042 134734 : FOR( k = 0; k < rem_bits; k++ )
2043 : {
2044 107550 : bits[k] = (UWord16) s_and( shr( (Word16) byte, sub( 7, k ) ), 1 );
2045 107550 : move16();
2046 : }
2047 : }
2048 :
2049 : /* Update output number of bits */
2050 30899 : *bit_pos = rc_tot_bits;
2051 30899 : move16();
2052 :
2053 30899 : return;
2054 : }
|