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 <stdint.h>
34 : #include <stdio.h>
35 : #include <string.h>
36 : #include "options.h"
37 : #include "ivas_cnst.h"
38 : #include "ivas_prot_fx.h"
39 : #include "ivas_rom_com.h"
40 : #include "prot_fx.h"
41 : #include <math.h>
42 : #include "wmc_auto.h"
43 : #include "ivas_prot_fx.h"
44 : #include "ivas_rom_com_fx.h"
45 :
46 :
47 : /*-----------------------------------------------------------------------*
48 : * Local constants
49 : *-----------------------------------------------------------------------*/
50 :
51 : #define ISM_NUM_PARAM 5 /* number of coded metadata parameters */
52 :
53 : #define ISM_MAX_AZIMUTH_DIFF_IDX ( ISM_AZIMUTH_NBITS - 1 /*zero*/ - 1 /*sign*/ )
54 : #define ISM_MAX_ELEVATION_DIFF_IDX ( ISM_ELEVATION_NBITS - 1 /*zero*/ - 1 /*sign*/ )
55 : #define ISM_MAX_RADIUS_DIFF_IDX ( ISM_RADIUS_NBITS - 1 /*zero*/ - 1 /*sign*/ )
56 :
57 : #define ISM_FEC_MAX 10
58 : #define ISM_MD_FEC_DIFF 10
59 : #define ISM_MD_FEC_DIFF_Q22 41943040
60 : #define ISM_MD_INC_DIFF_CNT_MAX 6
61 : #define ISM_MD_FEC_CNT_MAX 25
62 : #define ISM_MD_RAD_FEC_DIFF 1
63 : #define ISM_MD_RAD_FEC_DIFF_Q9 ONE_IN_Q9
64 :
65 : #define INTER_OBJECT_PARAM_CHECK ( ( ISM_FEC_MAX / 2 ) - 2 ) /* note: constant must be less than (ISM_FEC_MAX / number of coded parameters) */
66 :
67 :
68 : /*-----------------------------------------------------------------------*
69 : * Local function declarations
70 : *-----------------------------------------------------------------------*/
71 :
72 : static void encode_angle_indices_fx( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const Word16 last_ism_metadata_flag, const Word16 ini_frame, const Word16 idx_angle1_abs, const Word16 idx_angle2_abs, Word16 *flag_abs_angle1, Word16 *flag_abs_angle2 );
73 :
74 : static void encode_radius_fx( BSTR_ENC_HANDLE hBstr, Word16 *last_radius_idx, Word16 *radius_diff_cnt, const Word16 last_ism_metadata_flag, const Word16 idx_radius_abs, Word16 *flag_abs_radius );
75 :
76 :
77 : /*-------------------------------------------------------------------------*
78 : * ivas_set_ism_metadata()
79 : *
80 : * Set metadata of one ISM MD handle
81 : *-------------------------------------------------------------------------*/
82 427276 : ivas_error ivas_set_ism_metadata_fx(
83 : ISM_METADATA_HANDLE hIsmMeta, /* o : ISM metadata handle */
84 : const Word32 azimuth, /* i : azimuth value */
85 : const Word32 elevation, /* i : elevation */
86 : const Word16 radius_meta, /* i : radius */
87 : const Word32 yaw, /* i : yaw */
88 : const Word32 pitch, /* i : pitch */
89 : const Word16 non_diegetic_flag /* i : non-diegetic object flag*/
90 : )
91 : {
92 :
93 427276 : IF( hIsmMeta == NULL )
94 : {
95 0 : return IVAS_ERR_UNEXPECTED_NULL_POINTER;
96 : }
97 :
98 427276 : hIsmMeta->ism_metadata_flag = 1;
99 427276 : move16();
100 :
101 : /* save read metadata parameters to the internal codec structure */
102 427276 : hIsmMeta->azimuth_fx = azimuth; // Q22
103 427276 : move32();
104 427276 : hIsmMeta->elevation_fx = elevation; // Q22
105 427276 : move32();
106 427276 : hIsmMeta->radius_fx = radius_meta; // Q9
107 427276 : move16();
108 427276 : hIsmMeta->yaw_fx = yaw; // Q22
109 427276 : move16();
110 427276 : hIsmMeta->pitch_fx = pitch; // Q22
111 427276 : move16();
112 427276 : hIsmMeta->non_diegetic_flag = non_diegetic_flag;
113 427276 : move16();
114 :
115 427276 : return IVAS_ERR_OK;
116 : }
117 :
118 : /*-------------------------------------------------------------------------*
119 : * rate_ism_importance()
120 : *
121 : * Rate importance of particular ISM streams
122 : *-------------------------------------------------------------------------*/
123 :
124 101711 : static void rate_ism_importance_fx(
125 : const Word16 nchan_transport, /* i : number of transported channels */
126 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
127 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
128 : const Word16 lowrate_metadata_flag[MAX_NUM_OBJECTS], /* i : low-rate MD flag */
129 : Word16 ism_imp[] /* o : ISM importance flags */
130 : )
131 : {
132 : Word16 ch, ctype;
133 :
134 365441 : FOR( ch = 0; ch < nchan_transport; ch++ )
135 : {
136 263730 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
137 263730 : move16();
138 :
139 263730 : IF( hSCE[ch]->hCoreCoder[0]->tcxonly )
140 : {
141 99976 : IF( hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
142 : {
143 16985 : ctype = INACTIVE;
144 16985 : move16();
145 : }
146 82991 : ELSE IF( EQ_16( ctype, UNVOICED ) )
147 : {
148 5855 : ctype = GENERIC;
149 5855 : move16();
150 : }
151 : }
152 :
153 263730 : test();
154 263730 : test();
155 263730 : test();
156 263730 : IF( ( hIsmMeta[ch]->ism_metadata_flag == 0 || EQ_16( lowrate_metadata_flag[ch], 1 ) ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
157 : {
158 8314 : ism_imp[ch] = ISM_NO_META;
159 8314 : move16();
160 : }
161 255416 : ELSE IF( ctype == INACTIVE || EQ_16( ctype, UNVOICED ) )
162 : {
163 29072 : ism_imp[ch] = ISM_LOW_IMP;
164 29072 : move16();
165 : }
166 226344 : ELSE IF( EQ_16( ctype, VOICED ) )
167 : {
168 72514 : ism_imp[ch] = ISM_MEDIUM_IMP;
169 72514 : move16();
170 : }
171 : ELSE /* GENERIC */
172 : {
173 153830 : ism_imp[ch] = ISM_HIGH_IMP;
174 153830 : move16();
175 : }
176 : }
177 :
178 101711 : return;
179 : }
180 :
181 : /*-------------------------------------------------------------------------*
182 : * ivas_ism_metadata_enc()
183 : *
184 : * quantize and encode ISM metadata
185 : *-------------------------------------------------------------------------*/
186 :
187 123217 : ivas_error ivas_ism_metadata_enc_fx(
188 : Word32 *ism_total_brate, /* i/o: ISM total bitrate */
189 : const Word16 nchan_ism, /* i : number of ISM channels */
190 : const Word16 nchan_transport, /* i : number of transport channels */
191 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
192 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
193 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
194 : Word16 nb_bits_metadata[], /* o : number of metadata bits */
195 : const Word16 vad_flag[], /* i : VAD flag */
196 : const Word16 ism_mode, /* i : ISM mode */
197 : const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Enc Handle */
198 : const Word16 ism_extended_metadata_flag, /* i : Extended metadata flag */
199 : const Word16 lp_noise_CPE_fx, /* i : Q8 */
200 : const Word16 flag_omasa_ener_brate, /* i : less bitrate for objects in OMASA flag */
201 : Word16 *omasa_stereo_sw_cnt,
202 : const Word16 ini_frame )
203 : {
204 123217 : Word16 i, ch, nb_bits_start = 0;
205 123217 : move16();
206 : Word16 flag_abs_azimuth[MAX_NUM_OBJECTS];
207 : Word16 flag_abs_elevation[MAX_NUM_OBJECTS];
208 123217 : Word16 idx_angle1_abs = 0;
209 123217 : move16();
210 123217 : Word16 idx_angle2_abs = 0;
211 123217 : move16();
212 : Word16 flag_abs_yaw[MAX_NUM_OBJECTS];
213 : Word16 flag_abs_pitch[MAX_NUM_OBJECTS];
214 123217 : Word16 idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS];
215 123217 : move16();
216 : Word32 valQ_fx;
217 : ISM_METADATA_HANDLE hIsmMetaData;
218 : Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS];
219 : Word16 ism_metadata_flag_global;
220 : Word16 non_diegetic_flag_global;
221 : Word16 ism_imp[MAX_NUM_OBJECTS];
222 : Word16 null_metadata_flag[MAX_NUM_OBJECTS];
223 : Word16 lowrate_metadata_flag[MAX_NUM_OBJECTS];
224 : Word16 nbands, nblocks;
225 : ivas_error error;
226 :
227 123217 : error = IVAS_ERR_OK;
228 123217 : push_wmops( "ism_meta_enc" );
229 :
230 : /* initialization */
231 123217 : ism_metadata_flag_global = 0;
232 123217 : non_diegetic_flag_global = 0;
233 123217 : move16();
234 123217 : move16();
235 123217 : set16_fx( nb_bits_metadata, 0, nchan_transport );
236 123217 : set16_fx( flag_abs_azimuth, 0, nchan_ism );
237 123217 : set16_fx( flag_abs_elevation, 0, nchan_ism );
238 123217 : set16_fx( flag_abs_yaw, 0, nchan_ism );
239 123217 : set16_fx( flag_abs_pitch, 0, nchan_ism );
240 123217 : set16_fx( flag_abs_radius, 0, nchan_ism );
241 123217 : set16_fx( null_metadata_flag, 0, nchan_ism );
242 123217 : set16_fx( lowrate_metadata_flag, 0, nchan_ism );
243 :
244 123217 : test();
245 :
246 123217 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
247 : {
248 : /*----------------------------------------------------------------*
249 : * Rate importance of particular ISM streams in combined format coding
250 : *----------------------------------------------------------------*/
251 5196 : ivas_set_ism_importance_interformat_fx( *ism_total_brate, nchan_transport, hIsmMeta, hSCE, lp_noise_CPE_fx, ism_imp );
252 : }
253 : ELSE
254 : {
255 : /*----------------------------------------------------------------*
256 : * Set Metadata presence / importance flag
257 : *----------------------------------------------------------------*/
258 :
259 467219 : FOR( ch = 0; ch < nchan_ism; ch++ )
260 : {
261 349198 : test();
262 349198 : test();
263 349198 : IF( EQ_16( ism_mode, ISM_MODE_PARAM ) )
264 : {
265 74906 : hIsmMeta[ch]->ism_metadata_flag = 1;
266 74906 : move16();
267 : }
268 274292 : ELSE IF( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
269 : {
270 274292 : null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
271 274292 : move16();
272 :
273 274292 : IF( EQ_16( hIsmMeta[ch]->ism_metadata_flag, 1 ) )
274 : {
275 269622 : IF( NE_16( ism_mode, ISM_SBA_MODE_DISC ) )
276 : {
277 : /* In case of low level noise for low bitrate inactive frames, do not sent metadata */
278 218232 : test();
279 218232 : test();
280 218232 : hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || GT_16( hSCE[ch]->hCoreCoder[0]->lp_noise_fx, 2560 /*10 Q8*/ ) || hSCE[ch]->hCoreCoder[0]->tcxonly;
281 218232 : move16();
282 : }
283 :
284 : /* in inactive frames, send MD 1) in ISM_MD_INC_DIFF_CNT_MAX consecutive frames when MD significantly change, 2) at least every ISM_MD_FEC_DIFF frames */
285 269622 : IF( hIsmMeta[ch]->ism_metadata_flag == 0 )
286 : {
287 6562 : test();
288 6562 : test();
289 6562 : IF( ( GT_32( L_abs( L_sub( hIsmMeta[ch]->azimuth_fx, hIsmMeta[ch]->last_true_azimuth_fx ) ), ISM_MD_FEC_DIFF_Q22 ) ) ||
290 : ( GT_32( L_abs( L_sub( hIsmMeta[ch]->elevation_fx, hIsmMeta[ch]->last_true_elevation_fx ) ), ISM_MD_FEC_DIFF_Q22 ) ) || ( GT_16( abs_s( sub( hIsmMeta[ch]->radius_fx, hIsmMeta[ch]->last_true_radius_fx ) ), ISM_MD_RAD_FEC_DIFF_Q9 ) ) )
291 : {
292 :
293 5831 : lowrate_metadata_flag[ch] = 1;
294 5831 : move16();
295 :
296 5831 : hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
297 5831 : move16();
298 : }
299 731 : ELSE IF( LT_16( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX ) )
300 : {
301 :
302 498 : lowrate_metadata_flag[ch] = 1;
303 498 : move16();
304 498 : IF( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
305 : {
306 189 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
307 189 : move16();
308 : }
309 : ELSE
310 : {
311 309 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
312 309 : move16();
313 : }
314 : }
315 233 : ELSE IF( EQ_16( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ) )
316 : {
317 6 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
318 6 : move16();
319 6 : lowrate_metadata_flag[ch] = 1;
320 6 : move16();
321 6 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
322 6 : move16();
323 : }
324 : }
325 : }
326 : }
327 : }
328 :
329 : /*----------------------------------------------------------------*
330 : * Rate importance of particular ISM streams
331 : *----------------------------------------------------------------*/
332 :
333 118021 : IF( NE_16( ism_mode, ISM_SBA_MODE_DISC ) )
334 : {
335 101711 : rate_ism_importance_fx( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
336 : }
337 : }
338 :
339 : #ifdef DEBUG_FORCE_DIR
340 : if ( hSCE[0]->hCoreCoder[0]->force_dir[0] != '\0' )
341 : {
342 : dbgread( ism_imp, sizeof( int16_t ), nchan_ism, fname( hSCE[0]->hCoreCoder[0]->force_dir, "force_ism_imp.enf", -1, -1, -1 ) );
343 : }
344 : else
345 : {
346 : dbgwrite( ism_imp, sizeof( int16_t ), nchan_ism, 1, "res/force_ism_imp.enf" );
347 : }
348 : #endif
349 :
350 : /*----------------------------------------------------------------*
351 : * Write ISM common signaling
352 : *----------------------------------------------------------------*/
353 123217 : test();
354 123217 : test();
355 123217 : IF( NE_16( ism_mode, ISM_MASA_MODE_DISC ) && NE_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && NE_16( ism_mode, ISM_SBA_MODE_DISC ) )
356 : {
357 : /* write number of objects - unary coding */
358 297808 : FOR( ch = 1; ch < nchan_ism; ch++ )
359 : {
360 196097 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
361 : }
362 101711 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
363 : }
364 :
365 482929 : FOR( ch = 0; ch < nchan_ism; ch++ )
366 : {
367 359712 : ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
368 359712 : ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
369 359712 : non_diegetic_flag_global = s_or( non_diegetic_flag_global, hIsmMeta[ch]->non_diegetic_flag );
370 : }
371 :
372 : /* write extended metadata presence flag */
373 123217 : test();
374 123217 : test();
375 123217 : IF( ( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) ) && GE_32( *ism_total_brate, ISM_EXTENDED_METADATA_BRATE ) )
376 : {
377 74215 : push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
378 :
379 : /* Write global non-diegetic object flag */
380 74215 : IF( ism_extended_metadata_flag )
381 : {
382 8166 : push_indice( hBstr, IND_ISM_EXTENDED_NDP_FLAG, non_diegetic_flag_global, ISM_EXTENDED_METADATA_BITS );
383 : }
384 : }
385 :
386 : /* write ISM metadata flag (one per object) */
387 448851 : FOR( ch = 0; ch < nchan_transport; ch++ )
388 : {
389 325634 : test();
390 325634 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
391 : {
392 : /* flags will be written in ivas_masa_encode() */
393 10514 : hIsmMeta[ch]->ism_imp = ism_imp[ch];
394 10514 : move16();
395 10514 : hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
396 10514 : move16();
397 10514 : hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
398 10514 : move16();
399 : }
400 : ELSE
401 : {
402 315120 : IF( null_metadata_flag[ch] )
403 : {
404 : /* signal NULL metadata frame */
405 4670 : push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS );
406 :
407 : /* write the ISM class to ISM_NO_META and again the true ISM class */
408 4670 : IF( NE_16( ism_mode, ISM_SBA_MODE_DISC ) )
409 : {
410 4670 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
411 4670 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
412 : }
413 : ELSE
414 : {
415 0 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, 1 );
416 : }
417 : }
418 310450 : ELSE IF( NE_16( ism_mode, ISM_SBA_MODE_DISC ) )
419 : {
420 259060 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
421 :
422 259060 : IF( ism_imp[ch] == ISM_NO_META )
423 : {
424 : /* signal low-rate ISM_NO_META frame */
425 6562 : push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS );
426 :
427 : /* signal presence of MD in low-rate ISM_NO_META frame */
428 6562 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS );
429 : }
430 : }
431 : ELSE /*ism_mode == ISM_SBA_MODE_DISC*/
432 : {
433 : /* all objects are considered active*/
434 51390 : push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 );
435 : }
436 : }
437 : }
438 :
439 :
440 123217 : IF( ism_metadata_flag_global )
441 : {
442 : /*----------------------------------------------------------------*
443 : * Metadata quantization and coding, loop over all objects
444 : *----------------------------------------------------------------*/
445 :
446 123208 : Word16 total_bits_metadata = 0;
447 123208 : move16();
448 123208 : Word16 bits_metadata_ism = 0;
449 123208 : move16();
450 : Word16 nb_bits_objcod_written;
451 :
452 123208 : IF( EQ_16( ism_mode, ISM_MODE_PARAM ) )
453 : {
454 20414 : nb_bits_start = hBstr->nb_bits_tot;
455 20414 : move16();
456 : }
457 :
458 482893 : FOR( ch = 0; ch < nchan_ism; ch++ )
459 : {
460 359685 : hIsmMetaData = hIsmMeta[ch];
461 359685 : test();
462 359685 : test();
463 359685 : test();
464 359685 : if ( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
465 : {
466 284779 : nb_bits_start = hBstr->nb_bits_tot;
467 284779 : move16();
468 : }
469 359685 : test();
470 359685 : IF( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
471 : {
472 : /*----------------------------------------------------------------*
473 : * Quantize and encode azimuth and elevation
474 : *----------------------------------------------------------------*/
475 354815 : test();
476 354815 : IF( ism_extended_metadata_flag && non_diegetic_flag_global )
477 : {
478 : /* Write non-diegetic flag for each object */
479 2415 : push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS );
480 : }
481 354815 : test();
482 354815 : IF( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag )
483 : {
484 : /* Map azimuth to panning range [-90:90] */
485 805 : IF( GT_32( hIsmMetaData->azimuth_fx, 377487360 /*90.0f Q22*/ ) )
486 : {
487 0 : hIsmMetaData->azimuth_fx = L_sub( 754974720 /*180.0f Q22*/, hIsmMetaData->azimuth_fx ); // Q22
488 0 : move32();
489 : }
490 :
491 805 : IF( LT_32( hIsmMetaData->azimuth_fx, L_negate( 377487360 ) /*-90.0f Q22*/ ) )
492 : {
493 0 : hIsmMetaData->azimuth_fx = L_sub( L_negate( 754974720 ) /*-180.0f Q22*/, hIsmMetaData->azimuth_fx ); // Q22
494 0 : move32();
495 : }
496 :
497 805 : idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS );
498 805 : encode_angle_indices_fx( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL );
499 : }
500 : ELSE
501 : {
502 354010 : test();
503 354010 : test();
504 354010 : test();
505 354010 : IF( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
506 : {
507 279104 : idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS );
508 279104 : idx_angle2_abs = ism_quant_meta_fx( hIsmMetaData->elevation_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS );
509 : // valQ = fixedToFloat( valQ_fx, Q22 );
510 : }
511 : ELSE /* ISM_MODE_PARAM */
512 : {
513 74906 : idx_angle1_abs = hParamIsm->azi_index[ch];
514 74906 : move16();
515 74906 : idx_angle2_abs = hParamIsm->ele_index[ch];
516 74906 : move16();
517 : }
518 354010 : encode_angle_indices_fx( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] );
519 : /*----------------------------------------------------------------*
520 : * Quantize and encode radius, yaw, and pitch
521 : *----------------------------------------------------------------*/
522 354010 : test();
523 354010 : test();
524 354010 : IF( ( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) ) && ism_extended_metadata_flag )
525 : {
526 25625 : idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->yaw_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS );
527 25625 : idx_angle2_abs = ism_quant_meta_fx( hIsmMetaData->pitch_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS );
528 25625 : Word16 valQ_fx_tmp = extract_h( valQ_fx ); // 22 - 16 = 6
529 25625 : idx_radius_abs = usquant_fx( hIsmMetaData->radius_fx, &valQ_fx_tmp, ISM_RADIUS_MIN_Q9, ISM_RADIUS_DELTA_Q8, 1 << ISM_RADIUS_NBITS );
530 25625 : valQ_fx = L_shr( L_deposit_h( valQ_fx_tmp ), 3 ); // Q22
531 : // valQ = fixedToFloat( valQ_fx, Q22 );
532 25625 : encode_angle_indices_fx( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] );
533 25625 : encode_radius_fx( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] );
534 : }
535 : }
536 :
537 : /* save number of metadata bits written */
538 354815 : test();
539 354815 : test();
540 354815 : test();
541 354815 : IF( EQ_16( ism_mode, ISM_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
542 : {
543 279909 : nb_bits_metadata[ch] = sub( hBstr->nb_bits_tot, nb_bits_start );
544 279909 : move16();
545 : }
546 :
547 : /* Updates */
548 354815 : hIsmMeta[ch]->last_true_azimuth_fx = hIsmMeta[ch]->azimuth_fx; // Q22
549 354815 : move32();
550 354815 : hIsmMeta[ch]->last_true_elevation_fx = hIsmMeta[ch]->elevation_fx; // Q22
551 354815 : move32();
552 354815 : hIsmMeta[ch]->last_true_radius_fx = hIsmMeta[ch]->radius_fx; // Q22
553 354815 : move16();
554 : }
555 : }
556 :
557 : /*----------------------------------------------------------------*
558 : * inter-object logic minimizing the use of several absolutely coded
559 : * indexes in the same frame
560 : *----------------------------------------------------------------*/
561 :
562 123208 : i = 0;
563 123208 : move16();
564 123208 : test();
565 246416 : WHILE( i == 0 || i < ( nchan_ism / INTER_OBJECT_PARAM_CHECK ) )
566 : {
567 : Word16 num, abs_num, abs_first, abs_next, pos_zero;
568 : Word16 abs_matrice[INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM];
569 :
570 123208 : num = s_min( INTER_OBJECT_PARAM_CHECK, sub( nchan_ism, imult1616( i, INTER_OBJECT_PARAM_CHECK ) ) );
571 123208 : i = add( i, 1 );
572 :
573 123208 : set16_fx( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
574 :
575 425371 : FOR( ch = 0; ch < num; ch++ )
576 : {
577 302163 : if ( EQ_16( flag_abs_azimuth[ch], 1 ) )
578 : {
579 104855 : abs_matrice[ch * ISM_NUM_PARAM] = 1;
580 104855 : move16();
581 : }
582 :
583 302163 : if ( EQ_16( flag_abs_elevation[ch], 1 ) )
584 : {
585 21065 : abs_matrice[ch * ISM_NUM_PARAM + 1] = 1;
586 21065 : move16();
587 : }
588 : }
589 123208 : abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
590 :
591 123208 : abs_first = 0;
592 123208 : move16();
593 156807 : WHILE( abs_num > 1 )
594 : {
595 : /* find first "1" entry */
596 128361 : WHILE( abs_matrice[abs_first] == 0 )
597 : {
598 94762 : abs_first = add( abs_first, 1 );
599 : }
600 :
601 : /* find next "1" entry */
602 33599 : abs_next = add( abs_first, 1 );
603 221246 : WHILE( abs_matrice[abs_next] == 0 )
604 : {
605 187647 : abs_next = add( abs_next, 1 );
606 : }
607 :
608 : /* find "0" position */
609 33599 : pos_zero = 0;
610 33599 : move16();
611 44655 : WHILE( abs_matrice[pos_zero] == 1 )
612 : {
613 11056 : pos_zero = add( pos_zero, 1 );
614 : }
615 :
616 33599 : ch = idiv1616( abs_next, ISM_NUM_PARAM );
617 :
618 33599 : IF( abs_next % ISM_NUM_PARAM == 0 )
619 : {
620 31608 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = sub( abs_num, 1 );
621 31608 : move16();
622 : }
623 :
624 33599 : IF( EQ_16( abs_next % ISM_NUM_PARAM, 1 ) )
625 : {
626 1991 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = sub( abs_num, 1 );
627 1991 : move16();
628 : /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/
629 : }
630 :
631 33599 : abs_first = add( abs_first, 1 );
632 33599 : abs_num = sub( abs_num, 1 );
633 : }
634 123208 : test();
635 : }
636 :
637 123208 : IF( EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
638 : {
639 : Word16 md_diff_flag[MAX_NUM_OBJECTS];
640 :
641 16310 : set16_fx( md_diff_flag, 1, nchan_ism );
642 67700 : FOR( ch = 0; ch < nchan_ism; ch++ )
643 : {
644 51390 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
645 51390 : move16();
646 :
647 51390 : IF( hIsmMeta[ch]->ism_metadata_flag == 0 )
648 : {
649 0 : hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 );
650 0 : move16();
651 0 : hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
652 0 : move16();
653 : }
654 : ELSE
655 : {
656 51390 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
657 51390 : move16();
658 : }
659 51390 : hIsmMeta[ch]->ism_md_inc_diff_cnt = add( hIsmMeta[ch]->ism_md_inc_diff_cnt, 1 );
660 51390 : move16();
661 51390 : hIsmMeta[ch]->ism_md_inc_diff_cnt = s_min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
662 51390 : move16();
663 : }
664 :
665 16310 : update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
666 :
667 16310 : pop_wmops();
668 16310 : return error;
669 : }
670 106898 : IF( EQ_16( ism_mode, ISM_MODE_PARAM ) )
671 : {
672 : /* Keep the metdata transmission as is during active parts */
673 : /* But send the flag with 1 bit */
674 20414 : push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 );
675 :
676 : /* Loop over multiwave to write the object indices into bitstream */
677 61242 : FOR( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
678 : {
679 489936 : FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
680 : {
681 898216 : FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
682 : {
683 449108 : push_next_indice( hBstr, hParamIsm->obj_indices[nbands][nblocks][ch], PARAM_ISM_OBJ_IND_NBITS );
684 : }
685 : }
686 : }
687 :
688 : /* Loop over bands to write the power ratio's indices into bitstream */
689 244968 : FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
690 : {
691 449108 : FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
692 : {
693 224554 : push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS );
694 : }
695 : }
696 :
697 : /* total metadata bits */
698 20414 : total_bits_metadata = sub( hBstr->nb_bits_tot, nb_bits_start );
699 :
700 : /* bits per ISM*/
701 20414 : bits_metadata_ism = idiv1616( total_bits_metadata, nchan_transport );
702 :
703 : /* Divide the metadata bits into n_Isms*/
704 20414 : nb_bits_objcod_written = 0;
705 20414 : move16();
706 61242 : FOR( ch = 0; ch < nchan_transport; ch++ )
707 : {
708 40828 : IF( EQ_16( ch, sub( nchan_transport, 1 ) ) )
709 : {
710 20414 : nb_bits_metadata[ch] = sub( total_bits_metadata, nb_bits_objcod_written );
711 20414 : move16();
712 : }
713 : ELSE
714 : {
715 20414 : nb_bits_metadata[ch] = bits_metadata_ism;
716 20414 : move16();
717 20414 : nb_bits_objcod_written = add( nb_bits_objcod_written, bits_metadata_ism );
718 20414 : move16();
719 : }
720 : }
721 : }
722 : }
723 9 : ELSE IF( EQ_16( ism_mode, ISM_SBA_MODE_DISC ) )
724 : {
725 0 : pop_wmops();
726 0 : return error;
727 : }
728 :
729 : /*----------------------------------------------------------------*
730 : * Take into account the combined format bit-budget distribution
731 : *----------------------------------------------------------------*/
732 106907 : test();
733 106907 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
734 : {
735 : Word16 bits_ism, bits_element[MAX_NUM_OBJECTS];
736 : Word16 brate_limit_flag;
737 : Word32 ism_total_brate_ref;
738 5196 : ism_total_brate_ref = *ism_total_brate;
739 5196 : move32();
740 5196 : brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, nchan_ism );
741 :
742 5196 : bits_ism = extract_l( div_l( *ism_total_brate, FRAMES_PER_SEC >> 1 ) );
743 5196 : set16_fx( bits_element, idiv1616( bits_ism, nchan_ism ), nchan_ism );
744 5196 : bits_element[nchan_ism - 1] = add( bits_element[nchan_ism - 1], bits_ism % nchan_ism );
745 5196 : move16();
746 5196 : bitbudget_to_brate( bits_element, element_brate, nchan_ism );
747 :
748 5196 : *ism_total_brate = 0;
749 5196 : move32();
750 15710 : FOR( ch = 0; ch < nchan_ism; ch++ )
751 : {
752 10514 : *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag ) );
753 10514 : move32();
754 10514 : test();
755 10514 : test();
756 10514 : IF( GT_16( ism_imp[ch], 1 ) && EQ_16( flag_omasa_ener_brate, 1 ) && brate_limit_flag >= 0 )
757 : {
758 442 : *ism_total_brate = L_sub( *ism_total_brate, ADJUST_ISM_BRATE_NEG );
759 442 : move32();
760 : }
761 :
762 10514 : test();
763 10514 : test();
764 10514 : test();
765 10514 : IF( EQ_16( brate_limit_flag, -1 ) && GE_16( ism_imp[ch], 1 ) && GE_16( nchan_ism, 3 ) && ( GT_32( L_sub( ism_total_brate_ref, *ism_total_brate ), IVAS_48k ) ) )
766 : {
767 0 : *ism_total_brate = L_add( *ism_total_brate, ADJUST_ISM_BRATE_POS );
768 0 : move32();
769 : }
770 : }
771 5196 : ism_metadata_flag_global = 1;
772 5196 : move16();
773 :
774 5196 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) )
775 : {
776 3142 : brate_limit_flag = 0;
777 3142 : move16();
778 11602 : FOR( Word16 n = 0; n < nchan_ism; n++ )
779 : {
780 8460 : brate_limit_flag = add( brate_limit_flag, ism_imp[n] );
781 : }
782 :
783 3142 : if ( GE_16( brate_limit_flag, sub( imult1616( nchan_ism, ISM_HIGH_IMP ), 2 ) ) )
784 : {
785 2929 : *omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX;
786 2929 : move16();
787 : }
788 : }
789 : }
790 :
791 : /*----------------------------------------------------------------*
792 : * Configuration and decision about bitrates per channel
793 : *----------------------------------------------------------------*/
794 :
795 106907 : test();
796 106907 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
797 : {
798 5196 : IF( NE_32( ( error = ivas_ism_config_fx( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 1 ) ), IVAS_ERR_OK ) )
799 : {
800 0 : return error;
801 : }
802 : }
803 : ELSE
804 : {
805 101711 : IF( NE_32( ( error = ivas_ism_config_fx( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 0 ) ), IVAS_ERR_OK ) )
806 : {
807 0 : return error;
808 : }
809 : }
810 :
811 415229 : FOR( ch = 0; ch < nchan_ism; ch++ )
812 : {
813 308322 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
814 308322 : move16();
815 :
816 308322 : IF( hIsmMeta[ch]->ism_metadata_flag == 0 )
817 : {
818 11232 : hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 );
819 11232 : move16();
820 11232 : hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
821 11232 : move16();
822 : }
823 : ELSE
824 : {
825 297090 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
826 297090 : move16();
827 : }
828 308322 : hIsmMeta[ch]->ism_md_inc_diff_cnt = add( hIsmMeta[ch]->ism_md_inc_diff_cnt, 1 );
829 308322 : move16();
830 308322 : hIsmMeta[ch]->ism_md_inc_diff_cnt = s_min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
831 308322 : move16();
832 : }
833 :
834 381151 : FOR( ch = 0; ch < nchan_transport; ch++ )
835 : {
836 274244 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
837 274244 : move16();
838 274244 : test();
839 274244 : IF( EQ_16( ism_mode, ISM_MODE_DISC ) )
840 : {
841 222902 : test();
842 222902 : test();
843 222902 : test();
844 222902 : test();
845 229434 : if ( EQ_16( ism_imp[ch], ISM_NO_META ) && ( ( LT_32( total_brate[ch], ACELP_8k00 ) && LT_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ||
846 12345 : ( LE_32( total_brate[ch], ACELP_16k_LOW_LIMIT ) && GE_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ) )
847 : {
848 7518 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
849 7518 : move16();
850 : }
851 :
852 222902 : hSCE[ch]->element_brate = element_brate[ch];
853 222902 : move32();
854 : }
855 51342 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
856 : {
857 10514 : IF( ism_imp[ch] == ISM_INACTIVE_IMP )
858 : {
859 0 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
860 0 : move16();
861 : }
862 : }
863 :
864 274244 : hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
865 274244 : move32();
866 :
867 : /* write metadata only in active frames */
868 274244 : IF( GT_32( hSCE[0]->hCoreCoder[0]->core_brate, SID_2k40 ) )
869 : {
870 0 : reset_indices_enc_fx( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot );
871 : }
872 : }
873 :
874 106907 : pop_wmops();
875 :
876 106907 : return error;
877 : }
878 :
879 : /*-------------------------------------------------------------------------
880 : * ivas_ism_metadata_enc_create()
881 : *
882 : * Create, allocate, initialize and configure IVAS encoder ISM metadata handles
883 : *-------------------------------------------------------------------------*/
884 :
885 153 : ivas_error ivas_ism_metadata_enc_create_fx(
886 : Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
887 : const Word16 n_ISms, /* i : number of objects */
888 : Word32 element_brate_tmp[] /* o : element bitrate per object */
889 : )
890 : {
891 : Word16 ch, nchan_transport;
892 : ivas_error error;
893 :
894 153 : nchan_transport = st_ivas->nchan_transport;
895 153 : move16();
896 153 : IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) )
897 : {
898 44 : nchan_transport = MAX_PARAM_ISM_WAVE;
899 44 : move16();
900 44 : ivas_set_omasa_TC_fx( st_ivas->ism_mode, n_ISms, &st_ivas->nSCE, &st_ivas->nCPE );
901 : }
902 109 : ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) )
903 : {
904 35 : nchan_transport = n_ISms;
905 35 : move16();
906 : }
907 : ELSE
908 : {
909 74 : IF( EQ_32( st_ivas->ism_mode, ISM_MODE_NONE ) )
910 : {
911 0 : nchan_transport = st_ivas->nchan_transport;
912 0 : move16();
913 :
914 0 : IF( EQ_16( nchan_transport, 1 ) )
915 : {
916 0 : st_ivas->nSCE = 1;
917 0 : move16();
918 0 : st_ivas->nCPE = 0;
919 0 : move16();
920 : }
921 : ELSE
922 : {
923 0 : st_ivas->nSCE = 0;
924 0 : move16();
925 0 : st_ivas->nCPE = 1;
926 0 : move16();
927 : }
928 : }
929 74 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
930 : {
931 17 : nchan_transport = 2;
932 17 : move16();
933 : }
934 : ELSE
935 : {
936 57 : nchan_transport = n_ISms;
937 57 : move16();
938 : }
939 :
940 74 : st_ivas->nchan_transport = nchan_transport;
941 74 : st_ivas->nSCE = nchan_transport;
942 74 : st_ivas->nCPE = 0;
943 74 : move16();
944 74 : move16();
945 74 : move16();
946 : }
947 :
948 : /* allocate ISM metadata handles */
949 612 : FOR( ch = 0; ch < n_ISms; ch++ )
950 : {
951 459 : IF( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
952 : {
953 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
954 : }
955 459 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0;
956 459 : move16();
957 459 : st_ivas->hIsmMetaData[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
958 459 : move16();
959 459 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 0;
960 459 : move16();
961 459 : st_ivas->hIsmMetaData[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX - 1;
962 459 : move16();
963 459 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0;
964 459 : move16();
965 459 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle1_diff_cnt = ISM_FEC_MAX - 2;
966 459 : move16();
967 459 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 0;
968 459 : move16();
969 459 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle2_diff_cnt = ISM_FEC_MAX - 2;
970 459 : move16();
971 459 : st_ivas->hIsmMetaData[ch]->last_radius_idx = 0;
972 459 : move16();
973 459 : st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2;
974 459 : move16();
975 459 : st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
976 459 : move16();
977 :
978 459 : st_ivas->hIsmMetaData[ch]->ism_imp = -1;
979 459 : move16();
980 459 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
981 459 : move16();
982 459 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
983 459 : move16();
984 :
985 459 : st_ivas->hIsmMetaData[ch]->q_azimuth_old_fx = 0;
986 459 : move16();
987 459 : st_ivas->hIsmMetaData[ch]->q_elevation_old_fx = 0;
988 459 : move16();
989 :
990 459 : ivas_ism_reset_metadata_enc( st_ivas->hIsmMetaData[ch] );
991 :
992 459 : st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0; // Q22
993 459 : move32();
994 459 : st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0; // Q22
995 459 : move32();
996 :
997 459 : st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0; // Q22
998 459 : move32();
999 459 : st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0; // Q22
1000 459 : move32();
1001 :
1002 459 : st_ivas->hIsmMetaData[ch]->ism_md_fec_cnt_enc = 0;
1003 459 : move16();
1004 459 : st_ivas->hIsmMetaData[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
1005 459 : move16();
1006 459 : st_ivas->hIsmMetaData[ch]->last_true_radius_fx = ONE_IN_Q9; // Q9
1007 459 : move16();
1008 : }
1009 :
1010 153 : IF( EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) )
1011 : {
1012 44 : test();
1013 44 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
1014 : {
1015 20 : IF( NE_32( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, 1, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ), IVAS_ERR_OK ) )
1016 : {
1017 0 : return error;
1018 : }
1019 : }
1020 24 : ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
1021 : {
1022 17 : IF( NE_32( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ), IVAS_ERR_OK ) )
1023 : {
1024 0 : return error;
1025 : }
1026 : }
1027 : }
1028 : ELSE
1029 : {
1030 109 : IF( NE_32( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ), IVAS_ERR_OK ) )
1031 : {
1032 0 : return error;
1033 : }
1034 : }
1035 :
1036 153 : return IVAS_ERR_OK;
1037 : }
1038 :
1039 : /*-------------------------------------------------------------------------
1040 : * encode_radius()
1041 : *
1042 : * Radius index encoding
1043 : *-------------------------------------------------------------------------*/
1044 25625 : static void encode_radius_fx(
1045 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
1046 : Word16 *last_radius_idx, /* i/o: last radius index */
1047 : Word16 *radius_diff_cnt, /* i/o: radius diff coding counter */
1048 : const Word16 last_ism_metadata_flag, /* last frame ism_metadata_flag */
1049 : const Word16 idx_radius_abs, /* i : Azimuth index */
1050 : Word16 *flag_abs_radius /* o : Radius encoding mode */
1051 : )
1052 : {
1053 : Word16 idx_radius, nbits_diff_radius, diff;
1054 :
1055 25625 : idx_radius = idx_radius_abs;
1056 25625 : nbits_diff_radius = 0;
1057 25625 : move16();
1058 25625 : *flag_abs_radius = 0; /* differential coding by default */
1059 25625 : move16();
1060 :
1061 25625 : test();
1062 25625 : if ( EQ_16( *radius_diff_cnt, ISM_FEC_MAX ) /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
1063 23793 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1064 : )
1065 : {
1066 2190 : *flag_abs_radius = 1;
1067 2190 : move16();
1068 : }
1069 :
1070 25625 : diff = sub( idx_radius_abs, *last_radius_idx );
1071 :
1072 : /* try differential coding */
1073 25625 : IF( *flag_abs_radius == 0 )
1074 : {
1075 23435 : IF( diff == 0 )
1076 : {
1077 15312 : idx_radius = 0;
1078 15312 : move16();
1079 15312 : nbits_diff_radius = 1;
1080 15312 : move16();
1081 : }
1082 8123 : ELSE IF( LE_16( ABSVAL( diff ), ISM_MAX_RADIUS_DIFF_IDX ) )
1083 : {
1084 3096 : idx_radius = 2; // shl( 1, 1 );
1085 3096 : move16();
1086 3096 : nbits_diff_radius = 1;
1087 3096 : move16();
1088 :
1089 3096 : IF( diff < 0 )
1090 : {
1091 1428 : idx_radius = add( idx_radius, 1 ); /* negative sign */
1092 1428 : diff = imult1616( diff, -1 );
1093 : }
1094 : ELSE
1095 : {
1096 1668 : idx_radius = add( idx_radius, 0 ); /* positive sign */
1097 : }
1098 :
1099 3096 : idx_radius = shl( idx_radius, diff );
1100 3096 : nbits_diff_radius = add( nbits_diff_radius, 1 );
1101 :
1102 : /* unary coding of "diff */
1103 3096 : idx_radius = add( idx_radius, sub( shl( 1, diff ), 1 ) );
1104 3096 : nbits_diff_radius = add( nbits_diff_radius, diff );
1105 :
1106 3096 : IF( LT_16( nbits_diff_radius, ISM_RADIUS_NBITS ) )
1107 : {
1108 : /* add stop bit */
1109 2910 : idx_radius = shl( idx_radius, 1 );
1110 2910 : nbits_diff_radius = add( nbits_diff_radius, 1 );
1111 : }
1112 : }
1113 : ELSE
1114 : {
1115 5027 : *flag_abs_radius = 1;
1116 5027 : move16();
1117 : }
1118 : }
1119 :
1120 : /* update counter */
1121 25625 : IF( *flag_abs_radius == 0 )
1122 : {
1123 18408 : *radius_diff_cnt = add( *radius_diff_cnt, 1 );
1124 18408 : move16();
1125 18408 : *radius_diff_cnt = s_min( *radius_diff_cnt, ISM_FEC_MAX );
1126 18408 : move16();
1127 : }
1128 : ELSE
1129 : {
1130 7217 : *radius_diff_cnt = 0;
1131 7217 : move16();
1132 : }
1133 :
1134 : /* Write radius */
1135 25625 : push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 );
1136 :
1137 25625 : IF( *flag_abs_radius )
1138 : {
1139 7217 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS );
1140 : }
1141 : ELSE
1142 : {
1143 18408 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius );
1144 : }
1145 :
1146 : /* Updates */
1147 25625 : *last_radius_idx = idx_radius_abs;
1148 25625 : move16();
1149 :
1150 25625 : return;
1151 : }
1152 :
1153 : /*----------------------------------------------------------------*
1154 : * encode_angle_indices()
1155 : *
1156 : * Encoding of an angle
1157 : *----------------------------------------------------------------*/
1158 :
1159 380440 : static void encode_angle_indices_fx(
1160 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
1161 : ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */
1162 : const Word16 last_ism_metadata_flag, /* i : last frame ism_metadata_flag */
1163 : const Word16 ini_frame, /* i : initialization frames counter */
1164 : const Word16 idx_angle1_abs, /* i : Azimuth index */
1165 : const Word16 idx_angle2_abs, /* i : Elevation index */
1166 : Word16 *flag_abs_angle1, /* o : Azimuth/yaw encoding mode */
1167 : Word16 *flag_abs_angle2 /* o : Elevation/pitch encoding mode */
1168 : )
1169 : {
1170 : Word16 idx_angle1, nbits_diff_angle1, diff;
1171 : Word16 idx_angle2, nbits_diff_angle2;
1172 :
1173 : /*----------------------------------------------------------------*
1174 : * Azimuth/yaw index encoding
1175 : *----------------------------------------------------------------*/
1176 :
1177 380440 : idx_angle1 = idx_angle1_abs;
1178 380440 : move16();
1179 :
1180 380440 : nbits_diff_angle1 = 0;
1181 380440 : move16();
1182 380440 : *flag_abs_angle1 = 0; /* differential coding by default */
1183 380440 : test();
1184 380440 : IF( EQ_16( angle->angle1_diff_cnt, ISM_FEC_MAX ) /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
1185 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1186 : )
1187 : {
1188 32275 : *flag_abs_angle1 = 1;
1189 32275 : move16();
1190 : }
1191 :
1192 : /* try differential coding */
1193 380440 : IF( *flag_abs_angle1 == 0 )
1194 : {
1195 348165 : diff = sub( idx_angle1_abs, angle->last_angle1_idx );
1196 :
1197 : /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
1198 348165 : IF( GT_16( abs_s( diff ), ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX ) )
1199 : {
1200 3859 : IF( diff > 0 )
1201 : {
1202 1376 : diff = sub( diff, ( 1 << ISM_AZIMUTH_NBITS ) - 1 );
1203 : }
1204 : ELSE
1205 : {
1206 2483 : diff = add( diff, ( 1 << ISM_AZIMUTH_NBITS ) - 1 );
1207 : }
1208 : }
1209 :
1210 348165 : IF( diff == 0 )
1211 : {
1212 60108 : idx_angle1 = 0;
1213 60108 : move16();
1214 60108 : nbits_diff_angle1 = 1;
1215 60108 : move16();
1216 : }
1217 288057 : ELSE IF( LT_16( abs_s( diff ), ISM_MAX_AZIMUTH_DIFF_IDX ) ) /* when diff bits >= abs bits, prefer abs */
1218 : {
1219 201103 : idx_angle1 = 2; // shl( 1, 1 );
1220 201103 : move16();
1221 201103 : nbits_diff_angle1 = 1;
1222 201103 : move16();
1223 :
1224 201103 : IF( diff < 0 )
1225 : {
1226 65134 : idx_angle1 = add( idx_angle1, 1 ); /* negative sign */
1227 65134 : diff = imult1616( diff, -1 );
1228 : }
1229 : ELSE
1230 : {
1231 135969 : idx_angle1 = add( idx_angle1, 0 ); /* positive sign */
1232 : }
1233 :
1234 201103 : idx_angle1 = shl( idx_angle1, diff );
1235 201103 : nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
1236 :
1237 : /* unary coding of "diff */
1238 201103 : idx_angle1 = add( idx_angle1, sub( shl( 1, diff ), 1 ) );
1239 201103 : nbits_diff_angle1 = add( nbits_diff_angle1, diff );
1240 :
1241 201103 : IF( LT_16( nbits_diff_angle1, ( ISM_AZIMUTH_NBITS - 1 ) ) )
1242 : {
1243 : /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */
1244 184150 : idx_angle1 = shl( idx_angle1, 1 );
1245 184150 : nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
1246 : }
1247 : }
1248 : ELSE
1249 : {
1250 86954 : *flag_abs_angle1 = 1;
1251 86954 : move16();
1252 : }
1253 : }
1254 :
1255 : /* update counter */
1256 380440 : IF( *flag_abs_angle1 == 0 )
1257 : {
1258 261211 : angle->angle1_diff_cnt = add( angle->angle1_diff_cnt, 1 );
1259 261211 : move16();
1260 261211 : angle->angle1_diff_cnt = s_min( angle->angle1_diff_cnt, ISM_FEC_MAX );
1261 261211 : move16();
1262 : }
1263 : ELSE
1264 : {
1265 119229 : angle->angle1_diff_cnt = 0;
1266 119229 : move16();
1267 : }
1268 :
1269 : /* Write azimuth/yaw */
1270 380440 : push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 );
1271 :
1272 380440 : IF( *flag_abs_angle1 )
1273 : {
1274 119229 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS );
1275 : }
1276 : ELSE
1277 : {
1278 261211 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 );
1279 : }
1280 :
1281 : /*----------------------------------------------------------------*
1282 : * Elevation/pitch index encoding
1283 : *----------------------------------------------------------------*/
1284 :
1285 380440 : IF( flag_abs_angle2 )
1286 : {
1287 379635 : idx_angle2 = idx_angle2_abs;
1288 379635 : move16();
1289 379635 : nbits_diff_angle2 = 0;
1290 379635 : move16();
1291 379635 : *flag_abs_angle2 = 0; /* differential coding by default */
1292 379635 : move16();
1293 379635 : if ( EQ_16( angle->angle2_diff_cnt, ISM_FEC_MAX ) /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
1294 270977 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1295 : )
1296 : {
1297 109216 : *flag_abs_angle2 = 1;
1298 109216 : move16();
1299 : }
1300 :
1301 : /* note: elevation/pitch is coded starting from the second frame only (it is meaningless in the init_frame) */
1302 379635 : IF( ini_frame == 0 )
1303 : {
1304 1135 : *flag_abs_angle2 = 1;
1305 1135 : move16();
1306 1135 : angle->last_angle2_idx = idx_angle2_abs;
1307 1135 : move16();
1308 : }
1309 :
1310 379635 : diff = sub( idx_angle2_abs, angle->last_angle2_idx );
1311 :
1312 : /* avoid absolute coding of elevation/pitch if absolute coding was already used for azimuth/yaw */
1313 379635 : IF( EQ_16( *flag_abs_angle1, 1 ) )
1314 : {
1315 119154 : Word16 diff_orig = diff;
1316 :
1317 119154 : *flag_abs_angle2 = 0;
1318 119154 : move16();
1319 :
1320 :
1321 119154 : IF( diff >= 0 )
1322 : {
1323 74487 : diff = s_min( diff, ISM_MAX_ELEVATION_DIFF_IDX );
1324 : }
1325 : ELSE
1326 : {
1327 44667 : diff = imult1616( -1, s_min( -diff, ISM_MAX_ELEVATION_DIFF_IDX ) );
1328 : }
1329 :
1330 119154 : test();
1331 119154 : if ( last_ism_metadata_flag == 0 || GT_16( abs_s( sub( diff_orig, diff ) ), ISM_MAX_ELEVATION_DIFF_IDX ) )
1332 : {
1333 46226 : angle->angle2_diff_cnt = ISM_FEC_MAX - 1;
1334 46226 : move16();
1335 : }
1336 : }
1337 :
1338 : /* try differential coding */
1339 379635 : IF( *flag_abs_angle2 == 0 )
1340 : {
1341 351903 : IF( diff == 0 )
1342 : {
1343 143070 : idx_angle2 = 0;
1344 143070 : move16();
1345 143070 : nbits_diff_angle2 = 1;
1346 143070 : move16();
1347 : }
1348 208833 : ELSE IF( LE_16( abs_s( diff ), ISM_MAX_ELEVATION_DIFF_IDX ) )
1349 : {
1350 204402 : idx_angle2 = 2; // shl( 1, 1 );
1351 204402 : move16();
1352 204402 : nbits_diff_angle2 = 1;
1353 204402 : move16();
1354 :
1355 204402 : IF( diff < 0 )
1356 : {
1357 102469 : idx_angle2 = add( idx_angle2, 1 ); /* negative sign */
1358 102469 : diff = imult1616( diff, -1 );
1359 : }
1360 : ELSE
1361 : {
1362 101933 : idx_angle2 = add( idx_angle2, 0 ); /* positive sign */
1363 : }
1364 :
1365 204402 : idx_angle2 = shl( idx_angle2, diff );
1366 204402 : nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
1367 :
1368 : /* unary coding of "diff */
1369 204402 : idx_angle2 = add( idx_angle2, sub( shl( 1, diff ), 1 ) );
1370 204402 : nbits_diff_angle2 = add( nbits_diff_angle2, diff );
1371 :
1372 204402 : IF( LT_16( nbits_diff_angle2, ISM_ELEVATION_NBITS ) )
1373 : {
1374 : /* add stop bit */
1375 136562 : idx_angle2 = shl( idx_angle2, 1 );
1376 136562 : nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
1377 : }
1378 : }
1379 : ELSE
1380 : {
1381 4431 : *flag_abs_angle2 = 1;
1382 4431 : move16();
1383 : }
1384 : }
1385 :
1386 : /* update counter */
1387 379635 : IF( *flag_abs_angle2 == 0 )
1388 : {
1389 347472 : angle->angle2_diff_cnt = add( angle->angle2_diff_cnt, 1 );
1390 347472 : move16();
1391 347472 : angle->angle2_diff_cnt = s_min( angle->angle2_diff_cnt, ISM_FEC_MAX );
1392 347472 : move16();
1393 : }
1394 : ELSE
1395 : {
1396 32163 : angle->angle2_diff_cnt = 0;
1397 32163 : move16();
1398 : }
1399 :
1400 : /* Write elevation */
1401 379635 : IF( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */
1402 : {
1403 260481 : push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 );
1404 : }
1405 :
1406 379635 : IF( *flag_abs_angle2 )
1407 : {
1408 32163 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS );
1409 : }
1410 : ELSE
1411 : {
1412 347472 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 );
1413 : }
1414 : }
1415 :
1416 : /*----------------------------------------------------------------*
1417 : * Updates
1418 : *----------------------------------------------------------------*/
1419 :
1420 380440 : angle->last_angle1_idx = idx_angle1_abs;
1421 380440 : move16();
1422 380440 : angle->last_angle2_idx = idx_angle2_abs;
1423 380440 : move16();
1424 :
1425 380440 : return;
1426 : }
1427 :
1428 : /*-------------------------------------------------------------------*
1429 : * ivas_ism_metadata_sid_enc()
1430 : *
1431 : * Quantize and encode ISM metadata in SID frame
1432 : *-------------------------------------------------------------------*/
1433 :
1434 2115 : void ivas_ism_metadata_sid_enc_fx(
1435 : ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */
1436 : const Word16 flag_noisy_speech, /* i : noisy speech flag */
1437 : const Word16 nchan_ism, /* i : number of objects */
1438 : const Word16 nchan_transport, /* i : number of transport channels */
1439 : const ISM_MODE ism_mode, /* i : ISM mode */
1440 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
1441 : const Word16 sid_flag, /* i : indication of SID frame */
1442 : const Word16 md_diff_flag[], /* i : metadata differental flag */
1443 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
1444 : Word16 nb_bits_metadata[] /* o : number of metadata bits */
1445 : )
1446 : {
1447 : Word16 i, ch, nBits, nBits_start, nBits_unused;
1448 : Word32 q_step_fx, q_step_border_fx;
1449 : Word16 idx, idx_azimuth, idx_elevation;
1450 : Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
1451 : Word32 valQ_fx;
1452 :
1453 : ISM_METADATA_HANDLE hIsmMetaData;
1454 :
1455 2115 : IF( sid_flag )
1456 : {
1457 535 : nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
1458 535 : move16();
1459 535 : nBits = sub( nBits, SID_FORMAT_NBITS );
1460 535 : nBits_start = hBstr->nb_bits_tot;
1461 535 : move16();
1462 :
1463 : /*----------------------------------------------------------------*
1464 : * Write ISm common signaling
1465 : *----------------------------------------------------------------*/
1466 :
1467 : /* write number of objects - unary coding */
1468 1765 : FOR( ch = 1; ch < nchan_ism; ch++ )
1469 : {
1470 1230 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
1471 : }
1472 535 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
1473 :
1474 : /* write SID metadata flag (one per object) */
1475 2300 : FOR( ch = 0; ch < nchan_ism; ch++ )
1476 : {
1477 1765 : push_indice( hBstr, IND_ISM_METADATA_FLAG, md_diff_flag[ch], 1 );
1478 : }
1479 :
1480 : /*----------------------------------------------------------------*
1481 : * Set quantization bits based on the number of coded objects
1482 : *----------------------------------------------------------------*/
1483 :
1484 535 : ivas_get_ism_sid_quan_bitbudget_fx( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step_fx, &q_step_border_fx, &nBits_coh, &nBits_sce_id );
1485 :
1486 : /*----------------------------------------------------------------*
1487 : * Spatial parameters, loop over TCs - 1
1488 : *----------------------------------------------------------------*/
1489 :
1490 : /* write ISM mode flag to explicitly signal number of spatial parameters */
1491 535 : IF( GT_16( nchan_ism, 2 ) )
1492 : {
1493 375 : IF( EQ_16( ism_mode, ISM_MODE_DISC ) )
1494 : {
1495 282 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 );
1496 : }
1497 : ELSE
1498 : {
1499 93 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 );
1500 : }
1501 :
1502 375 : IF( EQ_16( ism_mode, ISM_MODE_PARAM ) )
1503 : {
1504 : /* write noisy speech flag */
1505 93 : push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 );
1506 93 : nBits_sce_id = 1;
1507 93 : move16();
1508 : }
1509 : }
1510 :
1511 535 : IF( GT_16( nchan_transport, 1 ) )
1512 : {
1513 : /* write sce id */
1514 480 : push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id );
1515 :
1516 : /* quantize and write coherence */
1517 2004 : FOR( ch = 0; ch < nchan_transport; ch++ )
1518 : {
1519 1524 : IF( EQ_16( ch, hISMDTX->sce_id_dtx ) )
1520 : {
1521 480 : CONTINUE;
1522 : }
1523 1044 : Word32 tmp = Mpy_32_32( L_shr( L_deposit_h( hISMDTX->coh_fx[ch] ), 1 ) /*Q30*/, L_deposit_h( sub( shl( 1, nBits_coh ), 1 ) ) ); // Q15
1524 1044 : Word32 tmp_2 = L_add( tmp, 16384 /*0.5f in Q15*/ );
1525 1044 : idx = extract_l( L_shr( tmp_2, Q15 ) );
1526 : // idx = (Word16) ( hISMDTX->coh[ch] * sub( shl( 1, nBits_coh ), 1 ) + 0.5f );
1527 1044 : assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) );
1528 1044 : push_indice( hBstr, IND_ISM_DTX_COH_SCA, idx, nBits_coh );
1529 : }
1530 : }
1531 :
1532 : /*----------------------------------------------------------------*
1533 : * Metadata quantization and coding, loop over all objects
1534 : *----------------------------------------------------------------*/
1535 :
1536 2300 : FOR( ch = 0; ch < nchan_ism; ch++ )
1537 : {
1538 1765 : IF( EQ_16( md_diff_flag[ch], 1 ) )
1539 : {
1540 631 : hIsmMetaData = hIsmMeta[ch];
1541 :
1542 631 : idx_azimuth = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, shl( 1, nBits_azimuth ) );
1543 631 : idx_elevation = ism_quant_meta_fx( hIsmMetaData->elevation_fx, &valQ_fx, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, shl( 1, nBits_elevation ) );
1544 631 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth );
1545 631 : push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation );
1546 :
1547 : /* update last indexes to correspond to active frames coding */
1548 631 : IF( GT_16( nBits_azimuth, ISM_AZIMUTH_NBITS ) )
1549 : {
1550 210 : hIsmMetaData->position_angle.last_angle1_idx = shr( idx_azimuth, sub( nBits_azimuth, ISM_AZIMUTH_NBITS ) );
1551 210 : move16();
1552 210 : hIsmMetaData->position_angle.last_angle2_idx = shr( idx_elevation, sub( nBits_elevation, ISM_ELEVATION_NBITS ) );
1553 210 : move16();
1554 : }
1555 : ELSE
1556 : {
1557 421 : hIsmMetaData->position_angle.last_angle1_idx = shl( idx_azimuth, sub( ISM_AZIMUTH_NBITS, nBits_azimuth ) );
1558 421 : move16();
1559 421 : hIsmMetaData->position_angle.last_angle2_idx = shl( idx_elevation, sub( ISM_ELEVATION_NBITS, nBits_elevation ) );
1560 421 : move16();
1561 : }
1562 :
1563 631 : hIsmMetaData->ism_md_fec_cnt_enc = 0;
1564 631 : move16();
1565 631 : hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
1566 631 : move16();
1567 : }
1568 : }
1569 :
1570 : /* Write unused (padding) bits */
1571 535 : nBits_unused = sub( nBits, hBstr->nb_bits_tot );
1572 1550 : WHILE( nBits_unused > 0 )
1573 : {
1574 1015 : i = s_min( nBits_unused, 16 );
1575 1015 : push_indice( hBstr, IND_UNUSED, 0, i );
1576 1015 : nBits_unused = sub( nBits_unused, i );
1577 : }
1578 :
1579 535 : nb_bits_metadata[0] = sub( hBstr->nb_bits_tot, nBits_start );
1580 535 : move16();
1581 : }
1582 :
1583 2115 : return;
1584 : }
|