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