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