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.h"
39 : #include "ivas_rom_com.h"
40 : #include "prot.h"
41 : #include <math.h>
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include "wmc_auto.h"
46 :
47 :
48 : /*-----------------------------------------------------------------------*
49 : * Local constants
50 : *-----------------------------------------------------------------------*/
51 :
52 : #define ISM_NUM_PARAM 5 /* number of coded metadata parameters */
53 :
54 : #define ISM_MAX_AZIMUTH_DIFF_IDX ( ISM_AZIMUTH_NBITS - 1 /*zero*/ - 1 /*sign*/ )
55 : #define ISM_MAX_ELEVATION_DIFF_IDX ( ISM_ELEVATION_NBITS - 1 /*zero*/ - 1 /*sign*/ )
56 : #define ISM_MAX_RADIUS_DIFF_IDX ( ISM_RADIUS_NBITS - 1 /*zero*/ - 1 /*sign*/ )
57 :
58 : #define ISM_MD_FEC_DIFF 10
59 : #define ISM_MD_INC_DIFF_CNT_MAX 6
60 : #define ISM_MD_FEC_CNT_MAX 25
61 : #define ISM_MD_RAD_FEC_DIFF 1
62 : #define INTER_OBJECT_PARAM_CHECK ( ( ISM_FEC_MAX / 2 ) - 2 ) /* note: constant must be less than (ISM_FEC_MAX / number of coded parameters) */
63 :
64 :
65 : /*-----------------------------------------------------------------------*
66 : * Local function declarations
67 : *-----------------------------------------------------------------------*/
68 :
69 : static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_angle1_abs, const int16_t idx_angle2_abs, int16_t *flag_abs_angle1, int16_t *flag_abs_angle2 );
70 :
71 : static void encode_radius( BSTR_ENC_HANDLE hBstr, int16_t *last_radius_idx, int16_t *radius_diff_cnt, const int16_t last_ism_metadata_flag, const int16_t idx_radius_abs, int16_t *flag_abs_radius );
72 :
73 :
74 : /*-------------------------------------------------------------------------*
75 : * ivas_set_ism_metadata()
76 : *
77 : * Set metadata of one ISM MD handle
78 : *-------------------------------------------------------------------------*/
79 :
80 433276 : ivas_error ivas_set_ism_metadata(
81 : ISM_METADATA_HANDLE hIsmMeta, /* o : ISM metadata handle */
82 : const float azimuth, /* i : azimuth value */
83 : const float elevation, /* i : elevation */
84 : const float radius_meta, /* i : radius */
85 : const float yaw, /* i : yaw */
86 : const float pitch, /* i : pitch */
87 : const int16_t non_diegetic_flag /* i : non-diegetic object flag*/
88 : )
89 : {
90 433276 : if ( hIsmMeta == NULL )
91 : {
92 0 : return IVAS_ERR_UNEXPECTED_NULL_POINTER;
93 : }
94 :
95 433276 : hIsmMeta->ism_metadata_flag = 1;
96 :
97 : /* save read metadata parameters to the internal codec structure */
98 433276 : hIsmMeta->azimuth = azimuth;
99 433276 : hIsmMeta->elevation = elevation;
100 433276 : hIsmMeta->radius = radius_meta;
101 433276 : hIsmMeta->yaw = yaw;
102 433276 : hIsmMeta->pitch = pitch;
103 433276 : hIsmMeta->non_diegetic_flag = non_diegetic_flag;
104 :
105 433276 : return IVAS_ERR_OK;
106 : }
107 :
108 :
109 : /*-------------------------------------------------------------------------*
110 : * rate_ism_importance()
111 : *
112 : * Rate importance of particular ISM streams
113 : *-------------------------------------------------------------------------*/
114 :
115 101673 : static void rate_ism_importance(
116 : const int16_t nchan_transport, /* i : number of transported channels */
117 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
118 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
119 : const int16_t lowrate_metadata_flag[MAX_NUM_OBJECTS], /* i : low-rate MD flag */
120 : int16_t ism_imp[] /* o : ISM importance flags */
121 : )
122 : {
123 : int16_t ch, ctype;
124 :
125 365326 : for ( ch = 0; ch < nchan_transport; ch++ )
126 : {
127 263653 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
128 :
129 263653 : if ( hSCE[ch]->hCoreCoder[0]->tcxonly )
130 : {
131 101044 : if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
132 : {
133 17341 : ctype = INACTIVE;
134 : }
135 83703 : else if ( ctype == UNVOICED )
136 : {
137 6047 : ctype = GENERIC;
138 : }
139 : }
140 :
141 263653 : if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
142 : {
143 8350 : ism_imp[ch] = ISM_NO_META;
144 : }
145 255303 : else if ( ctype == INACTIVE || ctype == UNVOICED )
146 : {
147 29108 : ism_imp[ch] = ISM_LOW_IMP;
148 : }
149 226195 : else if ( ctype == VOICED )
150 : {
151 72596 : ism_imp[ch] = ISM_MEDIUM_IMP;
152 : }
153 : else /* GENERIC */
154 : {
155 153599 : ism_imp[ch] = ISM_HIGH_IMP;
156 : }
157 : }
158 :
159 101673 : return;
160 : }
161 :
162 :
163 : /*-------------------------------------------------------------------------*
164 : * ivas_ism_metadata_enc()
165 : *
166 : * quantize and encode ISM metadata
167 : *-------------------------------------------------------------------------*/
168 :
169 128949 : ivas_error ivas_ism_metadata_enc(
170 : int32_t *ism_total_brate, /* i/o: ISM total bitrate */
171 : const int16_t nchan_ism, /* i : number of ISM channels */
172 : const int16_t nchan_transport, /* i : number of transport channels */
173 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
174 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
175 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
176 : int16_t nb_bits_metadata[], /* o : number of metadata bits */
177 : const int16_t vad_flag[], /* i : VAD flag */
178 : const int16_t ism_mode, /* i : ISM mode */
179 : const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Enc Handle */
180 : const int16_t ism_extended_metadata_flag, /* i : Extended metadata flag */
181 : const float lp_noise_CPE,
182 : const int16_t flag_omasa_ener_brate, /* i : less bitrate for objects in OMASA flag */
183 : int16_t *omasa_stereo_sw_cnt,
184 : const int16_t ini_frame )
185 : {
186 128949 : int16_t i, ch, nb_bits_start = 0;
187 : int16_t flag_abs_azimuth[MAX_NUM_OBJECTS];
188 : int16_t flag_abs_elevation[MAX_NUM_OBJECTS];
189 128949 : int16_t idx_angle1_abs = 0;
190 128949 : int16_t idx_angle2_abs = 0;
191 : int16_t flag_abs_yaw[MAX_NUM_OBJECTS];
192 : int16_t flag_abs_pitch[MAX_NUM_OBJECTS];
193 128949 : int16_t idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS];
194 : float valQ;
195 : ISM_METADATA_HANDLE hIsmMetaData;
196 : int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS];
197 : int16_t ism_metadata_flag_global;
198 : int16_t non_diegetic_flag_global;
199 : int16_t ism_imp[MAX_NUM_OBJECTS];
200 : int16_t null_metadata_flag[MAX_NUM_OBJECTS];
201 : int16_t lowrate_metadata_flag[MAX_NUM_OBJECTS];
202 : int16_t nbands, nblocks;
203 : ivas_error error;
204 :
205 128949 : error = IVAS_ERR_OK;
206 128949 : push_wmops( "ism_meta_enc" );
207 :
208 : /* initialization */
209 128949 : ism_metadata_flag_global = 0;
210 128949 : non_diegetic_flag_global = 0;
211 128949 : set_s( nb_bits_metadata, 0, nchan_transport );
212 128949 : set_s( flag_abs_azimuth, 0, nchan_ism );
213 128949 : set_s( flag_abs_elevation, 0, nchan_ism );
214 128949 : set_s( flag_abs_yaw, 0, nchan_ism );
215 128949 : set_s( flag_abs_pitch, 0, nchan_ism );
216 128949 : set_s( flag_abs_radius, 0, nchan_ism );
217 128949 : set_s( null_metadata_flag, 0, nchan_ism );
218 128949 : set_s( lowrate_metadata_flag, 0, nchan_ism );
219 :
220 128949 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
221 : {
222 : /*----------------------------------------------------------------*
223 : * Rate importance of particular ISM streams in combined format coding
224 : *----------------------------------------------------------------*/
225 :
226 5196 : ivas_set_ism_importance_interformat( *ism_total_brate, nchan_transport, hIsmMeta, hSCE, lp_noise_CPE, ism_imp );
227 : }
228 : else
229 : {
230 : /*----------------------------------------------------------------*
231 : * Set Metadata presence / importance flag
232 : *----------------------------------------------------------------*/
233 :
234 490770 : for ( ch = 0; ch < nchan_ism; ch++ )
235 : {
236 367017 : if ( ism_mode == ISM_MODE_PARAM )
237 : {
238 74758 : hIsmMeta[ch]->ism_metadata_flag = 1;
239 : }
240 292259 : else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC )
241 : {
242 292259 : null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
243 :
244 292259 : if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
245 : {
246 287589 : if ( ism_mode != ISM_SBA_MODE_DISC )
247 : {
248 : /* In case of low level noise for low bitrate inactive frames, do not sent metadata */
249 218229 : hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10 || hSCE[ch]->hCoreCoder[0]->tcxonly;
250 : }
251 :
252 : /* 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 */
253 287589 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
254 : {
255 6597 : if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
256 875 : ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_true_elevation ) > ISM_MD_FEC_DIFF ) || ( fabsf( hIsmMeta[ch]->radius - hIsmMeta[ch]->last_true_radius ) > ISM_MD_RAD_FEC_DIFF ) )
257 : {
258 :
259 5817 : lowrate_metadata_flag[ch] = 1;
260 :
261 5817 : hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
262 : }
263 780 : else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
264 : {
265 :
266 499 : lowrate_metadata_flag[ch] = 1;
267 :
268 499 : if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
269 : {
270 191 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
271 : }
272 : else
273 : {
274 308 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
275 : }
276 : }
277 281 : else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
278 : {
279 6 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
280 6 : lowrate_metadata_flag[ch] = 1;
281 :
282 6 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
283 : }
284 : }
285 : }
286 : }
287 : }
288 :
289 : /*----------------------------------------------------------------*
290 : * Rate importance of particular ISM streams
291 : *----------------------------------------------------------------*/
292 :
293 123753 : if ( ism_mode != ISM_SBA_MODE_DISC )
294 : {
295 101673 : rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
296 : }
297 : }
298 :
299 : /*----------------------------------------------------------------*
300 : * Write ISM common signaling
301 : *----------------------------------------------------------------*/
302 :
303 128949 : if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ && ism_mode != ISM_SBA_MODE_DISC )
304 : {
305 : /* write number of objects - unary coding */
306 297657 : for ( ch = 1; ch < nchan_ism; ch++ )
307 : {
308 195984 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
309 : }
310 101673 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
311 : }
312 :
313 506480 : for ( ch = 0; ch < nchan_ism; ch++ )
314 : {
315 377531 : ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag;
316 377531 : ism_metadata_flag_global |= lowrate_metadata_flag[ch];
317 377531 : non_diegetic_flag_global |= hIsmMeta[ch]->non_diegetic_flag;
318 : }
319 :
320 : /* write extended metadata presence flag */
321 128949 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
322 : {
323 79985 : push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
324 :
325 : /* Write global non-diegetic object flag */
326 79985 : if ( ism_extended_metadata_flag )
327 : {
328 8166 : push_indice( hBstr, IND_ISM_EXTENDED_NDP_FLAG, non_diegetic_flag_global, ISM_EXTENDED_METADATA_BITS );
329 : }
330 : }
331 :
332 : /* write ISM metadata flag (one per object) */
333 472476 : for ( ch = 0; ch < nchan_transport; ch++ )
334 : {
335 343527 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
336 : {
337 : /* flags will be written in ivas_masa_encode() */
338 10514 : hIsmMeta[ch]->ism_imp = ism_imp[ch];
339 10514 : hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
340 10514 : hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
341 : }
342 : else
343 : {
344 333013 : if ( null_metadata_flag[ch] )
345 : {
346 : /* signal NULL metadata frame */
347 4670 : push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS );
348 :
349 : /* write the ISM class to ISM_NO_META and again the true ISM class */
350 4670 : if ( ism_mode != ISM_SBA_MODE_DISC )
351 : {
352 4670 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
353 4670 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
354 : }
355 : else
356 : {
357 0 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, 1 );
358 : }
359 : }
360 328343 : else if ( ism_mode != ISM_SBA_MODE_DISC )
361 : {
362 258983 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
363 :
364 258983 : if ( ism_imp[ch] == ISM_NO_META )
365 : {
366 : /* signal low-rate ISM_NO_META frame */
367 6597 : push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS );
368 :
369 : /* signal presence of MD in low-rate ISM_NO_META frame */
370 6597 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS );
371 : }
372 : }
373 : else /*ism_mode == ISM_SBA_MODE_DISC*/
374 : {
375 : /* all objects are considered active*/
376 69360 : push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 );
377 : }
378 : }
379 : }
380 :
381 :
382 128949 : if ( ism_metadata_flag_global )
383 : {
384 : /*----------------------------------------------------------------*
385 : * Metadata quantization and coding, loop over all objects
386 : *----------------------------------------------------------------*/
387 :
388 128932 : int16_t total_bits_metadata = 0;
389 128932 : int16_t bits_metadata_ism = 0;
390 : int16_t nb_bits_objcod_written;
391 :
392 128932 : if ( ism_mode == ISM_MODE_PARAM )
393 : {
394 20377 : nb_bits_start = hBstr->nb_bits_tot;
395 : }
396 :
397 506428 : for ( ch = 0; ch < nchan_ism; ch++ )
398 : {
399 377496 : hIsmMetaData = hIsmMeta[ch];
400 377496 : if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
401 : {
402 302738 : nb_bits_start = hBstr->nb_bits_tot;
403 : }
404 :
405 377496 : if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
406 : {
407 : /*----------------------------------------------------------------*
408 : * Quantize and encode azimuth and elevation
409 : *----------------------------------------------------------------*/
410 :
411 372586 : if ( ism_extended_metadata_flag && non_diegetic_flag_global )
412 : {
413 : /* Write non-diegetic flag for each object */
414 2415 : push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS );
415 : }
416 :
417 372586 : if ( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag )
418 : {
419 : /* Map azimuth to panning range [-90:90] */
420 805 : if ( hIsmMetaData->azimuth > 90.0f )
421 : {
422 0 : hIsmMetaData->azimuth = 180.0f - hIsmMetaData->azimuth;
423 : }
424 :
425 805 : if ( hIsmMetaData->azimuth < -90.0f )
426 : {
427 0 : hIsmMetaData->azimuth = -180.0f - hIsmMetaData->azimuth;
428 : }
429 :
430 805 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
431 :
432 805 : encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL );
433 : }
434 : else
435 : {
436 371781 : if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
437 : {
438 297023 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
439 297023 : idx_angle2_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
440 : }
441 : else /* ISM_MODE_PARAM */
442 : {
443 74758 : idx_angle1_abs = hParamIsm->azi_index[ch];
444 74758 : idx_angle2_abs = hParamIsm->ele_index[ch];
445 : }
446 :
447 371781 : encode_angle_indices( 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] );
448 :
449 : /*----------------------------------------------------------------*
450 : * Quantize and encode radius, yaw, and pitch
451 : *----------------------------------------------------------------*/
452 371781 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_extended_metadata_flag )
453 : {
454 25625 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
455 25625 : idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
456 25625 : idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS );
457 :
458 25625 : encode_angle_indices( 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] );
459 25625 : encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] );
460 : }
461 : }
462 :
463 : /* save number of metadata bits written */
464 372586 : if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
465 : {
466 297828 : nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start;
467 : }
468 :
469 : /* Updates */
470 372586 : hIsmMeta[ch]->last_true_azimuth = hIsmMeta[ch]->azimuth;
471 372586 : hIsmMeta[ch]->last_true_elevation = hIsmMeta[ch]->elevation;
472 372586 : hIsmMeta[ch]->last_true_radius = hIsmMeta[ch]->radius;
473 : }
474 : }
475 :
476 : /*----------------------------------------------------------------*
477 : * inter-object logic minimizing the use of several absolutely coded
478 : * indexes in the same frame
479 : *----------------------------------------------------------------*/
480 :
481 128932 : i = 0;
482 257864 : while ( i == 0 || i < nchan_ism / INTER_OBJECT_PARAM_CHECK )
483 : {
484 : int16_t num, abs_num, abs_first, abs_next, pos_zero;
485 : int16_t abs_matrice[INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM];
486 :
487 128932 : num = min( INTER_OBJECT_PARAM_CHECK, nchan_ism - i * INTER_OBJECT_PARAM_CHECK );
488 128932 : i++;
489 :
490 128932 : set_s( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
491 :
492 448013 : for ( ch = 0; ch < num; ch++ )
493 : {
494 319081 : if ( flag_abs_azimuth[ch] == 1 )
495 : {
496 112055 : abs_matrice[ch * ISM_NUM_PARAM] = 1;
497 : }
498 :
499 319081 : if ( flag_abs_elevation[ch] == 1 )
500 : {
501 22129 : abs_matrice[ch * ISM_NUM_PARAM + 1] = 1;
502 : }
503 : }
504 128932 : abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
505 :
506 128932 : abs_first = 0;
507 164892 : while ( abs_num > 1 )
508 : {
509 : /* find first "1" entry */
510 137858 : while ( abs_matrice[abs_first] == 0 )
511 : {
512 101898 : abs_first++;
513 : }
514 :
515 : /* find next "1" entry */
516 35960 : abs_next = abs_first + 1;
517 236324 : while ( abs_matrice[abs_next] == 0 )
518 : {
519 200364 : abs_next++;
520 : }
521 :
522 : /* find "0" position */
523 35960 : pos_zero = 0;
524 47720 : while ( abs_matrice[pos_zero] == 1 )
525 : {
526 11760 : pos_zero++;
527 : }
528 :
529 35960 : ch = abs_next / ISM_NUM_PARAM;
530 :
531 35960 : if ( abs_next % ISM_NUM_PARAM == 0 )
532 : {
533 33905 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1;
534 : }
535 :
536 35960 : if ( abs_next % ISM_NUM_PARAM == 1 )
537 : {
538 2055 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = abs_num - 1;
539 : /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/
540 : }
541 :
542 35960 : abs_first++;
543 35960 : abs_num--;
544 : }
545 : }
546 :
547 128932 : if ( ism_mode == ISM_SBA_MODE_DISC )
548 : {
549 : int16_t md_diff_flag[MAX_NUM_OBJECTS];
550 :
551 22080 : set_s( md_diff_flag, 1, nchan_ism );
552 91440 : for ( ch = 0; ch < nchan_ism; ch++ )
553 : {
554 69360 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
555 :
556 69360 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
557 : {
558 0 : hIsmMeta[ch]->ism_md_fec_cnt_enc++;
559 0 : hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
560 : }
561 : else
562 : {
563 69360 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
564 : }
565 69360 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
566 69360 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
567 : }
568 :
569 22080 : update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag );
570 :
571 22080 : pop_wmops();
572 22080 : return error;
573 : }
574 106852 : if ( ism_mode == ISM_MODE_PARAM )
575 : {
576 : /* Keep the metdata transmission as is during active parts */
577 : /* But send the flag with 1 bit */
578 20377 : push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 );
579 :
580 : /* Loop over multiwave to write the object indices into bitstream */
581 61131 : for ( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
582 : {
583 489048 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
584 : {
585 896588 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
586 : {
587 448294 : push_next_indice( hBstr, hParamIsm->obj_indices[nbands][nblocks][ch], PARAM_ISM_OBJ_IND_NBITS );
588 : }
589 : }
590 : }
591 :
592 : /* Loop over bands to write the power ratio's indices into bitstream */
593 244524 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
594 : {
595 448294 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
596 : {
597 224147 : push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS );
598 : }
599 : }
600 :
601 : /* total metadata bits */
602 20377 : total_bits_metadata = hBstr->nb_bits_tot - nb_bits_start;
603 :
604 : /* bits per ISM*/
605 20377 : bits_metadata_ism = (int16_t) ( total_bits_metadata / nchan_transport );
606 :
607 : /* Divide the metadata bits into n_Isms*/
608 20377 : nb_bits_objcod_written = 0;
609 61131 : for ( ch = 0; ch < nchan_transport; ch++ )
610 : {
611 40754 : if ( ch == nchan_transport - 1 )
612 : {
613 20377 : nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_written;
614 : }
615 : else
616 : {
617 20377 : nb_bits_metadata[ch] = bits_metadata_ism;
618 20377 : nb_bits_objcod_written += bits_metadata_ism;
619 : }
620 : }
621 : }
622 : }
623 17 : else if ( ism_mode == ISM_SBA_MODE_DISC )
624 : {
625 0 : pop_wmops();
626 0 : return error;
627 : }
628 :
629 : /*----------------------------------------------------------------*
630 : * Take into account the combined format bit-budget distribution
631 : *----------------------------------------------------------------*/
632 :
633 106869 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
634 : {
635 : int16_t bits_ism, bits_element[MAX_NUM_OBJECTS];
636 : int16_t brate_limit_flag;
637 : int32_t ism_total_brate_ref;
638 5196 : ism_total_brate_ref = *ism_total_brate;
639 5196 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism );
640 :
641 5196 : bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC );
642 5196 : set_s( bits_element, bits_ism / nchan_ism, nchan_ism );
643 5196 : bits_element[nchan_ism - 1] += bits_ism % nchan_ism;
644 5196 : bitbudget_to_brate( bits_element, element_brate, nchan_ism );
645 :
646 5196 : *ism_total_brate = 0;
647 15710 : for ( ch = 0; ch < nchan_ism; ch++ )
648 : {
649 10514 : *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag );
650 :
651 10514 : if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 )
652 : {
653 146 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
654 : }
655 :
656 10514 : if ( brate_limit_flag == -1 && ism_imp[ch] >= 1 && nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
657 : {
658 0 : *ism_total_brate += ADJUST_ISM_BRATE_POS;
659 : }
660 : }
661 5196 : ism_metadata_flag_global = 1;
662 :
663 5196 : if ( ism_mode == ISM_MASA_MODE_DISC )
664 : {
665 3142 : brate_limit_flag = 0;
666 11602 : for ( int16_t n = 0; n < nchan_ism; n++ )
667 : {
668 8460 : brate_limit_flag += ism_imp[n];
669 : }
670 :
671 3142 : if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 )
672 : {
673 2927 : *omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX;
674 : }
675 : }
676 : }
677 :
678 : /*----------------------------------------------------------------*
679 : * Configuration and decision about bitrates per channel
680 : *----------------------------------------------------------------*/
681 :
682 106869 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
683 : {
684 5196 : if ( ( error = ivas_ism_config( *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 )
685 : {
686 0 : return error;
687 : }
688 : }
689 : else
690 : {
691 101673 : if ( ( error = ivas_ism_config( *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 )
692 : {
693 0 : return error;
694 : }
695 : }
696 :
697 415040 : for ( ch = 0; ch < nchan_ism; ch++ )
698 : {
699 308171 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
700 :
701 308171 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
702 : {
703 11267 : hIsmMeta[ch]->ism_md_fec_cnt_enc++;
704 11267 : hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
705 : }
706 : else
707 : {
708 296904 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
709 : }
710 308171 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
711 308171 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
712 : }
713 :
714 381036 : for ( ch = 0; ch < nchan_transport; ch++ )
715 : {
716 274167 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
717 274167 : if ( ism_mode == ISM_MODE_DISC )
718 : {
719 222899 : if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
720 6562 : ( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
721 : {
722 7534 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
723 : }
724 :
725 222899 : hSCE[ch]->element_brate = element_brate[ch];
726 : }
727 51268 : else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
728 : {
729 10514 : if ( ism_imp[ch] == ISM_INACTIVE_IMP )
730 : {
731 0 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
732 : }
733 : }
734 :
735 274167 : hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
736 :
737 : /* write metadata only in active frames */
738 274167 : if ( hSCE[0]->hCoreCoder[0]->core_brate > SID_2k40 )
739 : {
740 0 : reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot );
741 : }
742 : }
743 :
744 106869 : pop_wmops();
745 :
746 106869 : return error;
747 : }
748 :
749 :
750 : /*-------------------------------------------------------------------------
751 : * ivas_ism_metadata_enc_create()
752 : *
753 : * Create, allocate, initialize and configure IVAS encoder ISM metadata handles
754 : *-------------------------------------------------------------------------*/
755 :
756 155 : ivas_error ivas_ism_metadata_enc_create(
757 : Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
758 : const int16_t n_ISms, /* i : number of objects */
759 : int32_t element_brate_tmp[] /* o : element bitrate per object */
760 : )
761 : {
762 : int16_t ch, nchan_transport;
763 : ivas_error error;
764 :
765 155 : nchan_transport = st_ivas->nchan_transport;
766 155 : if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
767 : {
768 44 : nchan_transport = MAX_PARAM_ISM_WAVE;
769 44 : ivas_set_omasa_TC( st_ivas->ism_mode, n_ISms, &st_ivas->nSCE, &st_ivas->nCPE );
770 : }
771 111 : else if ( st_ivas->hEncoderConfig->ivas_format == SBA_ISM_FORMAT )
772 : {
773 37 : nchan_transport = n_ISms;
774 : }
775 : else
776 : {
777 74 : if ( st_ivas->ism_mode == ISM_MODE_NONE )
778 : {
779 0 : nchan_transport = st_ivas->nchan_transport;
780 :
781 0 : if ( nchan_transport == 1 )
782 : {
783 0 : st_ivas->nSCE = 1;
784 0 : st_ivas->nCPE = 0;
785 : }
786 : else
787 : {
788 0 : st_ivas->nSCE = 0;
789 0 : st_ivas->nCPE = 1;
790 : }
791 : }
792 74 : else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
793 : {
794 17 : nchan_transport = 2;
795 : }
796 : else
797 : {
798 57 : nchan_transport = n_ISms;
799 : }
800 :
801 74 : st_ivas->nchan_transport = nchan_transport;
802 74 : st_ivas->nSCE = nchan_transport;
803 74 : st_ivas->nCPE = 0;
804 : }
805 :
806 : /* allocate ISM metadata handles */
807 620 : for ( ch = 0; ch < n_ISms; ch++ )
808 : {
809 465 : if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
810 : {
811 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
812 : }
813 465 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0;
814 465 : st_ivas->hIsmMetaData[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
815 465 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 0;
816 465 : st_ivas->hIsmMetaData[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX - 1;
817 465 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0;
818 465 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle1_diff_cnt = ISM_FEC_MAX - 2;
819 465 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 0;
820 465 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle2_diff_cnt = ISM_FEC_MAX - 2;
821 465 : st_ivas->hIsmMetaData[ch]->last_radius_idx = 0;
822 465 : st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2;
823 465 : st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
824 :
825 465 : st_ivas->hIsmMetaData[ch]->ism_imp = -1;
826 465 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
827 465 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
828 465 : st_ivas->hIsmMetaData[ch]->q_azimuth_old = 0.0f;
829 465 : st_ivas->hIsmMetaData[ch]->q_elevation_old = 0.0f;
830 :
831 465 : ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
832 :
833 465 : st_ivas->hIsmMetaData[ch]->last_azimuth = 0.0f;
834 465 : st_ivas->hIsmMetaData[ch]->last_elevation = 0.0f;
835 :
836 465 : st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0.0f;
837 465 : st_ivas->hIsmMetaData[ch]->last_true_elevation = 0.0f;
838 465 : st_ivas->hIsmMetaData[ch]->ism_md_fec_cnt_enc = 0;
839 465 : st_ivas->hIsmMetaData[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
840 465 : st_ivas->hIsmMetaData[ch]->last_true_radius = 1.0f;
841 : }
842 :
843 155 : if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
844 : {
845 44 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
846 : {
847 20 : if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, 1, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
848 : {
849 0 : return error;
850 : }
851 : }
852 24 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
853 : {
854 17 : if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
855 : {
856 0 : return error;
857 : }
858 : }
859 : }
860 : else
861 : {
862 111 : if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK )
863 : {
864 0 : return error;
865 : }
866 : }
867 :
868 155 : return IVAS_ERR_OK;
869 : }
870 :
871 :
872 : /*-------------------------------------------------------------------------
873 : * encode_radius()
874 : *
875 : * Radius index encoding
876 : *-------------------------------------------------------------------------*/
877 :
878 25625 : static void encode_radius(
879 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
880 : int16_t *last_radius_idx, /* i/o: last radius index */
881 : int16_t *radius_diff_cnt, /* i/o: radius diff coding counter */
882 : const int16_t last_ism_metadata_flag, /* last frame ism_metadata_flag */
883 : const int16_t idx_radius_abs, /* i : Azimuth index */
884 : int16_t *flag_abs_radius /* o : Radius encoding mode */
885 : )
886 : {
887 : int16_t idx_radius, nbits_diff_radius, diff;
888 :
889 25625 : idx_radius = idx_radius_abs;
890 25625 : nbits_diff_radius = 0;
891 25625 : *flag_abs_radius = 0; /* differential coding by default */
892 :
893 25625 : if ( *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) */
894 23791 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
895 : )
896 : {
897 2184 : *flag_abs_radius = 1;
898 : }
899 :
900 25625 : diff = idx_radius_abs - *last_radius_idx;
901 :
902 : /* try differential coding */
903 25625 : if ( *flag_abs_radius == 0 )
904 : {
905 23441 : if ( diff == 0 )
906 : {
907 15315 : idx_radius = 0;
908 15315 : nbits_diff_radius = 1;
909 : }
910 8126 : else if ( ABSVAL( diff ) <= ISM_MAX_RADIUS_DIFF_IDX )
911 : {
912 3098 : idx_radius = 1 << 1;
913 3098 : nbits_diff_radius = 1;
914 :
915 3098 : if ( diff < 0 )
916 : {
917 1428 : idx_radius += 1; /* negative sign */
918 1428 : diff *= -1;
919 : }
920 : else
921 : {
922 1670 : idx_radius += 0; /* positive sign */
923 : }
924 :
925 3098 : idx_radius = idx_radius << diff;
926 3098 : nbits_diff_radius++;
927 :
928 : /* unary coding of "diff */
929 3098 : idx_radius += ( ( 1 << diff ) - 1 );
930 3098 : nbits_diff_radius += diff;
931 :
932 3098 : if ( nbits_diff_radius < ISM_RADIUS_NBITS )
933 : {
934 : /* add stop bit */
935 2911 : idx_radius = idx_radius << 1;
936 2911 : nbits_diff_radius++;
937 : }
938 : }
939 : else
940 : {
941 5028 : *flag_abs_radius = 1;
942 : }
943 : }
944 :
945 : /* update counter */
946 25625 : if ( *flag_abs_radius == 0 )
947 : {
948 18413 : ( *radius_diff_cnt )++;
949 18413 : *radius_diff_cnt = min( *radius_diff_cnt, ISM_FEC_MAX );
950 : }
951 : else
952 : {
953 7212 : *radius_diff_cnt = 0;
954 : }
955 :
956 : /* Write radius */
957 25625 : push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 );
958 :
959 25625 : if ( *flag_abs_radius )
960 : {
961 7212 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS );
962 : }
963 : else
964 : {
965 18413 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius );
966 : }
967 :
968 : /* Updates */
969 25625 : *last_radius_idx = idx_radius_abs;
970 :
971 25625 : return;
972 : }
973 :
974 :
975 : /*----------------------------------------------------------------*
976 : * encode_angle_indices()
977 : *
978 : * Encoding of an angle
979 : *----------------------------------------------------------------*/
980 :
981 398211 : static void encode_angle_indices(
982 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
983 : ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */
984 : const int16_t last_ism_metadata_flag, /* i : last frame ism_metadata_flag */
985 : const int16_t ini_frame, /* i : initialization frames counter */
986 : const int16_t idx_angle1_abs, /* i : Azimuth index */
987 : const int16_t idx_angle2_abs, /* i : Elevation index */
988 : int16_t *flag_abs_angle1, /* o : Azimuth/yaw encoding mode */
989 : int16_t *flag_abs_angle2 /* o : Elevation/pitch encoding mode */
990 : )
991 : {
992 : int16_t idx_angle1, nbits_diff_angle1, diff;
993 : int16_t idx_angle2, nbits_diff_angle2;
994 :
995 : /*----------------------------------------------------------------*
996 : * Azimuth/yaw index encoding
997 : *----------------------------------------------------------------*/
998 :
999 398211 : idx_angle1 = idx_angle1_abs;
1000 :
1001 398211 : nbits_diff_angle1 = 0;
1002 :
1003 398211 : *flag_abs_angle1 = 0; /* differential coding by default */
1004 398211 : if ( 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) */
1005 370706 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1006 : )
1007 : {
1008 34087 : *flag_abs_angle1 = 1;
1009 : }
1010 :
1011 : /* try differential coding */
1012 398211 : if ( *flag_abs_angle1 == 0 )
1013 : {
1014 364124 : diff = idx_angle1_abs - angle->last_angle1_idx;
1015 :
1016 : /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
1017 364124 : if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX )
1018 : {
1019 3996 : if ( diff > 0 )
1020 : {
1021 1447 : diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1022 : }
1023 : else
1024 : {
1025 2549 : diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1026 : }
1027 : }
1028 :
1029 364124 : if ( diff == 0 )
1030 : {
1031 62131 : idx_angle1 = 0;
1032 62131 : nbits_diff_angle1 = 1;
1033 : }
1034 301993 : else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */
1035 : {
1036 209539 : idx_angle1 = 1 << 1;
1037 209539 : nbits_diff_angle1 = 1;
1038 :
1039 209539 : if ( diff < 0 )
1040 : {
1041 68454 : idx_angle1 += 1; /* negative sign */
1042 68454 : diff *= -1;
1043 : }
1044 : else
1045 : {
1046 141085 : idx_angle1 += 0; /* positive sign */
1047 : }
1048 :
1049 209539 : idx_angle1 = idx_angle1 << diff;
1050 209539 : nbits_diff_angle1++;
1051 :
1052 : /* unary coding of "diff */
1053 209539 : idx_angle1 += ( ( 1 << diff ) - 1 );
1054 209539 : nbits_diff_angle1 += diff;
1055 :
1056 209539 : if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 )
1057 : {
1058 : /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */
1059 191731 : idx_angle1 = idx_angle1 << 1;
1060 191731 : nbits_diff_angle1++;
1061 : }
1062 : }
1063 : else
1064 : {
1065 92454 : *flag_abs_angle1 = 1;
1066 : }
1067 : }
1068 :
1069 : /* update counter */
1070 398211 : if ( *flag_abs_angle1 == 0 )
1071 : {
1072 271670 : angle->angle1_diff_cnt++;
1073 271670 : angle->angle1_diff_cnt = min( angle->angle1_diff_cnt, ISM_FEC_MAX );
1074 : }
1075 : else
1076 : {
1077 126541 : angle->angle1_diff_cnt = 0;
1078 : }
1079 :
1080 : /* Write azimuth/yaw */
1081 398211 : push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 );
1082 :
1083 398211 : if ( *flag_abs_angle1 )
1084 : {
1085 126541 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS );
1086 : }
1087 : else
1088 : {
1089 271670 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 );
1090 : }
1091 :
1092 : /*----------------------------------------------------------------*
1093 : * Elevation/pitch index encoding
1094 : *----------------------------------------------------------------*/
1095 :
1096 398211 : if ( flag_abs_angle2 )
1097 : {
1098 397406 : idx_angle2 = idx_angle2_abs;
1099 397406 : nbits_diff_angle2 = 0;
1100 397406 : *flag_abs_angle2 = 0; /* differential coding by default */
1101 397406 : if ( 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) */
1102 282318 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1103 : )
1104 : {
1105 115705 : *flag_abs_angle2 = 1;
1106 : }
1107 :
1108 : /* note: elevation/pitch is coded starting from the second frame only (it is meaningless in the init_frame) */
1109 397406 : if ( ini_frame == 0 )
1110 : {
1111 1377 : *flag_abs_angle2 = 1;
1112 1377 : angle->last_angle2_idx = idx_angle2_abs;
1113 : }
1114 :
1115 397406 : diff = idx_angle2_abs - angle->last_angle2_idx;
1116 :
1117 : /* avoid absolute coding of elevation/pitch if absolute coding was already used for azimuth/yaw */
1118 397406 : if ( *flag_abs_angle1 == 1 )
1119 : {
1120 126466 : int16_t diff_orig = diff;
1121 :
1122 126466 : *flag_abs_angle2 = 0;
1123 :
1124 :
1125 126466 : if ( diff >= 0 )
1126 : {
1127 79202 : diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX );
1128 : }
1129 : else
1130 : {
1131 47264 : diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX );
1132 : }
1133 :
1134 126466 : if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX )
1135 : {
1136 48670 : angle->angle2_diff_cnt = ISM_FEC_MAX - 1;
1137 : }
1138 : }
1139 :
1140 : /* try differential coding */
1141 397406 : if ( *flag_abs_angle2 == 0 )
1142 : {
1143 368497 : if ( diff == 0 )
1144 : {
1145 149539 : idx_angle2 = 0;
1146 149539 : nbits_diff_angle2 = 1;
1147 : }
1148 218958 : else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX )
1149 : {
1150 214547 : idx_angle2 = 1 << 1;
1151 214547 : nbits_diff_angle2 = 1;
1152 :
1153 214547 : if ( diff < 0 )
1154 : {
1155 107514 : idx_angle2 += 1; /* negative sign */
1156 107514 : diff *= -1;
1157 : }
1158 : else
1159 : {
1160 107033 : idx_angle2 += 0; /* positive sign */
1161 : }
1162 :
1163 214547 : idx_angle2 = idx_angle2 << diff;
1164 214547 : nbits_diff_angle2++;
1165 :
1166 : /* unary coding of "diff */
1167 214547 : idx_angle2 += ( ( 1 << diff ) - 1 );
1168 214547 : nbits_diff_angle2 += diff;
1169 :
1170 214547 : if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS )
1171 : {
1172 : /* add stop bit */
1173 142343 : idx_angle2 = idx_angle2 << 1;
1174 142343 : nbits_diff_angle2++;
1175 : }
1176 : }
1177 : else
1178 : {
1179 4411 : *flag_abs_angle2 = 1;
1180 : }
1181 : }
1182 :
1183 : /* update counter */
1184 397406 : if ( *flag_abs_angle2 == 0 )
1185 : {
1186 364086 : angle->angle2_diff_cnt++;
1187 364086 : angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX );
1188 : }
1189 : else
1190 : {
1191 33320 : angle->angle2_diff_cnt = 0;
1192 : }
1193 :
1194 : /* Write elevation */
1195 397406 : if ( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */
1196 : {
1197 270940 : push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 );
1198 : }
1199 :
1200 397406 : if ( *flag_abs_angle2 )
1201 : {
1202 33320 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS );
1203 : }
1204 : else
1205 : {
1206 364086 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 );
1207 : }
1208 : }
1209 :
1210 : /*----------------------------------------------------------------*
1211 : * Updates
1212 : *----------------------------------------------------------------*/
1213 :
1214 398211 : angle->last_angle1_idx = idx_angle1_abs;
1215 398211 : angle->last_angle2_idx = idx_angle2_abs;
1216 :
1217 398211 : return;
1218 : }
1219 :
1220 :
1221 : /*-------------------------------------------------------------------*
1222 : * ivas_ism_metadata_sid_enc()
1223 : *
1224 : * Quantize and encode ISM metadata in SID frame
1225 : *-------------------------------------------------------------------*/
1226 :
1227 2153 : void ivas_ism_metadata_sid_enc(
1228 : ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */
1229 : const int16_t flag_noisy_speech, /* i : noisy speech flag */
1230 : const int16_t nchan_ism, /* i : number of objects */
1231 : const int16_t nchan_transport, /* i : number of transport channels */
1232 : const ISM_MODE ism_mode, /* i : ISM mode */
1233 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
1234 : const int16_t sid_flag, /* i : indication of SID frame */
1235 : const int16_t md_diff_flag[], /* i : metadata differental flag */
1236 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
1237 : int16_t nb_bits_metadata[] /* o : number of metadata bits */
1238 : )
1239 : {
1240 : int16_t i, ch, nBits, nBits_start, nBits_unused;
1241 : float q_step, q_step_border;
1242 : int16_t idx, idx_azimuth, idx_elevation;
1243 : int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
1244 : float valQ;
1245 : ISM_METADATA_HANDLE hIsmMetaData;
1246 :
1247 2153 : if ( sid_flag )
1248 : {
1249 555 : nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
1250 555 : nBits -= SID_FORMAT_NBITS;
1251 555 : nBits_start = hBstr->nb_bits_tot;
1252 :
1253 : /*----------------------------------------------------------------*
1254 : * Write ISm common signaling
1255 : *----------------------------------------------------------------*/
1256 :
1257 : /* write number of objects - unary coding */
1258 1833 : for ( ch = 1; ch < nchan_ism; ch++ )
1259 : {
1260 1278 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
1261 : }
1262 555 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
1263 :
1264 : /* write SID metadata flag (one per object) */
1265 2388 : for ( ch = 0; ch < nchan_ism; ch++ )
1266 : {
1267 1833 : push_indice( hBstr, IND_ISM_METADATA_FLAG, md_diff_flag[ch], 1 );
1268 : }
1269 :
1270 : /*----------------------------------------------------------------*
1271 : * Set quantization bits based on the number of coded objects
1272 : *----------------------------------------------------------------*/
1273 :
1274 555 : ivas_get_ism_sid_quan_bitbudget( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step, &q_step_border, &nBits_coh, &nBits_sce_id );
1275 :
1276 : /*----------------------------------------------------------------*
1277 : * Spatial parameters, loop over TCs - 1
1278 : *----------------------------------------------------------------*/
1279 :
1280 : /* write ISM mode flag to explicitly signal number of spatial parameters */
1281 555 : if ( nchan_ism > 2 )
1282 : {
1283 389 : if ( ism_mode == ISM_MODE_DISC )
1284 : {
1285 282 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 );
1286 : }
1287 : else
1288 : {
1289 107 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 );
1290 : }
1291 :
1292 389 : if ( ism_mode == ISM_MODE_PARAM )
1293 : {
1294 : /* write noisy speech flag */
1295 107 : push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 );
1296 107 : nBits_sce_id = 1;
1297 : }
1298 : }
1299 :
1300 555 : if ( nchan_transport > 1 )
1301 : {
1302 : /* write sce id */
1303 500 : push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id );
1304 :
1305 : /* quantize and write coherence */
1306 2064 : for ( ch = 0; ch < nchan_transport; ch++ )
1307 : {
1308 1564 : if ( ch == hISMDTX->sce_id_dtx )
1309 : {
1310 500 : continue;
1311 : }
1312 :
1313 1064 : idx = (int16_t) ( hISMDTX->coh[ch] * ( ( 1 << nBits_coh ) - 1 ) + 0.5f );
1314 1064 : assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) );
1315 1064 : push_indice( hBstr, IND_ISM_DTX_COH_SCA, idx, nBits_coh );
1316 : }
1317 : }
1318 :
1319 : /*----------------------------------------------------------------*
1320 : * Metadata quantization and coding, loop over all objects
1321 : *----------------------------------------------------------------*/
1322 :
1323 2388 : for ( ch = 0; ch < nchan_ism; ch++ )
1324 : {
1325 1833 : if ( md_diff_flag[ch] == 1 )
1326 : {
1327 647 : hIsmMetaData = hIsmMeta[ch];
1328 :
1329 647 : idx_azimuth = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth );
1330 647 : idx_elevation = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation );
1331 :
1332 647 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth );
1333 647 : push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation );
1334 :
1335 : /* update last indexes to correspond to active frames coding */
1336 647 : if ( nBits_azimuth > ISM_AZIMUTH_NBITS )
1337 : {
1338 210 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS );
1339 210 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS );
1340 : }
1341 : else
1342 : {
1343 437 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth );
1344 437 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation );
1345 : }
1346 :
1347 647 : hIsmMetaData->ism_md_fec_cnt_enc = 0;
1348 647 : hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
1349 : }
1350 : }
1351 :
1352 : /* Write unused (padding) bits */
1353 555 : nBits_unused = nBits - hBstr->nb_bits_tot;
1354 1614 : while ( nBits_unused > 0 )
1355 : {
1356 1059 : i = min( nBits_unused, 16 );
1357 1059 : push_indice( hBstr, IND_UNUSED, 0, i );
1358 1059 : nBits_unused -= i;
1359 : }
1360 :
1361 555 : nb_bits_metadata[0] = hBstr->nb_bits_tot - nBits_start;
1362 : }
1363 :
1364 2153 : return;
1365 : }
|