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