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