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 "options.h"
34 : #include <stdlib.h>
35 : #include <math.h>
36 : #include "ivas_cnst.h"
37 : #include "ivas_prot_fx.h"
38 : #include "prot_fx.h"
39 : #include "ivas_prot_rend_fx.h"
40 : #include "ivas_rom_com.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_prot_fx.h"
43 :
44 :
45 : /*-------------------------------------------------------------------------
46 : * Local constants
47 : *------------------------------------------------------------------------*/
48 :
49 :
50 : #define EXT_RENDER_IIR_FAC 0.95f
51 : #define MULT_17_DIV_20_Q15 ( Word16 )( ( 17.0 / 20.0f ) * pow( 2, 15 ) + 0.5f )
52 : #define MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ( Word16 )( ( 1.0 / CLDFB_NO_COL_MAX ) * pow( 2, 15 ) + 0.5f )
53 : #define ONEMINUX_EXT_RENDER_IIR_FAC_Q31 ( Word32 )( ( 1.0f - EXT_RENDER_IIR_FAC ) * pow( 2, 31 ) + 0.5f )
54 : #define EXT_RENDER_IIR_FAC_Q31 ( Word32 )( EXT_RENDER_IIR_FAC * pow( 2, 31 ) + 0.5f )
55 :
56 : // Calculated as (Word16)(((1.0f / (50 * MAX_PARAM_SPATIAL_SUBFRAMES)) * pow(2, 15)) + 0.5f)
57 : #define OMASA_DELAYFRAMES_PER_SEC_Q15 (Word16) 164 // Q15
58 :
59 : static Word16 interpolator_table_48k_q15[] = {
60 : 0, 137, 273, 410, 546, 683, 819, 956, 1092, 1229,
61 : 1365, 1502, 1638, 1775, 1911, 2048, 2185, 2321, 2458, 2594,
62 : 2731, 2867, 3004, 3140, 3277, 3413, 3550, 3686, 3823, 3959,
63 : 4096, 4233, 4369, 4506, 4642, 4779, 4915, 5052, 5188, 5325,
64 : 5461, 5598, 5734, 5871, 6007, 6144, 6281, 6417, 6554, 6690,
65 : 6827, 6963, 7100, 7236, 7373, 7509, 7646, 7782, 7919, 8055,
66 : 8192, 8329, 8465, 8602, 8738, 8875, 9011, 9148, 9284, 9421,
67 : 9557, 9694, 9830, 9967, 10103, 10240, 10377, 10513, 10650, 10786,
68 : 10923, 11059, 11196, 11332, 11469, 11605, 11742, 11878, 12015, 12151,
69 : 12288, 12425, 12561, 12698, 12834, 12971, 13107, 13244, 13380, 13517,
70 : 13653, 13790, 13926, 14063, 14199, 14336, 14473, 14609, 14746, 14882,
71 : 15019, 15155, 15292, 15428, 15565, 15701, 15838, 15974, 16111, 16247,
72 : 16384, 16521, 16657, 16794, 16930, 17067, 17203, 17340, 17476, 17613,
73 : 17749, 17886, 18022, 18159, 18295, 18432, 18569, 18705, 18842, 18978,
74 : 19115, 19251, 19388, 19524, 19661, 19797, 19934, 20070, 20207, 20343,
75 : 20480, 20617, 20753, 20890, 21026, 21163, 21299, 21436, 21572, 21709,
76 : 21845, 21982, 22118, 22255, 22391, 22528, 22665, 22801, 22938, 23074,
77 : 23211, 23347, 23484, 23620, 23757, 23893, 24030, 24166, 24303, 24439,
78 : 24576, 24713, 24849, 24986, 25122, 25259, 25395, 25532, 25668, 25805,
79 : 25941, 26078, 26214, 26351, 26487, 26624, 26761, 26897, 27034, 27170,
80 : 27307, 27443, 27580, 27716, 27853, 27989, 28126, 28262, 28399, 28535,
81 : 28672, 28809, 28945, 29082, 29218, 29355, 29491, 29628, 29764, 29901,
82 : 30037, 30174, 30310, 30447, 30583, 30720, 30857, 30993, 31130, 31266,
83 : 31403, 31539, 31676, 31812, 31949, 32085, 32222, 32358, 32495, 32631
84 : };
85 :
86 : static Word16 interpolator_table_32k_q15[] = {
87 : 0, 205, 410, 614, 819, 1024, 1229, 1434, 1638, 1843,
88 : 2048, 2253, 2458, 2662, 2867, 3072, 3277, 3482, 3686, 3891,
89 : 4096, 4301, 4506, 4710, 4915, 5120, 5325, 5530, 5734, 5939,
90 : 6144, 6349, 6554, 6758, 6963, 7168, 7373, 7578, 7782, 7987,
91 : 8192, 8397, 8602, 8806, 9011, 9216, 9421, 9626, 9830, 10035,
92 : 10240, 10445, 10650, 10854, 11059, 11264, 11469, 11674, 11878, 12083,
93 : 12288, 12493, 12698, 12902, 13107, 13312, 13517, 13722, 13926, 14131,
94 : 14336, 14541, 14746, 14950, 15155, 15360, 15565, 15770, 15974, 16179,
95 : 16384, 16589, 16794, 16998, 17203, 17408, 17613, 17818, 18022, 18227,
96 : 18432, 18637, 18842, 19046, 19251, 19456, 19661, 19866, 20070, 20275,
97 : 20480, 20685, 20890, 21094, 21299, 21504, 21709, 21914, 22118, 22323,
98 : 22528, 22733, 22938, 23142, 23347, 23552, 23757, 23962, 24166, 24371,
99 : 24576, 24781, 24986, 25190, 25395, 25600, 25805, 26010, 26214, 26419,
100 : 26624, 26829, 27034, 27238, 27443, 27648, 27853, 28058, 28262, 28467,
101 : 28672, 28877, 29082, 29286, 29491, 29696, 29901, 30106, 30310, 30515,
102 : 30720, 30925, 31130, 31334, 31539, 31744, 31949, 32154, 32358, 32563
103 : };
104 :
105 : static Word16 interpolator_table_16k_q15[] = {
106 : 0, 410, 819, 1229, 1638, 2048, 2458, 2867, 3277, 3686,
107 : 4096, 4506, 4915, 5325, 5734, 6144, 6554, 6963, 7373, 7782,
108 : 8192, 8602, 9011, 9421, 9830, 10240, 10650, 11059, 11469, 11878,
109 : 12288, 12698, 13107, 13517, 13926, 14336, 14746, 15155, 15565, 15974,
110 : 16384, 16794, 17203, 17613, 18022, 18432, 18842, 19251, 19661, 20070,
111 : 20480, 20890, 21299, 21709, 22118, 22528, 22938, 23347, 23757, 24166,
112 : 24576, 24986, 25395, 25805, 26214, 26624, 27034, 27443, 27853, 28262,
113 : 28672, 29082, 29491, 29901, 30310, 30720, 31130, 31539, 31949, 32358
114 : };
115 :
116 :
117 : /*-------------------------------------------------------------------------
118 : * Local functions
119 : *------------------------------------------------------------------------*/
120 :
121 : /**
122 : * Calculate mantissa (Q31) * gain (Q31).
123 : *
124 : * Exponent for the mantissa value is also included as input parameter.
125 : * Adjust the result so that accuracy of the mantissa multiplication is maximixed
126 : * and the corresponding exponent is minimized.
127 : */
128 :
129 2772480 : static Word32 mult32_mantissa_fx(
130 : const Word32 mantissa,
131 : const Word32 gain,
132 : const Word16 exp,
133 : Word16 *exp_result )
134 : {
135 2772480 : Word64 mult = W_mult_32_32( mantissa, gain ); // Q31 * Q31 -> Q63
136 2772480 : Word16 norm = W_norm( mult );
137 2772480 : Word32 result = W_extract_h( W_shl( mult, norm ) ); // Q63 -> Q31
138 2772480 : *exp_result = sub( exp, norm );
139 :
140 2772480 : return result;
141 : }
142 :
143 :
144 : /**
145 : * Calculate re^2 + im^2 using exponent (Q0) and mantissa (Q31) format.
146 : */
147 334080 : static Word32 sample_energy_fx(
148 : const Word32 re_m,
149 : const Word16 re_e,
150 : const Word32 im_m,
151 : const Word16 im_e,
152 : Word16 *exp_result )
153 : {
154 334080 : Word16 re_exp = add( re_e, re_e );
155 334080 : Word32 re_mult = mult32_mantissa_fx( re_m, re_m, re_exp, &re_exp );
156 334080 : move32();
157 :
158 334080 : Word16 im_exp = add( im_e, im_e );
159 334080 : Word32 im_mult = mult32_mantissa_fx( im_m, im_m, im_exp, &im_exp );
160 334080 : move32();
161 :
162 334080 : return BASOP_Util_Add_Mant32Exp( re_mult, re_exp, im_mult, im_exp, exp_result );
163 : }
164 :
165 :
166 : /**
167 : * Accumulate sum of re^2 + im^2 over the specified length using exponent (Q0) and mantissa (Q31) format.
168 : */
169 41472 : static void sample_energy_acc_fx(
170 : Word32 *re_m,
171 : Word16 *re_e,
172 : Word32 *im_m,
173 : Word16 *im_e,
174 : Word32 *out_m,
175 : Word16 *out_e,
176 : const Word16 len )
177 : {
178 : Word16 i;
179 :
180 145152 : FOR( i = 0; i < len; i++ )
181 : {
182 : Word16 exp;
183 :
184 : // energy = re^2 + im^2
185 103680 : Word32 mantissa = sample_energy_fx( re_m[i], re_e[i], im_m[i], im_e[i], &exp );
186 103680 : move32();
187 :
188 : // Accumulate energy
189 103680 : *out_m = BASOP_Util_Add_Mant32Exp( *out_m, *out_e, mantissa, exp, out_e );
190 103680 : move32();
191 : }
192 :
193 41472 : return;
194 : }
195 :
196 : // Multiplication of vector (comprising of exponent and mantissa parts) by constant value (Q31)
197 5120 : static void v_multc_exp_mantissa_fx(
198 : const Word32 *in_mantissa,
199 : const Word16 *in_exp,
200 : const Word32 c,
201 : Word32 *out_mantissa,
202 : Word16 *out_exp,
203 : const Word16 len )
204 : {
205 : Word16 i;
206 :
207 312320 : FOR( i = 0; i < len; i++ )
208 : {
209 307200 : out_mantissa[i] = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &out_exp[i] );
210 307200 : move32();
211 : }
212 5120 : return;
213 : }
214 :
215 :
216 : // Multiplication of vector (comprising of exponent and mantissa parts) by constant acumulate to the output
217 5264 : static void v_multc_acc_exp_mantissa_fx(
218 : const Word32 *in_mantissa,
219 : const Word16 *in_exp,
220 : const Word32 c,
221 : Word32 *out_mantissa,
222 : Word16 *out_exp,
223 : const Word16 len )
224 : {
225 : Word16 i;
226 :
227 364304 : FOR( i = 0; i < len; i++ )
228 : {
229 : Word16 exp;
230 359040 : Word32 mantissa = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &exp );
231 359040 : move32();
232 :
233 359040 : out_mantissa[i] = BASOP_Util_Add_Mant32Exp( out_mantissa[i], out_exp[i], mantissa, exp, &out_exp[i] );
234 359040 : move32();
235 : }
236 :
237 5264 : return;
238 : }
239 :
240 :
241 : // Calculate min( 4, sqrtf( target / proto ) )
242 : // target and proto values are expressed using exponent and mantissa
243 :
244 192000 : static Word32 get_processing_gain_fx(
245 : const Word32 proto_m,
246 : const Word16 proto_e,
247 : const Word32 target_m,
248 : const Word16 target_e,
249 : Word16 *exp )
250 : {
251 192000 : Word16 b = extract_h( proto_m );
252 192000 : IF( EQ_16( b, 0 ) )
253 : {
254 2700 : b = 1;
255 2700 : move16();
256 : }
257 :
258 : Word16 mantissa;
259 192000 : BASOP_Util_Divide_MantExp( extract_h( target_m ), target_e, b, proto_e, &mantissa, exp );
260 :
261 192000 : Word32 sqrt_mantissa = Sqrt32( L_shl( mantissa, 16 ), exp );
262 :
263 192000 : Word16 norm = norm_l( sqrt_mantissa );
264 192000 : sqrt_mantissa = L_shl( sqrt_mantissa, norm );
265 192000 : *exp = sub( *exp, norm );
266 :
267 192000 : test();
268 192000 : IF( GT_16( *exp, 2 ) && NE_32( sqrt_mantissa, 0 ) )
269 : {
270 : // (2^3) * (1073741824 / 2^31) == 4.0
271 31 : sqrt_mantissa = ONE_IN_Q30; // 0.5 in Q31
272 31 : *exp = 3;
273 31 : move32();
274 31 : move16();
275 : }
276 :
277 192000 : return sqrt_mantissa;
278 : }
279 :
280 :
281 7752 : static void mantissa_exp_to_qvalue(
282 : Word16 *exp,
283 : Word32 *output,
284 : const Word16 target_exp,
285 : const Word16 len )
286 : {
287 : Word16 bin;
288 :
289 537672 : FOR( bin = 0; bin < len; bin++ )
290 : {
291 529920 : IF( LT_16( exp[bin], -Q31 ) )
292 : {
293 0 : output[bin] = 0;
294 0 : move32();
295 : }
296 : ELSE
297 : {
298 529920 : Word16 shift = sub( target_exp, exp[bin] );
299 529920 : output[bin] = W_sat_l( W_shr( output[bin], shift ) );
300 : }
301 : }
302 :
303 7752 : return;
304 : }
305 :
306 :
307 : /*-------------------------------------------------------------------*
308 : * ivas_omasa_data_open()
309 : *
310 : * Allocate and initialize MASA_ISM rendering handle
311 : *-------------------------------------------------------------------*/
312 :
313 35 : ivas_error ivas_omasa_data_open_fx(
314 : Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
315 : )
316 : {
317 : MASA_ISM_DATA_HANDLE hMasaIsmData;
318 : Word16 ch, bin;
319 : Word16 sf, obj_idx;
320 :
321 35 : IF( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
322 : {
323 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
324 : }
325 :
326 2135 : FOR( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
327 : {
328 6300 : FOR( ch = 0; ch < 2; ch++ )
329 : {
330 4200 : hMasaIsmData->ismPreprocMatrix_fx[ch][ch][bin] = 32767; /* 1.0f in Q15 */
331 4200 : move16();
332 4200 : hMasaIsmData->ismPreprocMatrix_fx[1 - ch][ch][bin] = 0; // Q15
333 4200 : move16();
334 4200 : hMasaIsmData->eneMoveIIR_fx[ch][bin] = 0; // Q22
335 4200 : move32();
336 4200 : hMasaIsmData->enePreserveIIR_fx[ch][bin] = 0; // Q22
337 4200 : move32();
338 : }
339 2100 : hMasaIsmData->preprocEneTarget_fx[bin] = 0; // Q19
340 2100 : move32();
341 2100 : hMasaIsmData->preprocEneRealized_fx[bin] = 0; // Q19
342 2100 : move32();
343 : }
344 :
345 35 : hMasaIsmData->objectsMoved = 0;
346 35 : move16();
347 35 : hMasaIsmData->delayBuffer_fx = NULL;
348 :
349 175 : FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
350 : {
351 140 : hMasaIsmData->ism_is_edited[ch] = 0;
352 140 : move16();
353 140 : hMasaIsmData->q_elevation_old_fx[ch] = 0; // Q22
354 140 : move32();
355 140 : hMasaIsmData->q_azimuth_old_fx[ch] = 0; // Q22
356 140 : move32();
357 : }
358 :
359 175 : FOR( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
360 : {
361 140 : set16_fx( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
362 140 : set16_fx( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
363 980 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
364 : {
365 840 : set32_fx( hMasaIsmData->energy_ratio_ism_fx[obj_idx][sf], 0, CLDFB_NO_CHANNELS_MAX );
366 : }
367 : }
368 35 : set16_fx( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
369 35 : set16_fx( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
370 :
371 35 : hMasaIsmData->hExtData = NULL;
372 35 : move32();
373 :
374 35 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
375 : {
376 : MASA_ISM_EXT_DATA_HANDLE hExtData;
377 4 : hExtData = (MASA_ISM_EXT_DATA_HANDLE) malloc( sizeof( MASA_ISM_EXT_DATA ) );
378 4 : move32();
379 :
380 4 : IF( hExtData == NULL )
381 : {
382 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
383 : }
384 :
385 4 : hExtData->prev_idx_separated_ism = 0;
386 4 : move16();
387 :
388 20 : FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
389 : {
390 16 : set32_fx( hExtData->prev_panning_gains[ch], 0, 2 );
391 : }
392 :
393 20 : FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
394 : {
395 16 : set32_fx( hExtData->ism_render_proto_energy_frac[ch], 0, CLDFB_NO_CHANNELS_MAX );
396 16 : set16_fx( hExtData->ism_render_proto_energy_exp[ch], 0, CLDFB_NO_CHANNELS_MAX );
397 16 : set32_fx( hExtData->ism_render_target_energy_frac[ch], 0, CLDFB_NO_CHANNELS_MAX );
398 16 : set16_fx( hExtData->ism_render_target_energy_exp[ch], 0, CLDFB_NO_CHANNELS_MAX );
399 : }
400 :
401 4 : set32_fx( hExtData->masa_render_proto_energy_frac, 0, CLDFB_NO_CHANNELS_MAX );
402 4 : set16_fx( hExtData->masa_render_proto_energy_exp, 0, CLDFB_NO_CHANNELS_MAX );
403 4 : set32_fx( hExtData->masa_render_target_energy_frac, 0, CLDFB_NO_CHANNELS_MAX );
404 4 : set16_fx( hExtData->masa_render_target_energy_exp, 0, CLDFB_NO_CHANNELS_MAX );
405 :
406 28 : FOR( sf = 0; sf < add( MAX_PARAM_SPATIAL_SUBFRAMES, DELAY_MASA_PARAM_DEC_SFR ); sf++ )
407 : {
408 24 : set32_fx( hExtData->masa_render_masa_to_total[sf], 0, CLDFB_NO_CHANNELS_MAX );
409 : }
410 :
411 4 : hMasaIsmData->hExtData = hExtData;
412 4 : move32();
413 : }
414 :
415 35 : st_ivas->hMasaIsmData = hMasaIsmData;
416 :
417 35 : return IVAS_ERR_OK;
418 : }
419 :
420 :
421 : /*-------------------------------------------------------------------*
422 : * ivas_omasa_data_close()
423 : *
424 : * Deallocate MASA_ISM rendering handle
425 : *-------------------------------------------------------------------*/
426 :
427 613 : void ivas_omasa_data_close_fx(
428 : MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle */
429 : )
430 : {
431 : Word16 i;
432 :
433 613 : test();
434 613 : IF( hMasaIsmData == NULL || *hMasaIsmData == NULL )
435 : {
436 578 : return;
437 : }
438 :
439 35 : IF( ( *hMasaIsmData )->delayBuffer_fx != NULL )
440 : {
441 41 : FOR( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
442 : {
443 28 : free( ( *hMasaIsmData )->delayBuffer_fx[i] ); // Q11
444 : }
445 13 : free( ( *hMasaIsmData )->delayBuffer_fx );
446 13 : ( *hMasaIsmData )->delayBuffer_fx = NULL;
447 : }
448 :
449 35 : IF( ( *hMasaIsmData )->hExtData != NULL )
450 : {
451 4 : free( ( *hMasaIsmData )->hExtData );
452 4 : ( *hMasaIsmData )->hExtData = NULL;
453 4 : move32();
454 : }
455 :
456 35 : free( *hMasaIsmData );
457 35 : *hMasaIsmData = NULL;
458 :
459 35 : return;
460 : }
461 :
462 :
463 : /*--------------------------------------------------------------------------*
464 : * ivas_omasa_dec_config()
465 : *
466 : * oMASA decoder configuration
467 : *--------------------------------------------------------------------------*/
468 :
469 1534 : ivas_error ivas_omasa_dec_config_fx(
470 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
471 : UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */
472 : Word16 *num_src,
473 : Word16 SrcInd[MAX_NUM_TDREND_CHANNELS],
474 : Word16 *data /* o : output synthesis signal Qx*/
475 : )
476 : {
477 : Word16 k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD;
478 : Word32 ivas_total_brate, ism_total_brate, cpe_brate;
479 : Word32 brate_SCE, brate_CPE;
480 : ISM_MODE ism_mode_old;
481 : IVAS_FORMAT ivas_format_orig;
482 : Word16 nchan_out_buff, nchan_out_buff_old;
483 : ivas_error error;
484 : RENDERER_TYPE old_renderer_type;
485 :
486 : /* initializations */
487 1534 : ism_total_brate = 0;
488 1534 : move32();
489 1534 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
490 1534 : move32();
491 :
492 : /* save previous frame parameters */
493 1534 : ism_mode_old = ivas_omasa_ism_mode_select_fx( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
494 1534 : move16();
495 1534 : st_ivas->ism_mode = ism_mode_old;
496 1534 : move16();
497 :
498 1534 : ivas_format_orig = st_ivas->ivas_format;
499 1534 : move16();
500 1534 : st_ivas->ivas_format = st_ivas->last_ivas_format;
501 1534 : move16();
502 1534 : ivas_init_dec_get_num_cldfb_instances_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
503 1534 : nchan_out_buff_old = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
504 1534 : move16();
505 :
506 1534 : st_ivas->ivas_format = ivas_format_orig;
507 1534 : move16();
508 :
509 1534 : nSCE_old = st_ivas->nSCE;
510 1534 : move16();
511 1534 : nchan_hp20_old = getNumChanSynthesis( st_ivas );
512 1534 : move16();
513 :
514 : /* set ism_mode of current frame */
515 1534 : st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
516 1534 : move16();
517 :
518 : /*-----------------------------------------------------------------*
519 : * Renderer selection
520 : *-----------------------------------------------------------------*/
521 :
522 1534 : old_renderer_type = st_ivas->renderer_type;
523 1534 : move32();
524 :
525 : /* MASA reconfig. */
526 1534 : cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
527 1534 : move32();
528 1534 : test();
529 1534 : test();
530 1534 : test();
531 1534 : IF( ( st_ivas->ini_active_frame == 0 ) && ( ivas_total_brate != FRAME_NO_DATA ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
532 : {
533 0 : st_ivas->hCPE[0]->nchan_out = 1;
534 0 : move16();
535 : }
536 : ELSE
537 : {
538 1534 : IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
539 : {
540 0 : return error;
541 : }
542 : }
543 :
544 1534 : IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
545 : {
546 501 : st_ivas->hCPE[0]->nchan_out = 1;
547 501 : move16();
548 : }
549 : ELSE
550 : {
551 1033 : st_ivas->hCPE[0]->nchan_out = 2;
552 1033 : move16();
553 : }
554 :
555 : /* OMASA reconfig. */
556 1534 : test();
557 1534 : IF( st_ivas->hMasaIsmData == NULL && EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
558 : {
559 2 : IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
560 : {
561 0 : return error;
562 : }
563 : }
564 :
565 1534 : ivas_set_omasa_TC_fx( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
566 :
567 : /* re-configure hp20 memories */
568 1534 : IF( NE_32( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ), IVAS_ERR_OK ) )
569 : {
570 0 : return error;
571 : }
572 :
573 : /* reconfigure core-coders for ISMs */
574 1534 : k = 0;
575 1534 : move16();
576 12179 : WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
577 : {
578 10645 : k = add( k, 1 );
579 : }
580 :
581 3538 : FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
582 : {
583 2004 : ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
584 : }
585 :
586 1534 : brate_SCE = 0;
587 1534 : move32();
588 1534 : IF( st_ivas->nSCE > 0 )
589 : {
590 1121 : brate_SCE = sep_object_brate[k - 2][st_ivas->nSCE - 1];
591 1121 : move32();
592 : }
593 1534 : brate_CPE = L_sub( ivas_total_brate, ism_total_brate );
594 :
595 1534 : IF( NE_32( ( error = ivas_corecoder_dec_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, brate_SCE, brate_CPE ) ), IVAS_ERR_OK ) )
596 : {
597 0 : return error;
598 : }
599 :
600 1534 : IF( NE_16( ism_mode_old, st_ivas->ism_mode ) )
601 : {
602 : /* ISM MD reconfig. */
603 1533 : n_MD = 0;
604 1533 : move16();
605 :
606 1533 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
607 : {
608 : /* the full number of hIsmMetaData are needed for EXT output */
609 74 : IF( st_ivas->hIsmMetaData[0] == NULL )
610 : {
611 0 : IF( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK )
612 : {
613 0 : return error;
614 : }
615 : }
616 : ELSE
617 : {
618 370 : FOR( k = 0; k < st_ivas->nchan_ism; k++ )
619 : {
620 296 : ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[k] );
621 : }
622 : }
623 : }
624 : ELSE
625 : {
626 1459 : test();
627 1459 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
628 : {
629 675 : n_MD = 1;
630 675 : move16();
631 :
632 675 : IF( st_ivas->hIsmMetaData[0] == NULL )
633 : {
634 233 : error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL );
635 233 : move32();
636 233 : IF( NE_32( error, IVAS_ERR_OK ) )
637 : {
638 0 : return error;
639 : }
640 : }
641 : ELSE
642 : {
643 442 : ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[0] );
644 : }
645 : }
646 784 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
647 : {
648 390 : n_MD = st_ivas->nchan_ism;
649 390 : move16();
650 :
651 390 : error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL );
652 390 : move32();
653 390 : IF( NE_32( error, IVAS_ERR_OK ) )
654 : {
655 0 : return error;
656 : }
657 : }
658 :
659 1459 : ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD );
660 : }
661 :
662 1533 : st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
663 :
664 : /*-----------------------------------------------------------------*
665 : * Renderer selection
666 : *-----------------------------------------------------------------*/
667 :
668 1533 : ivas_renderer_select( st_ivas );
669 :
670 : /*-------------------------------------------------------------------*
671 : * Reallocate rendering handles
672 : *--------------------------------------------------------------------*/
673 :
674 1533 : IF( NE_16( old_renderer_type, st_ivas->renderer_type ) )
675 : {
676 138 : IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
677 : {
678 38 : IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
679 : {
680 0 : return error;
681 : }
682 : }
683 : ELSE
684 : {
685 100 : ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
686 : }
687 : }
688 :
689 : /* objects renderer reconfig. */
690 1533 : test();
691 1533 : IF( st_ivas->hMasaIsmData != NULL || st_ivas->hIsmRendererData != NULL )
692 : {
693 : /* this calls also ivas_ism_renderer_close() closing st_ivas->hIsmRendererData used by the EXT renderers. also cleans st_ivas->hMasaIsmData */
694 1533 : ivas_omasa_separate_object_renderer_close( st_ivas );
695 : }
696 :
697 1533 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
698 : {
699 221 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
700 : {
701 : /* Allocate TD renderer for the objects in DISC mode */
702 54 : if ( st_ivas->hBinRendererTd == NULL )
703 : {
704 54 : IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ), IVAS_ERR_OK ) )
705 : {
706 0 : return error;
707 : }
708 :
709 54 : IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
710 : {
711 0 : IF( NE_32( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
712 : {
713 0 : return error;
714 : }
715 : }
716 : }
717 :
718 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
719 54 : IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
720 : {
721 0 : return error;
722 : }
723 : }
724 : ELSE
725 : {
726 167 : if ( st_ivas->hBinRendererTd != NULL )
727 : {
728 : /* TD renderer handle */
729 54 : ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
730 : }
731 :
732 : /* ISM renderer handle + ISM data handle */
733 167 : ivas_omasa_separate_object_renderer_close( st_ivas );
734 : }
735 : }
736 :
737 1533 : IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
738 : {
739 667 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
740 : {
741 0 : return error;
742 : }
743 :
744 667 : test();
745 667 : test();
746 667 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
747 : {
748 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
749 485 : IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
750 : {
751 0 : return error;
752 : }
753 :
754 485 : IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
755 : {
756 0 : return error;
757 : }
758 : }
759 : ELSE
760 : {
761 : /* ISM renderer handle + ISM data handle */
762 182 : ivas_omasa_separate_object_renderer_close( st_ivas );
763 : }
764 : }
765 :
766 1533 : IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
767 : {
768 : /* Allocate 'hIsmRendererData' handle */
769 18 : error = ivas_omasa_combine_separate_ism_with_masa_open_fx( st_ivas );
770 18 : move32();
771 18 : IF( NE_32( error, IVAS_ERR_OK ) )
772 : {
773 0 : return error;
774 : }
775 : }
776 :
777 1533 : IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
778 : {
779 : DIRAC_CONFIG_FLAG common_rend_config_flag;
780 19 : IF( st_ivas->hSpatParamRendCom == NULL )
781 : {
782 19 : common_rend_config_flag = DIRAC_OPEN;
783 : }
784 : ELSE
785 : {
786 0 : common_rend_config_flag = DIRAC_RECONFIGURE;
787 : }
788 19 : move32();
789 :
790 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
791 19 : IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
792 : {
793 0 : return error;
794 : }
795 :
796 19 : IF( NE_32( ( error = ivas_spat_hSpatParamRendCom_config_fx( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs, 0, 0 ) ), IVAS_ERR_OK ) )
797 : {
798 0 : return error;
799 : }
800 : }
801 :
802 : /*-----------------------------------------------------------------*
803 : * TD Decorrelator
804 : *-----------------------------------------------------------------*/
805 :
806 1533 : IF( st_ivas->hDiracDecBin[0] != NULL )
807 : {
808 657 : IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
809 : {
810 0 : return error;
811 : }
812 : }
813 :
814 : /*-----------------------------------------------------------------*
815 : * CLDFB instances
816 : *-----------------------------------------------------------------*/
817 :
818 1533 : IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
819 : {
820 0 : return error;
821 : }
822 :
823 : /*-----------------------------------------------------------------*
824 : * floating-point output audio buffers
825 : *-----------------------------------------------------------------*/
826 :
827 1533 : nchan_out_buff = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
828 1533 : IF( NE_32( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ), IVAS_ERR_OK ) )
829 : {
830 0 : return error;
831 : }
832 : }
833 :
834 1534 : return IVAS_ERR_OK;
835 : }
836 :
837 :
838 : /*--------------------------------------------------------------------------*
839 : * ivas_set_surplus_brate_dec()
840 : *
841 : * set bit-rate surplus in combined format coding
842 : *--------------------------------------------------------------------------*/
843 6529 : void ivas_set_surplus_brate_dec(
844 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
845 : Word32 *ism_total_brate /* i/o: ISM total bitrate */
846 : )
847 : {
848 : Word16 n, bits_ism, bits_element[MAX_NUM_OBJECTS];
849 : Word32 ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
850 :
851 6529 : *ism_total_brate = 0;
852 6529 : move32();
853 :
854 6529 : test();
855 6529 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
856 : {
857 3727 : *ism_total_brate = ivas_interformat_brate_fx( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
858 3727 : move32();
859 :
860 3727 : st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, *ism_total_brate );
861 3727 : move32();
862 :
863 : /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
864 3727 : st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
865 3727 : move32();
866 :
867 3727 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
868 3727 : move16();
869 3727 : if ( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
870 : {
871 0 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
872 0 : move16();
873 : }
874 : }
875 2802 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
876 : {
877 : Word16 brate_limit_flag, ism_imp[MAX_NUM_OBJECTS], tmp;
878 :
879 10277 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
880 : {
881 7475 : ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
882 7475 : move16();
883 : }
884 :
885 2802 : brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, st_ivas->nchan_ism );
886 :
887 2802 : ism_total_brate_ref = 0;
888 2802 : move32();
889 10277 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
890 : {
891 7475 : ism_total_brate_ref = L_add( ism_total_brate_ref, st_ivas->hSCE[n]->element_brate );
892 : }
893 :
894 : /* bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC ); */
895 2802 : bits_ism = extract_l( Mpy_32_32( ism_total_brate_ref, ONE_BY_FRAMES_PER_SEC_Q31 ) );
896 :
897 2802 : tmp = 0;
898 2802 : move16();
899 2802 : IF( bits_ism != 0 )
900 : {
901 2802 : tmp = idiv1616( bits_ism, st_ivas->nchan_ism );
902 : }
903 2802 : set16_fx( bits_element, tmp, st_ivas->nchan_ism );
904 2802 : bits_element[st_ivas->nchan_ism - 1] = add( bits_element[st_ivas->nchan_ism - 1], bits_ism % st_ivas->nchan_ism );
905 2802 : move16();
906 2802 : bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
907 :
908 2802 : *ism_total_brate = 0;
909 2802 : move32();
910 10277 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
911 : {
912 7475 : st_ivas->hSCE[n]->element_brate = element_brate[n];
913 7475 : move32();
914 :
915 7475 : *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag ) );
916 7475 : move32();
917 :
918 7475 : test();
919 7475 : test();
920 7475 : IF( GT_16( ism_imp[n], 1 ) && EQ_16( st_ivas->flag_omasa_brate, 1 ) && brate_limit_flag >= 0 )
921 : {
922 445 : *ism_total_brate = L_sub( *ism_total_brate, ADJUST_ISM_BRATE_NEG );
923 445 : move32();
924 : }
925 :
926 7475 : test();
927 7475 : test();
928 7475 : test();
929 7475 : IF( EQ_16( brate_limit_flag, -1 ) && GE_16( ism_imp[n], 1 ) && GE_16( st_ivas->nchan_ism, 3 ) && GT_32( L_sub( ism_total_brate_ref, *ism_total_brate ), IVAS_48k ) )
930 : {
931 0 : *ism_total_brate = L_add( *ism_total_brate, ADJUST_ISM_BRATE_POS );
932 0 : move32();
933 : }
934 : }
935 2802 : st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, *ism_total_brate );
936 2802 : move32();
937 :
938 : /* 'st->total_brate' is set in ivas_ism_config */
939 : }
940 : ELSE
941 : {
942 0 : st_ivas->hCPE[0]->brate_surplus = 0;
943 0 : move32();
944 : }
945 :
946 6529 : return;
947 : }
948 :
949 :
950 : /*--------------------------------------------------------------------------*
951 : * ivas_omasa_ism_metadata_dec()
952 : *
953 : * decode ISM metadata in OMASA format
954 : *--------------------------------------------------------------------------*/
955 :
956 6529 : ivas_error ivas_omasa_ism_metadata_dec_fx(
957 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
958 : const Word32 ism_total_brate, /* i : ISM total bitrate */
959 : Word16 *nchan_ism, /* o : number of ISM separated channels */
960 : Word16 *nchan_transport_ism, /* o : number of ISM TCs */
961 : const Word16 dirac_bs_md_write_idx, /* i : DirAC bitstream write index */
962 : Word16 nb_bits_metadata[] /* o : number of ISM metadata bits */
963 : )
964 : {
965 : Word16 n, block;
966 : Word16 azimuth_ism, elevation_ism, meta_write_index;
967 : ivas_error error;
968 :
969 : /* set ISM parameters */
970 6529 : *nchan_ism = st_ivas->nchan_ism;
971 6529 : move16();
972 6529 : *nchan_transport_ism = st_ivas->nchan_ism;
973 6529 : move16();
974 :
975 6529 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
976 : {
977 2065 : *nchan_ism = 1;
978 2065 : move16();
979 2065 : *nchan_transport_ism = 1;
980 2065 : move16();
981 : }
982 4464 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
983 : {
984 1662 : *nchan_ism = 0;
985 1662 : move16();
986 1662 : *nchan_transport_ism = 1;
987 1662 : move16();
988 : }
989 :
990 6529 : test();
991 6529 : test();
992 6529 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
993 : {
994 : /* decode ISM metadata */
995 4867 : IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
996 : nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ),
997 : IVAS_ERR_OK ) )
998 : {
999 0 : return error;
1000 : }
1001 :
1002 4867 : IF( st_ivas->hDirAC != NULL )
1003 : {
1004 3592 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
1005 : {
1006 6462 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
1007 : {
1008 : // azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
1009 : // elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
1010 4679 : azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->azimuth_fx /*Q22*/ ), 22 ) ); // Q0
1011 4679 : if ( st_ivas->hIsmMetaData[n]->azimuth_fx < 0 )
1012 : {
1013 2465 : azimuth_ism = negate( azimuth_ism );
1014 : }
1015 4679 : elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->elevation_fx /*Q22*/ ), 22 ) ); // Q0
1016 4679 : if ( st_ivas->hIsmMetaData[n]->elevation_fx < 0 )
1017 : {
1018 1487 : elevation_ism = negate( elevation_ism );
1019 : }
1020 :
1021 23395 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
1022 : {
1023 18716 : meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
1024 18716 : move16();
1025 18716 : st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
1026 18716 : move16();
1027 18716 : st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
1028 18716 : move16();
1029 : }
1030 : }
1031 : }
1032 : ELSE /* ISM_MASA_MODE_MASA_ONE_OBJ */
1033 : {
1034 1809 : azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
1035 1809 : if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
1036 : {
1037 982 : azimuth_ism = negate( azimuth_ism );
1038 : }
1039 1809 : elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
1040 1809 : if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
1041 : {
1042 566 : elevation_ism = negate( elevation_ism );
1043 : }
1044 :
1045 9045 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
1046 : {
1047 7236 : meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
1048 7236 : move16();
1049 7236 : st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
1050 7236 : move16();
1051 7236 : st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
1052 7236 : move16();
1053 : }
1054 : }
1055 : }
1056 1275 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
1057 : {
1058 36 : azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
1059 36 : if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
1060 : {
1061 19 : azimuth_ism = negate( azimuth_ism );
1062 : }
1063 36 : elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
1064 36 : if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
1065 : {
1066 3 : elevation_ism = negate( elevation_ism );
1067 : }
1068 :
1069 108 : FOR( block = 0; block < 2; block++ )
1070 : {
1071 72 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = st_ivas->hMasaIsmData->azimuth_separated_ism[add( block, 2 )];
1072 72 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = st_ivas->hMasaIsmData->elevation_separated_ism[add( block, 2 )];
1073 72 : move16();
1074 72 : move16();
1075 : }
1076 108 : FOR( block = 2; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
1077 : {
1078 72 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = azimuth_ism;
1079 72 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = elevation_ism;
1080 72 : move16();
1081 72 : move16();
1082 : }
1083 : }
1084 : }
1085 :
1086 6529 : return IVAS_ERR_OK;
1087 : }
1088 :
1089 : /*--------------------------------------------------------------------------*
1090 : * ivas_omasa_dirac_rend_jbm_fx()
1091 : *
1092 : * Rendering in OMASA format for JBM
1093 : *--------------------------------------------------------------------------*/
1094 :
1095 2735 : void ivas_omasa_dirac_rend_jbm_fx(
1096 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1097 : const UWord16 nSamplesAsked, /* i : number of samples requested */
1098 : UWord16 *nSamplesRendered, /* o : number of samples rendered */
1099 : UWord16 *nSamplesAvailable, /* o : number of samples still to render */
1100 : const Word16 nchan_transport, /* i : number of transport channels */
1101 : Word32 *output_f[] /* o : rendered time signal Q11*/
1102 : )
1103 : {
1104 : Word16 subframes_rendered;
1105 : Word16 slots_rendered;
1106 : Word16 n;
1107 : Word32 data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
1108 :
1109 2735 : test();
1110 2735 : IF( !st_ivas->hDecoderConfig->Opt_tsm )
1111 : {
1112 1800 : *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
1113 :
1114 :
1115 1800 : test();
1116 1800 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
1117 : {
1118 1050 : Copy32( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered );
1119 : }
1120 : ELSE
1121 : {
1122 2474 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
1123 : {
1124 1724 : Copy32( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered );
1125 : }
1126 : }
1127 : }
1128 :
1129 2735 : subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
1130 2735 : move16();
1131 2735 : slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
1132 2735 : move16();
1133 :
1134 2735 : ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
1135 :
1136 13675 : FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
1137 : {
1138 10940 : scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29
1139 : }
1140 :
1141 2735 : ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered );
1142 :
1143 13675 : FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
1144 : {
1145 10940 : scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30
1146 : }
1147 :
1148 2735 : return;
1149 : }
1150 :
1151 :
1152 : /*--------------------------------------------------------------------------*
1153 : * ivas_omasa_dirac_td_binaural_render()
1154 : *
1155 : * Binaural rendering in OMASA format for JBM
1156 : *--------------------------------------------------------------------------*/
1157 :
1158 129 : ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
1159 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1160 : const UWord16 nSamplesAsked, /* i : number of samples requested */
1161 : UWord16 *nSamplesRendered, /* o : number of samples rendered */
1162 : UWord16 *nSamplesAvailable, /* o : number of samples still to render */
1163 : const Word16 nchan_transport, /* i : number of transport channels */
1164 : Word32 *output_fx[] /* o : rendered time signal Q11*/
1165 : )
1166 : {
1167 : Word16 n;
1168 : ivas_error error;
1169 : Word32 *p_sepobj_fx[BINAURAL_CHANNELS]; // Q11
1170 : Word32 data_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k];
1171 : Word16 slot_idx_start;
1172 :
1173 129 : slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
1174 129 : move16();
1175 :
1176 387 : FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
1177 : {
1178 258 : p_sepobj_fx[n] = &data_separated_objects_fx[n][0];
1179 : }
1180 :
1181 : /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
1182 :
1183 129 : ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_fx );
1184 :
1185 : /* reset combined orientation access index before calling the td renderer */
1186 129 : ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
1187 :
1188 129 : IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
1189 0 : {
1190 : Word16 slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots;
1191 : Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
1192 : Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
1193 : Word32 *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */
1194 0 : Word16 q_cldfb, q_in = 11;
1195 0 : move16();
1196 :
1197 0 : FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); n++ )
1198 : {
1199 0 : p_rend_obj[n] = &output_fx[n][0];
1200 0 : move32();
1201 : }
1202 :
1203 0 : num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
1204 0 : move16();
1205 0 : nchan_transport_orig = st_ivas->nchan_transport;
1206 0 : move16();
1207 0 : st_ivas->nchan_transport = st_ivas->nchan_ism;
1208 0 : move16();
1209 :
1210 0 : IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */
1211 : {
1212 0 : return error;
1213 : }
1214 :
1215 0 : st_ivas->nchan_transport = nchan_transport_orig;
1216 0 : move16();
1217 0 : cldfb_slots = *nSamplesRendered / num_cldfb_bands;
1218 :
1219 0 : FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n )
1220 : {
1221 0 : q_cldfb = q_in;
1222 0 : Scale_sig32( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->cldfb_state_fx,
1223 0 : sub( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->p_filter_length, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->no_channels ),
1224 0 : sub( q_cldfb, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state ) );
1225 0 : st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state = q_cldfb;
1226 0 : FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
1227 : {
1228 0 : q_cldfb = q_in;
1229 0 : cldfbAnalysis_ts_fx_fixed_q( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb );
1230 :
1231 0 : Scale_sig32( Cldfb_RealBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) );
1232 0 : Scale_sig32( Cldfb_ImagBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) );
1233 : /* note: this intentionally differs from OSBA by: no scaling by 0.5 */
1234 0 : v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
1235 0 : v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
1236 : }
1237 : }
1238 : }
1239 : else
1240 : {
1241 129 : IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
1242 : {
1243 0 : return error;
1244 : }
1245 :
1246 387 : FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
1247 : {
1248 258 : v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
1249 : }
1250 : }
1251 :
1252 129 : return IVAS_ERR_OK;
1253 : }
1254 :
1255 :
1256 : /*--------------------------------------------------------------------------*
1257 : * ivas_omasa_rearrange_channels()
1258 : *
1259 : * in case of external rendering, rearrange the channels order
1260 : *--------------------------------------------------------------------------*/
1261 :
1262 753 : void ivas_omasa_rearrange_channels_fx(
1263 : Word32 *output[], /* o : output synthesis signal Q11*/
1264 : const Word16 nchan_transport_ism, /* o : number of ISM TCs */
1265 : const Word16 output_frame /* i : output frame length per channel */
1266 : )
1267 : {
1268 : Word16 n;
1269 : Word32 tmp_buff[CPE_CHANNELS][L_FRAME48k]; // Q11
1270 :
1271 753 : Copy32( output[0], tmp_buff[0], output_frame );
1272 753 : Copy32( output[1], tmp_buff[1], output_frame );
1273 :
1274 2865 : FOR( n = 0; n < nchan_transport_ism; n++ )
1275 : {
1276 2112 : Copy32( output[CPE_CHANNELS + n], output[n], output_frame );
1277 : }
1278 753 : Copy32( tmp_buff[0], output[n], output_frame );
1279 753 : Copy32( tmp_buff[1], output[add( n, 1 )], output_frame );
1280 :
1281 753 : return;
1282 : }
1283 :
1284 :
1285 : /*-------------------------------------------------------------------------*
1286 : * ivas_omasa_combine_separate_ism_with_masa_open_fx()
1287 : *
1288 : * Open structures, reserve memory, and init values.
1289 : *-------------------------------------------------------------------------*/
1290 :
1291 18 : ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx(
1292 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1293 : )
1294 : {
1295 : Word16 i;
1296 : Word16 *tmp;
1297 :
1298 18 : st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) );
1299 18 : move32();
1300 :
1301 18 : IF( st_ivas->hIsmRendererData == NULL )
1302 : {
1303 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
1304 : }
1305 :
1306 90 : FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
1307 : {
1308 72 : set_zero_fx( st_ivas->hIsmRendererData->prev_gains_fx[i], MAX_OUTPUT_CHANNELS );
1309 : }
1310 :
1311 18 : test();
1312 18 : test();
1313 18 : IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 16000 ) ||
1314 : EQ_32( st_ivas->hDecoderConfig->output_Fs, 32000 ) ||
1315 : EQ_32( st_ivas->hDecoderConfig->output_Fs, 48000 ) )
1316 : {
1317 18 : IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 16000 ) )
1318 : {
1319 0 : st_ivas->hIsmRendererData->interpolator_len = 80;
1320 0 : tmp = interpolator_table_16k_q15;
1321 : }
1322 18 : ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 32000 ) )
1323 : {
1324 0 : st_ivas->hIsmRendererData->interpolator_len = 160;
1325 0 : tmp = interpolator_table_32k_q15;
1326 : }
1327 : ELSE
1328 : {
1329 18 : st_ivas->hIsmRendererData->interpolator_len = 240;
1330 18 : tmp = interpolator_table_48k_q15;
1331 : }
1332 18 : move16();
1333 18 : move32();
1334 :
1335 18 : st_ivas->hIsmRendererData->interpolator_fx = (Word16 *) malloc( sizeof( Word16 ) * st_ivas->hIsmRendererData->interpolator_len );
1336 :
1337 18 : IF( st_ivas->hIsmRendererData->interpolator_fx == NULL )
1338 : {
1339 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM renderer interpolator\n" ) );
1340 : }
1341 :
1342 4338 : FOR( i = 0; i < st_ivas->hIsmRendererData->interpolator_len; i++ )
1343 : {
1344 4320 : st_ivas->hIsmRendererData->interpolator_fx[i] = tmp[i];
1345 4320 : move16();
1346 : }
1347 : }
1348 : ELSE
1349 : {
1350 0 : return ( IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Unsupported output sample rate\n" ) );
1351 : }
1352 :
1353 18 : return IVAS_ERR_OK;
1354 : }
1355 :
1356 :
1357 : /*--------------------------------------------------------------------------*
1358 : * ivas_omasa_combine_separate_ism_with_masa_fx()
1359 : *
1360 : * in case of external rendering, combine separated ISM signal with MASA stream
1361 : *--------------------------------------------------------------------------*/
1362 :
1363 36 : void ivas_omasa_combine_separate_ism_with_masa_fx(
1364 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1365 : Word32 *output[], /* i/o: output synthesis signal */
1366 : Word16 *output_q, /* i/o: output Q value */
1367 : const Word16 nchan_ism, /* i : number of ISMs */
1368 : const Word16 output_frame /* i : output frame length per channel */
1369 : )
1370 : {
1371 : Word16 n, sf, band, k;
1372 : MASA_DECODER_EXT_OUT_META_HANDLE masaMetaHandle;
1373 : MASA_DECODER_EXT_OUT_META_HANDLE ismMetaHandle;
1374 : MASA_DECODER_EXT_OUT_META ismMeta;
1375 : Word32 inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1376 : Word32 inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1377 : UWord16 directionIndex;
1378 : Word16 nchan_in;
1379 : Word16 nBins;
1380 : Word16 slot;
1381 : Word16 mrange[2], brange[2];
1382 : Word16 processing_len, offset;
1383 :
1384 : Word32 old_panning_gains_fx[2];
1385 : Word32 new_panning_gains_fx[2];
1386 :
1387 : Word16 inRe_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1388 : Word16 inIm_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1389 : Word16 out_exp[MASA_MAX_TRANSPORT_CHANNELS + 1][L_FRAME48k];
1390 :
1391 : Word16 eneMasa_exp[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
1392 : Word32 eneMasa_frac[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
1393 : Word16 eneIsm_exp[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
1394 : Word32 eneIsm_frac[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
1395 :
1396 : Word16 old_panning_gains_q15_fx[2];
1397 : Word16 new_panning_gains_q15_fx[2];
1398 :
1399 : Word16 exp;
1400 :
1401 36 : masaMetaHandle = st_ivas->hMasa->data.extOutMeta;
1402 36 : ismMetaHandle = &ismMeta;
1403 36 : move32();
1404 36 : move32();
1405 :
1406 : /* Compute CLDFB analysis */
1407 36 : nchan_in = add( st_ivas->nchan_transport, 1 );
1408 36 : nBins = mult( output_frame, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ); // Q15
1409 612 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1410 : {
1411 2304 : FOR( n = 0; n < nchan_in; n++ )
1412 : {
1413 1728 : Word16 in_q = *output_q;
1414 1728 : move16();
1415 :
1416 1728 : cldfbAnalysis_ts_fx_var_q( &( output[n][L_mult0( nBins, slot )] ),
1417 1728 : inRe[n][slot],
1418 1728 : inIm[n][slot],
1419 : nBins, st_ivas->cldfbAnaDec[n], &in_q );
1420 :
1421 : /* Assign input exponent */
1422 1728 : exp = sub( Q31, in_q );
1423 1728 : set16_fx( inRe_exp[n][slot], exp, nBins );
1424 1728 : set16_fx( inIm_exp[n][slot], exp, nBins );
1425 : }
1426 : }
1427 :
1428 : /* Convert output to exponent+mantissa representation */
1429 36 : exp = sub( Q31, *output_q );
1430 144 : FOR( n = 0; n < add( MASA_MAX_TRANSPORT_CHANNELS, 1 ); n++ )
1431 : {
1432 108 : set16_fx( out_exp[n], exp, output_frame );
1433 : }
1434 :
1435 180 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1436 : {
1437 144 : set16_fx( eneMasa_exp[sf], 0, MASA_FREQUENCY_BANDS );
1438 144 : set32_fx( eneMasa_frac[sf], 0, MASA_FREQUENCY_BANDS );
1439 :
1440 144 : set16_fx( eneIsm_exp[sf], 0, MASA_FREQUENCY_BANDS );
1441 144 : set32_fx( eneIsm_frac[sf], 0, MASA_FREQUENCY_BANDS );
1442 : }
1443 :
1444 : /* Determine energies */
1445 180 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1446 : {
1447 144 : mrange[0] = st_ivas->hMasa->config.block_grouping[sf];
1448 144 : mrange[1] = st_ivas->hMasa->config.block_grouping[add( sf, 1 )];
1449 144 : move16();
1450 144 : move16();
1451 :
1452 720 : FOR( slot = mrange[0]; slot < mrange[1]; slot++ )
1453 : {
1454 14400 : FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
1455 : {
1456 13824 : brange[0] = st_ivas->hMasa->config.band_grouping[band];
1457 13824 : brange[1] = st_ivas->hMasa->config.band_grouping[add( band, 1 )];
1458 13824 : move16();
1459 13824 : move16();
1460 :
1461 13824 : IF( GT_16( brange[1], nBins ) )
1462 : {
1463 0 : brange[1] = nBins;
1464 0 : move16();
1465 : }
1466 :
1467 13824 : Word16 len = sub( brange[1], brange[0] );
1468 :
1469 41472 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1470 : {
1471 27648 : sample_energy_acc_fx( &inRe[n][slot][brange[0]],
1472 27648 : &inRe_exp[n][slot][brange[0]],
1473 27648 : &inIm[n][slot][brange[0]],
1474 27648 : &inIm_exp[n][slot][brange[0]],
1475 27648 : &eneMasa_frac[sf][band],
1476 27648 : &eneMasa_exp[sf][band],
1477 : len );
1478 : }
1479 :
1480 13824 : sample_energy_acc_fx( &inRe[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
1481 13824 : &inRe_exp[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
1482 13824 : &inIm[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
1483 13824 : &inIm_exp[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
1484 13824 : &eneIsm_frac[sf][band],
1485 13824 : &eneIsm_exp[sf][band],
1486 : len );
1487 : }
1488 : }
1489 : }
1490 :
1491 : /* Determine MASA metadata for the object */
1492 36 : ismMetaHandle->descriptiveMeta.numberOfDirections = 0u;
1493 36 : move16();
1494 :
1495 180 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1496 : {
1497 : Word32 ele, azi;
1498 :
1499 144 : ele = st_ivas->hMasaIsmData->elevation_separated_ism[sf];
1500 144 : azi = st_ivas->hMasaIsmData->azimuth_separated_ism[sf];
1501 :
1502 144 : directionIndex = index_theta_phi_16_fx( &ele, &azi, st_ivas->hMasa->data.sph_grid16 );
1503 :
1504 3600 : FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
1505 : {
1506 3456 : ismMetaHandle->directionIndex[0][sf][band] = directionIndex;
1507 3456 : ismMetaHandle->directToTotalRatio[0][sf][band] = UINT8_MAX;
1508 3456 : ismMetaHandle->spreadCoherence[0][sf][band] = 0;
1509 3456 : ismMetaHandle->surroundCoherence[sf][band] = 0;
1510 3456 : ismMetaHandle->diffuseToTotalRatio[sf][band] = 0;
1511 3456 : move16();
1512 3456 : move16();
1513 3456 : move16();
1514 3456 : move16();
1515 3456 : move16();
1516 : }
1517 : }
1518 :
1519 : /* Merge MASA metadatas */
1520 36 : ivas_prerend_merge_masa_metadata_fx( masaMetaHandle, masaMetaHandle,
1521 : IVAS_REND_AUDIO_CONFIG_TYPE_MASA,
1522 : eneMasa_frac, eneMasa_exp, ismMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED,
1523 : eneIsm_frac, eneIsm_exp );
1524 :
1525 : /* Mix the separated object audio signal to the MASA audio signals */
1526 36 : ivas_get_stereo_panning_gains_fx( st_ivas->hMasaIsmData->azimuth_separated_ism[0],
1527 36 : st_ivas->hMasaIsmData->elevation_separated_ism[0], old_panning_gains_q15_fx );
1528 36 : ivas_get_stereo_panning_gains_fx( st_ivas->hMasaIsmData->azimuth_separated_ism[2],
1529 36 : st_ivas->hMasaIsmData->elevation_separated_ism[2], new_panning_gains_q15_fx );
1530 :
1531 : /* Subsequent processing in Q31 format */
1532 108 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1533 : {
1534 72 : new_panning_gains_fx[n] = L_shl( new_panning_gains_q15_fx[n], Q16 );
1535 72 : old_panning_gains_fx[n] = L_shl( old_panning_gains_q15_fx[n], Q16 );
1536 : }
1537 :
1538 36 : processing_len = shr( output_frame, 1 );
1539 108 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1540 : {
1541 72 : v_multc_acc_exp_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS],
1542 : out_exp[MASA_MAX_TRANSPORT_CHANNELS],
1543 : old_panning_gains_fx[n],
1544 72 : output[n],
1545 72 : out_exp[n],
1546 : processing_len );
1547 : }
1548 36 : offset = processing_len;
1549 36 : move16();
1550 :
1551 36 : processing_len = shr( output_frame, 2 ); /* divide by MAX_PARAM_SPATIAL_SUBFRAMES; */
1552 108 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1553 : {
1554 : Word32 mantissa;
1555 :
1556 : /* k == 0->gain == old_panning_gains[n] */
1557 : /* output[n][offset] += gain * output[MASA_MAX_TRANSPORT_CHANNELS][offset]; */
1558 72 : mantissa = mult32_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS][offset],
1559 : old_panning_gains_fx[n],
1560 72 : out_exp[MASA_MAX_TRANSPORT_CHANNELS][offset], &exp );
1561 :
1562 144 : output[n][offset] = BASOP_Util_Add_Mant32Exp( output[n][offset], out_exp[n][offset],
1563 72 : mantissa, exp, &out_exp[n][offset] );
1564 72 : move32();
1565 72 : move32();
1566 :
1567 17280 : FOR( k = 1; k < processing_len; k++ )
1568 : {
1569 17208 : Word16 index = add( k, offset );
1570 :
1571 17208 : Word32 g1_fx = L_shl( st_ivas->hIsmRendererData->interpolator_fx[k], Q16 );
1572 :
1573 : /* 1.0f - g1 */
1574 17208 : Word32 g2_fx = L_sub( MAX_32, L_sub( g1_fx, 1 ) );
1575 :
1576 : /* g1 *new_panning_gains[n] + g2 *old_panning_gains[n] */
1577 17208 : Word32 gain_k = W_extract_h( W_add( W_mult_32_32( g1_fx, new_panning_gains_fx[n] ),
1578 : W_mult_32_32( g2_fx, old_panning_gains_fx[n] ) ) );
1579 :
1580 : /* output[n][k + offset] += gain_k * output[MASA_MAX_TRANSPORT_CHANNELS][k + offset]; */
1581 17208 : mantissa = mult32_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS][index], gain_k,
1582 17208 : out_exp[MASA_MAX_TRANSPORT_CHANNELS][index], &exp );
1583 34416 : output[n][index] = BASOP_Util_Add_Mant32Exp( output[n][index], out_exp[n][index],
1584 17208 : mantissa, exp, &out_exp[n][index] );
1585 17208 : move32();
1586 17208 : move32();
1587 : }
1588 : }
1589 36 : offset = add( offset, processing_len );
1590 :
1591 108 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1592 : {
1593 72 : v_multc_acc_exp_mantissa_fx( &output[MASA_MAX_TRANSPORT_CHANNELS][offset],
1594 72 : &out_exp[MASA_MAX_TRANSPORT_CHANNELS][offset],
1595 : new_panning_gains_fx[n],
1596 72 : &output[n][offset],
1597 72 : &out_exp[n][offset],
1598 : processing_len );
1599 : }
1600 :
1601 : /* Convert output from exponent+mantissa representation to Q11 */
1602 108 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1603 : {
1604 72 : mantissa_exp_to_qvalue( &out_exp[n][0], &output[n][0], Q20, output_frame );
1605 : }
1606 :
1607 : /* Zero output object channels */
1608 180 : FOR( n = 0; n < nchan_ism; n++ )
1609 : {
1610 144 : set_zero_fx( output[add( MASA_MAX_TRANSPORT_CHANNELS, n )], output_frame );
1611 : }
1612 :
1613 36 : return;
1614 : }
1615 :
1616 :
1617 : /*-------------------------------------------------------------------------*
1618 : * ivas_omasa_objects_delay_open()
1619 : *
1620 : * Open structures, reserve memory, and init values for dela buffers of objects.
1621 : *-------------------------------------------------------------------------*/
1622 :
1623 569 : ivas_error ivas_omasa_objects_delay_open_fx(
1624 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1625 : )
1626 : {
1627 : Word16 i;
1628 : Word32 size;
1629 :
1630 569 : test();
1631 569 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
1632 : {
1633 341 : st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
1634 341 : move16();
1635 : }
1636 : ELSE
1637 : {
1638 228 : st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
1639 228 : move16();
1640 : }
1641 :
1642 569 : st_ivas->hMasaIsmData->delayBuffer_size = extract_l( Mult_32_16( st_ivas->hDecoderConfig->output_Fs,
1643 : OMASA_DELAYFRAMES_PER_SEC_Q15 ) );
1644 :
1645 569 : size = L_mult0( st_ivas->hMasaIsmData->delayBuffer_nchan, sizeof( Word16 * ) );
1646 569 : st_ivas->hMasaIsmData->delayBuffer_fx = (Word32 **) malloc( size );
1647 569 : move32();
1648 :
1649 569 : IF( st_ivas->hMasaIsmData->delayBuffer_fx == NULL )
1650 : {
1651 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1652 : }
1653 :
1654 569 : size = L_mult0( st_ivas->hMasaIsmData->delayBuffer_size, sizeof( Word32 ) );
1655 1694 : FOR( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
1656 : {
1657 1125 : st_ivas->hMasaIsmData->delayBuffer_fx[i] = (Word32 *) malloc( size );
1658 1125 : move32();
1659 :
1660 1125 : IF( st_ivas->hMasaIsmData->delayBuffer_fx[i] == NULL )
1661 : {
1662 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1663 : }
1664 1125 : set_zero_fx( st_ivas->hMasaIsmData->delayBuffer_fx[i], st_ivas->hMasaIsmData->delayBuffer_size );
1665 : }
1666 :
1667 569 : return IVAS_ERR_OK;
1668 : }
1669 :
1670 :
1671 : /*--------------------------------------------------------------------------*
1672 : * ivas_omasa_render_objects_from_mix()
1673 : *
1674 : * In case of external rendering, render objects from the transport signal
1675 : * mix containing MASA audio and object audio.
1676 : *--------------------------------------------------------------------------*/
1677 :
1678 40 : void ivas_omasa_render_objects_from_mix_fx(
1679 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1680 : Word32 *output[], /* o : output synthesis signal */
1681 : const Word16 nchan_ism, /* i : number of ISMs */
1682 : const Word16 output_frame, /* i : output frame length per channel */
1683 : Word16 *output_q /* i/o: output Q value */
1684 : )
1685 : {
1686 : Word16 n, m, i;
1687 : MASA_ISM_EXT_DATA_HANDLE hExtData;
1688 : Word32 separated_object[L_FRAME48k];
1689 : Word32 rendered_objects[MAX_NUM_OBJECTS][L_FRAME48k];
1690 : Word16 coding_delay;
1691 : Word32 inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1692 : Word32 inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1693 : Word32 outRe[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1694 : Word32 outIm[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1695 : Word16 slot;
1696 : Word16 sf;
1697 : Word16 bin;
1698 : Word16 nchan_transport;
1699 : Word16 nBins;
1700 :
1701 : Word16 inRe_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1702 : Word16 inIm_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1703 : Word16 outRe_exp[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1704 : Word16 outIm_exp[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1705 :
1706 : Word16 transport_energy_exp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1707 : Word32 transport_energy_frac[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1708 :
1709 : /* Create slot to metadata map */
1710 40 : slot = 0;
1711 40 : move16();
1712 200 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1713 : {
1714 : Word16 index;
1715 :
1716 800 : FOR( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ )
1717 : {
1718 640 : st_ivas->hSpatParamRendCom->render_to_md_map[slot] = st_ivas->hSpatParamRendCom->dirac_read_idx;
1719 640 : move16();
1720 640 : slot = add( slot, 1 );
1721 : }
1722 :
1723 160 : index = add( st_ivas->hSpatParamRendCom->dirac_read_idx, 1 );
1724 160 : IF( GE_16( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) )
1725 : {
1726 20 : index = 0;
1727 20 : move16();
1728 : }
1729 160 : st_ivas->hSpatParamRendCom->dirac_read_idx = index;
1730 160 : move16();
1731 : }
1732 :
1733 : /* Move separated object signal and object channels */
1734 40 : mvl2l( output[CPE_CHANNELS], separated_object, output_frame );
1735 200 : FOR( n = 0; n < nchan_ism; n++ )
1736 : {
1737 160 : set_zero_fx( output[CPE_CHANNELS + n], output_frame );
1738 : }
1739 :
1740 : /* Delay the separated object signal by the CLDFB delay */
1741 40 : delay_signal32_fx( separated_object, output_frame, st_ivas->hMasaIsmData->delayBuffer_fx[0],
1742 40 : st_ivas->hMasaIsmData->delayBuffer_size );
1743 :
1744 : /* Set object metadata to the ism struct */
1745 200 : FOR( n = 0; n < nchan_ism; n++ )
1746 : {
1747 : // Q0 -> Q22
1748 160 : Word32 azi = L_shl( st_ivas->hMasaIsmData->azimuth_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx], Q22 );
1749 160 : Word32 ele = L_shl( st_ivas->hMasaIsmData->elevation_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx], Q22 );
1750 :
1751 160 : st_ivas->hIsmMetaData[n]->azimuth_fx = azi;
1752 160 : st_ivas->hIsmMetaData[n]->elevation_fx = ele;
1753 160 : move16();
1754 160 : move16();
1755 : }
1756 :
1757 : /* Move the separated object signal to the correct output channel */
1758 40 : hExtData = st_ivas->hMasaIsmData->hExtData;
1759 40 : move32();
1760 40 : coding_delay = mult( output_frame, MULT_17_DIV_20_Q15 ); /* Q15: 17 ms of coding and CLDFB delay */
1761 40 : mvl2l( separated_object, output[add( CPE_CHANNELS, hExtData->prev_idx_separated_ism )], coding_delay );
1762 80 : mvl2l( &separated_object[coding_delay],
1763 40 : &output[add( CPE_CHANNELS, st_ivas->hMasaIsmData->idx_separated_ism )][coding_delay],
1764 40 : sub( output_frame, coding_delay ) );
1765 :
1766 : /* Compute CLDFB analysis */
1767 40 : nchan_transport = st_ivas->nchan_transport;
1768 40 : move16();
1769 40 : nBins = mult( output_frame, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ); // Q15
1770 :
1771 680 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1772 : {
1773 1920 : FOR( n = 0; n < nchan_transport; n++ )
1774 : {
1775 1280 : Word16 in_q = *output_q;
1776 1280 : move16();
1777 :
1778 1280 : cldfbAnalysis_ts_fx_var_q( &( output[n][L_mult0( nBins, slot )] ),
1779 1280 : inRe[n][slot],
1780 1280 : inIm[n][slot],
1781 : nBins, st_ivas->cldfbAnaDec[n], &in_q );
1782 :
1783 : /* Assign input exponent */
1784 1280 : Word16 exp = sub( Q31, in_q );
1785 1280 : set16_fx( inRe_exp[n][slot], exp, nBins );
1786 1280 : set16_fx( inIm_exp[n][slot], exp, nBins );
1787 : }
1788 : }
1789 :
1790 : /* Create prototype signals */
1791 200 : for ( n = 0; n < nchan_ism; n++ )
1792 : {
1793 : Word32 panning_gains_fx[2];
1794 : Word16 new_panning_gains_fx[2];
1795 : Word16 azimuth_fx, elevation_fx;
1796 :
1797 : // Q22 -> Q0
1798 160 : azimuth_fx = extract_l( L_shr( st_ivas->hIsmMetaData[n]->azimuth_fx, Q22 ) );
1799 160 : elevation_fx = extract_l( L_shr( st_ivas->hIsmMetaData[n]->elevation_fx, Q22 ) );
1800 160 : ivas_get_stereo_panning_gains_fx( azimuth_fx, elevation_fx, new_panning_gains_fx );
1801 :
1802 160 : Word16 interpValInc = 0;
1803 160 : move16();
1804 :
1805 : // Represents (1.0f - interpVal) value
1806 160 : Word16 interpValDec = extract_l( L_sub( -MIN16B, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ) );
1807 :
1808 2560 : FOR( slot = 0; slot < sub( CLDFB_NO_COL_MAX, 1 ); slot++ )
1809 : {
1810 2400 : interpValInc = add( interpValInc, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 );
1811 :
1812 7200 : FOR( m = 0; m < 2; m++ )
1813 : {
1814 4800 : Word32 prev_gain = hExtData->prev_panning_gains[n][m];
1815 4800 : move32();
1816 :
1817 4800 : Word32 new_gain = L_shl( new_panning_gains_fx[m], 16 ); // Q15 -> Q31
1818 :
1819 4800 : panning_gains_fx[m] = L_add( Mpy_32_16( extract_h( prev_gain ), extract_l( prev_gain ),
1820 : interpValDec ),
1821 4800 : Mpy_32_16( extract_h( new_gain ), extract_l( new_gain ),
1822 : interpValInc ) );
1823 : }
1824 :
1825 2400 : interpValDec = sub( interpValDec, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 );
1826 :
1827 2400 : v_multc_exp_mantissa_fx( inRe[0][slot], inRe_exp[0][slot], panning_gains_fx[0],
1828 2400 : outRe[n][slot], outRe_exp[n][slot], nBins );
1829 2400 : v_multc_exp_mantissa_fx( inIm[0][slot], inIm_exp[0][slot], panning_gains_fx[0],
1830 2400 : outIm[n][slot], outIm_exp[n][slot], nBins );
1831 :
1832 2400 : v_multc_acc_exp_mantissa_fx( inRe[1][slot], inRe_exp[1][slot], panning_gains_fx[1],
1833 2400 : outRe[n][slot], outRe_exp[n][slot], nBins );
1834 2400 : v_multc_acc_exp_mantissa_fx( inIm[1][slot], inIm_exp[1][slot], panning_gains_fx[1],
1835 2400 : outIm[n][slot], outIm_exp[n][slot], nBins );
1836 : }
1837 :
1838 : // Special case where (1.0f - interpVal) = 0 and interpVal = 1
1839 480 : FOR( m = 0; m < 2; m++ )
1840 : {
1841 320 : panning_gains_fx[m] = L_shl( new_panning_gains_fx[m], 16 ); // Q15 -> Q31
1842 : }
1843 :
1844 160 : v_multc_exp_mantissa_fx( inRe[0][slot], inRe_exp[0][slot], panning_gains_fx[0],
1845 160 : outRe[n][slot], outRe_exp[n][slot], nBins );
1846 160 : v_multc_exp_mantissa_fx( inIm[0][slot], inIm_exp[0][slot], panning_gains_fx[0],
1847 160 : outIm[n][slot], outIm_exp[n][slot], nBins );
1848 :
1849 160 : v_multc_acc_exp_mantissa_fx( inRe[1][slot], inRe_exp[1][slot], panning_gains_fx[1],
1850 160 : outRe[n][slot], outRe_exp[n][slot], nBins );
1851 160 : v_multc_acc_exp_mantissa_fx( inIm[1][slot], inIm_exp[1][slot], panning_gains_fx[1],
1852 160 : outIm[n][slot], outIm_exp[n][slot], nBins );
1853 :
1854 480 : FOR( m = 0; m < 2; m++ )
1855 : {
1856 320 : hExtData->prev_panning_gains[n][m] = panning_gains_fx[m];
1857 320 : move32();
1858 : }
1859 : }
1860 :
1861 : /* Determine transport energy */
1862 680 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1863 : {
1864 640 : set_zero_fx( &transport_energy_frac[slot][0], nBins );
1865 640 : set16_zero_fx( &transport_energy_exp[slot][0], nBins );
1866 : }
1867 120 : FOR( n = 0; n < CPE_CHANNELS; n++ )
1868 : {
1869 1360 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1870 : {
1871 78080 : FOR( bin = 0; bin < nBins; bin++ )
1872 : {
1873 : Word16 exp;
1874 :
1875 : // energy = re^2 + im^2
1876 76800 : Word32 mantissa = sample_energy_fx( inRe[n][slot][bin], inRe_exp[n][slot][bin],
1877 76800 : inIm[n][slot][bin], inIm_exp[n][slot][bin], &exp );
1878 76800 : move32();
1879 :
1880 : // Accumulate energy
1881 153600 : transport_energy_frac[slot][bin] = BASOP_Util_Add_Mant32Exp( transport_energy_frac[slot][bin],
1882 76800 : transport_energy_exp[slot][bin],
1883 : mantissa,
1884 : exp,
1885 76800 : &transport_energy_exp[slot][bin] );
1886 76800 : move32();
1887 : }
1888 : }
1889 : }
1890 :
1891 : /* Determine temporally smoothed energies and determine gains using them */
1892 200 : FOR( n = 0; n < nchan_ism; n++ )
1893 : {
1894 2720 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1895 : {
1896 2560 : Word16 md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1897 2560 : move16();
1898 :
1899 156160 : FOR( bin = 0; bin < nBins; bin++ )
1900 : {
1901 : Word16 exp, exp_mult, proto_e, target_e;
1902 : Word32 mantissa, proto_m, target_m;
1903 :
1904 : Word32 ism_target_energy_frac;
1905 : Word16 ism_target_energy_exp;
1906 :
1907 : Word32 ism_proto_energy_frac;
1908 : Word16 ism_proto_energy_exp;
1909 :
1910 : // r1 = transport_energy[slot][bin] * st_ivas->hMasaIsmData->energy_ratio_ism[n][md_idx][bin]
1911 153600 : ism_target_energy_frac = mult32_mantissa_fx( transport_energy_frac[slot][bin],
1912 153600 : st_ivas->hMasaIsmData->energy_ratio_ism_fx[n][md_idx][bin],
1913 153600 : add( transport_energy_exp[slot][bin], 1 ),
1914 : &ism_target_energy_exp );
1915 153600 : move32();
1916 :
1917 : // r2 = r1 * (1.0 - EXT_RENDER_IIR_FAC)
1918 153600 : ism_target_energy_frac = mult32_mantissa_fx( ism_target_energy_frac,
1919 : ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
1920 : ism_target_energy_exp,
1921 : &ism_target_energy_exp );
1922 153600 : move32();
1923 :
1924 : // r3 = re^2 + im^2
1925 153600 : mantissa = sample_energy_fx( outRe[n][slot][bin],
1926 153600 : outRe_exp[n][slot][bin],
1927 : outIm[n][slot][bin],
1928 153600 : outIm_exp[n][slot][bin],
1929 : &exp );
1930 153600 : move32();
1931 :
1932 : // r4 = r3 * (1 - EXT_RENDER_IIR_FAC)
1933 153600 : ism_proto_energy_frac = mult32_mantissa_fx( mantissa, ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
1934 : exp, &ism_proto_energy_exp );
1935 153600 : move32();
1936 :
1937 :
1938 : // r5 = ism_render_proto_energy[n][bin] * EXT_RENDER_IIR_FAC
1939 153600 : proto_m = mult32_mantissa_fx( hExtData->ism_render_proto_energy_frac[n][bin], EXT_RENDER_IIR_FAC_Q31,
1940 153600 : hExtData->ism_render_proto_energy_exp[n][bin], &proto_e );
1941 153600 : move32();
1942 :
1943 : // r6 = r5 + r4
1944 153600 : proto_m = BASOP_Util_Add_Mant32Exp( proto_m, proto_e,
1945 : ism_proto_energy_frac,
1946 : ism_proto_energy_exp,
1947 : &proto_e );
1948 153600 : move32();
1949 :
1950 : // r7 = ism_render_target_energy[n][bin] * EXT_RENDER_IIR_FAC
1951 153600 : target_m = mult32_mantissa_fx( hExtData->ism_render_target_energy_frac[n][bin], EXT_RENDER_IIR_FAC_Q31,
1952 153600 : hExtData->ism_render_target_energy_exp[n][bin], &target_e );
1953 153600 : move32();
1954 :
1955 : // r8 = r7 + r2
1956 153600 : target_m = BASOP_Util_Add_Mant32Exp( target_m, target_e,
1957 : ism_target_energy_frac,
1958 : ism_target_energy_exp,
1959 : &target_e );
1960 153600 : move32();
1961 :
1962 153600 : hExtData->ism_render_proto_energy_frac[n][bin] = proto_m;
1963 153600 : hExtData->ism_render_proto_energy_exp[n][bin] = proto_e;
1964 153600 : move32();
1965 153600 : move16();
1966 :
1967 153600 : hExtData->ism_render_target_energy_frac[n][bin] = target_m;
1968 153600 : hExtData->ism_render_target_energy_exp[n][bin] = target_e;
1969 153600 : move32();
1970 153600 : move16();
1971 :
1972 : // r9 = sqrt(r8 / r6)
1973 153600 : mantissa = get_processing_gain_fx( proto_m, proto_e, target_m, target_e, &exp );
1974 153600 : move32();
1975 :
1976 : // outRe[n][slot][bin] *= r9
1977 153600 : exp_mult = add( exp, outRe_exp[n][slot][bin] );
1978 307200 : outRe[n][slot][bin] = mult32_mantissa_fx( outRe[n][slot][bin], mantissa, exp_mult,
1979 153600 : &outRe_exp[n][slot][bin] );
1980 153600 : move32();
1981 :
1982 : // outIm[n][slot][bin] *= r9
1983 153600 : exp_mult = add( exp, outIm_exp[n][slot][bin] );
1984 307200 : outIm[n][slot][bin] = mult32_mantissa_fx( outIm[n][slot][bin], mantissa, exp_mult,
1985 153600 : &outIm_exp[n][slot][bin] );
1986 153600 : move32();
1987 : }
1988 : }
1989 : }
1990 :
1991 680 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1992 : {
1993 640 : Word16 md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1994 640 : move16();
1995 :
1996 39040 : FOR( bin = 0; bin < nBins; bin++ )
1997 : {
1998 : Word16 exp, proto_e, target_e, transport_exp;
1999 : Word32 mantissa, proto_m, target_m, transport_mantissa;
2000 :
2001 : Word32 masa_target_energy_frac;
2002 : Word16 masa_target_energy_exp;
2003 :
2004 : // r1 = transport_energy[slot][bin] * hExtData->masa_render_masa_to_total[md_idx][bin]
2005 38400 : masa_target_energy_frac = mult32_mantissa_fx( transport_energy_frac[slot][bin],
2006 : hExtData->masa_render_masa_to_total[md_idx][bin],
2007 38400 : add( transport_energy_exp[slot][bin], 1 ),
2008 : &masa_target_energy_exp );
2009 38400 : move32();
2010 :
2011 : // r2 = r1 * EXT_RENDER_IIR_FAC
2012 38400 : masa_target_energy_frac = mult32_mantissa_fx( masa_target_energy_frac,
2013 : ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
2014 : masa_target_energy_exp,
2015 : &masa_target_energy_exp );
2016 38400 : move32();
2017 :
2018 : // r3 = masa_render_proto_energy[bin] * EXT_RENDER_IIR_FAC
2019 38400 : proto_m = mult32_mantissa_fx( hExtData->masa_render_proto_energy_frac[bin], EXT_RENDER_IIR_FAC_Q31,
2020 38400 : hExtData->masa_render_proto_energy_exp[bin], &proto_e );
2021 38400 : move32();
2022 :
2023 : // r4 = transport_energy[slot][bin] * EXT_RENDER_IIR_FAC
2024 38400 : transport_mantissa = mult32_mantissa_fx( transport_energy_frac[slot][bin],
2025 : ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
2026 38400 : transport_energy_exp[slot][bin], &transport_exp );
2027 38400 : move32();
2028 :
2029 : // r5 = r3 + r4
2030 38400 : proto_m = BASOP_Util_Add_Mant32Exp( proto_m, proto_e,
2031 : transport_mantissa,
2032 : transport_exp,
2033 : &proto_e );
2034 38400 : move32();
2035 :
2036 : // r6 = masa_render_target_energy[bin] * EXT_RENDER_IIR_FAC
2037 38400 : target_m = mult32_mantissa_fx( hExtData->masa_render_target_energy_frac[bin], EXT_RENDER_IIR_FAC_Q31,
2038 38400 : hExtData->masa_render_target_energy_exp[bin], &target_e );
2039 38400 : move32();
2040 :
2041 : // r7 = r6 + r2
2042 38400 : target_m = BASOP_Util_Add_Mant32Exp( target_m, target_e,
2043 : masa_target_energy_frac,
2044 : masa_target_energy_exp,
2045 : &target_e );
2046 38400 : move32();
2047 :
2048 38400 : hExtData->masa_render_proto_energy_frac[bin] = proto_m;
2049 38400 : hExtData->masa_render_proto_energy_exp[bin] = proto_e;
2050 38400 : move16();
2051 38400 : move32();
2052 :
2053 38400 : hExtData->masa_render_target_energy_frac[bin] = target_m;
2054 38400 : hExtData->masa_render_target_energy_exp[bin] = target_e;
2055 38400 : move16();
2056 38400 : move32();
2057 :
2058 : // r8 = sqrt(r7 / r5)
2059 38400 : mantissa = get_processing_gain_fx( proto_m, proto_e, target_m, target_e, &exp );
2060 38400 : move32();
2061 :
2062 115200 : FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
2063 : {
2064 : Word16 exp_mult;
2065 :
2066 : // inRe[n][slot][bin] *= r8
2067 76800 : exp_mult = add( exp, inRe_exp[n][slot][bin] );
2068 153600 : inRe[n][slot][bin] = mult32_mantissa_fx( inRe[n][slot][bin], mantissa, exp_mult,
2069 76800 : &inRe_exp[n][slot][bin] );
2070 76800 : move32();
2071 :
2072 : // inIm[n][slot][bin] *= r8
2073 76800 : exp_mult = add( exp, inIm_exp[n][slot][bin] );
2074 153600 : inIm[n][slot][bin] = mult32_mantissa_fx( inIm[n][slot][bin], mantissa, exp_mult,
2075 76800 : &inIm_exp[n][slot][bin] );
2076 76800 : move32();
2077 : }
2078 : }
2079 : }
2080 :
2081 40 : *output_q = Q11;
2082 :
2083 : /* Compute CLDFB synthesis */
2084 680 : FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
2085 : {
2086 : Word32 *outSlotRePr, *outSlotImPr;
2087 640 : Word32 index = L_mult0( nBins, slot );
2088 :
2089 1920 : FOR( n = 0; n < nchan_transport; n++ )
2090 : {
2091 1280 : outSlotRePr = &( inRe[n][slot][0] );
2092 1280 : outSlotImPr = &( inIm[n][slot][0] );
2093 1280 : move32();
2094 1280 : move32();
2095 :
2096 78080 : FOR( bin = 0; bin < nBins; bin++ )
2097 : {
2098 76800 : inRe_exp[n][slot][bin] = sub( inRe_exp[n][slot][bin], Q2 );
2099 76800 : inIm_exp[n][slot][bin] = sub( inIm_exp[n][slot][bin], Q2 );
2100 : }
2101 :
2102 1280 : mantissa_exp_to_qvalue( &inRe_exp[n][slot][0], &inRe[n][slot][0], Q20, nBins );
2103 1280 : mantissa_exp_to_qvalue( &inIm_exp[n][slot][0], &inIm[n][slot][0], Q20, nBins );
2104 :
2105 1280 : cldfbSynthesis_ivas_fx( &outSlotRePr, &outSlotImPr, &output[n][index],
2106 : nBins, Q2, 1, st_ivas->cldfbSynDec[n] );
2107 : }
2108 :
2109 3200 : FOR( n = 0; n < nchan_ism; n++ )
2110 : {
2111 2560 : Word32 index2 = add( n, CPE_CHANNELS );
2112 :
2113 2560 : outSlotRePr = &( outRe[n][slot][0] );
2114 2560 : outSlotImPr = &( outIm[n][slot][0] );
2115 2560 : move32();
2116 2560 : move32();
2117 :
2118 2560 : mantissa_exp_to_qvalue( &outRe_exp[n][slot][0], &outRe[n][slot][0], Q20, nBins );
2119 2560 : mantissa_exp_to_qvalue( &outIm_exp[n][slot][0], &outIm[n][slot][0], Q20, nBins );
2120 :
2121 2560 : cldfbSynthesis_ivas_fx( &outSlotRePr, &outSlotImPr, &rendered_objects[n][index],
2122 : nBins, 0, 1, st_ivas->cldfbSynDec[index2] );
2123 : }
2124 : }
2125 :
2126 : /* Combine the rendered objects with the separated objects */
2127 200 : FOR( n = 0; n < nchan_ism; n++ )
2128 : {
2129 160 : Word16 index = add( CPE_CHANNELS, n );
2130 160 : v_add_32( output[index], rendered_objects[n], output[index], output_frame );
2131 : }
2132 :
2133 40 : hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
2134 40 : move16();
2135 :
2136 40 : return;
2137 : }
|