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 124502 : 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 124502 : dirac_bs_md_write_idx = 0;
112 124502 : move16();
113 124502 : ism_imp = 0;
114 124502 : move16();
115 :
116 124502 : error = IVAS_ERR_OK;
117 124502 : move16();
118 124502 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
119 124502 : move32();
120 :
121 124502 : low_bitrate_mode = -1; /* This means that LBR mode is not used. */
122 124502 : move16();
123 :
124 124502 : test();
125 124502 : test();
126 124502 : test();
127 124502 : 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 31884 : masa_brate = st_ivas->hCPE[0]->element_brate;
130 31884 : move32();
131 : }
132 : ELSE
133 : {
134 92618 : masa_brate = ivas_total_brate;
135 92618 : move32();
136 : }
137 :
138 124502 : hMasa = st_ivas->hMasa;
139 124502 : hQMetaData = st_ivas->hQMetaData;
140 124502 : ivas_format = st_ivas->ivas_format;
141 124502 : move32();
142 :
143 124502 : hMasa->data.dir_decode_quality_fx = MAX16B; /* Set to default of max quality */ /* 1.0f in Q15 */
144 124502 : move16();
145 :
146 124502 : hQMetaData->is_masa_ivas_format = 1;
147 124502 : move16();
148 :
149 124502 : *nb_bits_read = 0;
150 124502 : move16();
151 :
152 124502 : next_bit_pos_orig = st->next_bit_pos;
153 124502 : move16();
154 :
155 : /* masa_brate / FRAMES_PER_SEC */
156 124502 : tmp = extract_l( Mpy_32_32( masa_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); // Q0
157 :
158 124502 : 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 124308 : st->next_bit_pos = sub( tmp, 1 );
165 : }
166 124502 : move16();
167 :
168 124502 : test();
169 124502 : test();
170 124502 : 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 124502 : test();
177 124502 : test();
178 124502 : test();
179 124502 : test();
180 124502 : test();
181 124502 : IF( st->bfi == 0 && GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
182 : {
183 121147 : test();
184 121147 : IF( NE_32( ivas_format, MC_FORMAT ) || NE_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
185 109366 : {
186 109366 : Word16 bits_per_frame = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
187 :
188 109366 : IF( EQ_32( ivas_format, MASA_FORMAT ) )
189 : {
190 : /* re-read the number of objects, needed in case of bad frame */
191 78805 : 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 78805 : if ( EQ_16( ch, 5 ) )
194 : {
195 70609 : ch = 0;
196 70609 : move16();
197 : }
198 78805 : st_ivas->nchan_ism = ch;
199 78805 : move16();
200 : }
201 :
202 109366 : test();
203 109366 : IF( EQ_32( ivas_format, MASA_FORMAT ) && GT_16( st_ivas->nchan_ism, 0 ) )
204 : {
205 : /* there was OMASA in the input */
206 8196 : hMasa->config.input_ivas_format = MASA_ISM_FORMAT;
207 8196 : move32();
208 8196 : 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 5936 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
237 5936 : move16();
238 5936 : *nb_bits_read = add( *nb_bits_read, 1 );
239 5936 : hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
240 :
241 : /* the two reserved bits were already read in ivas_init_dec()*/
242 5936 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
243 5936 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
244 5936 : move16();
245 5936 : move16();
246 5936 : *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
247 : }
248 : }
249 : ELSE
250 : {
251 101170 : 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 101170 : test();
261 101170 : 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 30561 : st->next_bit_pos = sub( st->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
265 30561 : *nb_bits_read = add( *nb_bits_read, NO_BITS_MASA_ISM_NO_OBJ );
266 30561 : move16();
267 30561 : move16();
268 :
269 30561 : 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 7949 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
274 7949 : move16();
275 7949 : *nb_bits_read = add( *nb_bits_read, 1 );
276 7949 : move16();
277 7949 : st_ivas->hMasaIsmData->idx_separated_ism = extract_l( L_add( L_shl( byteBuffer, 1 ), st->bit_stream[( st->next_bit_pos )--] ) );
278 7949 : move16();
279 7949 : *nb_bits_read = add( *nb_bits_read, 1 );
280 7949 : move16();
281 : }
282 : ELSE
283 : {
284 22612 : st_ivas->hMasaIsmData->idx_separated_ism = -1;
285 22612 : move16();
286 : }
287 :
288 : /* read ISM importance flag (one per object) */
289 30561 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
290 : {
291 7949 : ism_imp = 0;
292 7949 : move16();
293 :
294 23847 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
295 : {
296 15898 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
297 15898 : move16();
298 15898 : *nb_bits_read = add( *nb_bits_read, 1 );
299 15898 : move16();
300 15898 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
301 : }
302 7949 : st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
303 7949 : move16();
304 : }
305 :
306 30561 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
307 : {
308 10018 : ism_imp = 0;
309 10018 : move16();
310 30054 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
311 : {
312 20036 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
313 20036 : move16();
314 20036 : *nb_bits_read = add( *nb_bits_read, 1 );
315 20036 : move16();
316 20036 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
317 20036 : move16();
318 : }
319 10018 : st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
320 10018 : move16();
321 :
322 : /* reset */
323 10018 : st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0;
324 10018 : move16();
325 10018 : st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0;
326 10018 : move16();
327 :
328 10018 : 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 20543 : ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
342 : {
343 49842 : FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ )
344 : {
345 37248 : ism_imp = 0;
346 37248 : move16();
347 111744 : FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
348 : {
349 74496 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
350 74496 : move16();
351 74496 : *nb_bits_read = add( *nb_bits_read, 1 );
352 74496 : move16();
353 74496 : ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
354 : }
355 37248 : st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp;
356 37248 : move16();
357 :
358 : /* reset */
359 37248 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
360 37248 : move16();
361 37248 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
362 37248 : move16();
363 :
364 37248 : 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 12594 : st_ivas->flag_omasa_brate = 0;
379 12594 : move16();
380 :
381 12594 : test();
382 12594 : IF( GE_16( st_ivas->nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) )
383 : {
384 492 : st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--];
385 492 : move16();
386 492 : *nb_bits_read = add( *nb_bits_read, 1 );
387 492 : move16();
388 : }
389 : }
390 : }
391 101170 : byteBuffer = st->bit_stream[st->next_bit_pos];
392 101170 : move16();
393 101170 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
394 101170 : byteBuffer = add( byteBuffer, shl( st->bit_stream[st->next_bit_pos], 1 ) );
395 101170 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
396 :
397 101170 : test();
398 101170 : 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 30561 : hMasa->config.input_ivas_format = MASA_ISM_FORMAT;
406 30561 : move32();
407 : }
408 101170 : *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
409 :
410 : /* read number of directions */
411 101170 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
412 101170 : move16();
413 101170 : *nb_bits_read = add( *nb_bits_read, 1 );
414 101170 : move16();
415 101170 : hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
416 101170 : move16();
417 : }
418 : }
419 : ELSE
420 : {
421 11781 : hMasa->config.numberOfDirections = 1;
422 11781 : move16();
423 : }
424 :
425 121147 : test();
426 121147 : IF( NE_32( ivas_format, MC_FORMAT ) || NE_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
427 : {
428 : /* read subframe mode */
429 109366 : byteBuffer = st->bit_stream[( st->next_bit_pos )--];
430 109366 : move16();
431 109366 : *nb_bits_read = add( *nb_bits_read, 1 );
432 109366 : move16();
433 109366 : hMasa->config.joinedSubframes = (UWord8) byteBuffer;
434 109366 : move16();
435 : }
436 : ELSE
437 : {
438 11781 : hMasa->config.joinedSubframes = FALSE;
439 11781 : move16();
440 : }
441 :
442 121147 : 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 121147 : 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 121147 : test();
456 121147 : 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 35013 : byteBuffer = st->bit_stream[st->next_bit_pos];
460 35013 : move16();
461 35013 : st->next_bit_pos = sub( st->next_bit_pos, 1 );
462 35013 : move16();
463 35013 : *nb_bits_read = add( *nb_bits_read, 1 );
464 35013 : move16();
465 35013 : low_bitrate_mode = byteBuffer;
466 35013 : move16();
467 :
468 35013 : IF( EQ_16( low_bitrate_mode, 1 ) )
469 : {
470 28887 : hQMetaData->q_direction[0].cfg.nblocks = 1;
471 28887 : move16();
472 : }
473 : ELSE
474 : {
475 6126 : hQMetaData->q_direction[0].cfg.nbands = 1;
476 6126 : move16();
477 : }
478 : }
479 :
480 : /* Remove already read bits from the bit budget */
481 121147 : hQMetaData->metadata_max_bits = sub( hQMetaData->metadata_max_bits, *nb_bits_read );
482 121147 : move16();
483 :
484 121147 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
485 : {
486 30561 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
487 : {
488 7949 : IF( st_ivas->hDirAC != NULL )
489 : {
490 6211 : *nb_bits_read = add( *nb_bits_read,
491 6211 : ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
492 6211 : st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) );
493 6211 : move16();
494 32923 : FOR( obj = 0; obj <= st_ivas->nchan_ism; obj++ )
495 : {
496 26712 : IF( EQ_16( st_ivas->hMasaIsmData->idx_separated_ism, obj ) )
497 : {
498 : Word16 sf;
499 : Word16 meta_write_index;
500 :
501 31055 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
502 : {
503 24844 : meta_write_index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, sf ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
504 24844 : st_ivas->hMasaIsmData->azimuth_separated_ism_fx[meta_write_index] = st_ivas->hMasaIsmData->azimuth_ism_fx[obj][meta_write_index];
505 24844 : move16();
506 24844 : st_ivas->hMasaIsmData->elevation_separated_ism_fx[meta_write_index] = st_ivas->hMasaIsmData->elevation_ism_fx[obj][meta_write_index];
507 24844 : move16();
508 : }
509 : }
510 : }
511 : }
512 1738 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
513 : {
514 252 : *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData,
515 252 : st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
516 252 : 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 121147 : masa_total_brate = ivas_total_brate;
528 121147 : move32();
529 121147 : test();
530 121147 : IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
531 : {
532 12594 : masa_total_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
533 : }
534 :
535 121147 : 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 114114 : *nb_bits_read = add( *nb_bits_read,
553 114114 : ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos, 0 ) );
554 114114 : move16();
555 : }
556 :
557 121147 : test();
558 121147 : test();
559 121147 : 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 7949 : 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 121147 : if ( EQ_16( hQMetaData->ec_flag, 2 ) )
567 : {
568 8440 : hMasa->data.dir_decode_quality_fx = hQMetaData->dir_comp_ratio_fx; /* Q15 */
569 8440 : move16();
570 : }
571 :
572 121147 : hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero;
573 121147 : move16();
574 :
575 121147 : test();
576 121147 : test();
577 121147 : 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 18997 : 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 121147 : IF( NE_16( low_bitrate_mode, -1 ) )
584 : {
585 35013 : restore_lowbitrate_masa_fx( hQMetaData, low_bitrate_mode, hMasa->config.numCodingBands );
586 : }
587 86134 : ELSE IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
588 : {
589 49970 : replicate_subframes_fx( hQMetaData );
590 : }
591 : }
592 3355 : 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 3161 : 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 124502 : IF( st_ivas->hDirAC != NULL )
662 : {
663 95051 : dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
664 95051 : move16();
665 :
666 95051 : ivas_qmetadata_to_dirac_fx( hQMetaData, st_ivas->hDirAC, hMasa, st_ivas->hSpatParamRendCom, ivas_total_brate, ivas_format, 0, 0 );
667 : }
668 29451 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
669 : {
670 252 : Word16 index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, MAX_PARAM_SPATIAL_SUBFRAMES );
671 252 : IF( GE_16( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) )
672 : {
673 126 : index = sub( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length );
674 : }
675 :
676 252 : st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx = index;
677 252 : move16();
678 : }
679 :
680 124502 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
681 : {
682 31261 : 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 31261 : IF( st_ivas->hDirAC != NULL )
691 : {
692 : Word16 b;
693 : Word16 block;
694 : Word16 meta_write_index;
695 :
696 43918 : FOR( i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ )
697 : {
698 104620 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
699 : {
700 83696 : meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
701 :
702 4719696 : FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
703 : {
704 9272000 : st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b],
705 4636000 : st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][meta_write_index][b] ); // Q30
706 4636000 : move32();
707 : }
708 : }
709 : }
710 :
711 114970 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
712 : {
713 91976 : meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
714 :
715 5069816 : FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
716 : {
717 4977840 : 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 4977840 : move32();
719 : }
720 : }
721 : }
722 : }
723 :
724 124502 : st->next_bit_pos = next_bit_pos_orig;
725 124502 : move16();
726 :
727 124502 : IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) )
728 : {
729 : Word32 cpe_brate;
730 31261 : cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
731 :
732 31261 : test();
733 31261 : test();
734 31261 : IF( EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
735 : {
736 14649 : IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
737 : {
738 5757 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
739 5757 : move16();
740 : }
741 : ELSE
742 : {
743 8892 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
744 8892 : move16();
745 : }
746 :
747 14649 : 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 93241 : test();
757 93241 : test();
758 93241 : test();
759 93241 : 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 21943 : IF( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
762 : {
763 10062 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
764 10062 : move16();
765 : }
766 : ELSE
767 : {
768 11881 : st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
769 11881 : move16();
770 : }
771 :
772 21943 : 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 124502 : test();
781 124502 : IF( EQ_32( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) )
782 : {
783 51201 : st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0;
784 51201 : move16();
785 :
786 51201 : 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 124502 : test();
800 124502 : test();
801 124502 : 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 19460 : create_masa_ext_out_meta_fx( hMasa, hQMetaData, st_ivas->nchan_transport );
804 : }
805 :
806 124502 : return error /* *nb_bits_read*/;
807 : }
808 :
809 :
810 : /*-------------------------------------------------------------------*
811 : * ivas_masa_dec_open()
812 : *
813 : *
814 : *-------------------------------------------------------------------*/
815 :
816 458 : 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 458 : error = IVAS_ERR_OK;
826 458 : move16();
827 :
828 458 : 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 458 : ism_total_brate = 0;
834 458 : move32();
835 :
836 : /* ISM metadata */
837 :
838 458 : test();
839 458 : 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 458 : test();
846 458 : test();
847 458 : test();
848 458 : test();
849 458 : 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 108 : FOR( i = 0; i < st_ivas->nSCE; i++ )
852 : {
853 70 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
854 : }
855 : }
856 :
857 458 : 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 458 : Copy( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
860 458 : Copy( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 );
861 458 : hMasa->config.numberOfDirections = 1;
862 458 : move16();
863 458 : hMasa->config.joinedSubframes = FALSE;
864 458 : move16();
865 :
866 : /* Create spherical grid only for external output */
867 458 : test();
868 458 : test();
869 458 : 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 21 : 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 21 : generate_gridEq_fx( hMasa->data.sph_grid16 );
877 :
878 21 : 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 437 : hMasa->data.sph_grid16 = NULL;
886 437 : hMasa->data.extOutMeta = NULL;
887 : }
888 :
889 458 : 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 121 : hMasa->hMasaLfeSynth = NULL;
896 : }
897 :
898 458 : st_ivas->hMasa = hMasa;
899 :
900 : /* allocate transport channels*/
901 458 : test();
902 458 : test();
903 458 : test();
904 458 : test();
905 458 : 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 53 : buffer_mode = TC_BUFFER_MODE_RENDERER;
912 53 : move16();
913 53 : test();
914 53 : test();
915 53 : test();
916 53 : 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 50 : 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 53 : nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
928 53 : nchan_to_allocate = nchan_transport;
929 53 : move16();
930 :
931 53 : test();
932 53 : test();
933 53 : test();
934 53 : test();
935 53 : 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 48 : 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 1 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
945 1 : nchan_to_allocate = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
946 : }
947 47 : 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 53 : granularity = ivas_jbm_dec_get_render_granularity_fx( st_ivas->renderer_type, RENDERER_DISABLE, st_ivas->hDecoderConfig->output_Fs );
954 :
955 53 : 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 458 : return error;
962 : }
963 :
964 :
965 : /*-----------------------------------------------------------------------*
966 : * ivas_masa_dec_close()
967 : *
968 : * close MASA decoder
969 : *-----------------------------------------------------------------------*/
970 :
971 1729 : 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 1729 : test();
978 1729 : IF( hMasa_out == NULL || *hMasa_out == NULL )
979 : {
980 1271 : return;
981 : }
982 :
983 458 : hMasa = *hMasa_out;
984 :
985 : /* Free spherical grid memory if in use */
986 458 : IF( hMasa->data.sph_grid16 != NULL )
987 : {
988 49 : free( hMasa->data.sph_grid16 );
989 49 : hMasa->data.sph_grid16 = NULL;
990 : }
991 :
992 458 : IF( hMasa->data.extOutMeta != NULL )
993 : {
994 21 : free( hMasa->data.extOutMeta );
995 21 : hMasa->data.extOutMeta = NULL;
996 : }
997 :
998 458 : 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 458 : free( *hMasa_out );
1025 458 : *hMasa_out = NULL;
1026 :
1027 458 : return;
1028 : }
1029 :
1030 :
1031 : /*-------------------------------------------------------------------*
1032 : * ivas_masa_dec_config()
1033 : *
1034 : * Frame-by-frame configuration of MASA decoder
1035 : *-------------------------------------------------------------------*/
1036 :
1037 121147 : 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 121147 : error = IVAS_ERR_OK;
1049 121147 : move32();
1050 121147 : hMasa = st_ivas->hMasa;
1051 :
1052 121147 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
1053 121147 : move32();
1054 121147 : ism_total_brate = 0;
1055 121147 : move32();
1056 :
1057 121147 : test();
1058 121147 : test();
1059 121147 : test();
1060 121147 : test();
1061 121147 : 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 85776 : FOR( i = 0; i < st_ivas->nSCE; i++ )
1064 : {
1065 55215 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
1066 : }
1067 : }
1068 :
1069 121147 : 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 121147 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
1072 : {
1073 30561 : 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 90586 : 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 121147 : test();
1081 121147 : test();
1082 121147 : 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 3534 : hMasa->config.mergeRatiosOverSubframes = 0;
1085 3534 : move16();
1086 :
1087 : /* initialize spherical grid */
1088 3534 : IF( hMasa->data.sph_grid16 == NULL )
1089 : {
1090 28 : 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 28 : generate_gridEq_fx( hMasa->data.sph_grid16 );
1095 : }
1096 : }
1097 121147 : st_ivas->hQMetaData->metadata_max_bits = hMasa->config.max_metadata_bits;
1098 121147 : move16();
1099 121147 : st_ivas->hQMetaData->bandMap = hMasa->data.band_mapping;
1100 121147 : move16();
1101 121147 : st_ivas->hQMetaData->nchan_transport = st_ivas->nchan_transport;
1102 121147 : move16();
1103 :
1104 121147 : 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 121147 : st_ivas->hQMetaData->numTwoDirBands = st_ivas->hMasa->config.numTwoDirBands;
1110 121147 : move16();
1111 121147 : st_ivas->hQMetaData->useLowerRes = 0;
1112 121147 : move16();
1113 :
1114 259885 : FOR( i = 0; i < st_ivas->hQMetaData->no_directions; i++ )
1115 : {
1116 138738 : st_ivas->hQMetaData->q_direction[i].cfg.nbands = hMasa->config.numCodingBands;
1117 138738 : move16();
1118 138738 : IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
1119 : {
1120 56831 : st_ivas->hQMetaData->q_direction[i].cfg.nblocks = 1;
1121 : }
1122 : ELSE
1123 : {
1124 81907 : st_ivas->hQMetaData->q_direction[i].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
1125 : }
1126 138738 : move16();
1127 :
1128 138738 : test();
1129 138738 : 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 126957 : st_ivas->hQMetaData->q_direction[i].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
1137 126957 : move32();
1138 : }
1139 : }
1140 :
1141 121147 : ivas_set_qmetadata_maxbit_req_fx( st_ivas->hQMetaData, st_ivas->ivas_format );
1142 :
1143 : /* Find maximum band usable */
1144 121147 : maxBin = extract_l( Mpy_32_32( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) );
1145 121147 : maxBand = 0;
1146 121147 : move16();
1147 3120609 : WHILE( LE_16( maxBand, MASA_FREQUENCY_BANDS ) && LE_16( MASA_band_grouping_24[maxBand], maxBin ) )
1148 : {
1149 2999462 : maxBand = (UWord8) add( maxBand, 1 );
1150 : }
1151 121147 : maxBand = (UWord8) sub( maxBand, 1 );
1152 :
1153 121147 : 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 19237 : 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 101910 : masa_sample_rate_band_correction_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hQMetaData, maxBand, 0, NULL );
1161 : }
1162 :
1163 121147 : 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 81366 : 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 81366 : *q_shift = 0;
1182 81366 : move16();
1183 :
1184 81366 : test();
1185 81366 : test();
1186 81366 : IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nchan_transport, 2 ) && EQ_16( nchan_remapped, 1 ) )
1187 : {
1188 10841 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
1189 : {
1190 701 : Copy32( output_fx[0], output_fx[1], output_frame ); /* Copy mono signal to stereo output channels */
1191 : }
1192 : ELSE
1193 : {
1194 10140 : test();
1195 10140 : IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
1196 : {
1197 6059 : 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 6059 : *q_shift = -1; /* Q has decreased by 1. */
1199 6059 : move16();
1200 : }
1201 : }
1202 : }
1203 :
1204 81366 : return;
1205 : }
1206 :
1207 :
1208 : /*-------------------------------------------------------------------*
1209 : * Local functions
1210 : *-------------------------------------------------------------------*/
1211 :
1212 18997 : static void index_16bits_fx(
1213 : IVAS_QMETADATA_HANDLE hQMetaData,
1214 : SPHERICAL_GRID_DATA *Sph_Grid16 )
1215 : {
1216 : Word16 d, band, block;
1217 :
1218 42255 : 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 297983 : FOR( band = 0; band < hQMetaData->q_direction[0].cfg.nbands; band++ )
1222 : {
1223 891123 : FOR( block = 0; block < hQMetaData->q_direction[0].cfg.nblocks; block++ )
1224 : {
1225 1232796 : 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 616398 : &( hQMetaData->q_direction[d].band_data[band].azimuth_fx[block] ), Sph_Grid16 );
1227 616398 : move16();
1228 : }
1229 : }
1230 : }
1231 :
1232 18997 : return;
1233 : }
1234 :
1235 :
1236 : /* Replicate subframe data when there is only one subframe sent */
1237 49970 : static void replicate_subframes_fx(
1238 : IVAS_QMETADATA_HANDLE hQMetaData )
1239 : {
1240 : Word16 sf, band, dir, nbands, ndirs;
1241 :
1242 49970 : nbands = hQMetaData->q_direction->cfg.nbands;
1243 49970 : move16();
1244 49970 : ndirs = hQMetaData->no_directions;
1245 49970 : move16();
1246 :
1247 199880 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1248 : {
1249 1977321 : FOR( band = 0; band < nbands; band++ )
1250 : {
1251 3985842 : FOR( dir = 0; dir < ndirs; dir++ )
1252 : {
1253 2158431 : hQMetaData->q_direction[dir].band_data[band].spherical_index[sf] = hQMetaData->q_direction[dir].band_data[band].spherical_index[0];
1254 2158431 : move16();
1255 2158431 : hQMetaData->q_direction[dir].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[dir].band_data[band].azimuth_fx[0]; // Q22
1256 2158431 : move32();
1257 2158431 : hQMetaData->q_direction[dir].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[dir].band_data[band].elevation_fx[0]; // Q22
1258 2158431 : move32();
1259 2158431 : hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[0]; // Q30
1260 2158431 : move32();
1261 :
1262 2158431 : if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
1263 : {
1264 1754820 : hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[0];
1265 1754820 : move16();
1266 : }
1267 : }
1268 :
1269 1827411 : if ( hQMetaData->surcoh_band_data != NULL )
1270 : {
1271 1423800 : hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0];
1272 1423800 : move16();
1273 : }
1274 : }
1275 : }
1276 :
1277 49970 : return;
1278 : }
1279 :
1280 :
1281 35013 : 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 35013 : 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 115548 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1293 : {
1294 519966 : FOR( band = 0; band < numCodingBands; band++ )
1295 : {
1296 :
1297 433305 : hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[band].spherical_index[0];
1298 433305 : move16();
1299 433305 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[band].azimuth_fx[0]; // Q22
1300 433305 : move32();
1301 433305 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[band].elevation_fx[0]; // Q22
1302 433305 : move32();
1303 433305 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; // Q30
1304 433305 : move32();
1305 :
1306 433305 : 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 433305 : 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 28887 : hQMetaData->q_direction->cfg.nblocks = 4;
1319 28887 : 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 30630 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1326 : {
1327 122520 : FOR( band = 1; band < numCodingBands; band++ )
1328 : {
1329 98016 : hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[0].spherical_index[sf];
1330 98016 : move16();
1331 98016 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[sf]; // Q22
1332 98016 : move32();
1333 98016 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[0].elevation_fx[sf]; // Q22
1334 98016 : move32();
1335 98016 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[sf]; // Q30
1336 98016 : move32();
1337 :
1338 98016 : 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 98016 : 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 6126 : hQMetaData->q_direction->cfg.nbands = numCodingBands;
1351 6126 : move16();
1352 : }
1353 :
1354 35013 : 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 9198 : 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 : Word16 nchan_out_buff;
1693 : ivas_error error;
1694 : Word32 ism_total_brate;
1695 : Word16 pos_idx;
1696 :
1697 9198 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
1698 9198 : move32();
1699 9198 : last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
1700 9198 : move32();
1701 :
1702 9198 : test();
1703 9198 : test();
1704 : /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */
1705 9198 : 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 ) )
1706 : {
1707 7015 : Copy( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
1708 7015 : st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
1709 7015 : move16();
1710 7015 : st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
1711 7015 : move16();
1712 : }
1713 :
1714 9198 : ivas_init_dec_get_num_cldfb_instances_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
1715 :
1716 : /* renderer might have changed, reselect */
1717 9198 : ivas_renderer_select( st_ivas );
1718 :
1719 9198 : test();
1720 9198 : test();
1721 9198 : test();
1722 9198 : test();
1723 9198 : test();
1724 9198 : test();
1725 9198 : test();
1726 9198 : IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) ||
1727 : ( ( 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 ) )
1728 : {
1729 : /* init a new DirAC dec */
1730 118 : IF( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
1731 : {
1732 0 : return error;
1733 : }
1734 : }
1735 9080 : 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 ) )
1736 : {
1737 : /* close all unnecessary parametric decoding and rendering */
1738 1402 : ivas_dirac_dec_close_binaural_data_fx( st_ivas->hDiracDecBin );
1739 1402 : ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
1740 1402 : ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
1741 1402 : ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
1742 : }
1743 : /* possible reconfigure is done later */
1744 :
1745 : /*-----------------------------------------------------------------*
1746 : * Allocate and initialize SCE/CPE and other handles
1747 : *-----------------------------------------------------------------*/
1748 :
1749 9198 : IF( st_ivas->hSCE[0] != NULL )
1750 : {
1751 6177 : bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream;
1752 6177 : move16();
1753 : }
1754 : ELSE
1755 : {
1756 3021 : bit_stream = st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream;
1757 3021 : move16();
1758 : }
1759 :
1760 9198 : num_bits = 0;
1761 9198 : move16();
1762 :
1763 : Word16 tmp_e;
1764 : Word32 tmp32;
1765 :
1766 19611 : FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
1767 : {
1768 : // st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
1769 10413 : st_ivas->hSCE[sce_id]->element_brate = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
1770 10413 : st_ivas->hSCE[sce_id]->element_brate = L_shr( st_ivas->hSCE[sce_id]->element_brate, sub( 15, tmp_e ) ); // Q0
1771 10413 : move32();
1772 10413 : move32();
1773 :
1774 10413 : 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() */
1775 10413 : move32();
1776 :
1777 10413 : sts = st_ivas->hSCE[sce_id]->hCoreCoder;
1778 10413 : sts[0]->bit_stream = bit_stream + num_bits;
1779 :
1780 : // num_bits += (int16_t)(st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC);
1781 10413 : tmp = extract_l( Mpy_32_32( st_ivas->hSCE[sce_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
1782 10413 : num_bits = add( num_bits, tmp );
1783 :
1784 10413 : test();
1785 10413 : test();
1786 10413 : test();
1787 10413 : 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 )
1788 : {
1789 5779 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
1790 : {
1791 0 : return error;
1792 : }
1793 : }
1794 : }
1795 :
1796 17714 : FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
1797 : {
1798 : // st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
1799 8516 : tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
1800 8516 : tmp32 = L_shr( tmp32, sub( 15, tmp_e ) ); // Q0
1801 8516 : st_ivas->hCPE[cpe_id]->element_brate = imult3216( tmp32, CPE_CHANNELS );
1802 8516 : move32();
1803 :
1804 : /* prepare bitstream buffers */
1805 25548 : FOR( n = 0; n < CPE_CHANNELS; n++ )
1806 : {
1807 17032 : tmp = CPE_CHANNELS;
1808 17032 : move16();
1809 17032 : if ( GT_16( st_ivas->nCPE, 1 ) )
1810 : {
1811 0 : st_ivas->nCPE = 1;
1812 0 : move16();
1813 : }
1814 : /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
1815 : // st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / tmp;
1816 17032 : tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hCPE[cpe_id]->element_brate, tmp, &tmp_e ) );
1817 17032 : tmp32 = L_shr( tmp32, sub( 15, tmp_e ) );
1818 17032 : st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = tmp32;
1819 17032 : move32();
1820 : }
1821 8516 : sts = st_ivas->hCPE[cpe_id]->hCoreCoder;
1822 8516 : sts[0]->bit_stream = bit_stream + num_bits;
1823 :
1824 : // num_bits += (int16_t) ( st_ivas->hCPE[cpe_id]->element_brate / FRAMES_PER_SEC );
1825 8516 : tmp = extract_l( Mpy_32_32( st_ivas->hCPE[cpe_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
1826 8516 : num_bits = add( num_bits, tmp );
1827 :
1828 8516 : test();
1829 8516 : test();
1830 8516 : test();
1831 8516 : test();
1832 8516 : test();
1833 8516 : test();
1834 8516 : IF( ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && GE_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) ||
1835 : ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_32( last_ivas_total_brate, FRAME_NO_DATA ) ) ||
1836 : ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_32( last_ivas_total_brate, IVAS_SID_5k2 ) ) )
1837 : {
1838 1677 : st_ivas->hCPE[cpe_id]->nchan_out = 1;
1839 1677 : move16();
1840 :
1841 1677 : test();
1842 1677 : test();
1843 1677 : test();
1844 1677 : test();
1845 1677 : test();
1846 1677 : 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 ) )
1847 : {
1848 1372 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
1849 : {
1850 0 : return error;
1851 : }
1852 : }
1853 : }
1854 6839 : ELSE IF( GE_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && LT_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
1855 : {
1856 1689 : st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS;
1857 1689 : move16();
1858 :
1859 1689 : test();
1860 1689 : test();
1861 1689 : test();
1862 1689 : test();
1863 1689 : test();
1864 1689 : 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 ) )
1865 : {
1866 1423 : IF( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
1867 : {
1868 0 : return error;
1869 : }
1870 : }
1871 : }
1872 : }
1873 :
1874 82782 : FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
1875 : {
1876 73584 : IF( st_ivas->hDiracDecBin[pos_idx] != NULL )
1877 : {
1878 : /* regularization factor is bitrate-dependent */
1879 5148 : st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
1880 5148 : move16();
1881 : }
1882 : }
1883 :
1884 9198 : test();
1885 9198 : 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() */
1886 : {
1887 : /*-----------------------------------------------------------------*
1888 : * TD Decorrelator
1889 : *-----------------------------------------------------------------*/
1890 :
1891 1640 : IF( st_ivas->hDiracDecBin[0] != NULL )
1892 : {
1893 773 : 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 ) )
1894 : {
1895 0 : return error;
1896 : }
1897 : }
1898 :
1899 : /*-----------------------------------------------------------------*
1900 : * CLDFB instances
1901 : *-----------------------------------------------------------------*/
1902 :
1903 1640 : IF( st_ivas->hSpar )
1904 : {
1905 0 : Word16 Q_tmp = getScaleFactor16( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 16 );
1906 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
1907 0 : st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_tmp;
1908 0 : move16();
1909 : }
1910 :
1911 1640 : IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, st_ivas->nchan_transport, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
1912 : {
1913 0 : return error;
1914 : }
1915 : }
1916 :
1917 : /*-----------------------------------------------------------------*
1918 : * Set-up MASA coding elements and bitrates
1919 : *-----------------------------------------------------------------*/
1920 :
1921 9198 : ism_total_brate = 0;
1922 9198 : move32();
1923 :
1924 9198 : test();
1925 9198 : test();
1926 9198 : test();
1927 9198 : test();
1928 9198 : 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 ) ) )
1929 : {
1930 9607 : FOR( n = 0; n < st_ivas->nSCE; n++ )
1931 : {
1932 6181 : ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[n]->element_brate );
1933 : }
1934 : }
1935 :
1936 9198 : 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 );
1937 :
1938 : /*-----------------------------------------------------------------*
1939 : * JBM TC buffers
1940 : *-----------------------------------------------------------------*/
1941 : {
1942 : Word16 tc_nchan_to_allocate;
1943 : Word16 tc_nchan_transport;
1944 : TC_BUFFER_MODE buffer_mode_new;
1945 : Word16 n_samples_granularity;
1946 :
1947 9198 : 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 );
1948 9198 : buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode_fx( st_ivas );
1949 9198 : tc_nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
1950 :
1951 9198 : tc_nchan_to_allocate = tc_nchan_transport;
1952 9198 : move16();
1953 :
1954 9198 : test();
1955 9198 : test();
1956 9198 : test();
1957 9198 : test();
1958 9198 : test();
1959 9198 : test();
1960 9198 : 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 ) )
1961 : {
1962 5148 : IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
1963 : {
1964 3130 : tc_nchan_to_allocate = add( BINAURAL_CHANNELS, st_ivas->nchan_ism );
1965 : }
1966 : ELSE
1967 : {
1968 2018 : tc_nchan_to_allocate = BINAURAL_CHANNELS;
1969 2018 : move16();
1970 2018 : test();
1971 2018 : if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr )
1972 : {
1973 1160 : tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS;
1974 1160 : move16();
1975 : }
1976 : }
1977 :
1978 5148 : test();
1979 5148 : test();
1980 5148 : test();
1981 5148 : 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 ) )
1982 : {
1983 651 : IF( GT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
1984 : {
1985 651 : IF( NE_32( ( error = ivas_jbm_dec_set_discard_samples_fx( st_ivas ) ), IVAS_ERR_OK ) )
1986 : {
1987 0 : return error;
1988 : }
1989 : }
1990 : }
1991 4497 : ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
1992 : {
1993 2381 : IF( LT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
1994 : {
1995 : /* flush already done in IVAS_DEC_ReadFormat() */
1996 : }
1997 : }
1998 : }
1999 4050 : 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 ) ) )
2000 : {
2001 : /* addtl channel for CNG */
2002 188 : tc_nchan_to_allocate = add( tc_nchan_to_allocate, 1 );
2003 : }
2004 3862 : 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 ) ) )
2005 : {
2006 250 : tc_nchan_transport = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
2007 250 : tc_nchan_to_allocate = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
2008 : }
2009 9198 : test();
2010 9198 : test();
2011 9198 : 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 ) )
2012 : {
2013 6948 : 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 ) )
2014 : {
2015 0 : return error;
2016 : }
2017 : }
2018 :
2019 9198 : test();
2020 9198 : IF( st_ivas->hSpatParamRendCom != NULL && EQ_16( st_ivas->hSpatParamRendCom->slot_size, st_ivas->hTcBuffer->n_samples_granularity ) )
2021 : {
2022 7020 : Copy( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
2023 7020 : st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
2024 7020 : move16();
2025 7020 : st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
2026 7020 : move16();
2027 : }
2028 :
2029 9198 : test();
2030 9198 : test();
2031 9198 : 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 ) )
2032 : {
2033 651 : Word16 granularityMultiplier = idiv1616( st_ivas->hTcBuffer->n_samples_granularity, st_ivas->hSpatParamRendCom->slot_size );
2034 5859 : FOR( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ )
2035 : {
2036 5208 : st_ivas->hSpatParamRendCom->subframe_nbslots[n] = i_mult( st_ivas->hTcBuffer->subframe_nbslots[n], granularityMultiplier );
2037 5208 : move16();
2038 : }
2039 : }
2040 : }
2041 :
2042 : /*-----------------------------------------------------------------*
2043 : * output audio buffers
2044 : *-----------------------------------------------------------------*/
2045 :
2046 9198 : test();
2047 9198 : 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() */
2048 : {
2049 1640 : nchan_out_buff = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
2050 1640 : 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 )
2051 : {
2052 0 : return error;
2053 : }
2054 : }
2055 :
2056 9198 : return IVAS_ERR_OK;
2057 : }
2058 :
2059 :
2060 : /*-------------------------------------------------------------------*
2061 : * ivas_spar_param_to_masa_param_mapping()
2062 : *
2063 : * Determine MASA metadata from the SPAR metadata
2064 : *-------------------------------------------------------------------*/
2065 :
2066 157720 : void ivas_spar_param_to_masa_param_mapping_fx(
2067 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
2068 : Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */
2069 : Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */
2070 : Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME],
2071 : const Word16 subframe /* i : Subframe to map */
2072 : )
2073 : {
2074 : Word16 i, j, band, bin, slot, ch, nBins, nchan_transport;
2075 : Word16 mixer_mat_index;
2076 : Word16 dirac_write_idx;
2077 : DIRAC_DEC_HANDLE hDirAC;
2078 : DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist;
2079 : Word32 mixer_mat_sf_bands_real_fx[SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS];
2080 : Word32 mixer_mat_sf_bins_real_fx[CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS];
2081 : Word16 *band_grouping;
2082 : Word16 band_start, band_end;
2083 : Word32 transportSignalEnergies_32[2][CLDFB_NO_CHANNELS_MAX];
2084 : Word64 transportSignalEnergies_64[2][CLDFB_NO_CHANNELS_MAX];
2085 : Word32 transportSignalCrossCorrelation_32[CLDFB_NO_CHANNELS_MAX];
2086 : Word64 transportSignalCrossCorrelation_64[CLDFB_NO_CHANNELS_MAX];
2087 : Word64 instEne_fx;
2088 : Word32 inCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2089 157720 : Word16 q_inCovarianceMtx = 31;
2090 : Word32 foaCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2091 : Word32 Iy_fx, Iz_fx, Ix_fx, E_fx, azi_fx, ele_fx, I_fx, ratio_float_fx;
2092 : Word32 diffuseGainX_fx, diffuseGainY_fx, diffuseGainZ_fx, diffuseGainSum_fx;
2093 : Word16 slot_idx, slot_idx_start, sf;
2094 : SPAR_DEC_HANDLE hSpar;
2095 : Word16 slot_fac_fx;
2096 157720 : Word16 q_slot_fac = 0;
2097 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
2098 157720 : Word16 common_q = 31;
2099 : Word64 azi_val, ele_val;
2100 157720 : Word64 transportSignalEnergies_max = 0;
2101 157720 : Word64 transportSignalCrossCorrelation_max = 0;
2102 157720 : Word64 max_common_val = 0;
2103 157720 : Word16 azi_q = 0, ele_q = 0;
2104 : Word16 num_q, denom_q, res_q;
2105 157720 : Word16 headroom_left_max_common = 63; // 0 value
2106 157720 : Word16 q_max_common = 31;
2107 : Word32 ratio_fx; /* Q30 */
2108 157720 : move16();
2109 157720 : move16();
2110 157720 : move16();
2111 157720 : move16();
2112 157720 : move16();
2113 157720 : move16();
2114 157720 : move16();
2115 157720 : move64();
2116 157720 : move64();
2117 157720 : move64();
2118 :
2119 473160 : FOR( i = 0; i < 2; i++ )
2120 : {
2121 315440 : set64_fx( transportSignalEnergies_64[i], 0, CLDFB_NO_CHANNELS_MAX );
2122 315440 : set32_fx( transportSignalEnergies_32[i], 0, CLDFB_NO_CHANNELS_MAX );
2123 : }
2124 157720 : set32_fx( transportSignalCrossCorrelation_32, 0, CLDFB_NO_CHANNELS_MAX );
2125 157720 : set64_fx( transportSignalCrossCorrelation_64, 0, CLDFB_NO_CHANNELS_MAX );
2126 788600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2127 : {
2128 630880 : set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2129 630880 : set32_fx( foaCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2130 : }
2131 :
2132 1104040 : FOR( Word16 ind = 0; ind < 6; ind++ )
2133 : {
2134 4731600 : FOR( Word16 ind2 = 0; ind2 < 4; ind2++ )
2135 : {
2136 3785280 : if ( GT_16( common_q, q_cldfb[ind][ind2] ) )
2137 : {
2138 227158 : common_q = q_cldfb[ind][ind2];
2139 227158 : move16();
2140 : }
2141 : }
2142 : }
2143 : /* Set values */
2144 157720 : hDirAC = st_ivas->hDirAC;
2145 157720 : hSpatParamRendCom = st_ivas->hSpatParamRendCom;
2146 157720 : hSpatParamRendCom->numParametricDirections = 1;
2147 157720 : move16();
2148 157720 : hSpatParamRendCom->numSimultaneousDirections = 1;
2149 157720 : move16();
2150 157720 : hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist;
2151 157720 : nchan_transport = st_ivas->nchan_transport;
2152 157720 : move16();
2153 157720 : band_grouping = hDirAC->band_grouping;
2154 157720 : move16();
2155 157720 : hSpar = st_ivas->hSpar;
2156 157720 : dirac_write_idx = hSpatParamRendCom->render_to_md_map[subframe];
2157 157720 : move16();
2158 :
2159 : /* Init arrays */
2160 788600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2161 : {
2162 630880 : set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
2163 : }
2164 :
2165 : /* Delay the SPAR mixing matrices to have them synced with the audio */
2166 157720 : slot_idx_start = hSpar->slots_rendered;
2167 157720 : move16();
2168 157720 : slot_fac_fx = BASOP_Util_Divide3232_Scale( 1, hSpar->subframe_nbslots[subframe], &q_slot_fac );
2169 157720 : IF( q_slot_fac < 0 )
2170 : {
2171 154972 : slot_fac_fx = shr( slot_fac_fx, -1 * q_slot_fac ); // Q15
2172 : }
2173 783106 : FOR( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe]; slot_idx++ )
2174 : {
2175 625386 : IF( hSpar->render_to_md_map[slot_idx + slot_idx_start] == 0 )
2176 : {
2177 39098 : sf = 0;
2178 39098 : move16();
2179 : }
2180 : ELSE
2181 : {
2182 586288 : sf = shr( hSpar->render_to_md_map[slot_idx + slot_idx_start], JBM_CLDFB_SLOTS_IN_SUBFRAME_LOG2 );
2183 : }
2184 :
2185 625386 : IF( LT_16( sf, SPAR_META_DELAY_SUBFRAMES ) )
2186 : {
2187 312706 : mixer_mat_index = add( sf, add( sub( MAX_PARAM_SPATIAL_SUBFRAMES, SPAR_META_DELAY_SUBFRAMES ), 1 ) );
2188 2814354 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2189 : {
2190 12508240 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2191 : {
2192 50032960 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2193 : {
2194 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
2195 40026368 : move32();
2196 : }
2197 : }
2198 : }
2199 : }
2200 : ELSE
2201 : {
2202 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 );
2203 2814120 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2204 : {
2205 12507200 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2206 : {
2207 50028800 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2208 : {
2209 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
2210 40023040 : move32();
2211 : }
2212 : }
2213 : }
2214 : }
2215 : }
2216 :
2217 : /* Map the mixing matrices from the frequency bands to frequency bins */
2218 157720 : bin = 0;
2219 157720 : move16();
2220 1419480 : FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
2221 : {
2222 1261760 : band_start = band_grouping[band];
2223 1261760 : move16();
2224 1261760 : band_end = band_grouping[band + 1];
2225 1261760 : move16();
2226 2996680 : FOR( bin = band_start; bin < band_end; bin++ )
2227 : {
2228 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2229 : {
2230 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2231 : {
2232 27758720 : mixer_mat_sf_bins_real_fx[bin][i][j] = mixer_mat_sf_bands_real_fx[band][i][j]; // 31
2233 27758720 : move32();
2234 : }
2235 : }
2236 : }
2237 : }
2238 :
2239 157720 : nBins = bin;
2240 157720 : move16();
2241 :
2242 : /* Determine MASA metadata */
2243 : /* Determine transport signal energies and cross correlations when more than 1 TC */
2244 157720 : IF( EQ_16( nchan_transport, 2 ) )
2245 : {
2246 440415 : FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
2247 : {
2248 4225596 : FOR( bin = 0; bin < nBins; bin++ )
2249 : {
2250 11620389 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2251 : {
2252 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)
2253 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)
2254 7746926 : transportSignalEnergies_64[ch][bin] = W_add( transportSignalEnergies_64[ch][bin], instEne_fx ); // Q(2 * common_q)
2255 7746926 : move64();
2256 7746926 : move64();
2257 : }
2258 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)
2259 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)
2260 3873463 : move64();
2261 3873463 : move64();
2262 : }
2263 : }
2264 :
2265 :
2266 1059384 : FOR( bin = 0; bin < nBins; bin++ )
2267 : {
2268 2913306 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2269 : {
2270 : // transportSignalEnergies_max = GT_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) ? transportSignalEnergies_max : transportSignalEnergies_64[ch][bin];
2271 :
2272 1942204 : if ( LE_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) )
2273 : {
2274 120430 : transportSignalEnergies_max = transportSignalEnergies_64[ch][bin]; // Q(2 * common_q)
2275 120430 : move64();
2276 : }
2277 : }
2278 :
2279 : // transportSignalCrossCorrelation_max = GT_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) ? transportSignalCrossCorrelation_max : transportSignalCrossCorrelation_64[bin];
2280 :
2281 971102 : if ( LE_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) )
2282 : {
2283 120140 : transportSignalCrossCorrelation_max = transportSignalCrossCorrelation_64[bin]; // Q(2 * common_q)
2284 120140 : move64();
2285 : }
2286 : }
2287 :
2288 : // max_common_val = GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) ? transportSignalEnergies_max : transportSignalCrossCorrelation_max;
2289 :
2290 88282 : IF( GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) )
2291 : {
2292 88256 : max_common_val = transportSignalEnergies_max; // Q(2 * common_q)
2293 : }
2294 : ELSE
2295 : {
2296 26 : max_common_val = transportSignalCrossCorrelation_max; // Q(2 * common_q)
2297 : }
2298 88282 : move64();
2299 :
2300 88282 : IF( max_common_val != 0 )
2301 : {
2302 88256 : headroom_left_max_common = W_norm( max_common_val );
2303 88256 : IF( GT_16( headroom_left_max_common, 32 ) )
2304 : {
2305 14232 : FOR( bin = 0; bin < nBins; bin++ )
2306 : {
2307 39138 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2308 : {
2309 26092 : transportSignalEnergies_32[ch][bin] = W_extract_l( transportSignalEnergies_64[ch][bin] ); // Q(q_max_common)
2310 26092 : move32();
2311 : }
2312 13046 : transportSignalCrossCorrelation_32[bin] = W_extract_l( transportSignalCrossCorrelation_64[bin] ); // Q(q_max_common)
2313 13046 : move32();
2314 : }
2315 1186 : q_max_common = shl( common_q, 1 );
2316 : }
2317 : ELSE
2318 : {
2319 1044840 : FOR( bin = 0; bin < nBins; bin++ )
2320 : {
2321 2873310 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2322 : {
2323 1915540 : transportSignalEnergies_32[ch][bin] = W_extract_l( W_shr( transportSignalEnergies_64[ch][bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
2324 1915540 : move32();
2325 : }
2326 957770 : transportSignalCrossCorrelation_32[bin] = W_extract_l( W_shr( transportSignalCrossCorrelation_64[bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
2327 957770 : move32();
2328 : }
2329 87070 : q_max_common = sub( shl( common_q, 1 ), sub( 32, headroom_left_max_common ) );
2330 : }
2331 : }
2332 : ELSE
2333 : {
2334 312 : FOR( bin = 0; bin < nBins; bin++ )
2335 : {
2336 858 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2337 : {
2338 572 : transportSignalEnergies_32[ch][bin] = 0; // Q(q_max_common)
2339 572 : move32();
2340 : }
2341 286 : transportSignalCrossCorrelation_32[bin] = 0; // Q(q_max_common)
2342 286 : move32();
2343 : }
2344 26 : q_max_common = 31;
2345 26 : move16();
2346 : }
2347 : }
2348 :
2349 :
2350 157720 : IF( hDiffuseDist != NULL )
2351 : {
2352 157720 : set32_fx( hDiffuseDist->diffuseRatioX_fx, 0, CLDFB_NO_CHANNELS_MAX );
2353 157720 : set32_fx( hDiffuseDist->diffuseRatioY_fx, 0, CLDFB_NO_CHANNELS_MAX );
2354 157720 : set32_fx( hDiffuseDist->diffuseRatioZ_fx, 0, CLDFB_NO_CHANNELS_MAX );
2355 : }
2356 :
2357 1892640 : FOR( bin = 0; bin < nBins; bin++ )
2358 : {
2359 : /* Set the energy of the first transport signal */
2360 1734920 : IF( EQ_16( nchan_transport, 1 ) )
2361 : {
2362 763818 : inCovarianceMtx_fx[0][0] = ONE_IN_Q31; /* In case of 1TC, fixed value can be used, Q(q_inCovarianceMtx)*/
2363 763818 : move32();
2364 763818 : q_inCovarianceMtx = 31; /* In case of 1TC, fixed value can be used */
2365 763818 : move16();
2366 : }
2367 : ELSE
2368 : {
2369 971102 : inCovarianceMtx_fx[0][0] = transportSignalEnergies_32[0][bin]; /* In case of 2TC, use actual energies */
2370 971102 : move32();
2371 971102 : q_inCovarianceMtx = q_max_common; /* In case of 1TC, fixed value can be used */
2372 971102 : move16();
2373 : }
2374 :
2375 : /* Decorrelated channels assumed to have the same energy as the source channel */
2376 1734920 : inCovarianceMtx_fx[1][1] = inCovarianceMtx_fx[0][0];
2377 1734920 : move32();
2378 1734920 : inCovarianceMtx_fx[2][2] = inCovarianceMtx_fx[0][0];
2379 1734920 : move32();
2380 1734920 : inCovarianceMtx_fx[3][3] = inCovarianceMtx_fx[0][0];
2381 1734920 : move32();
2382 :
2383 : /* In case residuals were transmitted, use their actual energies and cross correlations */
2384 1734920 : IF( EQ_16( nchan_transport, 2 ) )
2385 : {
2386 :
2387 971102 : inCovarianceMtx_fx[1][1] = transportSignalEnergies_32[1][bin];
2388 971102 : move32();
2389 971102 : inCovarianceMtx_fx[0][1] = transportSignalCrossCorrelation_32[bin];
2390 971102 : move32();
2391 971102 : inCovarianceMtx_fx[1][0] = inCovarianceMtx_fx[0][1];
2392 971102 : move32();
2393 971102 : q_inCovarianceMtx = q_max_common;
2394 971102 : move16();
2395 : }
2396 :
2397 1734920 : compute_foa_cov_matrix_fx( foaCovarianceMtx_fx, inCovarianceMtx_fx, mixer_mat_sf_bins_real_fx[bin] );
2398 :
2399 1734920 : Iy_fx = foaCovarianceMtx_fx[0][1]; /* Intensity in Y direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2400 1734920 : move32();
2401 1734920 : Iz_fx = foaCovarianceMtx_fx[0][2]; /* Intensity in Z direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2402 1734920 : move32();
2403 1734920 : Ix_fx = foaCovarianceMtx_fx[0][3]; /* Intensity in X direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
2404 1734920 : move32();
2405 :
2406 1734920 : Word64 I1 = W_mult0_32_32( Ix_fx, Ix_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2407 1734920 : Word64 I2 = W_mult0_32_32( Iy_fx, Iy_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2408 1734920 : Word64 I3 = W_mult0_32_32( Iz_fx, Iz_fx ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2409 1734920 : Word64 I_res = W_add( W_add( I1, I2 ), I3 ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
2410 :
2411 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)
2412 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 );
2413 1734920 : E_fx_64 = W_shr( E_fx_64, 1 );
2414 :
2415 1734920 : Word16 headroom_left_I_res = W_norm( I_res );
2416 : Word16 q_I_res;
2417 1734920 : IF( LT_16( headroom_left_I_res, 32 ) )
2418 : {
2419 1404509 : I_res = W_shr( I_res, sub( 32, headroom_left_I_res ) ); // q_I_res
2420 1404509 : q_I_res = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_res ) ) );
2421 : }
2422 : ELSE
2423 : {
2424 330411 : q_I_res = sub( 31, shl( q_inCovarianceMtx, 1 ) );
2425 : }
2426 1734920 : I_fx = Sqrt32( (Word32) I_res, &q_I_res );
2427 1734920 : IF( q_I_res < 0 )
2428 : {
2429 721250 : I_fx = L_shr( I_fx, -1 * q_I_res );
2430 721250 : q_I_res = 0;
2431 721250 : move16();
2432 : }
2433 1734920 : azi_q = 0;
2434 1734920 : move16();
2435 1734920 : azi_fx = BASOP_util_atan2( Iy_fx, Ix_fx, azi_q ); /* Azimuth Q13*/
2436 :
2437 1734920 : Word64 I_ele_x = W_mult0_32_32( Ix_fx, Ix_fx ); // Q(ele_q)
2438 1734920 : Word64 I_ele_y = W_mult0_32_32( Iy_fx, Iy_fx ); // Q(ele_q)
2439 1734920 : Word64 I_ele = W_add( I_ele_x, I_ele_y ); // Q(ele_q)
2440 1734920 : Word16 headroom_left_I_ele = W_norm( I_ele );
2441 1734920 : IF( LT_16( headroom_left_I_ele, 32 ) )
2442 : {
2443 1394564 : I_ele = W_shr( I_ele, sub( 32, headroom_left_I_ele ) );
2444 1394564 : ele_q = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_ele ) ) );
2445 : }
2446 : ELSE
2447 : {
2448 340356 : ele_q = sub( 31, shl( q_inCovarianceMtx, 1 ) );
2449 : }
2450 1734920 : I_ele = Sqrt32( W_extract_l( I_ele ), &ele_q );
2451 1734920 : IF( ele_q < 0 )
2452 : {
2453 706124 : I_ele = W_shr( I_ele, negate( ele_q ) ); // Q0
2454 706124 : ele_q = 0;
2455 706124 : move16();
2456 : }
2457 1734920 : ele_fx = BASOP_util_atan2( Iz_fx, W_extract_l( I_ele ), sub( sub( 31, q_inCovarianceMtx ), ele_q ) ); // Q13
2458 :
2459 1734920 : num_q = sub( 31, q_I_res );
2460 1734920 : denom_q = q_inCovarianceMtx;
2461 1734920 : move16();
2462 1734920 : res_q = 0;
2463 1734920 : move16();
2464 1734920 : IF( E_fx <= 0 )
2465 : {
2466 4830 : E_fx = 1;
2467 4830 : move32();
2468 : }
2469 1734920 : ratio_float_fx = BASOP_Util_Divide3232_Scale( I_fx, E_fx, &res_q );
2470 1734920 : res_q = sub( res_q, sub( num_q, denom_q ) );
2471 1734920 : ratio_fx = L_shl_sat( ratio_float_fx, add( Q15, res_q ) ); // Q(15 + res_q)
2472 :
2473 1734920 : ratio_fx = L_max( 0, L_min( ratio_fx, ONE_IN_Q30 ) ); // Q30
2474 :
2475 1734920 : azi_val = W_mult0_32_32( azi_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + Q25
2476 1734920 : IF( azi_val < 0 )
2477 : {
2478 1059355 : azi_val = W_shr( W_neg( azi_val ), 13 + 25 ); // Q0
2479 1059355 : azi_val = W_neg( azi_val );
2480 : }
2481 : ELSE
2482 : {
2483 675565 : azi_val = W_shr( azi_val, 13 + 25 ); // Q0
2484 : }
2485 1734920 : ele_val = W_mult0_32_32( ele_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + q25
2486 1734920 : IF( ele_val < 0 )
2487 : {
2488 610588 : ele_val = W_shr( W_neg( ele_val ), 13 + 25 ); // Q0
2489 610588 : ele_val = W_neg( ele_val ); // Q0
2490 : }
2491 : ELSE
2492 : {
2493 1124332 : ele_val = W_shr( ele_val, 13 + 25 ); // Q0
2494 : }
2495 :
2496 1734920 : hSpatParamRendCom->azimuth[dirac_write_idx][bin] = extract_l( W_extract_l( azi_val ) ); // Q0
2497 1734920 : move16();
2498 1734920 : hSpatParamRendCom->elevation[dirac_write_idx][bin] = extract_l( W_extract_l( ele_val ) ); // Q0
2499 1734920 : move16();
2500 1734920 : hSpatParamRendCom->energy_ratio1_fx[dirac_write_idx][bin] = ratio_fx; // Q30
2501 1734920 : move32();
2502 1734920 : hSpatParamRendCom->diffuseness_vector_fx[dirac_write_idx][bin] = L_sub( ONE_IN_Q30, ratio_fx ); // Q30
2503 1734920 : move32();
2504 :
2505 1734920 : hSpatParamRendCom->spreadCoherence_fx[dirac_write_idx][bin] = 0; // Q15
2506 1734920 : move16();
2507 1734920 : hSpatParamRendCom->surroundingCoherence_fx[dirac_write_idx][bin] = 0; // q15
2508 1734920 : move16();
2509 :
2510 : /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */
2511 1734920 : IF( hDiffuseDist != NULL )
2512 : {
2513 1734920 : IF( EQ_16( nchan_transport, 1 ) )
2514 : {
2515 763818 : diffuseGainY_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][1][1] ); // Q31
2516 763818 : diffuseGainX_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][3][2] ); // Q31
2517 763818 : diffuseGainZ_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][2][3] ); // Q31
2518 : }
2519 971102 : ELSE IF( EQ_16( nchan_transport, 2 ) )
2520 : {
2521 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)
2522 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)
2523 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)
2524 : }
2525 : ELSE
2526 : {
2527 0 : diffuseGainY_fx = ONE_IN_Q31;
2528 0 : move32();
2529 0 : diffuseGainX_fx = ONE_IN_Q31;
2530 0 : move32();
2531 0 : diffuseGainZ_fx = ONE_IN_Q31;
2532 0 : move32();
2533 : }
2534 1734920 : diffuseGainSum_fx = L_add_sat( L_add_sat( diffuseGainY_fx, diffuseGainX_fx ), diffuseGainZ_fx );
2535 :
2536 1734920 : IF( diffuseGainSum_fx == 0 )
2537 : {
2538 38852 : hDiffuseDist->diffuseRatioX_fx[bin] = 715827904; //(1.0f / 3.0f) in Q31
2539 38852 : move32();
2540 38852 : hDiffuseDist->diffuseRatioY_fx[bin] = 715827904;
2541 38852 : move32();
2542 38852 : hDiffuseDist->diffuseRatioZ_fx[bin] = 715827904;
2543 38852 : move32();
2544 : }
2545 : ELSE
2546 : {
2547 1696068 : Word16 temp_q = 0;
2548 1696068 : move16();
2549 : Word16 intermediate_results; // temp_q
2550 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainX_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2551 : // saturating value to less than 1
2552 1696068 : IF( temp_q <= 0 )
2553 : {
2554 1495927 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2555 : }
2556 : ELSE
2557 : {
2558 200141 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2559 : }
2560 1696068 : hDiffuseDist->diffuseRatioX_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2561 1696068 : move32();
2562 :
2563 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainY_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2564 : // saturating value to less than 1
2565 1696068 : IF( temp_q <= 0 )
2566 : {
2567 1612124 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2568 : }
2569 : ELSE
2570 : {
2571 83944 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2572 : }
2573 1696068 : hDiffuseDist->diffuseRatioY_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2574 1696068 : move32();
2575 :
2576 1696068 : intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainZ_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
2577 : // saturating value to less than 1
2578 1696068 : IF( temp_q <= 0 )
2579 : {
2580 1469720 : intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
2581 : }
2582 : ELSE
2583 : {
2584 226348 : intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
2585 : }
2586 1696068 : hDiffuseDist->diffuseRatioZ_fx[bin] = L_deposit_h( intermediate_results ); // Q31
2587 1696068 : move32();
2588 : }
2589 : }
2590 : }
2591 :
2592 157720 : return;
2593 : }
2594 :
2595 :
2596 : /* Estimate FOA properties: foaCov = mixMtx * inCov * mixMtx' */
2597 1734920 : static void compute_foa_cov_matrix_fx(
2598 : Word32 foaCov_fx[FOA_CHANNELS][FOA_CHANNELS], /* o : Estimated FOA covariance matrix Qx*/
2599 : Word32 inCov_fx[FOA_CHANNELS][FOA_CHANNELS], /* i : Input covariance matrix Qx*/
2600 : Word32 mixMtx_fx[FOA_CHANNELS][FOA_CHANNELS] /* i : Mixing matrix Q31*/
2601 : )
2602 : {
2603 : Word32 tmpMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
2604 : Word16 i, j, k;
2605 : /* tmpMtx = mixMtx * inCov */
2606 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2607 : {
2608 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2609 : {
2610 27758720 : tmpMtx_fx[i][j] = 0;
2611 27758720 : move32();
2612 138793600 : FOR( k = 0; k < FOA_CHANNELS; k++ )
2613 : {
2614 111034880 : tmpMtx_fx[i][j] = L_add_sat( tmpMtx_fx[i][j], Mpy_32_32( mixMtx_fx[i][k], inCov_fx[k][j] ) ); // Qx
2615 111034880 : move32();
2616 : }
2617 : }
2618 : }
2619 :
2620 : /* foaCov = inCov * mixMtx' */
2621 8674600 : FOR( i = 0; i < FOA_CHANNELS; i++ )
2622 : {
2623 34698400 : FOR( j = 0; j < FOA_CHANNELS; j++ )
2624 : {
2625 27758720 : foaCov_fx[i][j] = 0;
2626 27758720 : move32();
2627 138793600 : FOR( k = 0; k < FOA_CHANNELS; k++ )
2628 : {
2629 111034880 : foaCov_fx[i][j] = L_add_sat( foaCov_fx[i][j], Mpy_32_32( tmpMtx_fx[i][k], mixMtx_fx[j][k] ) ); // Qx
2630 111034880 : move32();
2631 : }
2632 : }
2633 : }
2634 :
2635 1734920 : return;
2636 : }
2637 :
2638 :
2639 19460 : static void create_masa_ext_out_meta_fx(
2640 : MASA_DECODER *hMasa,
2641 : IVAS_QMETADATA_HANDLE hQMetaData,
2642 : const Word16 nchan_transport )
2643 : {
2644 : Word16 i, sf, b_old, b_new, dir;
2645 : MASA_DECRIPTIVE_META *descMeta;
2646 : Word16 *bandMap;
2647 : UWord8 numCodingBands;
2648 : UWord8 numDirections;
2649 : MASA_DECODER_EXT_OUT_META *extOutMeta;
2650 :
2651 19460 : numDirections = hMasa->config.numberOfDirections;
2652 19460 : move16();
2653 19460 : numCodingBands = hMasa->config.numCodingBands;
2654 19460 : move16();
2655 19460 : bandMap = hMasa->data.band_mapping;
2656 19460 : move16();
2657 19460 : extOutMeta = hMasa->data.extOutMeta;
2658 19460 : descMeta = &hMasa->data.extOutMeta->descriptiveMeta;
2659 :
2660 : /* Construct descriptive meta */
2661 175140 : FOR( i = 0; i < 8; i++ )
2662 : {
2663 155680 : descMeta->formatDescriptor[i] = ivasmasaFormatDescriptor[i];
2664 155680 : move16();
2665 : }
2666 19460 : descMeta->numberOfDirections = (UWord8) sub( numDirections, 1 );
2667 19460 : descMeta->numberOfChannels = (UWord8) ( sub( nchan_transport, 1 ) );
2668 : /* Following correspond to "unknown" values until transmission is implemented */
2669 19460 : descMeta->sourceFormat = 0x0u;
2670 19460 : descMeta->transportDefinition = 0x0u;
2671 19460 : descMeta->channelAngle = 0x0u;
2672 19460 : descMeta->channelDistance = 0x0u;
2673 19460 : descMeta->channelLayout = 0x0u;
2674 :
2675 19460 : move16();
2676 19460 : move16();
2677 19460 : move16();
2678 19460 : move16();
2679 19460 : move16();
2680 19460 : move16();
2681 19460 : move16();
2682 :
2683 : /* Construct spatial metadata from qmetadata */
2684 97300 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
2685 : {
2686 172912 : FOR( dir = 0; dir < numDirections; dir++ )
2687 : {
2688 : /* Spherical index */
2689 1215896 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2690 : {
2691 3394556 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2692 : {
2693 2273732 : extOutMeta->directionIndex[dir][sf][b_new] = hQMetaData->q_direction[dir].band_data[b_old].spherical_index[sf];
2694 2273732 : move16();
2695 : }
2696 : }
2697 :
2698 : /* Direct-to-total ratio */
2699 1215896 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2700 : {
2701 3394556 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2702 : {
2703 2273732 : 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
2704 2273732 : move16();
2705 2273732 : extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q0
2706 2273732 : move16();
2707 : }
2708 : }
2709 :
2710 : /* Spread coherence */
2711 95072 : IF( hQMetaData->q_direction[dir].coherence_band_data != NULL )
2712 : {
2713 1083656 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2714 : {
2715 2791544 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2716 : {
2717 1782144 : extOutMeta->spreadCoherence[dir][sf][b_new] = hQMetaData->q_direction[dir].coherence_band_data[b_old].spread_coherence[sf];
2718 1782144 : move16();
2719 : }
2720 : }
2721 : }
2722 : ELSE
2723 : {
2724 520400 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2725 : {
2726 499584 : extOutMeta->spreadCoherence[dir][sf][i] = 0;
2727 499584 : move16();
2728 : }
2729 : }
2730 : }
2731 :
2732 : /* Fill second direction with zero energy data for EXT output */
2733 77840 : IF( EQ_16( numDirections, 1 ) )
2734 : {
2735 1515200 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2736 : {
2737 1454592 : extOutMeta->directionIndex[1][sf][i] = SPH_IDX_FRONT;
2738 1454592 : move16();
2739 : }
2740 :
2741 1515200 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2742 : {
2743 1454592 : extOutMeta->directToTotalRatio[1][sf][i] = 0;
2744 1454592 : move16();
2745 : }
2746 :
2747 1515200 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2748 : {
2749 1454592 : extOutMeta->spreadCoherence[1][sf][i] = 0;
2750 1454592 : move16();
2751 : }
2752 : }
2753 :
2754 : /* Common spatial meta */
2755 : /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */
2756 983700 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2757 : {
2758 2766024 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2759 : {
2760 1860164 : extOutMeta->diffuseToTotalRatio[sf][b_new] = UINT8_MAX;
2761 1860164 : move16();
2762 4133896 : FOR( dir = 0; dir < numDirections; dir++ )
2763 : {
2764 :
2765 2273732 : 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
2766 2273732 : move16();
2767 2273732 : extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8
2768 2273732 : move16();
2769 : }
2770 : }
2771 : }
2772 :
2773 : /* Surround coherence */
2774 77840 : IF( hQMetaData->surcoh_band_data != NULL )
2775 : {
2776 851460 : FOR( b_old = 0; b_old < numCodingBands; b_old++ )
2777 : {
2778 2163012 : FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
2779 : {
2780 1368576 : extOutMeta->surroundCoherence[sf][b_new] = hQMetaData->surcoh_band_data[b_old].surround_coherence[sf];
2781 1368576 : move16();
2782 : }
2783 : }
2784 : }
2785 : ELSE
2786 : {
2787 520400 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
2788 : {
2789 499584 : extOutMeta->surroundCoherence[sf][i] = 0;
2790 499584 : move16();
2791 : }
2792 : }
2793 : }
2794 :
2795 19460 : return;
2796 : }
2797 :
2798 :
2799 10439 : static void decode_index_slice_fx(
2800 : Word16 index, /* i : index to decode */
2801 : Word16 *ratio_idx_ism, /* o : decodec array of integers Q0*/
2802 : const Word16 nchan_ism, /* i : number of elements in array (objects) */
2803 : const Word16 K /* i : sum of array elements Q0*/
2804 : )
2805 : {
2806 : Word16 i, j, sum, elem;
2807 : Word16 base[MAX_NUM_OBJECTS];
2808 :
2809 10439 : SWITCH( nchan_ism )
2810 : {
2811 1169 : case 2:
2812 1169 : ratio_idx_ism[0] = index;
2813 1169 : move16();
2814 1169 : ratio_idx_ism[1] = sub( K, ratio_idx_ism[0] );
2815 1169 : move16();
2816 1169 : BREAK;
2817 9270 : case 3:
2818 : case 4:
2819 : {
2820 9270 : j = 0;
2821 9270 : move16();
2822 1326400 : WHILE( index >= 0 )
2823 : {
2824 1317130 : IF( valid_ratio_index_fx( j, K, nchan_ism - 1 ) )
2825 : {
2826 344577 : index = sub( index, 1 );
2827 : }
2828 1317130 : j = add( j, 1 );
2829 : }
2830 9270 : j = sub( j, 1 );
2831 9270 : base[0] = 1;
2832 9270 : move16();
2833 25120 : FOR( i = 1; i < nchan_ism - 1; i++ )
2834 : {
2835 15850 : base[i] = i_mult( base[i - 1], 10 );
2836 15850 : move16();
2837 : }
2838 9270 : sum = 0;
2839 9270 : move16();
2840 34390 : FOR( i = nchan_ism - 2; i >= 0; i-- )
2841 : {
2842 25120 : IF( EQ_16( j, 0 ) )
2843 : {
2844 8305 : elem = 0;
2845 8305 : move16();
2846 : }
2847 : ELSE
2848 : {
2849 16815 : elem = idiv1616( j, base[i] );
2850 : }
2851 25120 : ratio_idx_ism[nchan_ism - i - 2] = elem;
2852 25120 : move16();
2853 25120 : sum = add( sum, elem );
2854 25120 : j = sub( j, i_mult( elem, base[i] ) );
2855 : }
2856 9270 : ratio_idx_ism[nchan_ism - 1] = sub( K, sum );
2857 9270 : move16();
2858 : }
2859 :
2860 9270 : default:
2861 9270 : BREAK;
2862 : }
2863 :
2864 10439 : return;
2865 : }
2866 :
2867 :
2868 18530 : static void read_ism_ratio_index_fx(
2869 : Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM read ratio indexes Q0*/
2870 : const Word16 nchan_ism, /* i : number of objects */
2871 : const Word16 numCodingBands, /* i : number of subbands */
2872 : const Word16 sf, /* i : index of subframe */
2873 : Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i : previous subframe ISM ratio indexes Q0*/
2874 : UWord16 *bit_stream, /* i : bitstream */
2875 : Word16 *next_bit_pos, /* i/o: position in bitstream */
2876 : const Word32 *masa_to_total_energy_ratio_fx, /* i : masa to total ratios Q30*/
2877 : const Word16 idx_sep_obj, /* i : index of separated index, -1 if none */
2878 : Word16 *num_zeros /* i/o: number of zero values in first subframe for separated object */
2879 : )
2880 : {
2881 : Word16 b, i, b_signif;
2882 : Word16 index;
2883 : Word16 GR_order, differential_subframe;
2884 : Word16 buf;
2885 : Word16 no_levels_ratio_ism;
2886 : Word16 bits_index;
2887 : Word16 ratio_ism_idx_ref[MAX_NUM_OBJECTS];
2888 : Word16 idx_sep_obj_local, shift_one;
2889 :
2890 18530 : idx_sep_obj_local = idx_sep_obj;
2891 18530 : move16();
2892 :
2893 18530 : IF( GT_16( idx_sep_obj, -1 ) )
2894 : {
2895 18530 : test();
2896 18530 : if ( EQ_16( idx_sep_obj, sub( nchan_ism, 1 ) ) && GT_16( nchan_ism, 2 ) )
2897 : {
2898 4965 : idx_sep_obj_local = 0;
2899 4965 : move16();
2900 : }
2901 : }
2902 :
2903 18530 : b_signif = 0;
2904 18530 : move16();
2905 18530 : no_levels_ratio_ism = sub( shl( 1, PARAM_ISM_POW_RATIO_NBITS ), 1 );
2906 :
2907 53267 : WHILE( ( LT_16( b_signif, numCodingBands ) ) && ( GE_32( masa_to_total_energy_ratio_fx[b_signif], MASA2TOTAL_THR_Q30 ) ) )
2908 : {
2909 34737 : test();
2910 : /* distribute evenly the objects */
2911 34737 : distribute_evenly_ism_fx( ratio_ism_idx[b_signif], no_levels_ratio_ism, nchan_ism );
2912 34737 : b_signif = add( b_signif, 1 );
2913 : }
2914 :
2915 18530 : IF( EQ_16( b_signif, numCodingBands ) )
2916 : {
2917 5227 : return;
2918 : }
2919 : ELSE
2920 : {
2921 :
2922 13303 : IF( sf == 0 )
2923 : {
2924 5401 : bits_index = bits_index_ism_ratio_fx( nchan_ism );
2925 :
2926 : /* read coding type */
2927 5401 : IF( EQ_32( bit_stream[( *next_bit_pos )--], 1 ) )
2928 : {
2929 : /* independent coding*/
2930 8289 : FOR( b = 0; b < numCodingBands; b++ )
2931 : {
2932 7174 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
2933 : {
2934 6153 : index = 0;
2935 6153 : move16();
2936 45721 : FOR( i = 0; i < bits_index; i++ )
2937 : {
2938 39568 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
2939 : }
2940 6153 : decode_index_slice_fx( index, ratio_ism_idx[b], nchan_ism, no_levels_ratio_ism );
2941 6153 : test();
2942 6153 : IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
2943 : {
2944 4522 : *num_zeros = add( *num_zeros, 1 );
2945 4522 : move16();
2946 : }
2947 : }
2948 : ELSE
2949 : {
2950 : /* distribute evenly the objects */
2951 1021 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
2952 : }
2953 : }
2954 : }
2955 : ELSE
2956 : {
2957 : /* differential coding */
2958 4286 : index = 0;
2959 4286 : move16();
2960 30425 : FOR( i = 0; i < bits_index; i++ )
2961 : {
2962 26139 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
2963 : }
2964 4286 : decode_index_slice_fx( index, ratio_ism_idx[b_signif], nchan_ism, no_levels_ratio_ism );
2965 4286 : test();
2966 4286 : IF( GT_16( idx_sep_obj, -1 ) && ratio_ism_idx[b_signif][idx_sep_obj_local] == 0 )
2967 : {
2968 3724 : *num_zeros = add( *num_zeros, 1 );
2969 3724 : move16();
2970 : }
2971 4286 : Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
2972 32429 : FOR( b = b_signif + 1; b < numCodingBands; b++ )
2973 : {
2974 28143 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
2975 : {
2976 24899 : ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
2977 24899 : move16();
2978 88457 : FOR( i = 0; i < nchan_ism - 1; i++ )
2979 : {
2980 63558 : buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, 0 );
2981 63558 : IF( EQ_16( buf % 2, 0 ) )
2982 : {
2983 59775 : ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
2984 59775 : move16();
2985 : }
2986 : ELSE
2987 : {
2988 3783 : ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
2989 3783 : move16();
2990 : }
2991 63558 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
2992 63558 : move16();
2993 63558 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
2994 63558 : move16();
2995 : }
2996 24899 : Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
2997 24899 : test();
2998 24899 : IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
2999 : {
3000 21548 : *num_zeros = add( *num_zeros, 1 );
3001 21548 : move16();
3002 : }
3003 : }
3004 : ELSE
3005 : {
3006 : /* distribute evenly the objects */
3007 3244 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3008 : }
3009 : }
3010 : }
3011 : }
3012 : ELSE
3013 : {
3014 7902 : IF( GT_16( numCodingBands, 1 ) )
3015 : {
3016 : /* read prediction type */
3017 7818 : differential_subframe = bit_stream[( *next_bit_pos )--];
3018 7818 : move16();
3019 : }
3020 : ELSE
3021 : {
3022 84 : differential_subframe = 1;
3023 84 : move16();
3024 : }
3025 :
3026 7902 : IF( EQ_16( *num_zeros, numCodingBands ) )
3027 : {
3028 4749 : shift_one = 1;
3029 4749 : move16();
3030 : }
3031 : ELSE
3032 : {
3033 3153 : shift_one = 0;
3034 3153 : move16();
3035 : }
3036 :
3037 7902 : test();
3038 7902 : IF( EQ_16( shift_one, 1 ) && EQ_16( nchan_ism, 2 ) )
3039 : {
3040 : /* nothing has been sent ; values can be inferred */
3041 168 : FOR( b = b_signif; b < numCodingBands; b++ )
3042 : {
3043 84 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3044 : {
3045 84 : IF( idx_sep_obj_local == 0 )
3046 : {
3047 48 : ratio_ism_idx[b][0] = 0;
3048 48 : move16();
3049 48 : ratio_ism_idx[b][1] = 7;
3050 48 : move16();
3051 : }
3052 : ELSE
3053 : {
3054 36 : ratio_ism_idx[b][0] = 7;
3055 36 : move16();
3056 36 : ratio_ism_idx[b][1] = 0;
3057 36 : move16();
3058 : }
3059 : }
3060 : }
3061 : }
3062 : ELSE
3063 : {
3064 : /* read GR order */
3065 7818 : GR_order = bit_stream[( *next_bit_pos )--];
3066 7818 : move16();
3067 :
3068 45438 : FOR( b = b_signif; b < numCodingBands; b++ )
3069 : {
3070 37620 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3071 : {
3072 103864 : FOR( i = 0; i < nchan_ism - ( 1 + shift_one ); i++ )
3073 : {
3074 69717 : buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, GR_order );
3075 69717 : IF( ( buf % 2 ) == 0 )
3076 : {
3077 63375 : ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
3078 63375 : move16();
3079 : }
3080 : ELSE
3081 : {
3082 6342 : ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
3083 6342 : move16();
3084 : }
3085 : }
3086 :
3087 : /* insert separated obj */
3088 34147 : IF( shift_one )
3089 : {
3090 65694 : FOR( i = nchan_ism - 1; i > idx_sep_obj_local; i-- )
3091 : {
3092 43104 : ratio_ism_idx[b][i] = ratio_ism_idx[b][i - 1];
3093 43104 : move16();
3094 : }
3095 22590 : ratio_ism_idx[b][idx_sep_obj_local] = 0; /* this is only difference; need to pdate later as well */
3096 22590 : move16();
3097 : }
3098 : }
3099 : }
3100 7818 : IF( differential_subframe )
3101 : {
3102 : /* differential to previous subframe */
3103 37935 : FOR( b = b_signif; b < numCodingBands; b++ )
3104 : {
3105 31404 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3106 : {
3107 28680 : ratio_ism_idx[b][sub( nchan_ism, 1 )] = no_levels_ratio_ism;
3108 28680 : move16();
3109 106094 : FOR( i = 0; i < nchan_ism - 1; i++ )
3110 : {
3111 77414 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_prev_sf[b][i] );
3112 77414 : move16();
3113 :
3114 77414 : test();
3115 77414 : if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
3116 : {
3117 20638 : ratio_ism_idx[b][i] = 0;
3118 20638 : move16();
3119 : }
3120 77414 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
3121 : }
3122 : }
3123 : ELSE
3124 : {
3125 : /* distribute evenly the objects */
3126 2724 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3127 : }
3128 : }
3129 : }
3130 : ELSE
3131 : {
3132 : /* difference to previous subband */
3133 1287 : ratio_ism_idx[b_signif][nchan_ism - 1] = no_levels_ratio_ism;
3134 1287 : move16();
3135 :
3136 : /* first significant subband - differential to previous subframe */
3137 4774 : FOR( i = 0; i < nchan_ism - 1; i++ )
3138 : {
3139 3487 : ratio_ism_idx[b_signif][i] = add( ratio_ism_idx[b_signif][i], ratio_ism_idx_prev_sf[b_signif][i] );
3140 3487 : move16();
3141 :
3142 3487 : test();
3143 3487 : if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
3144 : {
3145 403 : ratio_ism_idx[b_signif][i] = 0;
3146 403 : move16();
3147 : }
3148 3487 : ratio_ism_idx[b_signif][nchan_ism - 1] = sub( ratio_ism_idx[b_signif][nchan_ism - 1], ratio_ism_idx[b_signif][i] );
3149 3487 : move16();
3150 : }
3151 :
3152 : /* rest of subbands differential to previous subband */
3153 1287 : Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
3154 6216 : FOR( b = b_signif + 1; b < numCodingBands; b++ )
3155 : {
3156 4929 : IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
3157 : {
3158 4180 : ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
3159 4180 : move16();
3160 :
3161 15586 : FOR( i = 0; i < nchan_ism - 1; i++ )
3162 : {
3163 11406 : ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
3164 11406 : move16();
3165 :
3166 11406 : test();
3167 11406 : if ( NE_16( shift_one, 0 ) && EQ_16( i, idx_sep_obj_local ) )
3168 : {
3169 1549 : ratio_ism_idx[b][i] = 0;
3170 1549 : move16();
3171 : }
3172 11406 : ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
3173 11406 : move16();
3174 : }
3175 4180 : Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
3176 : }
3177 : ELSE
3178 : {
3179 : /* distribute evenly the objects */
3180 749 : distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
3181 : }
3182 : }
3183 : }
3184 : }
3185 : }
3186 :
3187 13303 : return;
3188 : }
3189 : }
3190 :
3191 :
3192 7949 : static void decode_ism_ratios_fx(
3193 : UWord16 *bit_stream, /* i : bitstream */
3194 : Word16 *next_bit_pos, /* i/o: position in bitstream */
3195 : Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : masa_to_total energy ratios Q30*/
3196 : Word32 ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM ratios Q30*/
3197 : const Word16 n_ism, /* i : number of objects */
3198 : const Word16 nbands, /* i : number of subbands */
3199 : const Word16 numSf, /* i : number of subframes */
3200 : const Word16 idx_separated_object /* i : index of separated object */
3201 : )
3202 : {
3203 : Word16 sf, band;
3204 : Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
3205 : Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
3206 : Word32 tmp32_fx;
3207 : Word16 num_zeros;
3208 7949 : num_zeros = 0;
3209 7949 : move16();
3210 :
3211 : /* hQMetaData->q_direction->cfg.nblocks; */
3212 26479 : FOR( sf = 0; sf < numSf; sf++ )
3213 : {
3214 : /* read ism ratio indexes */
3215 18530 : 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 );
3216 : /* save previous subframe index values */
3217 18530 : IF( LT_16( sf, sub( numSf, 1 ) ) )
3218 : {
3219 62730 : FOR( band = 0; band < nbands; band++ )
3220 : {
3221 52149 : Copy( ratio_ism_idx[band], ratio_ism_idx_prev_sf[band], n_ism );
3222 : }
3223 : }
3224 :
3225 : /* reconstructed values */
3226 130381 : FOR( band = 0; band < nbands; band++ )
3227 : {
3228 111851 : reconstruct_ism_ratios_fx( ratio_ism_idx[band], n_ism, STEP_PARAM_ISM_POW_RATIO_NBITS_Q31, ratio_ism[sf][band] );
3229 : }
3230 :
3231 18530 : test();
3232 18530 : IF( GT_16( n_ism, 2 ) && ( EQ_16( idx_separated_object, sub( n_ism, 1 ) ) ) )
3233 : {
3234 : /* rotate */
3235 34725 : FOR( band = 0; band < nbands; band++ )
3236 : {
3237 29760 : IF( LT_32( masa_to_total_energy_ratio_fx[sf][band], MASA2TOTAL_THR_Q30 ) )
3238 : {
3239 16772 : tmp32_fx = ratio_ism[sf][band][n_ism - 1]; // Q30
3240 16772 : move32();
3241 16772 : ratio_ism[sf][band][n_ism - 1] = ratio_ism[sf][band][0];
3242 16772 : move32();
3243 16772 : ratio_ism[sf][band][0] = tmp32_fx;
3244 16772 : move32();
3245 : }
3246 : }
3247 : }
3248 :
3249 18530 : IF( EQ_16( nbands, 1 ) )
3250 : {
3251 1260 : FOR( band = 1; band < 5; band++ )
3252 : {
3253 1008 : Copy32( ratio_ism[sf][0], ratio_ism[sf][band], n_ism );
3254 : }
3255 : }
3256 : }
3257 :
3258 7949 : IF( EQ_16( numSf, 1 ) )
3259 : {
3260 17688 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
3261 : {
3262 140223 : FOR( band = 0; band < nbands; band++ )
3263 : {
3264 126957 : Copy32( ratio_ism[0][band], ratio_ism[sf][band], n_ism );
3265 : }
3266 : }
3267 : }
3268 :
3269 7949 : return;
3270 : }
3271 :
3272 :
3273 7949 : static Word16 ivas_decode_masaism_metadata_fx(
3274 : IVAS_QMETADATA_HANDLE hQMetaData,
3275 : MASA_DECODER_HANDLE hMasa,
3276 : MASA_ISM_DATA_HANDLE hMasaIsmData,
3277 : const Word16 nchan_ism,
3278 : UWord16 *bit_stream,
3279 : Word16 *next_bit_pos,
3280 : const Word16 idx_separated_object,
3281 : const Word16 ism_imp,
3282 : const Word16 dirac_bs_md_write_idx,
3283 : const Word16 dirac_md_buffer_length )
3284 : {
3285 : Word16 sf, band, dir, nbands, nblocks, obj, i;
3286 : Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; // Q30
3287 : Word16 *band_mapping;
3288 : Word16 b;
3289 : Word16 bits_ism[MAX_NUM_OBJECTS], index;
3290 : UWord16 idx_el, idx_az;
3291 : Word32 azimuth, elevation; // Q22
3292 : Word16 nb_bits_read;
3293 : Word32 delta_phi; // Q22
3294 : Word16 meta_write_index;
3295 :
3296 7949 : nb_bits_read = *next_bit_pos;
3297 7949 : move16();
3298 7949 : nbands = hQMetaData->q_direction->cfg.nbands;
3299 7949 : move16();
3300 7949 : nblocks = hQMetaData->q_direction->cfg.nblocks;
3301 7949 : move16();
3302 :
3303 : /* Read MASA-to-total energy ratios */
3304 7949 : ivas_omasa_decode_masa_to_total_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, nbands, nblocks );
3305 :
3306 7949 : IF( GT_16( nchan_ism, 1 ) )
3307 : {
3308 : /* read ISM ratios */
3309 7949 : 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 );
3310 : }
3311 : ELSE
3312 : {
3313 0 : FOR( sf = 0; sf < nblocks; sf++ )
3314 : {
3315 0 : FOR( band = 0; band < nbands; band++ )
3316 : {
3317 0 : energy_ratio_ism_fx[sf][band][0] = ONE_IN_Q30;
3318 0 : move32();
3319 : }
3320 : }
3321 : }
3322 :
3323 : /* read ISM metadata */
3324 7949 : 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 );
3325 :
3326 34916 : FOR( obj = 0; obj < nchan_ism; obj++ )
3327 : {
3328 26967 : hMasaIsmData->bits_ism[obj] = bits_ism[obj];
3329 26967 : index = 0;
3330 26967 : move16();
3331 26967 : IF( LT_16( bits_ism[obj], 8 ) ) /* if low resolution, can look to the past */
3332 : {
3333 : /* read if same as previous */
3334 13238 : IF( bit_stream[( *next_bit_pos )--] )
3335 : {
3336 1513 : azimuth = hMasaIsmData->q_azimuth_old_fx[obj]; // Q22
3337 1513 : move32();
3338 1513 : elevation = hMasaIsmData->q_elevation_old_fx[obj]; // Q22
3339 1513 : move32();
3340 : }
3341 : ELSE
3342 : {
3343 75651 : FOR( i = 0; i < bits_ism[obj]; i++ )
3344 : {
3345 63926 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
3346 : }
3347 :
3348 11725 : deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
3349 :
3350 11725 : test();
3351 11725 : test();
3352 11725 : test();
3353 : /* if ( azimuth * hMasaIsmData->q_azimuth_old[obj] > 0 ) */
3354 11725 : IF( ( ( azimuth > 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] > 0 ) ) || ( ( azimuth < 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] < 0 ) ) )
3355 : {
3356 : Word16 tmp_e;
3357 9840 : delta_phi = L_deposit_h( BASOP_Util_Divide1616_Scale( 180, no_phi_masa[bits_ism[obj] - 1][idx_el], &tmp_e ) );
3358 9840 : delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); /* to maintain Q22 */
3359 :
3360 : Word32 tmp_32;
3361 : Word64 tmp_64;
3362 9840 : tmp_32 = L_sub( azimuth, hMasaIsmData->q_azimuth_old_fx[obj] );
3363 9840 : tmp_64 = W_mult_32_16( tmp_32, no_phi_masa[bits_ism[obj] - 1][idx_el] );
3364 :
3365 9840 : 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, */
3366 : {
3367 1122 : azimuth = L_sub( azimuth, delta_phi );
3368 : }
3369 : ELSE
3370 : {
3371 8718 : IF( GT_64( MINUS_TOLERANCE_360_Q22, tmp_64 ) )
3372 : {
3373 928 : azimuth = L_add( azimuth, delta_phi );
3374 : }
3375 : }
3376 : }
3377 :
3378 11725 : hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
3379 11725 : move32();
3380 11725 : hMasaIsmData->q_elevation_old_fx[obj] = elevation;
3381 11725 : move32();
3382 : }
3383 : }
3384 : ELSE
3385 : {
3386 157477 : FOR( i = 0; i < bits_ism[obj]; i++ )
3387 : {
3388 143748 : index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
3389 : }
3390 13729 : deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
3391 :
3392 13729 : hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
3393 13729 : move32();
3394 13729 : hMasaIsmData->q_elevation_old_fx[obj] = elevation;
3395 13729 : move32();
3396 : }
3397 :
3398 134835 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
3399 : {
3400 107868 : meta_write_index = add( dirac_bs_md_write_idx, sf ) % dirac_md_buffer_length;
3401 :
3402 107868 : Word16 int_azi = rint_fx( L_shr( azimuth, Q22 - 16 ) ); // Q0, extra -16 is added as int_azi is W16 and azimuth is W32
3403 107868 : Word16 int_ele = rint_fx( L_shr( elevation, Q22 - 16 ) ); // Q0
3404 :
3405 107868 : hMasaIsmData->azimuth_ism_fx[obj][meta_write_index] = int_azi; // Q0
3406 107868 : move16();
3407 107868 : hMasaIsmData->elevation_ism_fx[obj][meta_write_index] = int_ele; // Q0
3408 107868 : move16();
3409 : }
3410 : }
3411 :
3412 : /* Modify ISM metadata based on the MASA-to-total energy ratios */
3413 26479 : FOR( sf = 0; sf < nblocks; sf++ )
3414 : {
3415 130381 : FOR( band = 0; band < nbands; band++ )
3416 : {
3417 516085 : FOR( dir = 0; dir < nchan_ism; dir++ )
3418 : {
3419 404234 : 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
3420 404234 : move32();
3421 : }
3422 : }
3423 : }
3424 :
3425 : /* Set data to struct in bins */
3426 7949 : band_mapping = hMasa->data.band_mapping;
3427 7949 : move16();
3428 67665 : FOR( band = 0; band < hMasa->config.numCodingBands; ++band )
3429 : {
3430 508676 : FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
3431 : {
3432 2244800 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; ++sf )
3433 : {
3434 1795840 : IF( EQ_16( nblocks, 1 ) )
3435 : {
3436 1025280 : i = 0;
3437 1025280 : move16();
3438 : }
3439 : ELSE
3440 : {
3441 770560 : i = sf;
3442 770560 : move16();
3443 : }
3444 :
3445 1795840 : meta_write_index = ( add( dirac_bs_md_write_idx, sf ) ) % dirac_md_buffer_length;
3446 :
3447 7892480 : FOR( dir = 0; dir < nchan_ism; dir++ )
3448 : {
3449 6096640 : hMasaIsmData->energy_ratio_ism_fx[dir][meta_write_index][b] = energy_ratio_ism_fx[i][band][dir];
3450 6096640 : move32();
3451 : }
3452 :
3453 1795840 : IF( hMasaIsmData->hExtData != NULL )
3454 : {
3455 60480 : hMasaIsmData->hExtData->masa_render_masa_to_total[meta_write_index][b] =
3456 60480 : hMasaIsmData->masa_to_total_energy_ratio_fx[i][band];
3457 60480 : move32();
3458 : }
3459 : }
3460 : }
3461 : }
3462 :
3463 7949 : return sub( nb_bits_read, *next_bit_pos );
3464 : }
3465 :
3466 :
3467 : /*
3468 : Fixed point implementation of rint().
3469 : */
3470 : /* returns in Q0 */
3471 215736 : static Word16 rint_fx(
3472 : const Word32 num /* num in Q0 */
3473 : )
3474 : {
3475 215736 : Word32 frac_part = L_and( L_abs( num ), 0x0000FFFF ); // Q15
3476 215736 : Word16 int_part = extract_h( L_abs( num ) );
3477 215736 : Word16 res = int_part;
3478 215736 : move16();
3479 :
3480 215736 : test();
3481 215736 : test();
3482 215736 : if ( GT_32( frac_part, ONE_IN_Q15 ) || ( EQ_32( frac_part, ONE_IN_Q15 ) && EQ_16( s_and( int_part, 1 ), 1 ) ) )
3483 : {
3484 51536 : res = add( res, 1 );
3485 : }
3486 215736 : if ( num < 0 )
3487 : {
3488 87040 : res = negate( res );
3489 : }
3490 215736 : return res;
3491 : }
|