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