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