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