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 <math.h>
34 : #include "options.h"
35 : #include "lib_rend.h"
36 : #include "ivas_prot_rend_fx.h"
37 : #include "ivas_cnst.h"
38 : #include "prot_fx.h"
39 : #include "wmc_auto.h"
40 : #include "ivas_prot_fx.h"
41 :
42 : #define INV_UINT8_MAX 8421505 /* 1/UINT8_MAX in Q31 */
43 :
44 : /*---------------------------------------------------------------------*
45 : * Local function prototypes
46 : *---------------------------------------------------------------------*/
47 :
48 : static void copy_masa_meta_tile_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, const UWord8 sf, const UWord8 band );
49 :
50 : static void full_stream_merge_fx(
51 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */
52 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */
53 : Word32 inEne1_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal */
54 : Word16 inEne1_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1 Exponent */
55 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, /* i : Input metadata 2 */
56 : Word32 inEne2_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2 */
57 : Word16 inEne2_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 Exponent */
58 : );
59 :
60 : static void diffuse_meta_merge_1x1_fx(
61 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */
62 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : Input metadata 1 */
63 : Word32 inEne_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 1 */
64 : Word16 inEne_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 1 Exponent */
65 : MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, /* i : Input metadata 2 */
66 : Word32 inEneISM_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2 */
67 : Word16 inEneISM_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 Exponent */
68 : );
69 :
70 :
71 : /*---------------------------------------------------------------------*
72 : * copy_masa_meta_tile()
73 : *
74 : *
75 : *---------------------------------------------------------------------*/
76 :
77 43200 : void copy_masa_meta_tile_fx(
78 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : metadata to be written */
79 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : input metadata */
80 : const UWord8 sf, /* i : sub-frame index */
81 : const UWord8 band /* i : band index */
82 : )
83 : {
84 43200 : outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
85 43200 : move16();
86 43200 : outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
87 43200 : move16();
88 43200 : outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
89 43200 : move16();
90 :
91 43200 : outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
92 43200 : move16();
93 43200 : outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
94 43200 : move16();
95 :
96 43200 : IF( EQ_16( inMeta->descriptiveMeta.numberOfDirections, 1 ) )
97 : {
98 16559 : outMeta->directionIndex[1][sf][band] = inMeta->directionIndex[1][sf][band];
99 16559 : move16();
100 16559 : outMeta->directToTotalRatio[1][sf][band] = inMeta->directToTotalRatio[1][sf][band];
101 16559 : move16();
102 16559 : outMeta->spreadCoherence[1][sf][band] = inMeta->spreadCoherence[1][sf][band];
103 16559 : move16();
104 : }
105 : ELSE
106 : {
107 : /* make sure the output has zeroed data in the second direction */
108 26641 : outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
109 26641 : move16();
110 26641 : outMeta->directToTotalRatio[1][sf][band] = 0u;
111 26641 : move16();
112 26641 : outMeta->spreadCoherence[1][sf][band] = 0u;
113 26641 : move16();
114 : }
115 :
116 43200 : return;
117 : }
118 :
119 : /*---------------------------------------------------------------------*
120 : * copy_masa_descriptive_meta()
121 : *
122 : *
123 : *---------------------------------------------------------------------*/
124 :
125 150 : void copy_masa_descriptive_meta_fx(
126 : MASA_DECRIPTIVE_META *outMeta, /* o : metadata to be written */
127 : MASA_DECRIPTIVE_META *inMeta /* i : input metadata */
128 : )
129 : {
130 : UWord8 char_idx;
131 1350 : FOR( char_idx = 0; char_idx < 8; char_idx++ )
132 : {
133 1200 : outMeta->formatDescriptor[char_idx] = inMeta->formatDescriptor[char_idx];
134 1200 : move16();
135 : }
136 150 : outMeta->numberOfDirections = inMeta->numberOfDirections;
137 150 : move16();
138 150 : outMeta->numberOfChannels = inMeta->numberOfChannels;
139 150 : move16();
140 150 : outMeta->sourceFormat = inMeta->sourceFormat;
141 150 : move16();
142 150 : outMeta->transportDefinition = inMeta->transportDefinition;
143 150 : move16();
144 150 : outMeta->channelAngle = inMeta->channelAngle;
145 150 : move16();
146 150 : outMeta->channelDistance = inMeta->channelDistance;
147 150 : move16();
148 150 : outMeta->channelLayout = inMeta->channelLayout;
149 150 : move16();
150 :
151 150 : return;
152 : }
153 :
154 : /*---------------------------------------------------------------------*
155 : * diffuse_meta_merge_1x1()
156 : *
157 : *
158 : *---------------------------------------------------------------------*/
159 :
160 36 : void diffuse_meta_merge_1x1_fx(
161 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */
162 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : Input metadata 1 */
163 : Word32 inEne_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. energy after merge */
164 : Word16 inEne_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 1 Exponent */
165 : MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, /* i : Input metadata 2 */
166 : Word32 inEneISM_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2 */
167 : Word16 inEneISM_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 Exponent */
168 : )
169 : {
170 : Word8 sf, band;
171 180 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
172 : {
173 3600 : FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
174 : {
175 3456 : Word32 energyTimesRatio_fx, energyTimesRatioISM_fx, total_diff_nrg_fx, dir_nrg_ratio_fx, total_nrg_fx = 0;
176 : Word32 dir_ratio_ism_fx, L_tmp, L_tmp1, L_tmp2;
177 3456 : Word16 scale, energyTimesRatio_e, tmp, total_nrg_e = 0, total_diff_nrg_e, dir_ratio_ism_e, energyTimesRatioISM_e, dir_nrg_ratio_e;
178 3456 : move32();
179 3456 : move16();
180 :
181 3456 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta->directToTotalRatio[0][sf][band] ); // Q31 - 15 => Q16
182 3456 : scale = 15;
183 3456 : move16();
184 3456 : energyTimesRatio_fx = Mpy_32_32_r( inEne_fx[sf][band], L_tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */
185 3456 : energyTimesRatio_e = add( inEne_e[sf][band], scale );
186 3456 : total_nrg_fx = BASOP_Util_Add_Mant32Exp( inEne_fx[sf][band], inEne_e[sf][band], inEneISM_fx[sf][band], inEneISM_e[sf][band], &total_nrg_e );
187 :
188 : /* target is original MASA diffuseness */
189 3456 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta->diffuseToTotalRatio[sf][band] ); // Q31 - 15 => Q16
190 3456 : scale = 15;
191 3456 : move16();
192 3456 : total_diff_nrg_fx = Mpy_32_32_r( inEne_fx[sf][band], L_tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */
193 3456 : total_diff_nrg_e = add( inEne_e[sf][band], scale );
194 :
195 : /* criterion is mean of ISM ratio and new ratio */
196 3456 : dir_ratio_ism_fx = Mpy_32_16_1( INV_UINT8_MAX, inMetaISM->directToTotalRatio[0][sf][band] ); // Q31 - 15 => Q16
197 3456 : dir_ratio_ism_e = 15;
198 3456 : move16();
199 3456 : tmp = BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, L_add( total_nrg_fx, EPSILON_FX ), &scale );
200 3456 : L_tmp1 = L_deposit_h( tmp ); /* Q( 31 - ( scale + total_nrg_e - total_diff_nrg_e ) ) */
201 3456 : scale = add( scale, sub( total_diff_nrg_e, total_nrg_e ) );
202 3456 : IF( L_tmp1 == 0 )
203 : {
204 36 : scale = 0;
205 36 : move16();
206 36 : L_tmp2 = MAX_32;
207 36 : move32();
208 : }
209 : ELSE
210 : {
211 3420 : L_tmp2 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q31, 0, L_negate( L_tmp1 ), scale, &scale );
212 : }
213 :
214 3456 : L_tmp1 = BASOP_Util_Add_Mant32Exp( dir_ratio_ism_fx, dir_ratio_ism_e, L_tmp2, scale, &tmp );
215 3456 : L_tmp1 = L_shr( L_tmp1, 1 );
216 3456 : energyTimesRatioISM_fx = Mpy_32_32( L_tmp1, inEneISM_fx[sf][band] ); /* Q( 31 - ( tmp + inEneISM_e[sf] ) ) */
217 3456 : energyTimesRatioISM_e = add( tmp, inEneISM_e[sf][band] );
218 :
219 3456 : IF( ( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioISM_fx, energyTimesRatioISM_e, energyTimesRatio_fx, energyTimesRatio_e ) > 0 ) )
220 : {
221 : Word32 new_dir_ratio_fx, new_diff_ratio_fx;
222 : Word16 new_dir_ratio_e;
223 :
224 748 : outMeta->directionIndex[0][sf][band] = inMetaISM->directionIndex[0][sf][band];
225 748 : move16();
226 748 : outMeta->directToTotalRatio[0][sf][band] = inMetaISM->directToTotalRatio[0][sf][band];
227 748 : move16();
228 748 : outMeta->spreadCoherence[0][sf][band] = inMetaISM->spreadCoherence[0][sf][band];
229 748 : move16();
230 :
231 748 : outMeta->surroundCoherence[sf][band] = inMetaISM->surroundCoherence[sf][band];
232 748 : move16();
233 :
234 748 : tmp = BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, L_add( EPSILON_FX, total_nrg_fx ), &scale );
235 748 : scale = add( scale, sub( total_diff_nrg_e, total_nrg_e ) );
236 748 : Word32 temp32 = L_shr( L_deposit_h( tmp ), sub( sub( 31, scale ), Q30 ) ); // Q30
237 748 : scale = 1;
238 748 : move16();
239 748 : dir_nrg_ratio_fx = L_sub( ONE_IN_Q30, temp32 );
240 748 : dir_nrg_ratio_e = scale;
241 748 : move16();
242 :
243 748 : new_dir_ratio_fx = dir_ratio_ism_fx;
244 748 : move32();
245 748 : new_dir_ratio_e = dir_ratio_ism_e;
246 748 : move16();
247 748 : tmp = BASOP_Util_Cmp_Mant32Exp( dir_nrg_ratio_fx, dir_nrg_ratio_e, dir_ratio_ism_fx, dir_ratio_ism_e );
248 748 : IF( tmp <= 0 )
249 : {
250 748 : new_dir_ratio_fx = dir_nrg_ratio_fx;
251 748 : move32();
252 748 : new_dir_ratio_e = dir_nrg_ratio_e;
253 748 : move16();
254 : }
255 :
256 748 : outMeta->directToTotalRatio[0][sf][band] = (UWord8) extract_l( L_shr( Mpy_32_16_1( new_dir_ratio_fx, UINT8_MAX ) /* (31 - new_dir_ratio_e) - 15*/, sub( 31 - 15, new_dir_ratio_e ) ) ); /* Q0 */
257 :
258 748 : move16();
259 748 : IF( GT_16( sub( 31, new_dir_ratio_e ), Q30 ) )
260 : {
261 0 : new_dir_ratio_fx = L_shr( new_dir_ratio_fx, sub( sub( 31, new_dir_ratio_e ), Q30 ) ); /* Q30 */
262 0 : new_dir_ratio_e = 1;
263 0 : move16();
264 0 : new_diff_ratio_fx = L_sub( ONE_IN_Q30, new_dir_ratio_fx ); /* Q30 */
265 : }
266 : ELSE
267 : {
268 748 : new_diff_ratio_fx = L_sub( L_shl( 1, sub( 31, new_dir_ratio_e ) ), new_dir_ratio_fx ); /* Q(31 - new_dir_ratiio_e) */
269 : }
270 748 : outMeta->diffuseToTotalRatio[sf][band] = (UWord8) extract_l( L_shr( new_diff_ratio_fx, sub( sub( 31, new_dir_ratio_e ), 8 ) ) );
271 748 : move16();
272 : }
273 : ELSE
274 : {
275 : /* use the plain original meta for this tile */
276 2708 : outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
277 2708 : move16();
278 2708 : outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
279 2708 : move16();
280 2708 : outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
281 2708 : move16();
282 :
283 2708 : outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
284 2708 : move16();
285 2708 : outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
286 2708 : move16();
287 : }
288 3456 : outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
289 3456 : move16();
290 3456 : outMeta->directToTotalRatio[1][sf][band] = 0u;
291 3456 : move16();
292 3456 : outMeta->spreadCoherence[1][sf][band] = 0u;
293 3456 : move16();
294 :
295 3456 : inEne_fx[sf][band] = BASOP_Util_Add_Mant32Exp( inEne_fx[sf][band], inEne_e[sf][band], inEneISM_fx[sf][band], inEneISM_e[sf][band], &inEne_e[sf][band] ); /* Update energy for subsequent mergings */
296 3456 : move32();
297 : }
298 : }
299 :
300 : /* Set descriptive meta for mixed format */
301 36 : outMeta->descriptiveMeta.sourceFormat = 0u;
302 36 : move16();
303 36 : outMeta->descriptiveMeta.transportDefinition = 0u;
304 36 : move16();
305 36 : outMeta->descriptiveMeta.channelAngle = 0u;
306 36 : move16();
307 36 : outMeta->descriptiveMeta.channelDistance = 0u;
308 36 : move16();
309 36 : outMeta->descriptiveMeta.channelLayout = 0u;
310 36 : move16();
311 36 : outMeta->descriptiveMeta.numberOfDirections = 0u;
312 36 : move16();
313 : /* Number of transports should be set outside. */
314 :
315 36 : return;
316 : }
317 :
318 :
319 : /*---------------------------------------------------------------------*
320 : * full_stream_merge()
321 : *
322 : *
323 : *---------------------------------------------------------------------*/
324 :
325 450 : void full_stream_merge_fx(
326 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */
327 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */
328 : Word32 inEne1_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal */
329 : Word16 inEne1_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1 Exponent */
330 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, /* i : Input metadata 2 */
331 : Word32 inEne2_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2 */
332 : Word16 inEne2_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 Exponent */
333 : )
334 : {
335 : UWord8 n_dirs_1, n_dirs_2;
336 : UWord8 sf, band;
337 : Word16 scale, dir_nrg_1_e, dir_nrg_2_e;
338 : Word32 dir_nrg_1_fx, dir_nrg_2_fx, L_tmp;
339 :
340 : /* full stream select based on total direct energy */
341 450 : n_dirs_1 = (UWord8) add( inMeta1->descriptiveMeta.numberOfDirections, 1u ); /* to 1-based */
342 450 : n_dirs_2 = (UWord8) add( inMeta2->descriptiveMeta.numberOfDirections, 1u );
343 :
344 2250 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
345 : {
346 45000 : FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
347 : {
348 43200 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta1->directToTotalRatio[0][sf][band] ); // Q31 - 15 => Q16
349 43200 : scale = 15;
350 43200 : move16();
351 43200 : dir_nrg_1_fx = Mpy_32_32( L_tmp, inEne1_fx[sf][band] ); /* Q( 31 - ( scale + inEne1_e[sf] ) ) */
352 43200 : dir_nrg_1_e = add( scale, inEne1_e[sf][band] );
353 :
354 43200 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta2->directToTotalRatio[0][sf][band] ); // Q31 - 15 => Q16
355 43200 : scale = 15;
356 43200 : move16();
357 43200 : dir_nrg_2_fx = Mpy_32_32( L_tmp, inEne2_fx[sf][band] ); /* Q( 31 - ( scale + inEne2_e[sf] ) ) */
358 43200 : dir_nrg_2_e = add( scale, inEne2_e[sf][band] );
359 :
360 43200 : IF( EQ_16( n_dirs_1, 2 ) )
361 : {
362 14400 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta1->directToTotalRatio[1][sf][band] ); // Q31 - 15 => Q16
363 14400 : scale = 15;
364 14400 : move16();
365 14400 : L_tmp = Mpy_32_32( L_tmp, inEne1_fx[sf][band] ); /* Q( 31 - ( scale + inEne1_e[sf] ) ) */
366 14400 : scale = add( scale, inEne1_e[sf][band] );
367 14400 : dir_nrg_1_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale, dir_nrg_1_fx, dir_nrg_1_e, &dir_nrg_1_e );
368 : }
369 :
370 43200 : IF( EQ_16( n_dirs_2, 2 ) )
371 : {
372 14400 : L_tmp = Mpy_32_16_1( INV_UINT8_MAX, inMeta2->directToTotalRatio[1][sf][band] ); // Q31 - 15 => Q16
373 14400 : scale = 15;
374 14400 : move16();
375 14400 : L_tmp = Mpy_32_32( L_tmp, inEne2_fx[sf][band] ); /* Q( 31 - ( scale + inEne2_e[sf] ) ) */
376 14400 : scale = add( scale, inEne2_e[sf][band] );
377 14400 : dir_nrg_2_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale, dir_nrg_2_fx, dir_nrg_2_e, &dir_nrg_2_e );
378 : }
379 :
380 43200 : IF( BASOP_Util_Cmp_Mant32Exp( dir_nrg_1_fx, dir_nrg_1_e, dir_nrg_2_fx, dir_nrg_2_e ) > 0 )
381 : {
382 26590 : copy_masa_meta_tile_fx( outMeta, inMeta1, sf, band );
383 : }
384 : ELSE
385 : {
386 16610 : copy_masa_meta_tile_fx( outMeta, inMeta2, sf, band );
387 : }
388 :
389 43200 : inEne1_fx[sf][band] = BASOP_Util_Add_Mant32Exp( inEne1_fx[sf][band], inEne1_e[sf][band], inEne2_fx[sf][band], inEne2_e[sf][band], &inEne1_e[sf][band] );
390 43200 : move32();
391 : }
392 : }
393 :
394 : /* Set descriptive meta for mixed format */
395 450 : outMeta->descriptiveMeta.sourceFormat = 0u;
396 450 : move16();
397 450 : outMeta->descriptiveMeta.transportDefinition = 0u;
398 450 : move16();
399 450 : outMeta->descriptiveMeta.channelAngle = 0u;
400 450 : move16();
401 450 : outMeta->descriptiveMeta.channelDistance = 0u;
402 450 : move16();
403 450 : outMeta->descriptiveMeta.channelLayout = 0u;
404 450 : move16();
405 450 : test();
406 450 : IF( EQ_16( n_dirs_1, 2 ) || EQ_16( n_dirs_2, 2 ) )
407 : {
408 300 : outMeta->descriptiveMeta.numberOfDirections = 1u;
409 300 : move16();
410 : }
411 : ELSE
412 : {
413 150 : outMeta->descriptiveMeta.numberOfDirections = 0u;
414 150 : move16();
415 : }
416 :
417 : /* Number of transports should be set outside. */
418 :
419 450 : return;
420 : }
421 :
422 :
423 : /*---------------------------------------------------------------------*
424 : * ivas_prerend_merge_masa_metadata()
425 : *
426 : *
427 : *---------------------------------------------------------------------*/
428 :
429 486 : void ivas_prerend_merge_masa_metadata_fx(
430 : MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */
431 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */
432 : IVAS_REND_AudioConfigType inType1, /* i : Type of input 1 */
433 : Word32 inEne1_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal */
434 : Word16 inEne1_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1 Exponent */
435 : MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, /* i : Input metadata 2 */
436 : IVAS_REND_AudioConfigType inType2, /* i : Type of input 2 */
437 : Word32 inEne2_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2. may be altered */
438 : Word16 inEne2_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 Exponent */
439 : )
440 : {
441 : /* mixing ISMs with non-ISM use different merge */
442 486 : test();
443 486 : test();
444 486 : test();
445 486 : test();
446 486 : test();
447 486 : test();
448 486 : IF( EQ_32( inType1, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && NE_32( inType2, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
449 0 : {
450 : /* meta_1 is ISM and both are 1dir */
451 : Word8 sf;
452 :
453 0 : diffuse_meta_merge_1x1_fx( outMeta, inMeta2, inEne2_fx, inEne2_e, inMeta1, inEne1_fx, inEne1_e ); /* post-merge energy is now in inEne2 and needs to be copied to inEne1 */
454 :
455 0 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
456 : {
457 0 : Copy32( inEne2_fx[sf], inEne1_fx[sf], MASA_FREQUENCY_BANDS );
458 0 : Copy( inEne2_e[sf], inEne1_e[sf], MASA_FREQUENCY_BANDS );
459 : }
460 : }
461 486 : ELSE IF( EQ_32( inType2, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && NE_32( inType1, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
462 : {
463 : /* meta_2 is ISM and both are 1dir */
464 36 : diffuse_meta_merge_1x1_fx( outMeta, inMeta1, inEne1_fx, inEne1_e, inMeta2, inEne2_fx, inEne2_e );
465 : }
466 : ELSE
467 : {
468 :
469 450 : full_stream_merge_fx( outMeta, inMeta1, inEne1_fx, inEne1_e, inMeta2, inEne2_fx, inEne2_e );
470 : }
471 :
472 486 : return;
473 : }
474 :
475 :
476 : /*---------------------------------------------------------------------*
477 : * masaPrerendOpen()
478 : *
479 : *
480 : *---------------------------------------------------------------------*/
481 :
482 1 : ivas_error masaPrerendOpen_fx(
483 : MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o : handle to the opened prerenderer */
484 : Word16 numTransports, /* i : number of transport channels */
485 : Word32 input_Fs /* i : signal sampling rate */
486 : )
487 : {
488 : MASA_PREREND_HANDLE hMasaPrerend;
489 : Word16 i;
490 : ivas_error error;
491 :
492 1 : error = IVAS_ERR_OK;
493 1 : move32();
494 :
495 1 : hMasaPrerend = (MASA_PREREND_HANDLE) malloc( sizeof( MASA_PREREND_DATA ) );
496 1 : IF( hMasaPrerend == NULL )
497 : {
498 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
499 : }
500 :
501 1 : hMasaPrerend->num_Cldfb_instances = numTransports;
502 1 : move16();
503 3 : FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ )
504 : {
505 2 : IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK )
506 : {
507 0 : return error;
508 : }
509 : }
510 1 : FOR( ; i < MASA_MAX_TRANSPORT_CHANNELS; i++ )
511 : {
512 0 : hMasaPrerend->cldfbAnaEnc[i] = NULL;
513 : }
514 :
515 1 : IF( ( hMasaPrerend->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
516 : {
517 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
518 : }
519 :
520 1 : IF( ( hMasaPrerend->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
521 : {
522 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
523 : }
524 1 : generate_gridEq_fx( hMasaPrerend->sph_grid16 );
525 :
526 1 : IF( error == IVAS_ERR_OK )
527 : {
528 1 : *hMasaPrerendPtr = hMasaPrerend;
529 : }
530 :
531 1 : return error;
532 : }
533 :
534 : /*---------------------------------------------------------------------*
535 : * masaPrerendClose()
536 : *
537 : *
538 : *---------------------------------------------------------------------*/
539 :
540 666 : void masaPrerendClose_fx(
541 : MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */
542 : )
543 : {
544 : Word16 i;
545 :
546 666 : test();
547 666 : IF( hMasaPrerendPtr == NULL || *hMasaPrerendPtr == NULL )
548 : {
549 665 : return;
550 : }
551 :
552 3 : FOR( i = 0; i < ( *hMasaPrerendPtr )->num_Cldfb_instances; i++ )
553 : {
554 2 : deleteCldfb_ivas_fx( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) );
555 : }
556 :
557 1 : free( ( *hMasaPrerendPtr )->hMasaOut );
558 1 : ( *hMasaPrerendPtr )->hMasaOut = NULL;
559 1 : free( ( *hMasaPrerendPtr )->sph_grid16 );
560 1 : ( *hMasaPrerendPtr )->sph_grid16 = NULL;
561 :
562 1 : free( ( *hMasaPrerendPtr ) );
563 1 : ( *hMasaPrerendPtr ) = NULL;
564 :
565 1 : return;
566 : }
|