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 <assert.h>
34 : #include <stdint.h>
35 : #include <math.h>
36 : #include "options.h"
37 : #include "cnst.h"
38 : #include "ivas_cnst.h"
39 : #include "rom_com.h"
40 : #include "prot_fx.h"
41 : #include "ivas_stat_com.h"
42 : #include "ivas_rom_com.h"
43 : #include "wmc_auto.h"
44 : #include "ivas_prot_fx.h"
45 :
46 : /*-------------------------------------------------------------------*
47 : * ivas_sba_config()
48 : *
49 : * Configure SBA coding
50 : *-------------------------------------------------------------------*/
51 :
52 147178 : void ivas_sba_config_fx(
53 : const Word32 sba_total_brate, /* i : SBA total bitrate */
54 : Word16 sba_order, /* i : Ambisonic (SBA) order */
55 : Word16 nb_channels, /* i : Number of ambisonic channels */
56 : Word16 *nchan_transport, /* o : number of transport channels */
57 : const Word16 sba_planar, /* i : SBA Planar flag */
58 : Word16 *nSCE, /* o : number of SCEs */
59 : Word16 *nCPE, /* o : number of CPEs */
60 : Word16 *element_mode /* o : element mode of the core coder */
61 : )
62 : {
63 147178 : IF( nb_channels > 0 )
64 : {
65 0 : IF( sba_planar )
66 : {
67 0 : assert( ( EQ_16( add( shl( sba_order, 1 ), 1 ), nb_channels ) ) && "Order and number of channels do not correspond!" );
68 : }
69 : ELSE
70 : {
71 0 : assert( ( EQ_16( mult( add( sba_order, 1 ), add( sba_order, 1 ) ), nb_channels ) ) && "Order and number of channels do not correspond!" );
72 : }
73 : }
74 :
75 147178 : IF( nchan_transport != NULL )
76 : {
77 147178 : *nchan_transport = ivas_get_sba_num_TCs_fx( sba_total_brate, sba_order );
78 147178 : move16();
79 : }
80 :
81 : /* Configure core coder number of elements*/
82 147178 : test();
83 147178 : test();
84 147178 : IF( nchan_transport != NULL && nSCE != NULL && nCPE != NULL )
85 : {
86 147178 : IF( EQ_16( *nchan_transport, 1 ) )
87 : {
88 38031 : *nSCE = 1;
89 38031 : move16();
90 38031 : *nCPE = 0;
91 38031 : move16();
92 38031 : *element_mode = IVAS_SCE;
93 38031 : move16();
94 : }
95 : ELSE
96 : {
97 109147 : *nSCE = 0;
98 109147 : move16();
99 109147 : *nCPE = shr( *nchan_transport, 1 );
100 109147 : move16();
101 109147 : IF( NE_16( i_mult( 2, ( *nCPE ) ), *nchan_transport ) )
102 : {
103 31453 : *nCPE = add( *nCPE, 1 );
104 31453 : move16();
105 : }
106 109147 : *element_mode = IVAS_CPE_MDCT;
107 109147 : move16();
108 : }
109 : }
110 :
111 147178 : return;
112 : }
113 :
114 :
115 : /*-------------------------------------------------------------------*
116 : * ivas_sba_get_analysis_order()
117 : *
118 : * Get Ambisonic order used for analysis and coding
119 : *-------------------------------------------------------------------*/
120 :
121 : /*! r: Ambisonic (SBA) order used for analysis and coding */
122 299768 : Word16 ivas_sba_get_analysis_order_fx(
123 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
124 : const Word16 sba_order /* i : Ambisonic (SBA) order */
125 : )
126 : {
127 : Word16 sba_analysis_order;
128 :
129 299768 : sba_analysis_order = sba_order;
130 299768 : move16();
131 :
132 299768 : if ( LT_32( ivas_total_brate, SBA_MIN_BRATE_HOA ) )
133 : {
134 : /* Hard coding the sba_analysis_order as 1 as higher not supported below SBA_MIN_BRATE_HOA bitrate */
135 220747 : sba_analysis_order = SBA_FOA_ORDER;
136 220747 : move16();
137 : }
138 :
139 299768 : return sba_analysis_order;
140 : }
141 :
142 :
143 : /*-------------------------------------------------------------------*
144 : * ivas_sba_get_nchan()
145 : *
146 : * Get number of Ambisonic channels
147 : *-------------------------------------------------------------------*/
148 :
149 : /*! r: number of Ambisonic channels */
150 984202 : Word16 ivas_sba_get_nchan_fx(
151 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
152 : const Word16 sba_planar /* i : SBA planar flag */
153 : )
154 : {
155 : Word16 nb_channels;
156 :
157 984202 : IF( sba_planar )
158 : {
159 0 : nb_channels = add( shl( sba_order, 1 ), 1 );
160 : }
161 : ELSE
162 : {
163 984202 : nb_channels = i_mult( add( sba_order, 1 ), add( sba_order, 1 ) );
164 : }
165 :
166 984202 : return ( nb_channels );
167 : }
168 :
169 :
170 : /*-------------------------------------------------------------------*
171 : * ivas_sba_spar_sid_bitlen_fx()
172 : *
173 : * Get number of bits in SBA SID frame
174 : *-------------------------------------------------------------------*/
175 :
176 : /*! r: number of bits in SBA SID frame */
177 4212 : Word16 ivas_sba_spar_sid_bitlen_fx(
178 : const Word16 nchan_transport /* i : number of transport channels */
179 : )
180 : {
181 : Word16 num_bits;
182 :
183 4212 : num_bits = i_mult( SPAR_DTX_BANDS, SPAR_SID_BITS_TAR_PER_BAND );
184 4212 : IF( GT_16( nchan_transport, 1 ) )
185 : {
186 2308 : num_bits = sub( num_bits, 2 );
187 : }
188 :
189 4212 : return num_bits;
190 : }
191 :
192 :
193 : /*-------------------------------------------------------------------*
194 : * ivas_sba_get_nchan_metadata()
195 : *
196 : * Get number of Ambisonic channels for metadata coding
197 : *-------------------------------------------------------------------*/
198 :
199 : /*! r: number of ambisonics metadata channels */
200 4693490 : Word16 ivas_sba_get_nchan_metadata_fx(
201 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
202 : const Word32 ivas_total_brate /* i : IVAS total bitrate */
203 : )
204 : {
205 : Word16 nb_channels;
206 :
207 4693490 : IF( EQ_16( sba_order, SBA_FOA_ORDER ) )
208 : {
209 3502209 : nb_channels = FOA_CHANNELS;
210 3502209 : move16();
211 : }
212 : ELSE
213 : {
214 1191281 : IF( GE_32( ivas_total_brate, IVAS_512k ) )
215 : {
216 411856 : nb_channels = IVAS_SPAR_MAX_CH;
217 411856 : move16();
218 411856 : nb_channels = s_min( nb_channels, imult1616( add( sba_order, 1 ), add( sba_order, 1 ) ) );
219 : }
220 : ELSE
221 : {
222 : /* FOA + planar HOA */
223 779425 : nb_channels = add( FOA_CHANNELS, shl( sub( sba_order, 1 ), 1 ) );
224 : }
225 : }
226 :
227 4693490 : return ( nb_channels );
228 : }
229 :
230 : /*-------------------------------------------------------------------*
231 : * ivas_sba_get_spar_hoa_ch_ind()
232 : *
233 : *
234 : *-------------------------------------------------------------------*/
235 :
236 : /*! r: flag indicating to code SPAR HOA MD for all bands */
237 3816 : void ivas_sba_get_spar_hoa_ch_ind_fx(
238 : const Word16 num_md_chs, /* i : number of MD channels */
239 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
240 : Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] )
241 : {
242 : Word16 ch;
243 : const Word16 *hoa_ind;
244 :
245 3816 : IF( GE_32( ivas_total_brate, IVAS_512k ) )
246 : {
247 243 : hoa_ind = HOA_keep_ind_spar512;
248 : }
249 : ELSE
250 : {
251 3573 : hoa_ind = HOA_keep_ind_spar;
252 : }
253 :
254 21369 : FOR( ch = 0; ch < num_md_chs; ch++ )
255 : {
256 17553 : HOA_md_ind[ch] = hoa_ind[ch];
257 17553 : move16();
258 : }
259 :
260 3816 : return;
261 : }
262 :
263 :
264 : /*-------------------------------------------------------------------*
265 : * ivas_sba_get_spar_hoa_md_flag()
266 : *
267 : * Get the flag to code SPAR HOA MD for all band
268 : *-------------------------------------------------------------------*/
269 :
270 3816 : void ivas_sba_get_spar_hoa_md_flag_fx(
271 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
272 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
273 : Word16 *spar_hoa_md_flag,
274 : Word16 *spar_hoa_dirac2spar_md_flag )
275 : {
276 3816 : test();
277 3816 : IF( GT_16( sba_order, 1 ) && GE_32( ivas_total_brate, IVAS_256k ) )
278 : {
279 499 : *spar_hoa_md_flag = 1;
280 499 : move16();
281 : }
282 : ELSE
283 : {
284 3317 : *spar_hoa_md_flag = 0;
285 3317 : move16();
286 : }
287 :
288 3816 : test();
289 3816 : IF( GT_16( sba_order, 1 ) && GE_32( ivas_total_brate, IVAS_512k ) )
290 : {
291 183 : *spar_hoa_dirac2spar_md_flag = 0;
292 183 : move16();
293 : }
294 : ELSE
295 : {
296 3633 : *spar_hoa_dirac2spar_md_flag = 1;
297 3633 : move16();
298 : }
299 :
300 3816 : return;
301 : }
302 :
303 :
304 : /*-------------------------------------------------------------------*
305 : * ivas_sba_zero_vert_comp()
306 : *
307 : * Zero vertical Ambisonics components
308 : *-------------------------------------------------------------------*/
309 20500 : void ivas_sba_zero_vert_comp_fx(
310 : Word32 *sba_data[], /* i : SBA signals q_data */
311 : const Word16 sba_order, /* i : SBA order */
312 : const Word16 sba_planar, /* i : SBA planar flag */
313 : const Word16 input_frame /* i : frame length */
314 : )
315 : {
316 : Word16 i, j;
317 :
318 : /* Channels in the range i^2+1 to (i+1)^2 -1 are zeroed (retain only first and last channel for that order) */
319 48280 : FOR( i = 1; i <= sba_order; i++ )
320 : {
321 27780 : test();
322 : /* Keep Z if not planar */
323 27780 : IF( !sba_planar && EQ_16( i, 1 ) )
324 : {
325 0 : CONTINUE;
326 : }
327 :
328 75400 : FOR( j = ( i * i + 1 ); j < ( ( i + 1 ) * ( i + 1 ) - 1 ); j++ )
329 : {
330 47620 : set_val_Word32( sba_data[j], 0, input_frame );
331 : }
332 : }
333 :
334 20500 : return;
335 : }
|