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