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