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 <stdint.h>
34 : #include <math.h>
35 : #include <assert.h>
36 : #include "options.h"
37 : #include "ivas_cnst.h"
38 : #include "ivas_prot_rend_fx.h"
39 : #include "rom_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_stat_dec.h"
42 : #include "prot_fx.h"
43 : #include "wmc_auto.h"
44 : #include "ivas_prot_fx.h"
45 :
46 :
47 : /*-----------------------------------------------------------------------*
48 : * Local constants
49 : *-----------------------------------------------------------------------*/
50 :
51 : #define SPAR_META_DELAY_SUBFRAMES 2 /* Number of subframes to delay the SPAR metadata */
52 : #define SPH_IDX_FRONT ( MASA_NO_POINTS_EQUATOR / 2 ) /* Spherical index corresponding to front direction for setting as default value */
53 :
54 :
55 : /*-----------------------------------------------------------------------*
56 : * Local function prototypes
57 : *-----------------------------------------------------------------------*/
58 :
59 : static Word16 rint_fx( const Word32 num );
60 :
61 : static void index_16bits_fx( IVAS_QMETADATA_HANDLE hQMetaData, SPHERICAL_GRID_DATA *Sph_Grid16 );
62 :
63 : static void create_masa_ext_out_meta_fx( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const Word16 nchan_transport );
64 :
65 : static void replicate_subframes_fx( IVAS_QMETADATA_HANDLE hQMetaData );
66 :
67 : static void restore_lowbitrate_masa_fx( IVAS_QMETADATA_HANDLE hQMetaData, const Word16 low_bitrate_mode, const Word16 numCodingBands );
68 :
69 : static ivas_error init_lfe_synth_data_fx( Decoder_Struct *st_ivas, MASA_DECODER_HANDLE hMasa );
70 :
71 : static void compute_foa_cov_matrix_fx( Word32 foaCov_fx[FOA_CHANNELS][FOA_CHANNELS], Word32 inCov_fx[FOA_CHANNELS][FOA_CHANNELS], Word32 mixMtx_fx[FOA_CHANNELS][FOA_CHANNELS] );
72 :
73 : static Word16 decode_lfe_to_total_energy_ratio_fx( MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, UWord16 *bitstream, Word16 *index, const Word32 ivas_total_brate );
74 :
75 : static ivas_error ivas_masa_dec_config_fx( Decoder_Struct *st_ivas );
76 :
77 : static Word16 ivas_decode_masaism_metadata_fx( IVAS_QMETADATA_HANDLE hQMetaData, MASA_DECODER_HANDLE hMasa, MASA_ISM_DATA_HANDLE hMasaIsmData, const Word16 nchan_ism, UWord16 *bit_stream, Word16 *next_bit_pos, const Word16 idx_separated_object, const Word16 ism_imp, const Word16 dirac_bs_md_write_idx, const Word16 dirac_md_buffer_length );
78 :
79 : static void decode_index_slice_fx( Word16 index, Word16 *ratio_idx_ism, const Word16 nchan_ism, const Word16 K );
80 :
81 : static void decode_ism_ratios_fx( UWord16 *bit_stream, Word16 *next_bit_pos, Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const Word16 nchan_ism, const Word16 nbands, const Word16 nblocks, const Word16 idx_separated_object );
82 :
83 : static void read_ism_ratio_index_fx( Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const Word16 nchan_ism, const Word16 numCodingBands, const Word16 sf, Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], UWord16 *bit_stream, Word16 *next_bit_pos, const Word32 *masa_to_total_energy_ratio_fx, const Word16 idx_sep_obj, Word16 *num_zeros );
84 :
85 :
86 : /*-----------------------------------------------------------------------*
87 : * ivas_masa_decode_fx()
88 : *
89 : * MASA metadata decoder
90 : *-----------------------------------------------------------------------*/
91 :
92 119494 : ivas_error ivas_masa_decode_fx(
93 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
94 : Decoder_State *st, /* i/o: decoder state structure with bitstream */
95 : Word16 *nb_bits_read /* o : number of bits read Q0*/
96 : )
97 : {
98 : UWord16 byteBuffer;
99 : Word16 next_bit_pos_orig;
100 : Word32 masa_brate, ivas_total_brate;
101 : MASA_DECODER_HANDLE hMasa;
102 : IVAS_QMETADATA_HANDLE hQMetaData;
103 : IVAS_FORMAT ivas_format;
104 : Word16 low_bitrate_mode, tmp_elem_mode;
105 : ivas_error error;
106 : Word16 obj;
107 : Word16 i, ch, ism_imp;
108 : Word16 dirac_bs_md_write_idx, tmp;
109 : Word32 masa_total_brate;
110 :
111 119494 : dirac_bs_md_write_idx = 0;
112 119494 : move16();
113 119494 : ism_imp = 0;
114 119494 : move16();
115 :
116 119494 : error = IVAS_ERR_OK;
117 119494 : move16();
118 119494 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
119 119494 : move32();
120 :
121 119494 : low_bitrate_mode = -1; /* This means that LBR mode is not used. */
122 119494 : move16();
123 :
124 119494 : test();
125 119494 : test();
126 119494 : test();
127 119494 : IF( st_ivas->hOutSetup.separateChannelEnabled || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
128 : {
129 28112 : masa_brate = st_ivas->hCPE[0]->element_brate;
130 28112 : move32();
131 : }
132 : ELSE
133 : {
134 91382 : masa_brate = ivas_total_brate;
135 91382 : move32();
136 : }
137 :
138 119494 : hMasa = st_ivas->hMasa;
139 119494 : hQMetaData = st_ivas->hQMetaData;
140 119494 : ivas_format = st_ivas->ivas_format;
141 119494 : move32();
142 :
143 119494 : hMasa->data.dir_decode_quality_fx = MAX16B; /* Set to default of max quality */ /* 1.0f in Q15 */
144 119494 : move16();
145 :
146 119494 : hQMetaData->is_masa_ivas_format = 1;
147 119494 : move16();
148 :
149 119494 : *nb_bits_read = 0;
150 119494 : move16();
151 :
152 119494 : next_bit_pos_orig = st->next_bit_pos;
153 119494 : move16();
154 :
155 : /* masa_brate / FRAMES_PER_SEC */
156 119494 : tmp = extract_l( Mpy_32_32( masa_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); // Q0
157 :
158 119494 : IF( EQ_32( masa_brate, IVAS_SID_5k2 ) )
159 : {
160 194 : st->next_bit_pos = sub( sub( tmp, 1 ), SID_FORMAT_NBITS );
161 : }
162 : ELSE
163 : {
164 119300 : st->next_bit_pos = sub( tmp, 1 );
165 : }
166 119494 : move16();
167 :
168 119494 : test();
169 119494 : test();
170 119494 : IF( EQ_32( ivas_format, MASA_FORMAT ) && ( EQ_32( masa_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) )
171 : {
172 1414 : hMasa->config.numberOfDirections = 1;
173 1414 : move16();
174 : }
175 :
176 119494 : test();
177 119494 : test();
178 119494 : test();
179 119494 : test();
180 119494 : test();
181 119494 : IF( st->bfi == 0 && GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
182 : {
183 116361 : test();
184 116361 : IF( NE_32( ivas_format, MC_FORMAT ) || NE_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
185 104580 : {
186 104580 : Word16 bits_per_frame = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
187 :
188 104580 : IF( EQ_32( ivas_format, MASA_FORMAT ) )
189 : {
190 : /* re-read the number of objects, needed in case of bad frame */
191 77615 : ch = sub( 5, add( st_ivas->bit_stream[sub( bits_per_frame, 3 )], shl( st_ivas->bit_stream[sub( bits_per_frame, 2 )], 1 ) ) );
192 :
193 77615 : if ( EQ_16( ch, 5 ) )
194 : {
195 70609 : ch = 0;
196 70609 : move16();
197 : }
198 77615 : st_ivas->nchan_ism = ch;
199 77615 : move16();
200 : }
201 :
202 104580 : test();
203 104580 : IF( EQ_32( ivas_format, MASA_FORMAT ) && GT_16( st_ivas->nchan_ism, 0 ) )
204 : {
205 : /* there was OMASA in the input */
206 7006 : hMasa->config.input_ivas_format = MASA_ISM_FORMAT;
207 7006 : move32();
208 7006 : IF( LT_16( st_ivas->nchan_ism, 3 ) )
209 : {
210 : /* was read in ivas_init_dec() to distinguish between 1 and 2 objects */
211 2260 : IF( EQ_16( st_ivas->bit_stream[bits_per_frame - 1], 0 ) )
212 : {
213 1469 : st_ivas->nchan_ism = 1;
214 1469 : move16();
215 : }
216 2260 : st->next_bit_pos = sub( st->next_bit_pos, MASA_TRANSP_BITS );
217 2260 : *nb_bits_read = add( *nb_bits_read, MASA_TRANSP_BITS );
218 :
219 : /* the two reserved bits were already read in ivas_init_dec()*/
220 2260 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
221 2260 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
222 2260 : move16();
223 2260 : move16();
224 2260 : *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
225 :
226 : /* read number of directions */
227 2260 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
228 2260 : move16();
229 2260 : *nb_bits_read = add( *nb_bits_read, 1 );
230 2260 : hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
231 : }
232 : ELSE
233 : {
234 : /* if there are 3 or 4 objects the number of transport channels bit is given to MASA format
235 : and used to read number of directions*/
236 4746 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
237 4746 : move16();
238 4746 : *nb_bits_read = add( *nb_bits_read, 1 );
239 4746 : hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
240 :
241 : /* the two reserved bits were already read in ivas_init_dec()*/
242 4746 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
243 4746 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
244 4746 : move16();
245 4746 : move16();
246 4746 : *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
247 : }
248 : }
249 : ELSE
250 : {
251 97574 : IF( NE_32( ivas_format, MASA_ISM_FORMAT ) )
252 : {
253 : /* number of transport channels is always 2 for MASA_ISM format */
254 : /* the number of MASA transport channels was read in ivas_dec_setup() */
255 70609 : st->next_bit_pos = sub( st->next_bit_pos, MASA_TRANSP_BITS );
256 70609 : *nb_bits_read = add( *nb_bits_read, MASA_TRANSP_BITS );
257 70609 : move16();
258 : }
259 :
260 97574 : test();
261 97574 : IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) && NE_32( st_ivas->ism_mode, ISM_MODE_NONE ) )
262 : {
263 : /* the number of objects was read */
264 26965 : st->next_bit_pos = sub( st->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
265 26965 : *nb_bits_read = add( *nb_bits_read, NO_BITS_MASA_ISM_NO_OBJ );
266 26965 : move16();
267 26965 : move16();
268 :
269 26965 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
270 : {
271 : /* read index of separated object */
272 : /* nchan_ism should be > 1*/
273 6748 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
274 6748 : move16();
275 6748 : *nb_bits_read = add( *nb_bits_read, 1 );
276 6748 : move16();
277 6748 : st_ivas->hMasaIsmData->idx_separated_ism = extract_l( L_add( L_shl( byteBuffer, 1 ), st->bit_stream[( st->next_bit_pos )--] ) );
278 6748 : move16();
279 6748 : *nb_bits_read = add( *nb_bits_read, 1 );
280 6748 : move16();
281 : }
282 : ELSE
283 : {
284 20217 : st_ivas->hMasaIsmData->idx_separated_ism = -1;
285 20217 : move16();
286 : }
287 :
288 : /* read ISM importance flag (one per object) */
289 26965 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
290 : {
291 6748 : ism_imp = 0;
292 6748 : move16();
293 :
294 20244 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
295 : {
296 13496 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
297 13496 : move16();
298 13496 : *nb_bits_read = add( *nb_bits_read, 1 );
299 13496 : move16();
300 13496 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
301 : }
302 6748 : st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
303 6748 : move16();
304 : }
305 :
306 26965 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
307 : {
308 8812 : ism_imp = 0;
309 8812 : move16();
310 26436 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
311 : {
312 17624 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
313 17624 : move16();
314 17624 : *nb_bits_read = add( *nb_bits_read, 1 );
315 17624 : move16();
316 17624 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
317 17624 : move16();
318 : }
319 8812 : st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
320 8812 : move16();
321 :
322 : /* reset */
323 8812 : st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0;
324 8812 : move16();
325 8812 : st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0;
326 8812 : move16();
327 :
328 8812 : IF( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
329 : {
330 : /* read flags */
331 308 : st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
332 308 : move16();
333 308 : *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS );
334 308 : move16();
335 308 : st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
336 308 : move16();
337 308 : *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS );
338 308 : move16();
339 : }
340 : }
341 18153 : ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
342 : {
343 44360 : FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ )
344 : {
345 32955 : ism_imp = 0;
346 32955 : move16();
347 98865 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
348 : {
349 65910 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
350 65910 : move16();
351 65910 : *nb_bits_read = add( *nb_bits_read, 1 );
352 65910 : move16();
353 65910 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
354 : }
355 32955 : st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp;
356 32955 : move16();
357 :
358 : /* reset */
359 32955 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
360 32955 : move16();
361 32955 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
362 32955 : move16();
363 :
364 32955 : IF( EQ_16( st_ivas->hIsmMetaData[ch]->ism_imp, ISM_NO_META ) )
365 : {
366 : /* read flags */
367 87 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
368 87 : move16();
369 87 : *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS );
370 87 : move16();
371 87 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
372 87 : move16();
373 87 : *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS );
374 87 : move16();
375 : }
376 : }
377 :
378 11405 : st_ivas->flag_omasa_brate = 0;
379 11405 : move16();
380 :
381 11405 : test();
382 11405 : IF( GE_16( st_ivas->nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) )
383 : {
384 300 : st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--];
385 300 : move16();
386 300 : *nb_bits_read = add( *nb_bits_read, 1 );
387 300 : move16();
388 : }
389 : }
390 : }
391 97574 : byteBuffer = st->bit_stream[st->next_bit_pos];
392 97574 : move16();
393 97574 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
394 97574 : byteBuffer = add( byteBuffer, shl( st->bit_stream[st->next_bit_pos], 1 ) );
395 97574 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
396 :
397 97574 : test();
398 97574 : IF( EQ_16( byteBuffer, 0 ) && EQ_32( ivas_format, MASA_FORMAT ) )
399 : {
400 70609 : hMasa->config.input_ivas_format = MASA_FORMAT;
401 70609 : move32();
402 : }
403 : ELSE
404 : {
405 26965 : hMasa->config.input_ivas_format = MASA_ISM_FORMAT;
406 26965 : move32();
407 : }
408 97574 : *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
409 :
410 : /* read number of directions */
411 97574 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
412 97574 : move16();
413 97574 : *nb_bits_read = add( *nb_bits_read, 1 );
414 97574 : move16();
415 97574 : hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
416 97574 : move16();
417 : }
418 : }
419 : ELSE
420 : {
421 11781 : hMasa->config.numberOfDirections = 1;
422 11781 : move16();
423 : }
424 :
425 116361 : test();
426 116361 : IF( NE_32( ivas_format, MC_FORMAT ) || NE_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
427 : {
428 : /* read subframe mode */
429 104580 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
430 104580 : move16();
431 104580 : *nb_bits_read = add( *nb_bits_read, 1 );
432 104580 : move16();
433 104580 : hMasa->config.joinedSubframes = (UWord8) byteBuffer;
434 104580 : move16();
435 : }
436 : ELSE
437 : {
438 11781 : hMasa->config.joinedSubframes = FALSE;
439 11781 : move16();
440 : }
441 :
442 116361 : IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
443 : {
444 11781 : *nb_bits_read = add( *nb_bits_read, decode_lfe_to_total_energy_ratio_fx( hMasa->hMasaLfeSynth, st->bit_stream, &st->next_bit_pos, ivas_total_brate ) );
445 11781 : move16();
446 : }
447 :
448 : /* Once we know incoming configuration, we can config decoder further based on bitrate etc. */
449 116361 : if ( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
450 : {
451 0 : return error;
452 : }
453 :
454 : /* If we are under metadata bit budget limit and joined subframes is not signalled, then read LBR mode. */
455 116361 : test();
456 116361 : IF( LT_32( hMasa->config.max_metadata_bits, MINIMUM_BIT_BUDGET_NORMAL_META ) && EQ_16( hMasa->config.joinedSubframes, FALSE ) )
457 : {
458 : /* read low bitrate mode */
459 33667 : byteBuffer = st->bit_stream[st->next_bit_pos];
460 33667 : move16();
461 33667 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
462 33667 : move16();
463 33667 : *nb_bits_read = add( *nb_bits_read, 1 );
464 33667 : move16();
465 33667 : low_bitrate_mode = byteBuffer;
466 33667 : move16();
467 :
468 33667 : IF( EQ_16( low_bitrate_mode, 1 ) )
469 : {
470 27817 : hQMetaData->q_direction[0].cfg.nblocks = 1;
471 27817 : move16();
472 : }
473 : ELSE
474 : {
475 5850 : hQMetaData->q_direction[0].cfg.nbands = 1;
476 5850 : move16();
477 : }
478 : }
479 :
480 : /* Remove already read bits from the bit budget */
481 116361 : hQMetaData->metadata_max_bits = sub( hQMetaData->metadata_max_bits, *nb_bits_read );
482 116361 : move16();
483 :
484 116361 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
485 : {
486 26965 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
487 : {
488 6748 : IF( st_ivas->hDirAC != NULL )
489 : {
490 5262 : *nb_bits_read = add( *nb_bits_read,
491 5262 : ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
492 5262 : st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) );
493 5262 : move16();
494 27682 : FOR( obj = 0; obj <= st_ivas->nchan_ism; obj++ )
495 : {
496 22420 : IF( EQ_16( st_ivas->hMasaIsmData->idx_separated_ism, obj ) )
497 : {
498 : Word16 sf;
499 : Word16 meta_write_index;
500 :
501 26310 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
502 : {
503 21048 : meta_write_index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, sf ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
504 21048 : st_ivas->hMasaIsmData->azimuth_separated_ism_fx[meta_write_index] = st_ivas->hMasaIsmData->azimuth_ism_fx[obj][meta_write_index];
505 21048 : move16();
506 21048 : st_ivas->hMasaIsmData->elevation_separated_ism_fx[meta_write_index] = st_ivas->hMasaIsmData->elevation_ism_fx[obj][meta_write_index];
507 21048 : move16();
508 : }
509 : }
510 : }
511 : }
512 1486 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
513 : {
514 0 : *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData,
515 0 : st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
516 0 : st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) );
517 : }
518 : ELSE
519 : {
520 1486 : *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
521 1486 : st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, 0, MAX_PARAM_SPATIAL_SUBFRAMES ) );
522 1486 : move16();
523 : }
524 : }
525 : }
526 :
527 116361 : masa_total_brate = ivas_total_brate;
528 116361 : move32();
529 116361 : test();
530 116361 : IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
531 : {
532 11405 : masa_total_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
533 : }
534 :
535 116361 : IF( GE_32( masa_total_brate, IVAS_384k ) )
536 : {
537 7033 : IF( GE_32( masa_total_brate, IVAS_512k ) )
538 : {
539 2702 : *nb_bits_read = add( *nb_bits_read,
540 2702 : ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 16, 4, hMasa->config.numCodingBands ) );
541 2702 : move16();
542 : }
543 : ELSE
544 : {
545 4331 : *nb_bits_read = add( *nb_bits_read,
546 4331 : ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 11, 3, hMasa->config.numCodingBands ) );
547 4331 : move16();
548 : }
549 : }
550 : ELSE
551 : {
552 109328 : *nb_bits_read = add( *nb_bits_read,
553 109328 : ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos, 0 ) );
554 109328 : move16();
555 : }
556 :
557 116361 : test();
558 116361 : test();
559 116361 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
560 : {
561 : /* Modify spatial metadata based on the MASA-to-total energy ratios */
562 6748 : ivas_omasa_modify_masa_energy_ratios_fx( hQMetaData, st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx );
563 : }
564 :
565 : /* Get direction decoding quality. EC 1 and 2 are handled by the default value. */
566 116361 : if ( EQ_16( hQMetaData->ec_flag, 2 ) )
567 : {
568 7550 : hMasa->data.dir_decode_quality_fx = hQMetaData->dir_comp_ratio_fx; /* Q15 */
569 7550 : move16();
570 : }
571 :
572 116361 : hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero;
573 116361 : move16();
574 :
575 116361 : test();
576 116361 : test();
577 116361 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) ) )
578 : {
579 17997 : index_16bits_fx( hQMetaData, hMasa->data.sph_grid16 );
580 : }
581 :
582 : /* If LBR mode is not disabled, then we restore metadata to 5 bands and 4 subframes based on the LBR mode. */
583 116361 : IF( NE_16( low_bitrate_mode, -1 ) )
584 : {
585 33667 : restore_lowbitrate_masa_fx( hQMetaData, low_bitrate_mode, hMasa->config.numCodingBands );
586 : }
587 82694 : ELSE IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
588 : {
589 47756 : replicate_subframes_fx( hQMetaData );
590 : }
591 : }
592 3133 : ELSE IF( st->bfi == 0 && EQ_32( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
593 : {
594 194 : IF( hQMetaData->q_direction == NULL )
595 : {
596 : /* replicate ivas_masa_dec_config() in case that first good received frame is SID frame */
597 0 : if ( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
598 : {
599 0 : return error;
600 : }
601 :
602 0 : ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, 0 );
603 :
604 0 : hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
605 0 : move16();
606 :
607 0 : if ( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( hQMetaData, 5, 1, 0 ) ), IVAS_ERR_OK ) )
608 : {
609 0 : return error;
610 : }
611 :
612 0 : hQMetaData->numTwoDirBands = hMasa->config.numTwoDirBands;
613 0 : move16();
614 0 : hQMetaData->useLowerRes = 0;
615 0 : move16();
616 :
617 0 : hQMetaData->q_direction->cfg.nbands = 5;
618 0 : move16();
619 0 : hQMetaData->q_direction->cfg.nblocks = 4;
620 0 : move16();
621 :
622 0 : test();
623 0 : IF( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
624 : {
625 0 : hQMetaData->q_direction->cfg.mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config );
626 : }
627 : ELSE
628 : {
629 0 : hQMetaData->q_direction->cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
630 : }
631 0 : move16();
632 : }
633 :
634 194 : tmp_elem_mode = -1;
635 194 : move16();
636 :
637 194 : *nb_bits_read = add( *nb_bits_read,
638 194 : ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), st_ivas->nchan_transport, &tmp_elem_mode, ivas_format ) );
639 194 : move16();
640 :
641 194 : IF( EQ_16( st_ivas->nchan_transport, 2 ) )
642 : {
643 74 : assert( st_ivas->nCPE > 0 );
644 74 : st_ivas->hCPE[0]->element_mode = tmp_elem_mode;
645 74 : move16();
646 : }
647 194 : *nb_bits_read = add( *nb_bits_read, SID_FORMAT_NBITS );
648 194 : move16();
649 : }
650 2939 : ELSE IF( st->bfi == 0 && EQ_32( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, FRAME_NO_DATA ) )
651 : {
652 1220 : IF( hQMetaData->q_direction == NULL )
653 : {
654 0 : IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK )
655 : {
656 0 : return error;
657 : }
658 : }
659 : }
660 :
661 119494 : IF( st_ivas->hDirAC != NULL )
662 : {
663 91043 : dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
664 91043 : move16();
665 :
666 91043 : ivas_qmetadata_to_dirac_fx( hQMetaData, st_ivas->hDirAC, hMasa, st_ivas->hSpatParamRendCom, ivas_total_brate, ivas_format, 0, 0 );
667 : }
668 28451 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
669 : {
670 0 : Word16 index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, MAX_PARAM_SPATIAL_SUBFRAMES );
671 0 : IF( GE_16( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) )
672 : {
673 0 : index = sub( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length );
674 : }
675 :
676 0 : st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx = index;
677 0 : move16();
678 : }
679 :
680 119494 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
681 : {
682 27489 : IF( hQMetaData->q_direction == NULL )
683 : {
684 0 : IF( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
685 : {
686 0 : return error;
687 : }
688 : }
689 :
690 27489 : IF( st_ivas->hDirAC != NULL )
691 : {
692 : Word16 b;
693 : Word16 block;
694 : Word16 meta_write_index;
695 :
696 37368 : FOR( i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ )
697 : {
698 86980 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
699 : {
700 69584 : meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
701 :
702 3977904 : FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
703 : {
704 7816640 : st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b],
705 3908320 : st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][meta_write_index][b] ); // Q30
706 3908320 : move32();
707 : }
708 : }
709 : }
710 :
711 99860 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
712 : {
713 79888 : meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
714 :
715 4453488 : FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
716 : {
717 4373600 : st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_max( 0, st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] ); // Q30
718 4373600 : move32();
719 : }
720 : }
721 : }
722 : }
723 :
724 119494 : st->next_bit_pos = next_bit_pos_orig;
725 119494 : move16();
726 :
727 119494 : IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) )
728 : {
729 : Word32 cpe_brate;
730 27489 : cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
731 :
732 27489 : test();
733 27489 : test();
734 27489 : IF( EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
735 : {
736 12837 : IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
737 : {
738 5299 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
739 5299 : move16();
740 : }
741 : ELSE
742 : {
743 7538 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
744 7538 : move16();
745 : }
746 :
747 12837 : if ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
748 : {
749 0 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
750 0 : move32();
751 : }
752 : }
753 : }
754 : ELSE
755 : {
756 92005 : test();
757 92005 : test();
758 92005 : test();
759 92005 : IF( EQ_32( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
760 : {
761 21079 : IF( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
762 : {
763 9471 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
764 9471 : move16();
765 : }
766 : ELSE
767 : {
768 11608 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
769 11608 : move16();
770 : }
771 :
772 21079 : if ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
773 : {
774 528 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
775 528 : move16();
776 : }
777 : }
778 : }
779 :
780 119494 : test();
781 119494 : IF( EQ_32( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) )
782 : {
783 49965 : st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0;
784 49965 : move16();
785 :
786 49965 : IF( LE_32( st_ivas->hDecoderConfig->last_ivas_total_brate, IVAS_SID_5k2 ) )
787 : {
788 528 : st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1;
789 528 : move16();
790 :
791 528 : if ( GE_32( ivas_total_brate, IVAS_SID_5k2 ) )
792 : {
793 74 : st_ivas->hCPE[0]->element_brate = ivas_total_brate;
794 74 : move32();
795 : }
796 : }
797 : }
798 :
799 119494 : test();
800 119494 : test();
801 119494 : IF( ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
802 : {
803 18460 : create_masa_ext_out_meta_fx( hMasa, hQMetaData, st_ivas->nchan_transport );
804 : }
805 :
806 119494 : return error /* *nb_bits_read*/;
807 : }
808 :
809 :
810 : /*-------------------------------------------------------------------*
811 : * ivas_masa_dec_open()
812 : *
813 : *
814 : *-------------------------------------------------------------------*/
815 :
816 453 : ivas_error ivas_masa_dec_open_fx(
817 : Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
818 : )
819 : {
820 : MASA_DECODER_HANDLE hMasa;
821 : ivas_error error;
822 : Word16 i;
823 : Word32 ism_total_brate;
824 :
825 453 : error = IVAS_ERR_OK;
826 453 : move16();
827 :
828 453 : IF( ( hMasa = (MASA_DECODER_HANDLE) malloc( sizeof( MASA_DECODER ) ) ) == NULL )
829 : {
830 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
831 : }
832 :
833 453 : ism_total_brate = 0;
834 453 : move32();
835 :
836 : /* ISM metadata */
837 :
838 453 : test();
839 453 : IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->hIsmMetaData[0] != NULL )
840 : {
841 : /* these are not needed -> clean. EXT metafile writer in OMASA needs only the number of ISMs and writes default null-data */
842 0 : ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
843 : }
844 :
845 453 : test();
846 453 : test();
847 453 : test();
848 453 : test();
849 453 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && GT_16( st_ivas->nSCE, 0 ) && ( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
850 : {
851 98 : FOR( i = 0; i < st_ivas->nSCE; i++ )
852 : {
853 65 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
854 : }
855 : }
856 :
857 453 : ivas_masa_set_elements_fx( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
858 :
859 453 : Copy( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
860 453 : Copy( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 );
861 453 : hMasa->config.numberOfDirections = 1;
862 453 : move16();
863 453 : hMasa->config.joinedSubframes = FALSE;
864 453 : move16();
865 :
866 : /* Create spherical grid only for external output */
867 453 : test();
868 453 : test();
869 453 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) )
870 : {
871 20 : IF( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
872 : {
873 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
874 : }
875 :
876 20 : generate_gridEq_fx( hMasa->data.sph_grid16 );
877 :
878 20 : IF( ( hMasa->data.extOutMeta = (MASA_DECODER_EXT_OUT_META *) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
879 : {
880 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
881 : }
882 : }
883 : ELSE
884 : {
885 433 : hMasa->data.sph_grid16 = NULL;
886 433 : hMasa->data.extOutMeta = NULL;
887 : }
888 :
889 453 : IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
890 : {
891 337 : error = init_lfe_synth_data_fx( st_ivas, hMasa );
892 : }
893 : ELSE
894 : {
895 116 : hMasa->hMasaLfeSynth = NULL;
896 : }
897 :
898 453 : st_ivas->hMasa = hMasa;
899 :
900 : /* allocate transport channels*/
901 453 : test();
902 453 : test();
903 453 : test();
904 453 : test();
905 453 : IF( st_ivas->hTcBuffer == NULL && NE_16( st_ivas->renderer_type, RENDERER_DISABLE ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
906 : {
907 : Word16 nchan_to_allocate, nchan_transport;
908 : Word16 granularity;
909 : TC_BUFFER_MODE buffer_mode;
910 :
911 50 : buffer_mode = TC_BUFFER_MODE_RENDERER;
912 50 : move16();
913 50 : test();
914 50 : test();
915 50 : test();
916 50 : IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) ) )
917 : {
918 3 : buffer_mode = TC_BUFFER_MODE_BUFFER;
919 3 : move16();
920 : }
921 47 : ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
922 : {
923 5 : buffer_mode = TC_BUFFER_MODE_BUFFER;
924 5 : move16();
925 : }
926 :
927 50 : nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
928 50 : nchan_to_allocate = nchan_transport;
929 50 : move16();
930 :
931 50 : test();
932 50 : test();
933 50 : test();
934 50 : test();
935 50 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
936 : {
937 5 : nchan_transport = 1;
938 5 : move16();
939 5 : nchan_to_allocate = 1;
940 5 : move16();
941 : }
942 45 : ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) || EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) ) )
943 : {
944 0 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
945 0 : nchan_to_allocate = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
946 : }
947 45 : ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
948 : {
949 : /* addtl channel for CNG */
950 13 : nchan_to_allocate = add( nchan_to_allocate, 1 );
951 : }
952 :
953 50 : granularity = ivas_jbm_dec_get_render_granularity_fx( st_ivas->renderer_type, RENDERER_DISABLE, st_ivas->hDecoderConfig->output_Fs );
954 :
955 50 : IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, granularity ) ) != IVAS_ERR_OK )
956 : {
957 0 : return error;
958 : }
959 : }
960 :
961 453 : return error;
962 : }
963 :
964 :
965 : /*-----------------------------------------------------------------------*
966 : * ivas_masa_dec_close()
967 : *
968 : * close MASA decoder
969 : *-----------------------------------------------------------------------*/
970 :
971 1716 : void ivas_masa_dec_close_fx(
972 : MASA_DECODER_HANDLE *hMasa_out /* i/o: MASA metadata structure */
973 : )
974 : {
975 : MASA_DECODER_HANDLE hMasa;
976 :
977 1716 : test();
978 1716 : IF( hMasa_out == NULL || *hMasa_out == NULL )
979 : {
980 1263 : return;
981 : }
982 :
983 453 : hMasa = *hMasa_out;
984 :
985 : /* Free spherical grid memory if in use */
986 453 : IF( hMasa->data.sph_grid16 != NULL )
987 : {
988 44 : free( hMasa->data.sph_grid16 );
989 44 : hMasa->data.sph_grid16 = NULL;
990 : }
991 :
992 453 : IF( hMasa->data.extOutMeta != NULL )
993 : {
994 20 : free( hMasa->data.extOutMeta );
995 20 : hMasa->data.extOutMeta = NULL;
996 : }
997 :
998 453 : IF( hMasa->hMasaLfeSynth != NULL )
999 : {
1000 337 : IF( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx != NULL )
1001 : {
1002 13 : free( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx );
1003 13 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
1004 : }
1005 337 : IF( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx != NULL )
1006 : {
1007 13 : free( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx );
1008 13 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
1009 : }
1010 337 : IF( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx != NULL )
1011 : {
1012 13 : free( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx );
1013 13 : hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
1014 : }
1015 337 : IF( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx != NULL )
1016 : {
1017 13 : free( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx );
1018 13 : hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = NULL;
1019 : }
1020 337 : free( hMasa->hMasaLfeSynth );
1021 337 : hMasa->hMasaLfeSynth = NULL;
1022 : }
1023 :
1024 453 : free( *hMasa_out );
1025 453 : *hMasa_out = NULL;
1026 :
1027 453 : return;
1028 : }
1029 :
1030 :
1031 : /*-------------------------------------------------------------------*
1032 : * ivas_masa_dec_config()
1033 : *
1034 : * Frame-by-frame configuration of MASA decoder
1035 : *-------------------------------------------------------------------*/
1036 :
1037 116361 : static ivas_error ivas_masa_dec_config_fx(
1038 : Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
1039 : )
1040 : {
1041 : Word16 i;
1042 : MASA_DECODER_HANDLE hMasa;
1043 : UWord8 maxBand;
1044 : Word16 maxBin;
1045 : ivas_error error;
1046 : Word32 ivas_total_brate;
1047 : Word32 ism_total_brate;
1048 116361 : error = IVAS_ERR_OK;
1049 116361 : move32();
1050 116361 : hMasa = st_ivas->hMasa;
1051 :
1052 116361 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
1053 116361 : move32();
1054 116361 : ism_total_brate = 0;
1055 116361 : move32();
1056 :
1057 116361 : test();
1058 116361 : test();
1059 116361 : test();
1060 116361 : test();
1061 116361 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && st_ivas->nSCE > 0 && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
1062 : {
1063 75480 : FOR( i = 0; i < st_ivas->nSCE; i++ )
1064 : {
1065 48515 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
1066 : }
1067 : }
1068 :
1069 116361 : ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
1070 :
1071 116361 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
1072 : {
1073 26965 : ivas_masa_set_coding_config_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hCPE[0]->element_brate, st_ivas->nchan_transport, MC_MODE_NONE );
1074 : }
1075 : ELSE
1076 : {
1077 89396 : ivas_masa_set_coding_config_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) );
1078 : }
1079 :
1080 116361 : test();
1081 116361 : test();
1082 116361 : IF( ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_512k ) )
1083 : {
1084 3354 : hMasa->config.mergeRatiosOverSubframes = 0;
1085 3354 : move16();
1086 :
1087 : /* initialize spherical grid */
1088 3354 : IF( hMasa->data.sph_grid16 == NULL )
1089 : {
1090 24 : IF( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
1091 : {
1092 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA data handle\n" ) );
1093 : }
1094 24 : generate_gridEq_fx( hMasa->data.sph_grid16 );
1095 : }
1096 : }
1097 116361 : st_ivas->hQMetaData->metadata_max_bits = hMasa->config.max_metadata_bits;
1098 116361 : move16();
1099 116361 : st_ivas->hQMetaData->bandMap = hMasa->data.band_mapping;
1100 116361 : move16();
1101 116361 : st_ivas->hQMetaData->nchan_transport = st_ivas->nchan_transport;
1102 116361 : move16();
1103 :
1104 116361 : IF( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( st_ivas->hQMetaData, hMasa->config.numCodingBands, hMasa->config.numberOfDirections, hMasa->config.useCoherence ) ), IVAS_ERR_OK ) )
1105 : {
1106 0 : return error;
1107 : }
1108 :
1109 116361 : st_ivas->hQMetaData->numTwoDirBands = st_ivas->hMasa->config.numTwoDirBands;
1110 116361 : move16();
1111 116361 : st_ivas->hQMetaData->useLowerRes = 0;
1112 116361 : move16();
1113 :
1114 249471 : FOR( i = 0; i < st_ivas->hQMetaData->no_directions; i++ )
1115 : {
1116 133110 : st_ivas->hQMetaData->q_direction[i].cfg.nbands = hMasa->config.numCodingBands;
1117 133110 : move16();
1118 133110 : IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
1119 : {
1120 54269 : st_ivas->hQMetaData->q_direction[i].cfg.nblocks = 1;
1121 : }
1122 : ELSE
1123 : {
1124 78841 : st_ivas->hQMetaData->q_direction[i].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
1125 : }
1126 133110 : move16();
1127 :
1128 133110 : test();
1129 133110 : IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
1130 : {
1131 11781 : st_ivas->hQMetaData->q_direction[i].cfg.mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config );
1132 11781 : move32();
1133 : }
1134 : ELSE
1135 : {
1136 121329 : st_ivas->hQMetaData->q_direction[i].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
1137 121329 : move32();
1138 : }
1139 : }
1140 :
1141 116361 : ivas_set_qmetadata_maxbit_req_fx( st_ivas->hQMetaData, st_ivas->ivas_format );
1142 :
1143 : /* Find maximum band usable */
1144 116361 : maxBin = extract_l( Mpy_32_32( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) );
1145 116361 : maxBand = 0;
1146 116361 : move16();
1147 2998016 : WHILE( LE_16( maxBand, MASA_FREQUENCY_BANDS ) && LE_16( MASA_band_grouping_24[maxBand], maxBin ) )
1148 : {
1149 2881655 : maxBand = (UWord8) add( maxBand, 1 );
1150 : }
1151 116361 : maxBand = (UWord8) sub( maxBand, 1 );
1152 :
1153 116361 : IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
1154 : {
1155 : /* need to apply the sampling rate correction also for the EXT output MASA meta buffer */
1156 18237 : masa_sample_rate_band_correction_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hQMetaData, maxBand, 0, hMasa->data.extOutMeta );
1157 : }
1158 : ELSE
1159 : {
1160 98124 : masa_sample_rate_band_correction_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hQMetaData, maxBand, 0, NULL );
1161 : }
1162 :
1163 116361 : return error;
1164 : }
1165 :
1166 :
1167 : /*-------------------------------------------------------------------*
1168 : * ivas_masa_prerender_fx()
1169 : *
1170 : * Apply gaining and copying of transport signals when needed
1171 : *-------------------------------------------------------------------*/
1172 :
1173 80130 : void ivas_masa_prerender_fx(
1174 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1175 : Word32 *output_fx[], /* i/o: synthesized core-coder transport channels */
1176 : Word16 *q_shift, /* o : specifies how much the Q-factor of output has changed by. */
1177 : const Word16 output_frame, /* i : output frame length per channel */
1178 : const Word16 nchan_remapped /* i : number of transports used in core */
1179 : )
1180 : {
1181 80130 : *q_shift = 0;
1182 80130 : move16();
1183 :
1184 80130 : test();
1185 80130 : test();
1186 80130 : IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nchan_transport, 2 ) && EQ_16( nchan_remapped, 1 ) )
1187 : {
1188 10008 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
1189 : {
1190 533 : Copy32( output_fx[0], output_fx[1], output_frame ); /* Copy mono signal to stereo output channels */
1191 : }
1192 : ELSE
1193 : {
1194 9475 : test();
1195 9475 : IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
1196 : {
1197 5722 : v_multc_fx( output_fx[0], SQRT2_FX, output_fx[0], output_frame ); /* q + 30 - 31 = q - 1*/ /* Gain transport signal when transmitting mono with cpe in order to match loudness */
1198 5722 : *q_shift = -1; /* Q has decreased by 1. */
1199 5722 : move16();
1200 : }
1201 : }
1202 : }
1203 :
1204 80130 : return;
1205 : }
1206 :
1207 :
1208 : /*-------------------------------------------------------------------*
1209 : * Local functions
1210 : *-------------------------------------------------------------------*/
1211 :
1212 17997 : static void index_16bits_fx(
1213 : IVAS_QMETADATA_HANDLE hQMetaData,
1214 : SPHERICAL_GRID_DATA *Sph_Grid16 )
1215 : {
1216 : Word16 d, band, block;
1217 :
1218 40072 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
1219 : {
1220 : /* Note: The band information is read from the first direction as it contains the full information. */
1221 287476 : FOR( band = 0; band < hQMetaData->q_direction[0].cfg.nbands; band++ )
1222 : {
1223 863817 : FOR( block = 0; block < hQMetaData->q_direction[0].cfg.nblocks; block++ )
1224 : {
1225 1196832 : hQMetaData->q_direction[d].band_data[band].spherical_index[block] = index_theta_phi_16_fx( &( hQMetaData->q_direction[d].band_data[band].elevation_fx[block] ),
1226 598416 : &( hQMetaData->q_direction[d].band_data[band].azimuth_fx[block] ), Sph_Grid16 );
1227 598416 : move16();
1228 : }
1229 : }
1230 : }
1231 :
1232 17997 : return;
1233 : }
1234 :
1235 :
1236 : /* Replicate subframe data when there is only one subframe sent */
1237 47756 : static void replicate_subframes_fx(
1238 : IVAS_QMETADATA_HANDLE hQMetaData )
1239 : {
1240 : Word16 sf, band, dir, nbands, ndirs;
1241 :
1242 47756 : nbands = hQMetaData->q_direction->cfg.nbands;
1243 47756 : move16();
1244 47756 : ndirs = hQMetaData->no_directions;
1245 47756 : move16();
1246 :
1247 191024 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1248 : {
1249 1907451 : FOR( band = 0; band < nbands; band++ )
1250 : {
1251 3845112 : FOR( dir = 0; dir < ndirs; dir++ )
1252 : {
1253 2080929 : hQMetaData->q_direction[dir].band_data[band].spherical_index[sf] = hQMetaData->q_direction[dir].band_data[band].spherical_index[0];
1254 2080929 : move16();
1255 2080929 : hQMetaData->q_direction[dir].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[dir].band_data[band].azimuth_fx[0]; // Q22
1256 2080929 : move32();
1257 2080929 : hQMetaData->q_direction[dir].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[dir].band_data[band].elevation_fx[0]; // Q22
1258 2080929 : move32();
1259 2080929 : hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[0]; // Q30
1260 2080929 : move32();
1261 :
1262 2080929 : if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
1263 : {
1264 1699128 : hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[0];
1265 1699128 : move16();
1266 : }
1267 : }
1268 :
1269 1764183 : if ( hQMetaData->surcoh_band_data != NULL )
1270 : {
1271 1382382 : hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0];
1272 1382382 : move16();
1273 : }
1274 : }
1275 : }
1276 :
1277 47756 : return;
1278 : }
1279 :
1280 :
1281 33667 : static void restore_lowbitrate_masa_fx(
1282 : IVAS_QMETADATA_HANDLE hQMetaData,
1283 : const Word16 low_bitrate_mode,
1284 : const Word16 numCodingBands )
1285 : {
1286 : Word16 sf, band;
1287 :
1288 33667 : IF( EQ_16( low_bitrate_mode, 1 ) )
1289 : {
1290 : /* With signal 1, we are in 5 frequency bands, 1 subframe mode. */
1291 : /* Replicate data to all subframes */
1292 111268 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1293 : {
1294 500706 : FOR( band = 0; band < numCodingBands; band++ )
1295 : {
1296 :
1297 417255 : hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[band].spherical_index[0];
1298 417255 : move16();
1299 417255 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[band].azimuth_fx[0]; // Q22
1300 417255 : move32();
1301 417255 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[band].elevation_fx[0]; // Q22
1302 417255 : move32();
1303 417255 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; // Q30
1304 417255 : move32();
1305 :
1306 417255 : if ( hQMetaData->q_direction[0].coherence_band_data != NULL )
1307 : {
1308 81555 : hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[0];
1309 81555 : move16();
1310 : }
1311 417255 : if ( hQMetaData->surcoh_band_data != NULL )
1312 : {
1313 81555 : hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0];
1314 81555 : move16();
1315 : }
1316 : }
1317 : }
1318 27817 : hQMetaData->q_direction->cfg.nblocks = 4;
1319 27817 : move16();
1320 : }
1321 : ELSE
1322 : {
1323 : /* With signal 0, we are in 1 frequency bands, 4 subframes mode. */
1324 : /* Replicate data to all bands */
1325 29250 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1326 : {
1327 117000 : FOR( band = 1; band < numCodingBands; band++ )
1328 : {
1329 93600 : hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[0].spherical_index[sf];
1330 93600 : move16();
1331 93600 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[sf]; // Q22
1332 93600 : move32();
1333 93600 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[0].elevation_fx[sf]; // Q22
1334 93600 : move32();
1335 93600 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[sf]; // Q30
1336 93600 : move32();
1337 :
1338 93600 : if ( hQMetaData->q_direction[0].coherence_band_data != NULL )
1339 : {
1340 22320 : hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[0].spread_coherence[sf];
1341 22320 : move16();
1342 : }
1343 93600 : if ( hQMetaData->surcoh_band_data != NULL )
1344 : {
1345 22320 : hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[0].surround_coherence[sf];
1346 22320 : move16();
1347 : }
1348 : }
1349 : }
1350 5850 : hQMetaData->q_direction->cfg.nbands = numCodingBands;
1351 5850 : move16();
1352 : }
1353 :
1354 33667 : return;
1355 : }
1356 :
1357 :
1358 337 : static ivas_error init_lfe_synth_data_fx(
1359 : Decoder_Struct *st_ivas, /* i : IVAS decoder struct */
1360 : MASA_DECODER_HANDLE hMasa /* i/o: MASA decoder structure */
1361 : )
1362 : {
1363 : Word32 output_Fs;
1364 : AUDIO_CONFIG output_config;
1365 :
1366 337 : output_Fs = st_ivas->hDecoderConfig->output_Fs;
1367 337 : move16();
1368 337 : output_config = st_ivas->hDecoderConfig->output_config;
1369 337 : move32();
1370 :
1371 337 : IF( ( hMasa->hMasaLfeSynth = (MCMASA_LFE_SYNTH_DATA_HANDLE) malloc( sizeof( MCMASA_LFE_SYNTH_DATA ) ) ) == NULL )
1372 : {
1373 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1374 : }
1375 :
1376 337 : hMasa->hMasaLfeSynth->transportEneSmooth_fx = 0;
1377 337 : move32();
1378 337 : hMasa->hMasaLfeSynth->transportEneSmooth_q = Q31;
1379 337 : move16();
1380 337 : hMasa->hMasaLfeSynth->protoLfeEneSmooth_fx = 0;
1381 337 : move32();
1382 337 : hMasa->hMasaLfeSynth->protoLfeEneSmooth_q = Q31;
1383 337 : move16();
1384 337 : hMasa->hMasaLfeSynth->targetEneLfeSmooth_fx = 0;
1385 337 : move32();
1386 337 : hMasa->hMasaLfeSynth->targetEneLfeSmooth_q = Q31;
1387 337 : move16();
1388 337 : hMasa->hMasaLfeSynth->targetEneTransSmooth_fx = 0;
1389 337 : move32();
1390 337 : hMasa->hMasaLfeSynth->targetEneTransSmooth_q = Q31;
1391 337 : move16();
1392 :
1393 337 : set16_fx( hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
1394 337 : hMasa->hMasaLfeSynth->lfeGainPrevIndex = 0;
1395 337 : move16();
1396 :
1397 337 : test();
1398 337 : test();
1399 337 : test();
1400 337 : test();
1401 337 : test();
1402 337 : test();
1403 337 : test();
1404 337 : test();
1405 337 : test();
1406 337 : test();
1407 337 : test();
1408 337 : test();
1409 337 : IF( st_ivas->hOutSetup.separateChannelEnabled &&
1410 : ( EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
1411 : EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) ||
1412 : EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
1413 : EQ_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ||
1414 : EQ_16( output_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_HOA2 ) ||
1415 : EQ_16( output_config, IVAS_AUDIO_CONFIG_HOA3 ) ||
1416 : ( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && ( st_ivas->hOutSetup.num_lfe > 0 ) ) ) )
1417 13 : {
1418 : Word16 bufferSize;
1419 : Word16 i;
1420 : Word16 slot_size;
1421 :
1422 : /* Ring buffer for the filterbank of the LFE synthesis.
1423 : * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */
1424 : /* bufferSize = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES ); */
1425 13 : bufferSize = extract_l( Mpy_32_32_r( output_Fs, 10737418 /* 1 / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) in Q31 */ ) );
1426 :
1427 13 : IF( ( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
1428 : {
1429 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1430 : }
1431 13 : set32_fx( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx, 0, bufferSize ); // Q11
1432 :
1433 13 : hMasa->hMasaLfeSynth->ringBufferLoPointer = 0;
1434 13 : move16();
1435 13 : hMasa->hMasaLfeSynth->ringBufferHiPointer = shr( bufferSize, 1 );
1436 13 : move16();
1437 13 : hMasa->hMasaLfeSynth->lowpassSum_fx = 0; // Q11
1438 13 : move16();
1439 13 : hMasa->hMasaLfeSynth->ringBufferSize = bufferSize;
1440 13 : move16();
1441 :
1442 : /* Ring buffer for additional lowpass filter for the LFE signal.
1443 : * Moving average lowpass filter with the crossover of 240 Hz. */
1444 13 : bufferSize = shr( bufferSize, 1 );
1445 :
1446 13 : IF( ( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
1447 : {
1448 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1449 : }
1450 13 : set32_fx( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx, 0, bufferSize ); // Q11
1451 :
1452 13 : hMasa->hMasaLfeSynth->ringBufferLoPointer2 = 0;
1453 13 : move16();
1454 13 : hMasa->hMasaLfeSynth->lowpassSum2_fx = 0; // Q11
1455 13 : move32();
1456 13 : hMasa->hMasaLfeSynth->ringBufferSize2 = bufferSize;
1457 13 : move16();
1458 :
1459 : /* Delay buffer for matching the delay of the lowpass filter */
1460 13 : bufferSize = shr( bufferSize, 1 ); /* The delay of the moving average lowpass filter is bufferSize / 2 */
1461 13 : IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
1462 : {
1463 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1464 : }
1465 13 : set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx, 0, bufferSize ); // Q11
1466 13 : hMasa->hMasaLfeSynth->delayBuffer_syncLp_size = bufferSize;
1467 13 : move16();
1468 :
1469 : /* Delay buffer for syncing with DirAC rendering */
1470 13 : bufferSize = sub( sub( NS2SA_FX2( output_Fs, IVAS_FB_DEC_DELAY_NS ), shr( hMasa->hMasaLfeSynth->ringBufferSize, 1 ) ), shr( hMasa->hMasaLfeSynth->ringBufferSize2, 1 ) );
1471 13 : IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
1472 : {
1473 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1474 : }
1475 13 : set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, 0, bufferSize ); // Q11
1476 13 : hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size = bufferSize;
1477 13 : move16();
1478 :
1479 : /* Interpolation between slots */
1480 13 : hMasa->hMasaLfeSynth->lfeGainPrev_fx = 0; // Q15
1481 13 : move16();
1482 13 : hMasa->hMasaLfeSynth->transportGainPrev_fx = MAX_WORD16; // Q15
1483 13 : move16();
1484 :
1485 : /* slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); */
1486 13 : slot_size = extract_l( Mpy_32_32( output_Fs, 2684355 /* 1 / ( FRAMES_PER_SEC * CLDFB_NO_COL_MAX ) in Q31*/ ) );
1487 :
1488 753 : FOR( i = 0; i < slot_size; i++ )
1489 : {
1490 740 : hMasa->hMasaLfeSynth->interpolator_fx[i] = div_s( add( i, 1 ), slot_size ); // Q15
1491 740 : move16();
1492 : }
1493 : }
1494 324 : ELSE IF( st_ivas->hOutSetup.separateChannelEnabled && EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && EQ_16( st_ivas->hOutSetup.num_lfe, 0 ) )
1495 0 : {
1496 : Word16 bufferSize;
1497 :
1498 : /* Delay buffer for syncing with DirAC rendering */
1499 0 : bufferSize = NS2SA_FX2( output_Fs, IVAS_FB_DEC_DELAY_NS );
1500 0 : IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
1501 : {
1502 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
1503 : }
1504 0 : set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, 0, bufferSize ); // Q11
1505 0 : hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size = bufferSize;
1506 0 : move16();
1507 :
1508 0 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
1509 0 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
1510 0 : hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
1511 : }
1512 : ELSE
1513 : {
1514 324 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
1515 324 : hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
1516 324 : hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
1517 324 : hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = NULL;
1518 : }
1519 :
1520 337 : return IVAS_ERR_OK;
1521 : }
1522 :
1523 :
1524 : /*! r: Number of bits read */
1525 11781 : static Word16 decode_lfe_to_total_energy_ratio_fx(
1526 : MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: McMASA LFE structure */
1527 : UWord16 *bitstream, /* i : bitstream */
1528 : Word16 *index, /* i/o: bitstream position */
1529 : const Word32 ivas_total_brate /* i : total bitrate */
1530 : )
1531 : {
1532 : Word16 i;
1533 : Word16 lfeToTotalEnergyRatioIndices[3];
1534 : Word16 VQBits;
1535 : Word16 log2LFEaverage_fx;
1536 : Word16 lfeToTotalEnergyRatioTemp_fx;
1537 : UWord16 byteBuffer;
1538 : Word16 lfeBitsRead;
1539 :
1540 11781 : lfeBitsRead = 0;
1541 11781 : move16();
1542 11781 : byteBuffer = bitstream[( *index )--];
1543 11781 : move16();
1544 11781 : lfeBitsRead = add( lfeBitsRead, 1 );
1545 11781 : lfeToTotalEnergyRatioIndices[0] = byteBuffer; /* First LFE index */
1546 11781 : move16();
1547 :
1548 11781 : IF( EQ_32( ivas_total_brate, IVAS_13k2 ) ) /* 1-bit adaptive LFE gain quantizer at 13.2 kbps */
1549 : {
1550 1420 : lfeToTotalEnergyRatioTemp_fx = hMasaLfeSynth->lfeToTotalEnergyRatio_fx[3]; // Q14 /* Take memory from the last subframe */
1551 1420 : move16();
1552 1420 : IF( EQ_16( lfeToTotalEnergyRatioIndices[0], 1 ) )
1553 : {
1554 142 : IF( EQ_16( hMasaLfeSynth->lfeGainPrevIndex, 1 ) )
1555 : {
1556 97 : Word16 lfe_beta_theta = mult( MCMASA_LFE_THETA_Q14, MCMASA_LFE_BETA_Q15 ); // Q 14 + 15 - 15 = Q14
1557 97 : lfeToTotalEnergyRatioTemp_fx = add( lfeToTotalEnergyRatioTemp_fx, lfe_beta_theta ); /* larger "bump-up" energy */
1558 : }
1559 : ELSE
1560 : {
1561 45 : lfeToTotalEnergyRatioTemp_fx = add( lfeToTotalEnergyRatioTemp_fx, MCMASA_LFE_BETA_Q14 ); /* "bump-up" energy */
1562 : }
1563 : }
1564 : ELSE
1565 : {
1566 1278 : lfeToTotalEnergyRatioTemp_fx = mult( lfeToTotalEnergyRatioTemp_fx, MCMASA_LFE_ALPHA_Q15 ); // Q14
1567 : }
1568 1420 : if ( GT_16( lfeToTotalEnergyRatioTemp_fx, ONE_IN_Q14 ) )
1569 : {
1570 0 : lfeToTotalEnergyRatioTemp_fx = ONE_IN_Q14;
1571 0 : move16();
1572 : }
1573 1420 : hMasaLfeSynth->lfeGainPrevIndex = lfeToTotalEnergyRatioIndices[0];
1574 1420 : move16();
1575 7100 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
1576 : {
1577 5680 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = lfeToTotalEnergyRatioTemp_fx; /* will always be less than 16384 */
1578 5680 : move16();
1579 : }
1580 : }
1581 : ELSE /* Bitrates >= 16.4 kbps */
1582 : {
1583 10361 : IF( EQ_16( lfeToTotalEnergyRatioIndices[0], 0 ) )
1584 : {
1585 43330 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
1586 : {
1587 34664 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = 0;
1588 34664 : move16();
1589 : }
1590 : }
1591 : ELSE
1592 : {
1593 1695 : byteBuffer = (UWord16) L_shl( bitstream[( *index )--], 2 );
1594 1695 : byteBuffer = (UWord16) L_add( byteBuffer, L_shl( bitstream[( *index )--], 1 ) );
1595 1695 : byteBuffer = (UWord16) L_add( byteBuffer, bitstream[( *index )--] );
1596 1695 : move16();
1597 1695 : move16();
1598 1695 : move16();
1599 1695 : lfeBitsRead = add( lfeBitsRead, 3 );
1600 1695 : lfeToTotalEnergyRatioIndices[1] = byteBuffer; /* Scalar index */
1601 1695 : move16();
1602 1695 : log2LFEaverage_fx = usdequant_fx( lfeToTotalEnergyRatioIndices[1], MCMASA_LFE_QLOW_Q12, MCMASA_LFE_DELTA_Q11 ); // Q12
1603 :
1604 : /* 16.4 kbps sends only scalar gain, above it VQ is used */
1605 1695 : IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
1606 : {
1607 : /* Depending on average (scalar) gain more bits are sent for VQ LFE gain */
1608 1590 : SWITCH( lfeToTotalEnergyRatioIndices[1] )
1609 : {
1610 215 : case 0:
1611 : case 1:
1612 215 : VQBits = 0;
1613 215 : move16();
1614 215 : BREAK;
1615 98 : case 2:
1616 98 : VQBits = 1;
1617 98 : move16();
1618 98 : BREAK;
1619 97 : case 3:
1620 97 : VQBits = 2;
1621 97 : move16();
1622 97 : BREAK;
1623 243 : case 4:
1624 243 : VQBits = 3;
1625 243 : move16();
1626 243 : BREAK;
1627 937 : default:
1628 937 : VQBits = 4;
1629 937 : move16();
1630 : }
1631 1590 : byteBuffer = 0;
1632 1590 : move16();
1633 6359 : FOR( i = 0; i < VQBits; i++ )
1634 : {
1635 4769 : byteBuffer = (UWord16) L_add( byteBuffer, L_shl( bitstream[( *index )--], sub( sub( VQBits, 1 ), i ) ) );
1636 4769 : move16();
1637 4769 : lfeBitsRead = add( lfeBitsRead, 1 );
1638 : }
1639 1590 : lfeToTotalEnergyRatioIndices[2] = byteBuffer; /* VQ index */
1640 1590 : move16();
1641 : }
1642 :
1643 8475 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
1644 : {
1645 : Word16 tmp16, exp;
1646 : Word32 tmp32;
1647 6780 : IF( EQ_32( ivas_total_brate, IVAS_16k4 ) )
1648 : {
1649 420 : tmp32 = BASOP_util_Pow2( L_deposit_h( log2LFEaverage_fx ), 15 - Q12, &exp ); /* Q(31 - exp)*/
1650 420 : tmp16 = round_fx( tmp32 ); /* Q(31-exp) -> Q(15 - exp) */
1651 420 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = shr_sat( tmp16, sub( 1, exp ) ); /* should saturate. Q(15 - exp) - (1 - exp)->Q14 */
1652 420 : move16();
1653 : }
1654 : ELSE
1655 : {
1656 6360 : tmp16 = shr( extract_l( L_shr_r( McMASA_LFEGain_vectors_fx[4 * lfeToTotalEnergyRatioIndices[2] + i], Q12 ) ), 1 ); /* Q12 */
1657 6360 : tmp16 = add( log2LFEaverage_fx, tmp16 ); /* Q12 */
1658 6360 : tmp32 = BASOP_util_Pow2( L_deposit_h( tmp16 ), 15 - Q12, &exp ); /* Q(31 - exp) */
1659 6360 : tmp16 = round_fx( tmp32 ); /* Q(31-exp) -> Q(15 - exp) */
1660 6360 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = shr_sat( tmp16, sub( 1, exp ) ); /* should saturate. Q(15 - exp) - (1 - exp) -> Q14 */
1661 6360 : move16();
1662 : }
1663 :
1664 6780 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = s_min( hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i], ONE_IN_Q14 );
1665 6780 : move16();
1666 6780 : hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = s_max( hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i], 0 );
1667 6780 : move16();
1668 : }
1669 : }
1670 : }
1671 :
1672 11781 : return lfeBitsRead;
1673 : }
1674 :
1675 :
1676 : /*-------------------------------------------------------------------*
1677 : * ivas_masa_dec_reconfigure()
1678 : *
1679 : * Reconfigure IVAS MASA decoder
1680 : *-------------------------------------------------------------------*/
1681 :
1682 6776 : ivas_error ivas_masa_dec_reconfigure_fx(
1683 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1684 : )
1685 : {
1686 : Word16 n, tmp, num_bits;
1687 : Word16 sce_id, cpe_id;
1688 : UWord16 *bit_stream;
1689 : Decoder_State **sts;
1690 : UWord32 ivas_total_brate, last_ivas_total_brate;
1691 : Word16 numCldfbAnalyses_old, numCldfbSyntheses_old;
1692 : #ifdef FIX_NCHAN_BUFFERS
1693 : #ifdef FIX_1330_JBM_MEMORY
1694 : Word16 nchan_out_buff;
1695 : #else
1696 : Word16 nchan_out_buff_old, nchan_out_buff;
1697 : #endif
1698 : #endif
1699 : ivas_error error;
1700 : Word32 ism_total_brate;
1701 : Word16 pos_idx;
1702 :
1703 6776 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
1704 6776 : move32();
1705 6776 : last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
1706 6776 : move32();
1707 : #ifdef FIX_NCHAN_BUFFERS
1708 : #ifndef FIX_1330_JBM_MEMORY
1709 : nchan_out_buff_old = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
1710 : #endif
1711 : #endif
1712 :
1713 6776 : test();
1714 6776 : test();
1715 : /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */
1716 6776 : IF( st_ivas->hSpatParamRendCom != NULL && EQ_16( st_ivas->hSpatParamRendCom->slot_size, st_ivas->hTcBuffer->n_samples_granularity ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
1717 : {
1718 5092 : Copy( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
1719 5092 : st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
1720 5092 : move16();
1721 5092 : st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
1722 5092 : move16();
1723 : }
1724 :
1725 6776 : ivas_init_dec_get_num_cldfb_instances_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
1726 :
1727 : /* renderer might have changed, reselect */
1728 6776 : ivas_renderer_select( st_ivas );
1729 :
1730 6776 : test();
1731 6776 : test();
1732 6776 : test();
1733 6776 : test();
1734 6776 : test();
1735 6776 : test();
1736 6776 : test();
1737 6776 : IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) ||
1738 : ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] == NULL ) )
1739 : {
1740 : /* init a new DirAC dec */
1741 118 : IF( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
1742 : {
1743 0 : return error;
1744 : }
1745 : }
1746 6658 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DISABLE ) || EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) || EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
1747 : {
1748 : /* close all unnecessary parametric decoding and rendering */
1749 1028 : ivas_dirac_dec_close_binaural_data_fx( st_ivas->hDiracDecBin );
1750 1028 : ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
1751 1028 : ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
1752 1028 : ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
1753 : }
1754 : /* possible reconfigure is done later */
1755 :
1756 : /*-----------------------------------------------------------------*
1757 : * Allocate and initialize SCE/CPE and other handles
1758 : *-----------------------------------------------------------------*/
1759 :
1760 6776 : IF( st_ivas->hSCE[0] != NULL )
1761 : {
1762 4358 : bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream;
1763 4358 : move16();
1764 : }
1765 : ELSE
1766 : {
1767 2418 : bit_stream = st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream;
1768 2418 : move16();
1769 : }
1770 :
1771 6776 : num_bits = 0;
1772 6776 : move16();
1773 :
1774 : Word16 tmp_e;
1775 : Word32 tmp32;
1776 :
1777 13803 : FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
1778 : {
1779 : // st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
1780 7027 : st_ivas->hSCE[sce_id]->element_brate = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
1781 7027 : st_ivas->hSCE[sce_id]->element_brate = L_shr( st_ivas->hSCE[sce_id]->element_brate, sub( 15, tmp_e ) ); // Q0
1782 7027 : move32();
1783 7027 : move32();
1784 :
1785 7027 : st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
1786 7027 : move32();
1787 :
1788 7027 : sts = st_ivas->hSCE[sce_id]->hCoreCoder;
1789 7027 : sts[0]->bit_stream = bit_stream + num_bits;
1790 :
1791 : // num_bits += (int16_t)(st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC);
1792 7027 : tmp = extract_l( Mpy_32_32( st_ivas->hSCE[sce_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
1793 7027 : num_bits = add( num_bits, tmp );
1794 :
1795 7027 : test();
1796 7027 : test();
1797 7027 : test();
1798 7027 : IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL )
1799 : {
1800 4584 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
1801 : {
1802 0 : return error;
1803 : }
1804 : }
1805 : }
1806 :
1807 12870 : FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
1808 : {
1809 : // st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
1810 6094 : tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
1811 6094 : tmp32 = L_shr( tmp32, sub( 15, tmp_e ) ); // Q0
1812 6094 : st_ivas->hCPE[cpe_id]->element_brate = imult3216( tmp32, CPE_CHANNELS );
1813 6094 : move32();
1814 :
1815 : /* prepare bitstream buffers */
1816 18282 : FOR( n = 0; n < CPE_CHANNELS; n++ )
1817 : {
1818 12188 : tmp = CPE_CHANNELS;
1819 12188 : move16();
1820 12188 : if ( GT_16( st_ivas->nCPE, 1 ) )
1821 : {
1822 0 : st_ivas->nCPE = 1;
1823 0 : move16();
1824 : }
1825 : /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
1826 : // st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / tmp;
1827 12188 : tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hCPE[cpe_id]->element_brate, tmp, &tmp_e ) );
1828 12188 : tmp32 = L_shr( tmp32, sub( 15, tmp_e ) );
1829 12188 : st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = tmp32;
1830 12188 : move32();
1831 : }
1832 6094 : sts = st_ivas->hCPE[cpe_id]->hCoreCoder;
1833 6094 : sts[0]->bit_stream = bit_stream + num_bits;
1834 :
1835 : // num_bits += (int16_t) ( st_ivas->hCPE[cpe_id]->element_brate / FRAMES_PER_SEC );
1836 6094 : tmp = extract_l( Mpy_32_32( st_ivas->hCPE[cpe_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
1837 6094 : num_bits = add( num_bits, tmp );
1838 :
1839 6094 : test();
1840 6094 : test();
1841 6094 : test();
1842 6094 : test();
1843 6094 : test();
1844 6094 : test();
1845 6094 : IF( ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && GE_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) ||
1846 : ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_32( last_ivas_total_brate, FRAME_NO_DATA ) ) ||
1847 : ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_32( last_ivas_total_brate, IVAS_SID_5k2 ) ) )
1848 : {
1849 1270 : st_ivas->hCPE[cpe_id]->nchan_out = 1;
1850 1270 : move16();
1851 :
1852 1270 : test();
1853 1270 : test();
1854 1270 : test();
1855 1270 : test();
1856 1270 : test();
1857 1270 : IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) )
1858 : {
1859 1049 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
1860 : {
1861 0 : return error;
1862 : }
1863 : }
1864 : }
1865 4824 : ELSE IF( GE_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && LT_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
1866 : {
1867 1282 : st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS;
1868 1282 : move16();
1869 :
1870 1282 : test();
1871 1282 : test();
1872 1282 : test();
1873 1282 : test();
1874 1282 : test();
1875 1282 : IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) )
1876 : {
1877 1100 : IF( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
1878 : {
1879 0 : return error;
1880 : }
1881 : }
1882 : }
1883 : }
1884 :
1885 60984 : FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
1886 : {
1887 54208 : IF( st_ivas->hDiracDecBin[pos_idx] != NULL )
1888 : {
1889 : /* regularization factor is bitrate-dependent */
1890 4190 : st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
1891 4190 : move16();
1892 : }
1893 : }
1894 :
1895 6776 : test();
1896 6776 : IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */
1897 : {
1898 : /*-----------------------------------------------------------------*
1899 : * TD Decorrelator
1900 : *-----------------------------------------------------------------*/
1901 :
1902 1638 : IF( st_ivas->hDiracDecBin[0] != NULL )
1903 : {
1904 771 : IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
1905 : {
1906 0 : return error;
1907 : }
1908 : }
1909 :
1910 : /*-----------------------------------------------------------------*
1911 : * CLDFB instances
1912 : *-----------------------------------------------------------------*/
1913 :
1914 1638 : IF( st_ivas->hSpar )
1915 : {
1916 0 : Word16 Q_tmp = getScaleFactor16( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 16 );
1917 0 : Scale_sig( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 16, Q_tmp - st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q ); // st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q -> Q_tmp
1918 0 : st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_tmp;
1919 0 : move16();
1920 : }
1921 :
1922 1638 : IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, st_ivas->nchan_transport, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
1923 : {
1924 0 : return error;
1925 : }
1926 : }
1927 :
1928 : /*-----------------------------------------------------------------*
1929 : * Set-up MASA coding elements and bitrates
1930 : *-----------------------------------------------------------------*/
1931 :
1932 6776 : ism_total_brate = 0;
1933 6776 : move32();
1934 :
1935 6776 : test();
1936 6776 : test();
1937 6776 : test();
1938 6776 : test();
1939 6776 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && GT_32( st_ivas->nSCE, 0 ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
1940 : {
1941 6145 : FOR( n = 0; n < st_ivas->nSCE; n++ )
1942 : {
1943 3934 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[n]->element_brate );
1944 : }
1945 : }
1946 :
1947 6776 : ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
1948 :
1949 : /*-----------------------------------------------------------------*
1950 : * JBM TC buffers
1951 : *-----------------------------------------------------------------*/
1952 : {
1953 : Word16 tc_nchan_to_allocate;
1954 : Word16 tc_nchan_transport;
1955 : TC_BUFFER_MODE buffer_mode_new;
1956 : Word16 n_samples_granularity;
1957 :
1958 6776 : n_samples_granularity = ivas_jbm_dec_get_render_granularity_fx( st_ivas->renderer_type, ivas_renderer_secondary_select_fx( st_ivas ), st_ivas->hDecoderConfig->output_Fs );
1959 6776 : buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode_fx( st_ivas );
1960 6776 : tc_nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
1961 :
1962 6776 : tc_nchan_to_allocate = tc_nchan_transport;
1963 6776 : move16();
1964 :
1965 6776 : test();
1966 6776 : test();
1967 6776 : test();
1968 6776 : test();
1969 6776 : test();
1970 6776 : test();
1971 6776 : IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
1972 : {
1973 4190 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
1974 : {
1975 2413 : tc_nchan_to_allocate = add( BINAURAL_CHANNELS, st_ivas->nchan_ism );
1976 : }
1977 : ELSE
1978 : {
1979 : #ifdef FIX_NCHAN_BUFFERS
1980 1777 : tc_nchan_to_allocate = BINAURAL_CHANNELS;
1981 1777 : move16();
1982 1777 : test();
1983 1777 : if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr )
1984 : {
1985 999 : tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS;
1986 999 : move16();
1987 : }
1988 : #else
1989 : tc_nchan_to_allocate = shl( BINAURAL_CHANNELS, 1 );
1990 : #endif
1991 : }
1992 :
1993 4190 : test();
1994 4190 : test();
1995 4190 : test();
1996 4190 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
1997 : {
1998 651 : IF( GT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
1999 : {
2000 651 : IF( NE_32( ( error = ivas_jbm_dec_set_discard_samples_fx( st_ivas ) ), IVAS_ERR_OK ) )
2001 : {
2002 0 : return error;
2003 : }
2004 : }
2005 : }
2006 3539 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
2007 : {
2008 2381 : IF( LT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
2009 : {
2010 : /* flush already done in IVAS_DEC_ReadFormat() */
2011 : }
2012 : }
2013 : }
2014 2586 : ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && EQ_32( st_ivas->hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) )
2015 : {
2016 : /* addtl channel for CNG */
2017 188 : tc_nchan_to_allocate = add( tc_nchan_to_allocate, 1 );
2018 : }
2019 2398 : ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) || EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) ) )
2020 : {
2021 0 : tc_nchan_transport = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
2022 0 : tc_nchan_to_allocate = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
2023 : }
2024 6776 : test();
2025 6776 : test();
2026 6776 : IF( NE_16( tc_nchan_transport, st_ivas->hTcBuffer->nchan_transport_jbm ) || NE_16( tc_nchan_to_allocate, st_ivas->hTcBuffer->nchan_transport_internal ) || NE_16( buffer_mode_new, st_ivas->hTcBuffer->tc_buffer_mode ) )
2027 : {
2028 4972 : IF( NE_32( error = ivas_jbm_dec_tc_buffer_reconfigure_fx( st_ivas, buffer_mode_new, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, n_samples_granularity ), IVAS_ERR_OK ) )
2029 : {
2030 0 : return error;
2031 : }
2032 : }
2033 :
2034 6776 : test();
2035 6776 : IF( st_ivas->hSpatParamRendCom != NULL && EQ_16( st_ivas->hSpatParamRendCom->slot_size, st_ivas->hTcBuffer->n_samples_granularity ) )
2036 : {
2037 5097 : Copy( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
2038 5097 : st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
2039 5097 : move16();
2040 5097 : st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
2041 5097 : move16();
2042 : }
2043 :
2044 6776 : test();
2045 6776 : test();
2046 6776 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
2047 : {
2048 651 : Word16 granularityMultiplier = idiv1616( st_ivas->hTcBuffer->n_samples_granularity, st_ivas->hSpatParamRendCom->slot_size );
2049 5859 : FOR( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ )
2050 : {
2051 5208 : st_ivas->hSpatParamRendCom->subframe_nbslots[n] = i_mult( st_ivas->hTcBuffer->subframe_nbslots[n], granularityMultiplier );
2052 5208 : move16();
2053 : }
2054 : }
2055 : }
2056 :
2057 : #ifdef FIX_NCHAN_BUFFERS
2058 : /*-----------------------------------------------------------------*
2059 : * output audio buffers
2060 : *-----------------------------------------------------------------*/
2061 :
2062 6776 : test();
2063 6776 : IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) /* note: switching with OMASA is addressed in ivas_omasa_dec_config() */
2064 : {
2065 1638 : nchan_out_buff = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
2066 : #ifdef FIX_1330_JBM_MEMORY
2067 1638 : IF( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK )
2068 : #else
2069 : IF( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK )
2070 : #endif
2071 : {
2072 0 : return error;
2073 : }
2074 : }
2075 :
2076 : #endif
2077 6776 : return IVAS_ERR_OK;
2078 : }
2079 :
2080 :
2081 : /*-------------------------------------------------------------------*
2082 : * ivas_spar_param_to_masa_param_mapping()
2083 : *
2084 : * Determine MASA metadata from the SPAR metadata
2085 : *-------------------------------------------------------------------*/
2086 :
2087 157720 : void ivas_spar_param_to_masa_param_mapping_fx(
2088 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
2089 : Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */
2090 : Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */
2091 : Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME],
2092 : const Word16 subframe /* i : Subframe to map */
2093 : )
2094 : {
2095 : Word16 i, j, band, bin, slot, ch, nBins, nchan_transport;
2096 : Word16 mixer_mat_index;
2097 : Word16 dirac_write_idx;
2098 : DIRAC_DEC_HANDLE hDirAC;
2099 : DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist;
2100 : Word32 mixer_mat_sf_bands_real_fx[SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS];
2101 : Word32 mixer_mat_sf_bins_real_fx[CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS];
2102 : Word16 *band_grouping;
2103 : Word16 band_start, band_end;
2104 : Word32 transportSignalEnergies_32[2][CLDFB_NO_CHANNELS_MAX];
2105 : Word64 transportSignalEnergies_64[2][CLDFB_NO_CHANNELS_MAX];
2106 : Word32 transportSignalCrossCorrelation_32[CLDFB_NO_CHANNELS_MAX];
2107 : Word64 transportSignalCrossCorrelation_64[CLDFB_NO_CHANNELS_MAX];
2108 : Word64 instEne_fx;
2109 : Word32 inCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2110 157720 : Word16 q_inCovarianceMtx = 31;
2111 : Word32 foaCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2112 : Word32 Iy_fx, Iz_fx, Ix_fx, E_fx, azi_fx, ele_fx, I_fx, ratio_float_fx;
2113 : Word32 diffuseGainX_fx, diffuseGainY_fx, diffuseGainZ_fx, diffuseGainSum_fx;
2114 : Word16 slot_idx, slot_idx_start, sf;
2115 : SPAR_DEC_HANDLE hSpar;
2116 : Word16 slot_fac_fx;
2117 157720 : Word16 q_slot_fac = 0;
2118 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
2119 157720 : Word16 common_q = 31;
2120 : Word64 azi_val, ele_val;
2121 157720 : Word64 transportSignalEnergies_max = 0;
2122 157720 : Word64 transportSignalCrossCorrelation_max = 0;
2123 157720 : Word64 max_common_val = 0;
2124 157720 : Word16 azi_q = 0, ele_q = 0;
2125 : Word16 num_q, denom_q, res_q;
2126 157720 : Word16 headroom_left_max_common = 63; // 0 value
2127 157720 : Word16 q_max_common = 31;
2128 : Word32 ratio_fx; /* Q30 */
2129 157720 : move16();
2130 157720 : move16();
2131 157720 : move16();
2132 157720 : move16();
2133 157720 : move16();
2134 157720 : move16();
2135 157720 : move16();
2136 157720 : move64();
2137 157720 : move64();
2138 157720 : move64();
2139 :
2140 473160 : FOR( i = 0; i < 2; i++ )
2141 : {
2142 315440 : set64_fx( transportSignalEnergies_64[i], 0, CLDFB_NO_CHANNELS_MAX );
2143 315440 : set32_fx( transportSignalEnergies_32[i], 0, CLDFB_NO_CHANNELS_MAX );
2144 : }
2145 157720 : set32_fx( transportSignalCrossCorrelation_32, 0, CLDFB_NO_CHANNELS_MAX );
2146 157720 : set64_fx( transportSignalCrossCorrelation_64, 0, CLDFB_NO_CHANNELS_MAX );
2147 788600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2148 : {
2149 630880 : set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2150 630880 : set32_fx( foaCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2151 : }
2152 :
2153 1104040 : FOR( Word16 ind = 0; ind < 6; ind++ )
2154 : {
2155 4731600 : FOR( Word16 ind2 = 0; ind2 < 4; ind2++ )
2156 : {
2157 3785280 : if ( GT_16( common_q, q_cldfb[ind][ind2] ) )
2158 : {
2159 227158 : common_q = q_cldfb[ind][ind2];
2160 227158 : move16();
2161 : }
2162 : }
2163 : }
2164 : /* Set values */
2165 157720 : hDirAC = st_ivas->hDirAC;
2166 157720 : hSpatParamRendCom = st_ivas->hSpatParamRendCom;
2167 157720 : hSpatParamRendCom->numParametricDirections = 1;
2168 157720 : move16();
2169 157720 : hSpatParamRendCom->numSimultaneousDirections = 1;
2170 157720 : move16();
2171 157720 : hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist;
2172 157720 : nchan_transport = st_ivas->nchan_transport;
2173 157720 : move16();
2174 157720 : band_grouping = hDirAC->band_grouping;
2175 157720 : move16();
2176 157720 : hSpar = st_ivas->hSpar;
2177 157720 : dirac_write_idx = hSpatParamRendCom->render_to_md_map[subframe];
2178 157720 : move16();
2179 :
2180 : /* Init arrays */
2181 788600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2182 : {
2183 630880 : set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2184 : }
2185 :
2186 : /* Delay the SPAR mixing matrices to have them synced with the audio */
2187 157720 : slot_idx_start = hSpar->slots_rendered;
2188 157720 : move16();
2189 157720 : slot_fac_fx = BASOP_Util_Divide3232_Scale( 1, hSpar->subframe_nbslots[subframe], &q_slot_fac );
2190 157720 : IF( q_slot_fac < 0 )
2191 : {
2192 154972 : slot_fac_fx = shr( slot_fac_fx, -1 * q_slot_fac ); // Q15
2193 : }
2194 783106 : FOR( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe]; slot_idx++ )
2195 : {
2196 625386 : IF( hSpar->render_to_md_map[slot_idx + slot_idx_start] == 0 )
2197 : {
2198 39098 : sf = 0;
2199 39098 : move16();
2200 : }
2201 : ELSE
2202 : {
2203 586288 : sf = shr( hSpar->render_to_md_map[slot_idx + slot_idx_start], JBM_CLDFB_SLOTS_IN_SUBFRAME_LOG2 );
2204 : }
2205 :
2206 625386 : IF( LT_16( sf, SPAR_META_DELAY_SUBFRAMES ) )
2207 : {
2208 312706 : mixer_mat_index = add( sf, add( sub( MAX_PARAM_SPATIAL_SUBFRAMES, SPAR_META_DELAY_SUBFRAMES ), 1 ) );
2209 2814354 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2210 : {
2211 12508240 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2212 : {
2213 50032960 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2214 : {
2215 40026368 : mixer_mat_sf_bands_real_fx[band][i][j] = L_shl( Mpy_32_16_1( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[mixer_mat_index][i][j][band], slot_fac_fx ), 1 ); // 30//making q to 31
2216 40026368 : move32();
2217 : }
2218 : }
2219 : }
2220 : }
2221 : ELSE
2222 : {
2223 312680 : mixer_mat_index = ( ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) == 1 ) ? 0 : ( sf - SPAR_META_DELAY_SUBFRAMES );
2224 2814120 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2225 : {
2226 12507200 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2227 : {
2228 50028800 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2229 : {
2230 40023040 : mixer_mat_sf_bands_real_fx[band][i][j] = L_shl( Mpy_32_16_1( st_ivas->hSpar->hMdDec->mixer_mat_fx[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS], slot_fac_fx ), 1 ); // 30//making q to 31
2231 40023040 : move32();
2232 : }
2233 : }
2234 : }
2235 : }
2236 : }
2237 :
2238 : /* Map the mixing matrices from the frequency bands to frequency bins */
2239 157720 : bin = 0;
2240 157720 : move16();
2241 1419480 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2242 : {
2243 1261760 : band_start = band_grouping[band];
2244 1261760 : move16();
2245 1261760 : band_end = band_grouping[band + 1];
2246 1261760 : move16();
2247 2996680 : FOR( bin = band_start; bin < band_end; bin++ )
2248 : {
2249 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2250 : {
2251 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2252 : {
2253 27758720 : mixer_mat_sf_bins_real_fx[bin][i][j] = mixer_mat_sf_bands_real_fx[band][i][j]; // 31
2254 27758720 : move32();
2255 : }
2256 : }
2257 : }
2258 : }
2259 :
2260 157720 : nBins = bin;
2261 157720 : move16();
2262 :
2263 : /* Determine MASA metadata */
2264 : /* Determine transport signal energies and cross correlations when more than 1 TC */
2265 157720 : IF( EQ_16( nchan_transport, 2 ) )
2266 : {
2267 440415 : FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
2268 : {
2269 4225596 : FOR( bin = 0; bin < nBins; bin++ )
2270 : {
2271 11620389 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2272 : {
2273 7746926 : instEne_fx = W_mult0_32_32( L_shr_sat( inRe_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ), L_shr_sat( inRe_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ) ); // Q(2 * common_q)
2274 7746926 : instEne_fx = W_add( instEne_fx, W_mult0_32_32( (Word64) L_shr_sat( inIm_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ), L_shr_sat( inIm_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ) ) ); // Q(2 * common_q)
2275 7746926 : transportSignalEnergies_64[ch][bin] = W_add( transportSignalEnergies_64[ch][bin], instEne_fx ); // Q(2 * common_q)
2276 7746926 : move64();
2277 7746926 : move64();
2278 : }
2279 3873463 : transportSignalCrossCorrelation_64[bin] = W_add( transportSignalCrossCorrelation_64[bin], W_mult0_32_32( L_shr_sat( inRe_fx[0][slot][bin], sub( q_cldfb[0][slot], common_q ) ), L_shr_sat( inRe_fx[1][slot][bin], sub( q_cldfb[0][slot], common_q ) ) ) ); // Q(2 * common_q)
2280 3873463 : transportSignalCrossCorrelation_64[bin] = W_add( transportSignalCrossCorrelation_64[bin], W_mult0_32_32( L_shr_sat( inIm_fx[0][slot][bin], sub( q_cldfb[0][slot], common_q ) ), L_shr_sat( inIm_fx[1][slot][bin], sub( q_cldfb[0][slot], common_q ) ) ) ); // Q(2 * common_q)
2281 3873463 : move64();
2282 3873463 : move64();
2283 : }
2284 : }
2285 :
2286 :
2287 1059384 : FOR( bin = 0; bin < nBins; bin++ )
2288 : {
2289 2913306 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2290 : {
2291 : // transportSignalEnergies_max = GT_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) ? transportSignalEnergies_max : transportSignalEnergies_64[ch][bin];
2292 :
2293 1942204 : if ( LE_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) )
2294 : {
2295 120430 : transportSignalEnergies_max = transportSignalEnergies_64[ch][bin]; // Q(2 * common_q)
2296 120430 : move64();
2297 : }
2298 : }
2299 :
2300 : // transportSignalCrossCorrelation_max = GT_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) ? transportSignalCrossCorrelation_max : transportSignalCrossCorrelation_64[bin];
2301 :
2302 971102 : if ( LE_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) )
2303 : {
2304 120140 : transportSignalCrossCorrelation_max = transportSignalCrossCorrelation_64[bin]; // Q(2 * common_q)
2305 120140 : move64();
2306 : }
2307 : }
2308 :
2309 : // max_common_val = GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) ? transportSignalEnergies_max : transportSignalCrossCorrelation_max;
2310 :
2311 88282 : IF( GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) )
2312 : {
2313 88256 : max_common_val = transportSignalEnergies_max; // Q(2 * common_q)
2314 : }
2315 : ELSE
2316 : {
2317 26 : max_common_val = transportSignalCrossCorrelation_max; // Q(2 * common_q)
2318 : }
2319 88282 : move64();
2320 :
2321 88282 : IF( max_common_val != 0 )
2322 : {
2323 88256 : headroom_left_max_common = W_norm( max_common_val );
2324 88256 : IF( GT_16( headroom_left_max_common, 32 ) )
2325 : {
2326 14232 : FOR( bin = 0; bin < nBins; bin++ )
2327 : {
2328 39138 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2329 : {
2330 26092 : transportSignalEnergies_32[ch][bin] = W_extract_l( transportSignalEnergies_64[ch][bin] ); // Q(q_max_common)
2331 26092 : move32();
2332 : }
2333 13046 : transportSignalCrossCorrelation_32[bin] = W_extract_l( transportSignalCrossCorrelation_64[bin] ); // Q(q_max_common)
2334 13046 : move32();
2335 : }
2336 1186 : q_max_common = shl( common_q, 1 );
2337 : }
2338 : ELSE
2339 : {
2340 1044840 : FOR( bin = 0; bin < nBins; bin++ )
2341 : {
2342 2873310 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2343 : {
2344 1915540 : transportSignalEnergies_32[ch][bin] = W_extract_l( W_shr( transportSignalEnergies_64[ch][bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
2345 1915540 : move32();
2346 : }
2347 957770 : transportSignalCrossCorrelation_32[bin] = W_extract_l( W_shr( transportSignalCrossCorrelation_64[bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
2348 957770 : move32();
2349 : }
2350 87070 : q_max_common = sub( shl( common_q, 1 ), sub( 32, headroom_left_max_common ) );
2351 : }
2352 : }
2353 : ELSE
2354 : {
2355 312 : FOR( bin = 0; bin < nBins; bin++ )
2356 : {
2357 858 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2358 : {
2359 572 : transportSignalEnergies_32[ch][bin] = 0; // Q(q_max_common)
2360 572 : move32();
2361 : }
2362 286 : transportSignalCrossCorrelation_32[bin] = 0; // Q(q_max_common)
2363 286 : move32();
2364 : }
2365 26 : q_max_common = 31;
2366 26 : move16();
2367 : }
2368 : }
2369 :
2370 :
2371 157720 : IF( hDiffuseDist != NULL )
2372 : {
2373 157720 : set32_fx( hDiffuseDist->diffuseRatioX_fx, 0, CLDFB_NO_CHANNELS_MAX );
2374 157720 : set32_fx( hDiffuseDist->diffuseRatioY_fx, 0, CLDFB_NO_CHANNELS_MAX );
2375 157720 : set32_fx( hDiffuseDist->diffuseRatioZ_fx, 0, CLDFB_NO_CHANNELS_MAX );
2376 : }
2377 :
2378 1892640 : FOR( bin = 0; bin < nBins; bin++ )
2379 : {
2380 : /* Set the energy of the first transport signal */
2381 1734920 : IF( EQ_16( nchan_transport, 1 ) )
2382 : {
2383 763818 : inCovarianceMtx_fx[0][0] = ONE_IN_Q31; /* In case of 1TC, fixed value can be used, Q(q_inCovarianceMtx)*/
2384 763818 : move32();
2385 763818 : q_inCovarianceMtx = 31; /* In case of 1TC, fixed value can be used */
2386 763818 : move16();
2387 : }
2388 : ELSE
2389 : {
2390 971102 : inCovarianceMtx_fx[0][0] = transportSignalEnergies_32[0][bin]; /* In case of 2TC, use actual energies */
2391 971102 : move32();
2392 971102 : q_inCovarianceMtx = q_max_common; /* In case of 1TC, fixed value can be used */
2393 971102 : move16();
2394 : }
2395 :
2396 : /* Decorrelated channels assumed to have the same energy as the source channel */
2397 1734920 : inCovarianceMtx_fx[1][1] = inCovarianceMtx_fx[0][0];
2398 1734920 : move32();
2399 1734920 : inCovarianceMtx_fx[2][2] = inCovarianceMtx_fx[0][0];
2400 1734920 : move32();
2401 1734920 : inCovarianceMtx_fx[3][3] = inCovarianceMtx_fx[0][0];
2402 1734920 : move32();
2403 :
2404 : /* In case residuals were transmitted, use their actual energies and cross correlations */
2405 1734920 : IF( EQ_16( nchan_transport, 2 ) )
2406 : {
2407 :
2408 971102 : inCovarianceMtx_fx[1][1] = transportSignalEnergies_32[1][bin];
2409 971102 : move32();
2410 971102 : inCovarianceMtx_fx[0][1] = transportSignalCrossCorrelation_32[bin];
2411 971102 : move32();
2412 971102 : inCovarianceMtx_fx[1][0] = inCovarianceMtx_fx[0][1];
2413 971102 : move32();
2414 971102 : q_inCovarianceMtx = q_max_common;
2415 971102 : move16();
2416 : }
2417 :
2418 1734920 : compute_foa_cov_matrix_fx( foaCovarianceMtx_fx, inCovarianceMtx_fx, mixer_mat_sf_bins_real_fx[bin] );
2419 :
2420 1734920 : Iy_fx = foaCovarianceMtx_fx[0][1]; /* Intensity in Y direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2421 1734920 : move32();
2422 1734920 : Iz_fx = foaCovarianceMtx_fx[0][2]; /* Intensity in Z direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2423 1734920 : move32();
2424 1734920 : Ix_fx = foaCovarianceMtx_fx[0][3]; /* Intensity in X direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2425 1734920 : move32();
2426 :
2427 1734920 : Word64 I1 = W_mult0_32_32( Ix_fx, Ix_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2428 1734920 : Word64 I2 = W_mult0_32_32( Iy_fx, Iy_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2429 1734920 : Word64 I3 = W_mult0_32_32( Iz_fx, Iz_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2430 1734920 : Word64 I_res = W_add( W_add( I1, I2 ), I3 ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2431 :
2432 1734920 : Word64 E_fx_64 = W_add( W_add( W_add( foaCovarianceMtx_fx[0][0], foaCovarianceMtx_fx[1][1] ), foaCovarianceMtx_fx[2][2] ), foaCovarianceMtx_fx[3][3] ); // Q(q_inCovarianceMtx)
2433 1734920 : E_fx = L_shr_sat( L_add_sat( L_add_sat( L_add_sat( foaCovarianceMtx_fx[0][0], foaCovarianceMtx_fx[1][1] ), foaCovarianceMtx_fx[2][2] ), foaCovarianceMtx_fx[3][3] ), 1 );
2434 1734920 : E_fx_64 = W_shr( E_fx_64, 1 );
2435 :
2436 1734920 : Word16 headroom_left_I_res = W_norm( I_res );
2437 : Word16 q_I_res;
2438 1734920 : IF( LT_16( headroom_left_I_res, 32 ) )
2439 : {
2440 1404509 : I_res = W_shr( I_res, sub( 32, headroom_left_I_res ) ); // q_I_res
2441 1404509 : q_I_res = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_res ) ) );
2442 : }
2443 : ELSE
2444 : {
2445 330411 : q_I_res = sub( 31, shl( q_inCovarianceMtx, 1 ) );
2446 : }
2447 1734920 : I_fx = Sqrt32( (Word32) I_res, &q_I_res );
2448 1734920 : IF( q_I_res < 0 )
2449 : {
2450 721250 : I_fx = L_shr( I_fx, -1 * q_I_res );
2451 721250 : q_I_res = 0;
2452 721250 : move16();
2453 : }
2454 1734920 : azi_q = 0;
2455 1734920 : move16();
2456 1734920 : azi_fx = BASOP_util_atan2( Iy_fx, Ix_fx, azi_q ); /* Azimuth Q13*/
2457 :
2458 1734920 : Word64 I_ele_x = W_mult0_32_32( Ix_fx, Ix_fx ); // Q(ele_q)
2459 1734920 : Word64 I_ele_y = W_mult0_32_32( Iy_fx, Iy_fx ); // Q(ele_q)
2460 1734920 : Word64 I_ele = W_add( I_ele_x, I_ele_y ); // Q(ele_q)
2461 1734920 : Word16 headroom_left_I_ele = W_norm( I_ele );
2462 1734920 : IF( LT_16( headroom_left_I_ele, 32 ) )
2463 : {
2464 1394564 : I_ele = W_shr( I_ele, sub( 32, headroom_left_I_ele ) );
2465 1394564 : ele_q = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_ele ) ) );
2466 : }
2467 : ELSE
2468 : {
2469 340356 : ele_q = sub( 31, shl( q_inCovarianceMtx, 1 ) );
2470 : }
2471 1734920 : I_ele = Sqrt32( W_extract_l( I_ele ), &ele_q );
2472 1734920 : IF( ele_q < 0 )
2473 : {
2474 706124 : I_ele = W_shr( I_ele, negate( ele_q ) ); // Q0
2475 706124 : ele_q = 0;
2476 706124 : move16();
2477 : }
2478 1734920 : ele_fx = BASOP_util_atan2( Iz_fx, W_extract_l( I_ele ), sub( sub( 31, q_inCovarianceMtx ), ele_q ) ); // Q13
2479 :
2480 1734920 : num_q = sub( 31, q_I_res );
2481 1734920 : denom_q = q_inCovarianceMtx;
2482 1734920 : move16();
2483 1734920 : res_q = 0;
2484 1734920 : move16();
2485 1734920 : IF( E_fx <= 0 )
2486 : {
2487 4830 : E_fx = 1;
2488 4830 : move32();
2489 : }
2490 1734920 : ratio_float_fx = BASOP_Util_Divide3232_Scale( I_fx, E_fx, &res_q );
2491 1734920 : res_q = sub( res_q, sub( num_q, denom_q ) );
2492 1734920 : ratio_fx = L_shl_sat( ratio_float_fx, add( Q15, res_q ) ); // Q(15 + res_q)
2493 :
2494 1734920 : ratio_fx = L_max( 0, L_min( ratio_fx, ONE_IN_Q30 ) ); // Q30
2495 :
2496 1734920 : azi_val = W_mult0_32_32( azi_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + Q25
2497 1734920 : IF( azi_val < 0 )
2498 : {
2499 1059355 : azi_val = W_shr( W_neg( azi_val ), 13 + 25 ); // Q0
2500 1059355 : azi_val = W_neg( azi_val );
2501 : }
2502 : ELSE
2503 : {
2504 675565 : azi_val = W_shr( azi_val, 13 + 25 ); // Q0
2505 : }
2506 1734920 : ele_val = W_mult0_32_32( ele_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + q25
2507 1734920 : IF( ele_val < 0 )
2508 : {
2509 610588 : ele_val = W_shr( W_neg( ele_val ), 13 + 25 ); // Q0
2510 610588 : ele_val = W_neg( ele_val ); // Q0
2511 : }
2512 : ELSE
2513 : {
2514 1124332 : ele_val = W_shr( ele_val, 13 + 25 ); // Q0
2515 : }
2516 :
2517 1734920 : hSpatParamRendCom->azimuth[dirac_write_idx][bin] = extract_l( W_extract_l( azi_val ) ); // Q0
2518 1734920 : move16();
2519 1734920 : hSpatParamRendCom->elevation[dirac_write_idx][bin] = extract_l( W_extract_l( ele_val ) ); // Q0
2520 1734920 : move16();
2521 1734920 : hSpatParamRendCom->energy_ratio1_fx[dirac_write_idx][bin] = ratio_fx; // Q30
2522 1734920 : move32();
2523 1734920 : hSpatParamRendCom->diffuseness_vector_fx[dirac_write_idx][bin] = L_sub( ONE_IN_Q30, ratio_fx ); // Q30
2524 1734920 : move32();
2525 :
2526 1734920 : hSpatParamRendCom->spreadCoherence_fx[dirac_write_idx][bin] = 0; // Q15
2527 1734920 : move16();
2528 1734920 : hSpatParamRendCom->surroundingCoherence_fx[dirac_write_idx][bin] = 0; // q15
2529 1734920 : move16();
2530 :
2531 : /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */
2532 1734920 : IF( hDiffuseDist != NULL )
2533 : {
2534 1734920 : IF( EQ_16( nchan_transport, 1 ) )
2535 : {
2536 763818 : diffuseGainY_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][1][1] ); // Q31
2537 763818 : diffuseGainX_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][3][2] ); // Q31
2538 763818 : diffuseGainZ_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][2][3] ); // Q31
2539 : }
2540 971102 : ELSE IF( EQ_16( nchan_transport, 2 ) )
2541 : {
2542 971102 : diffuseGainY_fx = L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][1][1], transportSignalEnergies_32[1][bin] ) ); // Q(q_max_common)
2543 971102 : diffuseGainX_fx = L_add_sat( L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][3][2], transportSignalEnergies_32[0][bin] ) ), L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][3][1], transportSignalEnergies_32[1][bin] ) ) ); // Q(q_max_common)
2544 971102 : diffuseGainZ_fx = L_add_sat( L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][2][3], transportSignalEnergies_32[0][bin] ) ), L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][2][1], transportSignalEnergies_32[1][bin] ) ) ); // Q(q_max_common)
2545 : }
2546 : ELSE
2547 : {
2548 0 : diffuseGainY_fx = ONE_IN_Q31;
2549 0 : move32();
2550 0 : diffuseGainX_fx = ONE_IN_Q31;
2551 0 : move32();
2552 0 : diffuseGainZ_fx = ONE_IN_Q31;
2553 0 : move32();
2554 : }
2555 1734920 : diffuseGainSum_fx = L_add_sat( L_add_sat( diffuseGainY_fx, diffuseGainX_fx ), diffuseGainZ_fx );
2556 :
2557 1734920 : IF( diffuseGainSum_fx == 0 )
2558 : {
2559 38852 : hDiffuseDist->diffuseRatioX_fx[bin] = 715827904; //(1.0f / 3.0f) in Q31
2560 38852 : move32();
2561 38852 : hDiffuseDist->diffuseRatioY_fx[bin] = 715827904;
2562 38852 : move32();
2563 38852 : hDiffuseDist->diffuseRatioZ_fx[bin] = 715827904;
2564 38852 : move32();
2565 : }
2566 : ELSE
2567 : {
2568 1696068 : Word16 temp_q = 0;
2569 1696068 : move16();
2570 : Word16 intermediate_results; // temp_q
2571 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainX_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2572 : // saturating value to less than 1
2573 1696068 : IF( temp_q <= 0 )
2574 : {
2575 1495927 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2576 : }
2577 : ELSE
2578 : {
2579 200141 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2580 : }
2581 1696068 : hDiffuseDist->diffuseRatioX_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2582 1696068 : move32();
2583 :
2584 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainY_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2585 : // saturating value to less than 1
2586 1696068 : IF( temp_q <= 0 )
2587 : {
2588 1612124 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2589 : }
2590 : ELSE
2591 : {
2592 83944 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2593 : }
2594 1696068 : hDiffuseDist->diffuseRatioY_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2595 1696068 : move32();
2596 :
2597 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainZ_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2598 : // saturating value to less than 1
2599 1696068 : IF( temp_q <= 0 )
2600 : {
2601 1469720 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2602 : }
2603 : ELSE
2604 : {
2605 226348 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2606 : }
2607 1696068 : hDiffuseDist->diffuseRatioZ_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2608 1696068 : move32();
2609 : }
2610 : }
2611 : }
2612 :
2613 157720 : return;
2614 : }
2615 :
2616 :
2617 : /* Estimate FOA properties: foaCov = mixMtx * inCov * mixMtx' */
2618 1734920 : static void compute_foa_cov_matrix_fx(
2619 : Word32 foaCov_fx[FOA_CHANNELS][FOA_CHANNELS], /* o : Estimated FOA covariance matrix Qx*/
2620 : Word32 inCov_fx[FOA_CHANNELS][FOA_CHANNELS], /* i : Input covariance matrix Qx*/
2621 : Word32 mixMtx_fx[FOA_CHANNELS][FOA_CHANNELS] /* i : Mixing matrix Q31*/
2622 : )
2623 : {
2624 : Word32 tmpMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2625 : Word16 i, j, k;
2626 : /* tmpMtx = mixMtx * inCov */
2627 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2628 : {
2629 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2630 : {
2631 27758720 : tmpMtx_fx[i][j] = 0;
2632 27758720 : move32();
2633 138793600 : FOR( k = 0; k < FOA_CHANNELS; k++ )
2634 : {
2635 111034880 : tmpMtx_fx[i][j] = L_add_sat( tmpMtx_fx[i][j], Mpy_32_32( mixMtx_fx[i][k], inCov_fx[k][j] ) ); // Qx
2636 111034880 : move32();
2637 : }
2638 : }
2639 : }
2640 :
2641 : /* foaCov = inCov * mixMtx' */
2642 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2643 : {
2644 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2645 : {
2646 27758720 : foaCov_fx[i][j] = 0;
2647 27758720 : move32();
2648 138793600 : FOR( k = 0; k < FOA_CHANNELS; k++ )
2649 : {
2650 111034880 : foaCov_fx[i][j] = L_add_sat( foaCov_fx[i][j], Mpy_32_32( tmpMtx_fx[i][k], mixMtx_fx[j][k] ) ); // Qx
2651 111034880 : move32();
2652 : }
2653 : }
2654 : }
2655 :
2656 1734920 : return;
2657 : }
2658 :
2659 :
2660 18460 : static void create_masa_ext_out_meta_fx(
2661 : MASA_DECODER *hMasa,
2662 : IVAS_QMETADATA_HANDLE hQMetaData,
2663 : const Word16 nchan_transport )
2664 : {
2665 : Word16 i, sf, b_old, b_new, dir;
2666 : MASA_DECRIPTIVE_META *descMeta;
2667 : Word16 *bandMap;
2668 : UWord8 numCodingBands;
2669 : UWord8 numDirections;
2670 : MASA_DECODER_EXT_OUT_META *extOutMeta;
2671 :
2672 18460 : numDirections = hMasa->config.numberOfDirections;
2673 18460 : move16();
2674 18460 : numCodingBands = hMasa->config.numCodingBands;
2675 18460 : move16();
2676 18460 : bandMap = hMasa->data.band_mapping;
2677 18460 : move16();
2678 18460 : extOutMeta = hMasa->data.extOutMeta;
2679 18460 : descMeta = &hMasa->data.extOutMeta->descriptiveMeta;
2680 :
2681 : /* Construct descriptive meta */
2682 166140 : FOR( i = 0; i < 8; i++ )
2683 : {
2684 147680 : descMeta->formatDescriptor[i] = ivasmasaFormatDescriptor[i];
2685 147680 : move16();
2686 : }
2687 18460 : descMeta->numberOfDirections = (UWord8) sub( numDirections, 1 );
2688 18460 : descMeta->numberOfChannels = (UWord8) ( sub( nchan_transport, 1 ) );
2689 : /* Following correspond to "unknown" values until transmission is implemented */
2690 18460 : descMeta->sourceFormat = 0x0u;
2691 18460 : descMeta->transportDefinition = 0x0u;
2692 18460 : descMeta->channelAngle = 0x0u;
2693 18460 : descMeta->channelDistance = 0x0u;
2694 18460 : descMeta->channelLayout = 0x0u;
2695 :
2696 18460 : move16();
2697 18460 : move16();
2698 18460 : move16();
2699 18460 : move16();
2700 18460 : move16();
2701 18460 : move16();
2702 18460 : move16();
2703 :
2704 : /* Construct spatial metadata from qmetadata */
2705 92300 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
2706 : {
2707 164180 : FOR( dir = 0; dir < numDirections; dir++ )
2708 : {
2709 : /* Spherical index */
2710 1173068 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2711 : {
2712 3242892 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2713 : {
2714 2160164 : extOutMeta->directionIndex[dir][sf][b_new] = hQMetaData->q_direction[dir].band_data[b_old].spherical_index[sf];
2715 2160164 : move16();
2716 : }
2717 : }
2718 :
2719 : /* Direct-to-total ratio */
2720 1173068 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2721 : {
2722 3242892 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2723 : {
2724 2160164 : UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0
2725 2160164 : move16();
2726 2160164 : extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q0
2727 2160164 : move16();
2728 : }
2729 : }
2730 :
2731 : /* Spread coherence */
2732 90340 : IF( hQMetaData->q_direction[dir].coherence_band_data != NULL )
2733 : {
2734 1054724 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2735 : {
2736 2703640 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2737 : {
2738 1720608 : extOutMeta->spreadCoherence[dir][sf][b_new] = hQMetaData->q_direction[dir].coherence_band_data[b_old].spread_coherence[sf];
2739 1720608 : move16();
2740 : }
2741 : }
2742 : }
2743 : ELSE
2744 : {
2745 466200 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2746 : {
2747 447552 : extOutMeta->spreadCoherence[dir][sf][i] = 0;
2748 447552 : move16();
2749 : }
2750 : }
2751 : }
2752 :
2753 : /* Fill second direction with zero energy data for EXT output */
2754 73840 : IF( EQ_16( numDirections, 1 ) )
2755 : {
2756 1433500 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2757 : {
2758 1376160 : extOutMeta->directionIndex[1][sf][i] = SPH_IDX_FRONT;
2759 1376160 : move16();
2760 : }
2761 :
2762 1433500 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2763 : {
2764 1376160 : extOutMeta->directToTotalRatio[1][sf][i] = 0;
2765 1376160 : move16();
2766 : }
2767 :
2768 1433500 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2769 : {
2770 1376160 : extOutMeta->spreadCoherence[1][sf][i] = 0;
2771 1376160 : move16();
2772 : }
2773 : }
2774 :
2775 : /* Common spatial meta */
2776 : /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */
2777 948684 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2778 : {
2779 2639008 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2780 : {
2781 1764164 : extOutMeta->diffuseToTotalRatio[sf][b_new] = UINT8_MAX;
2782 1764164 : move16();
2783 3924328 : FOR( dir = 0; dir < numDirections; dir++ )
2784 : {
2785 :
2786 2160164 : UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0
2787 2160164 : move16();
2788 2160164 : extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8
2789 2160164 : move16();
2790 : }
2791 : }
2792 : }
2793 :
2794 : /* Surround coherence */
2795 73840 : IF( hQMetaData->surcoh_band_data != NULL )
2796 : {
2797 830340 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2798 : {
2799 2099756 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2800 : {
2801 1324608 : extOutMeta->surroundCoherence[sf][b_new] = hQMetaData->surcoh_band_data[b_old].surround_coherence[sf];
2802 1324608 : move16();
2803 : }
2804 : }
2805 : }
2806 : ELSE
2807 : {
2808 466200 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2809 : {
2810 447552 : extOutMeta->surroundCoherence[sf][i] = 0;
2811 447552 : move16();
2812 : }
2813 : }
2814 : }
2815 :
2816 18460 : return;
2817 : }
2818 :
2819 :
2820 8599 : static void decode_index_slice_fx(
2821 : Word16 index, /* i : index to decode */
2822 : Word16 *ratio_idx_ism, /* o : decodec array of integers Q0*/
2823 : const Word16 nchan_ism, /* i : number of elements in array (objects) */
2824 : const Word16 K /* i : sum of array elements Q0*/
2825 : )
2826 : {
2827 : Word16 i, j, sum, elem;
2828 : Word16 base[MAX_NUM_OBJECTS];
2829 :
2830 8599 : SWITCH( nchan_ism )
2831 : {
2832 1169 : case 2:
2833 1169 : ratio_idx_ism[0] = index;
2834 1169 : move16();
2835 1169 : ratio_idx_ism[1] = sub( K, ratio_idx_ism[0] );
2836 1169 : move16();
2837 1169 : BREAK;
2838 7430 : case 3:
2839 : case 4:
2840 : {
2841 7430 : j = 0;
2842 7430 : move16();
2843 1101631 : WHILE( index >= 0 )
2844 : {
2845 1094201 : IF( valid_ratio_index_fx( j, K, nchan_ism - 1 ) )
2846 : {
2847 280698 : index = sub( index, 1 );
2848 : }
2849 1094201 : j = add( j, 1 );
2850 : }
2851 7430 : j = sub( j, 1 );
2852 7430 : base[0] = 1;
2853 7430 : move16();
2854 20152 : FOR( i = 1; i < nchan_ism - 1; i++ )
2855 : {
2856 12722 : base[i] = i_mult( base[i - 1], 10 );
2857 12722 : move16();
2858 : }
2859 7430 : sum = 0;
2860 7430 : move16();
2861 27582 : FOR( i = nchan_ism - 2; i >= 0; i-- )
2862 : {
2863 20152 : IF( EQ_16( j, 0 ) )
2864 : {
2865 7210 : elem = 0;
2866 7210 : move16();
2867 : }
2868 : ELSE
2869 : {
2870 12942 : elem = idiv1616( j, base[i] );
2871 : }
2872 20152 : ratio_idx_ism[nchan_ism - i - 2] = elem;
2873 20152 : move16();
2874 20152 : sum = add( sum, elem );
2875 20152 : j = sub( j, i_mult( elem, base[i] ) );
2876 : }
2877 7430 : ratio_idx_ism[nchan_ism - 1] = sub( K, sum );
2878 7430 : move16();
2879 : }
2880 :
2881 7430 : default:
2882 7430 : BREAK;
2883 : }
2884 :
2885 8599 : return;
2886 : }
2887 :
2888 :
2889 15391 : static void read_ism_ratio_index_fx(
2890 : Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM read ratio indexes Q0*/
2891 : const Word16 nchan_ism, /* i : number of objects */
2892 : const Word16 numCodingBands, /* i : number of subbands */
2893 : const Word16 sf, /* i : index of subframe */
2894 : Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i : previous subframe ISM ratio indexes Q0*/
2895 : UWord16 *bit_stream, /* i : bitstream */
2896 : Word16 *next_bit_pos, /* i/o: position in bitstream */
2897 : const Word32 *masa_to_total_energy_ratio_fx, /* i : masa to total ratios Q30*/
2898 : const Word16 idx_sep_obj, /* i : index of separated index, -1 if none */
2899 : Word16 *num_zeros /* i/o: number of zero values in first subframe for separated object */
2900 : )
2901 : {
2902 : Word16 b, i, b_signif;
2903 : Word16 index;
2904 : Word16 GR_order, differential_subframe;
2905 : Word16 buf;
2906 : Word16 no_levels_ratio_ism;
2907 : Word16 bits_index;
2908 : Word16 ratio_ism_idx_ref[MAX_NUM_OBJECTS];
2909 : Word16 idx_sep_obj_local, shift_one;
2910 :
2911 15391 : idx_sep_obj_local = idx_sep_obj;
2912 15391 : move16();
2913 :
2914 15391 : IF( GT_16( idx_sep_obj, -1 ) )
2915 : {
2916 15391 : test();
2917 15391 : if ( EQ_16( idx_sep_obj, sub( nchan_ism, 1 ) ) && GT_16( nchan_ism, 2 ) )
2918 : {
2919 4041 : idx_sep_obj_local = 0;
2920 4041 : move16();
2921 : }
2922 : }
2923 :
2924 15391 : b_signif = 0;
2925 15391 : move16();
2926 15391 : no_levels_ratio_ism = sub( shl( 1, PARAM_ISM_POW_RATIO_NBITS ), 1 );
2927 :
2928 44805 : WHILE( ( LT_16( b_signif, numCodingBands ) ) && ( GE_32( masa_to_total_energy_ratio_fx[b_signif], MASA2TOTAL_THR_Q30 ) ) )
2929 : {
2930 29414 : test();
2931 : /* distribute evenly the objects */
2932 29414 : distribute_evenly_ism_fx( ratio_ism_idx[b_signif], no_levels_ratio_ism, nchan_ism );
2933 29414 : b_signif = add( b_signif, 1 );
2934 : }
2935 :
2936 15391 : IF( EQ_16( b_signif, numCodingBands ) )
2937 : {
2938 4489 : return;
2939 : }
2940 : ELSE
2941 : {
2942 :
2943 10902 : IF( sf == 0 )
2944 : {
2945 4507 : bits_index = bits_index_ism_ratio_fx( nchan_ism );
2946 :
2947 : /* read coding type */
2948 4507 : IF( EQ_32( bit_stream[( *next_bit_pos )--], 1 ) )
2949 : {
2950 : /* independent coding*/
2951 6844 : FOR( b = 0; b < numCodingBands; b++ )
2952 : {
2953 5915 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
2954 : {
2955 5021 : index = 0;
2956 5021 : move16();
2957 36934 : FOR( i = 0; i < bits_index; i++ )
2958 : {
2959 31913 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
2960 : }
2961 5021 : decode_index_slice_fx( index, ratio_ism_idx[b], nchan_ism, no_levels_ratio_ism );
2962 5021 : test();
2963 5021 : IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
2964 : {
2965 3896 : *num_zeros = add( *num_zeros, 1 );
2966 3896 : move16();
2967 : }
2968 : }
2969 : ELSE
2970 : {
2971 : /* distribute evenly the objects */
2972 894 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
2973 : }
2974 : }
2975 : }
2976 : ELSE
2977 : {
2978 : /* differential coding */
2979 3578 : index = 0;
2980 3578 : move16();
2981 25044 : FOR( i = 0; i < bits_index; i++ )
2982 : {
2983 21466 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
2984 : }
2985 3578 : decode_index_slice_fx( index, ratio_ism_idx[b_signif], nchan_ism, no_levels_ratio_ism );
2986 3578 : test();
2987 3578 : IF( GT_16( idx_sep_obj, -1 ) && ratio_ism_idx[b_signif][idx_sep_obj_local] == 0 )
2988 : {
2989 3182 : *num_zeros = add( *num_zeros, 1 );
2990 3182 : move16();
2991 : }
2992 3578 : Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
2993 26615 : FOR( b = b_signif + 1; b < numCodingBands; b++ )
2994 : {
2995 23037 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
2996 : {
2997 20390 : ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
2998 20390 : move16();
2999 72186 : FOR( i = 0; i < nchan_ism - 1; i++ )
3000 : {
3001 51796 : buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, 0 );
3002 51796 : IF( EQ_16( buf % 2, 0 ) )
3003 : {
3004 48699 : ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
3005 48699 : move16();
3006 : }
3007 : ELSE
3008 : {
3009 3097 : ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
3010 3097 : move16();
3011 : }
3012 51796 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
3013 51796 : move16();
3014 51796 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
3015 51796 : move16();
3016 : }
3017 20390 : Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
3018 20390 : test();
3019 20390 : IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
3020 : {
3021 18227 : *num_zeros = add( *num_zeros, 1 );
3022 18227 : move16();
3023 : }
3024 : }
3025 : ELSE
3026 : {
3027 : /* distribute evenly the objects */
3028 2647 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3029 : }
3030 : }
3031 : }
3032 : }
3033 : ELSE
3034 : {
3035 6395 : IF( GT_16( numCodingBands, 1 ) )
3036 : {
3037 : /* read prediction type */
3038 6311 : differential_subframe = bit_stream[( *next_bit_pos )--];
3039 6311 : move16();
3040 : }
3041 : ELSE
3042 : {
3043 84 : differential_subframe = 1;
3044 84 : move16();
3045 : }
3046 :
3047 6395 : IF( EQ_16( *num_zeros, numCodingBands ) )
3048 : {
3049 3990 : shift_one = 1;
3050 3990 : move16();
3051 : }
3052 : ELSE
3053 : {
3054 2405 : shift_one = 0;
3055 2405 : move16();
3056 : }
3057 :
3058 6395 : test();
3059 6395 : IF( EQ_16( shift_one, 1 ) && EQ_16( nchan_ism, 2 ) )
3060 : {
3061 : /* nothing has been sent ; values can be inferred */
3062 168 : FOR( b = b_signif; b < numCodingBands; b++ )
3063 : {
3064 84 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3065 : {
3066 84 : IF( idx_sep_obj_local == 0 )
3067 : {
3068 48 : ratio_ism_idx[b][0] = 0;
3069 48 : move16();
3070 48 : ratio_ism_idx[b][1] = 7;
3071 48 : move16();
3072 : }
3073 : ELSE
3074 : {
3075 36 : ratio_ism_idx[b][0] = 7;
3076 36 : move16();
3077 36 : ratio_ism_idx[b][1] = 0;
3078 36 : move16();
3079 : }
3080 : }
3081 : }
3082 : }
3083 : ELSE
3084 : {
3085 : /* read GR order */
3086 6311 : GR_order = bit_stream[( *next_bit_pos )--];
3087 6311 : move16();
3088 :
3089 36726 : FOR( b = b_signif; b < numCodingBands; b++ )
3090 : {
3091 30415 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3092 : {
3093 83657 : FOR( i = 0; i < nchan_ism - ( 1 + shift_one ); i++ )
3094 : {
3095 56036 : buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, GR_order );
3096 56036 : IF( ( buf % 2 ) == 0 )
3097 : {
3098 50971 : ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
3099 50971 : move16();
3100 : }
3101 : ELSE
3102 : {
3103 5065 : ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
3104 5065 : move16();
3105 : }
3106 : }
3107 :
3108 : /* insert separated obj */
3109 27621 : IF( shift_one )
3110 : {
3111 53433 : FOR( i = nchan_ism - 1; i > idx_sep_obj_local; i-- )
3112 : {
3113 34511 : ratio_ism_idx[b][i] = ratio_ism_idx[b][i - 1];
3114 34511 : move16();
3115 : }
3116 18922 : ratio_ism_idx[b][idx_sep_obj_local] = 0; /* this is only difference; need to pdate later as well */
3117 18922 : move16();
3118 : }
3119 : }
3120 : }
3121 6311 : IF( differential_subframe )
3122 : {
3123 : /* differential to previous subframe */
3124 30967 : FOR( b = b_signif; b < numCodingBands; b++ )
3125 : {
3126 25641 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3127 : {
3128 23425 : ratio_ism_idx[b][sub( nchan_ism, 1 )] = no_levels_ratio_ism;
3129 23425 : move16();
3130 86850 : FOR( i = 0; i < nchan_ism - 1; i++ )
3131 : {
3132 63425 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_prev_sf[b][i] );
3133 63425 : move16();
3134 :
3135 63425 : test();
3136 63425 : if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
3137 : {
3138 17331 : ratio_ism_idx[b][i] = 0;
3139 17331 : move16();
3140 : }
3141 63425 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
3142 : }
3143 : }
3144 : ELSE
3145 : {
3146 : /* distribute evenly the objects */
3147 2216 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3148 : }
3149 : }
3150 : }
3151 : ELSE
3152 : {
3153 : /* difference to previous subband */
3154 985 : ratio_ism_idx[b_signif][nchan_ism - 1] = no_levels_ratio_ism;
3155 985 : move16();
3156 :
3157 : /* first significant subband - differential to previous subframe */
3158 3681 : FOR( i = 0; i < nchan_ism - 1; i++ )
3159 : {
3160 2696 : ratio_ism_idx[b_signif][i] = add( ratio_ism_idx[b_signif][i], ratio_ism_idx_prev_sf[b_signif][i] );
3161 2696 : move16();
3162 :
3163 2696 : test();
3164 2696 : if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
3165 : {
3166 325 : ratio_ism_idx[b_signif][i] = 0;
3167 325 : move16();
3168 : }
3169 2696 : ratio_ism_idx[b_signif][nchan_ism - 1] = sub( ratio_ism_idx[b_signif][nchan_ism - 1], ratio_ism_idx[b_signif][i] );
3170 2696 : move16();
3171 : }
3172 :
3173 : /* rest of subbands differential to previous subband */
3174 985 : Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
3175 4774 : FOR( b = b_signif + 1; b < numCodingBands; b++ )
3176 : {
3177 3789 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3178 : {
3179 3211 : ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
3180 3211 : move16();
3181 :
3182 12048 : FOR( i = 0; i < nchan_ism - 1; i++ )
3183 : {
3184 8837 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
3185 8837 : move16();
3186 :
3187 8837 : test();
3188 8837 : if ( NE_16( shift_one, 0 ) && EQ_16( i, idx_sep_obj_local ) )
3189 : {
3190 1266 : ratio_ism_idx[b][i] = 0;
3191 1266 : move16();
3192 : }
3193 8837 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
3194 8837 : move16();
3195 : }
3196 3211 : Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
3197 : }
3198 : ELSE
3199 : {
3200 : /* distribute evenly the objects */
3201 578 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3202 : }
3203 : }
3204 : }
3205 : }
3206 : }
3207 :
3208 10902 : return;
3209 : }
3210 : }
3211 :
3212 :
3213 6748 : static void decode_ism_ratios_fx(
3214 : UWord16 *bit_stream, /* i : bitstream */
3215 : Word16 *next_bit_pos, /* i/o: position in bitstream */
3216 : Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : masa_to_total energy ratios Q30*/
3217 : Word32 ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM ratios Q30*/
3218 : const Word16 n_ism, /* i : number of objects */
3219 : const Word16 nbands, /* i : number of subbands */
3220 : const Word16 numSf, /* i : number of subframes */
3221 : const Word16 idx_separated_object /* i : index of separated object */
3222 : )
3223 : {
3224 : Word16 sf, band;
3225 : Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
3226 : Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
3227 : Word32 tmp32_fx;
3228 : Word16 num_zeros;
3229 6748 : num_zeros = 0;
3230 6748 : move16();
3231 :
3232 : /* hQMetaData->q_direction->cfg.nblocks; */
3233 22139 : FOR( sf = 0; sf < numSf; sf++ )
3234 : {
3235 : /* read ism ratio indexes */
3236 15391 : read_ism_ratio_index_fx( ratio_ism_idx, n_ism, nbands, sf, ratio_ism_idx_prev_sf, bit_stream, next_bit_pos, masa_to_total_energy_ratio_fx[sf], idx_separated_object, &num_zeros );
3237 : /* save previous subframe index values */
3238 15391 : IF( LT_16( sf, sub( numSf, 1 ) ) )
3239 : {
3240 51102 : FOR( band = 0; band < nbands; band++ )
3241 : {
3242 42459 : Copy( ratio_ism_idx[band], ratio_ism_idx_prev_sf[band], n_ism );
3243 : }
3244 : }
3245 :
3246 : /* reconstructed values */
3247 107662 : FOR( band = 0; band < nbands; band++ )
3248 : {
3249 92271 : reconstruct_ism_ratios_fx( ratio_ism_idx[band], n_ism, STEP_PARAM_ISM_POW_RATIO_NBITS_Q31, ratio_ism[sf][band] );
3250 : }
3251 :
3252 15391 : test();
3253 15391 : IF( GT_16( n_ism, 2 ) && ( EQ_16( idx_separated_object, sub( n_ism, 1 ) ) ) )
3254 : {
3255 : /* rotate */
3256 28117 : FOR( band = 0; band < nbands; band++ )
3257 : {
3258 24076 : IF( LT_32( masa_to_total_energy_ratio_fx[sf][band], MASA2TOTAL_THR_Q30 ) )
3259 : {
3260 13158 : tmp32_fx = ratio_ism[sf][band][n_ism - 1]; // Q30
3261 13158 : move32();
3262 13158 : ratio_ism[sf][band][n_ism - 1] = ratio_ism[sf][band][0];
3263 13158 : move32();
3264 13158 : ratio_ism[sf][band][0] = tmp32_fx;
3265 13158 : move32();
3266 : }
3267 : }
3268 : }
3269 :
3270 15391 : IF( EQ_16( nbands, 1 ) )
3271 : {
3272 1260 : FOR( band = 1; band < 5; band++ )
3273 : {
3274 1008 : Copy32( ratio_ism[sf][0], ratio_ism[sf][band], n_ism );
3275 : }
3276 : }
3277 : }
3278 :
3279 6748 : IF( EQ_16( numSf, 1 ) )
3280 : {
3281 15468 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
3282 : {
3283 118578 : FOR( band = 0; band < nbands; band++ )
3284 : {
3285 106977 : Copy32( ratio_ism[0][band], ratio_ism[sf][band], n_ism );
3286 : }
3287 : }
3288 : }
3289 :
3290 6748 : return;
3291 : }
3292 :
3293 :
3294 6748 : static Word16 ivas_decode_masaism_metadata_fx(
3295 : IVAS_QMETADATA_HANDLE hQMetaData,
3296 : MASA_DECODER_HANDLE hMasa,
3297 : MASA_ISM_DATA_HANDLE hMasaIsmData,
3298 : const Word16 nchan_ism,
3299 : UWord16 *bit_stream,
3300 : Word16 *next_bit_pos,
3301 : const Word16 idx_separated_object,
3302 : const Word16 ism_imp,
3303 : const Word16 dirac_bs_md_write_idx,
3304 : const Word16 dirac_md_buffer_length )
3305 : {
3306 : Word16 sf, band, dir, nbands, nblocks, obj, i;
3307 : Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; // Q30
3308 : Word16 *band_mapping;
3309 : Word16 b;
3310 : Word16 bits_ism[MAX_NUM_OBJECTS], index;
3311 : UWord16 idx_el, idx_az;
3312 : Word32 azimuth, elevation; // Q22
3313 : Word16 nb_bits_read;
3314 : Word32 delta_phi; // Q22
3315 : Word16 meta_write_index;
3316 :
3317 6748 : nb_bits_read = *next_bit_pos;
3318 6748 : move16();
3319 6748 : nbands = hQMetaData->q_direction->cfg.nbands;
3320 6748 : move16();
3321 6748 : nblocks = hQMetaData->q_direction->cfg.nblocks;
3322 6748 : move16();
3323 :
3324 : /* Read MASA-to-total energy ratios */
3325 6748 : ivas_omasa_decode_masa_to_total_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, nbands, nblocks );
3326 :
3327 6748 : IF( GT_16( nchan_ism, 1 ) )
3328 : {
3329 : /* read ISM ratios */
3330 6748 : decode_ism_ratios_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, energy_ratio_ism_fx, nchan_ism, nbands, nblocks, idx_separated_object );
3331 : }
3332 : ELSE
3333 : {
3334 0 : FOR( sf = 0; sf < nblocks; sf++ )
3335 : {
3336 0 : FOR( band = 0; band < nbands; band++ )
3337 : {
3338 0 : energy_ratio_ism_fx[sf][band][0] = ONE_IN_Q30;
3339 0 : move32();
3340 : }
3341 : }
3342 : }
3343 :
3344 : /* read ISM metadata */
3345 6748 : calculate_nbits_meta_fx( nchan_ism, energy_ratio_ism_fx, hMasaIsmData->masa_to_total_energy_ratio_fx, nblocks, nbands, bits_ism, idx_separated_object, ism_imp );
3346 :
3347 29364 : FOR( obj = 0; obj < nchan_ism; obj++ )
3348 : {
3349 22616 : hMasaIsmData->bits_ism[obj] = bits_ism[obj];
3350 22616 : index = 0;
3351 22616 : move16();
3352 22616 : IF( LT_16( bits_ism[obj], 8 ) ) /* if low resolution, can look to the past */
3353 : {
3354 : /* read if same as previous */
3355 11013 : IF( bit_stream[( *next_bit_pos )--] )
3356 : {
3357 1146 : azimuth = hMasaIsmData->q_azimuth_old_fx[obj]; // Q22
3358 1146 : move32();
3359 1146 : elevation = hMasaIsmData->q_elevation_old_fx[obj]; // Q22
3360 1146 : move32();
3361 : }
3362 : ELSE
3363 : {
3364 63717 : FOR( i = 0; i < bits_ism[obj]; i++ )
3365 : {
3366 53850 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
3367 : }
3368 :
3369 9867 : deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
3370 :
3371 9867 : test();
3372 9867 : test();
3373 9867 : test();
3374 : /* if ( azimuth * hMasaIsmData->q_azimuth_old[obj] > 0 ) */
3375 9867 : IF( ( ( azimuth > 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] > 0 ) ) || ( ( azimuth < 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] < 0 ) ) )
3376 : {
3377 : Word16 tmp_e;
3378 8233 : delta_phi = L_deposit_h( BASOP_Util_Divide1616_Scale( 180, no_phi_masa[bits_ism[obj] - 1][idx_el], &tmp_e ) );
3379 8233 : delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); /* to maintain Q22 */
3380 :
3381 : Word32 tmp_32;
3382 : Word64 tmp_64;
3383 8233 : tmp_32 = L_sub( azimuth, hMasaIsmData->q_azimuth_old_fx[obj] );
3384 8233 : tmp_64 = W_mult_32_16( tmp_32, no_phi_masa[bits_ism[obj] - 1][idx_el] );
3385 :
3386 8233 : IF( GT_64( tmp_64, TOLERANCE_360_Q22 ) ) /* >= 360 in Q22 (because there is an additional shift left in W_mult_32_16) + 0.02 in Q22 to counteract for precision loss, */
3387 : {
3388 851 : azimuth = L_sub( azimuth, delta_phi );
3389 : }
3390 : ELSE
3391 : {
3392 7382 : IF( GT_64( MINUS_TOLERANCE_360_Q22, tmp_64 ) )
3393 : {
3394 752 : azimuth = L_add( azimuth, delta_phi );
3395 : }
3396 : }
3397 : }
3398 :
3399 9867 : hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
3400 9867 : move32();
3401 9867 : hMasaIsmData->q_elevation_old_fx[obj] = elevation;
3402 9867 : move32();
3403 : }
3404 : }
3405 : ELSE
3406 : {
3407 132978 : FOR( i = 0; i < bits_ism[obj]; i++ )
3408 : {
3409 121375 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
3410 : }
3411 11603 : deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
3412 :
3413 11603 : hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
3414 11603 : move32();
3415 11603 : hMasaIsmData->q_elevation_old_fx[obj] = elevation;
3416 11603 : move32();
3417 : }
3418 :
3419 113080 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
3420 : {
3421 90464 : meta_write_index = add( dirac_bs_md_write_idx, sf ) % dirac_md_buffer_length;
3422 :
3423 90464 : Word16 int_azi = rint_fx( L_shr( azimuth, Q22 - 16 ) ); // Q0, extra -16 is added as int_azi is W16 and azimuth is W32
3424 90464 : Word16 int_ele = rint_fx( L_shr( elevation, Q22 - 16 ) ); // Q0
3425 :
3426 90464 : hMasaIsmData->azimuth_ism_fx[obj][meta_write_index] = int_azi; // Q0
3427 90464 : move16();
3428 90464 : hMasaIsmData->elevation_ism_fx[obj][meta_write_index] = int_ele; // Q0
3429 90464 : move16();
3430 : }
3431 : }
3432 :
3433 : /* Modify ISM metadata based on the MASA-to-total energy ratios */
3434 22139 : FOR( sf = 0; sf < nblocks; sf++ )
3435 : {
3436 107662 : FOR( band = 0; band < nbands; band++ )
3437 : {
3438 425549 : FOR( dir = 0; dir < nchan_ism; dir++ )
3439 : {
3440 333278 : energy_ratio_ism_fx[sf][band][dir] = L_shl( Mpy_32_32( energy_ratio_ism_fx[sf][band][dir], L_sub( ONE_IN_Q30, hMasaIsmData->masa_to_total_energy_ratio_fx[sf][band] ) ), 1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30
3441 333278 : move32();
3442 : }
3443 : }
3444 : }
3445 :
3446 : /* Set data to struct in bins */
3447 6748 : band_mapping = hMasa->data.band_mapping;
3448 6748 : move16();
3449 56574 : FOR( band = 0; band < hMasa->config.numCodingBands; ++band )
3450 : {
3451 435786 : FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
3452 : {
3453 1929800 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; ++sf )
3454 : {
3455 1543840 : IF( EQ_16( nblocks, 1 ) )
3456 : {
3457 909040 : i = 0;
3458 909040 : move16();
3459 : }
3460 : ELSE
3461 : {
3462 634800 : i = sf;
3463 634800 : move16();
3464 : }
3465 :
3466 1543840 : meta_write_index = ( add( dirac_bs_md_write_idx, sf ) ) % dirac_md_buffer_length;
3467 :
3468 6704960 : FOR( dir = 0; dir < nchan_ism; dir++ )
3469 : {
3470 5161120 : hMasaIsmData->energy_ratio_ism_fx[dir][meta_write_index][b] = energy_ratio_ism_fx[i][band][dir];
3471 5161120 : move32();
3472 : }
3473 :
3474 1543840 : IF( hMasaIsmData->hExtData != NULL )
3475 : {
3476 0 : hMasaIsmData->hExtData->masa_render_masa_to_total[meta_write_index][b] =
3477 0 : hMasaIsmData->masa_to_total_energy_ratio_fx[i][band];
3478 0 : move32();
3479 : }
3480 : }
3481 : }
3482 : }
3483 :
3484 6748 : return sub( nb_bits_read, *next_bit_pos );
3485 : }
3486 :
3487 :
3488 : /*
3489 : Fixed point implementation of rint().
3490 : */
3491 : /* returns in Q0 */
3492 180928 : static Word16 rint_fx(
3493 : const Word32 num /* num in Q0 */
3494 : )
3495 : {
3496 180928 : Word32 frac_part = L_and( L_abs( num ), 0x0000FFFF ); // Q15
3497 180928 : Word16 int_part = extract_h( L_abs( num ) );
3498 180928 : Word16 res = int_part;
3499 180928 : move16();
3500 :
3501 180928 : test();
3502 180928 : test();
3503 180928 : if ( GT_32( frac_part, ONE_IN_Q15 ) || ( EQ_32( frac_part, ONE_IN_Q15 ) && EQ_16( s_and( int_part, 1 ), 1 ) ) )
3504 : {
3505 42968 : res = add( res, 1 );
3506 : }
3507 180928 : if ( num < 0 )
3508 : {
3509 72176 : res = negate( res );
3510 : }
3511 180928 : return res;
3512 : }
|