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 4159636 : 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 4159636 : if ( hIsmMeta == NULL )
91 : {
92 0 : return IVAS_ERR_UNEXPECTED_NULL_POINTER;
93 : }
94 :
95 4159636 : hIsmMeta->ism_metadata_flag = 1;
96 :
97 : /* save read metadata parameters to the internal codec structure */
98 4159636 : hIsmMeta->azimuth = azimuth;
99 4159636 : hIsmMeta->elevation = elevation;
100 4159636 : hIsmMeta->radius = radius_meta;
101 4159636 : hIsmMeta->yaw = yaw;
102 4159636 : hIsmMeta->pitch = pitch;
103 4159636 : hIsmMeta->non_diegetic_flag = non_diegetic_flag;
104 :
105 4159636 : return IVAS_ERR_OK;
106 : }
107 :
108 :
109 : /*-------------------------------------------------------------------------*
110 : * rate_ism_importance()
111 : *
112 : * Rate importance of particular ISM streams
113 : *-------------------------------------------------------------------------*/
114 :
115 749765 : 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 2731271 : for ( ch = 0; ch < nchan_transport; ch++ )
126 : {
127 1981506 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
128 :
129 1981506 : if ( hSCE[ch]->hCoreCoder[0]->tcxonly )
130 : {
131 711263 : if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
132 : {
133 312400 : ctype = INACTIVE;
134 : }
135 398863 : else if ( ctype == UNVOICED )
136 : {
137 31204 : ctype = GENERIC;
138 : }
139 : }
140 :
141 1981506 : if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
142 : {
143 401974 : ism_imp[ch] = ISM_NO_META;
144 : }
145 1579532 : else if ( ctype == INACTIVE || ctype == UNVOICED )
146 : {
147 367278 : ism_imp[ch] = ISM_LOW_IMP;
148 : }
149 1212254 : else if ( ctype == VOICED )
150 : {
151 460780 : ism_imp[ch] = ISM_MEDIUM_IMP;
152 : }
153 : else /* GENERIC */
154 : {
155 751474 : ism_imp[ch] = ISM_HIGH_IMP;
156 : }
157 : }
158 :
159 749765 : return;
160 : }
161 :
162 :
163 : /*-------------------------------------------------------------------------*
164 : * ivas_ism_metadata_enc()
165 : *
166 : * quantize and encode ISM metadata
167 : *-------------------------------------------------------------------------*/
168 :
169 1138184 : 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 1138184 : 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 1138184 : int16_t idx_angle1_abs = 0;
190 1138184 : 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 1138184 : 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 1138184 : error = IVAS_ERR_OK;
206 1138184 : push_wmops( "ism_meta_enc" );
207 :
208 : /* initialization */
209 1138184 : ism_metadata_flag_global = 0;
210 1138184 : non_diegetic_flag_global = 0;
211 1138184 : set_s( nb_bits_metadata, 0, nchan_transport );
212 1138184 : set_s( flag_abs_azimuth, 0, nchan_ism );
213 1138184 : set_s( flag_abs_elevation, 0, nchan_ism );
214 1138184 : set_s( flag_abs_yaw, 0, nchan_ism );
215 1138184 : set_s( flag_abs_pitch, 0, nchan_ism );
216 1138184 : set_s( flag_abs_radius, 0, nchan_ism );
217 1138184 : set_s( null_metadata_flag, 0, nchan_ism );
218 1138184 : set_s( lowrate_metadata_flag, 0, nchan_ism );
219 :
220 1138184 : 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 164566 : 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 3903393 : for ( ch = 0; ch < nchan_ism; ch++ )
235 : {
236 2929775 : if ( ism_mode == ISM_MODE_PARAM )
237 : {
238 563326 : hIsmMeta[ch]->ism_metadata_flag = 1;
239 : }
240 2366449 : else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC )
241 : {
242 2366449 : null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
243 :
244 2366449 : if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
245 : {
246 2319882 : 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 1627201 : 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 2319882 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
254 : {
255 374002 : if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
256 242913 : ( 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 140120 : lowrate_metadata_flag[ch] = 1;
260 :
261 140120 : hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
262 : }
263 233882 : else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
264 : {
265 :
266 160000 : lowrate_metadata_flag[ch] = 1;
267 :
268 160000 : if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
269 : {
270 63528 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
271 : }
272 : else
273 : {
274 96472 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
275 : }
276 : }
277 73882 : else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
278 : {
279 9112 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
280 9112 : lowrate_metadata_flag[ch] = 1;
281 :
282 9112 : 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 973618 : if ( ism_mode != ISM_SBA_MODE_DISC )
294 : {
295 749765 : rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
296 : }
297 : }
298 :
299 : /*----------------------------------------------------------------*
300 : * Write ISM common signaling
301 : *----------------------------------------------------------------*/
302 :
303 1138184 : 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 2237094 : for ( ch = 1; ch < nchan_ism; ch++ )
307 : {
308 1487329 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
309 : }
310 749765 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
311 : }
312 :
313 4411223 : for ( ch = 0; ch < nchan_ism; ch++ )
314 : {
315 3273039 : ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag;
316 3273039 : ism_metadata_flag_global |= lowrate_metadata_flag[ch];
317 3273039 : non_diegetic_flag_global |= hIsmMeta[ch]->non_diegetic_flag;
318 : }
319 :
320 : /* write extended metadata presence flag */
321 1138184 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
322 : {
323 652777 : push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
324 :
325 : /* Write global non-diegetic object flag */
326 652777 : if ( ism_extended_metadata_flag )
327 : {
328 73382 : 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 4155635 : for ( ch = 0; ch < nchan_transport; ch++ )
334 : {
335 3017451 : 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 343264 : hIsmMeta[ch]->ism_imp = ism_imp[ch];
339 343264 : hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
340 343264 : hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
341 : }
342 : else
343 : {
344 2674187 : if ( null_metadata_flag[ch] )
345 : {
346 : /* signal NULL metadata frame */
347 46567 : 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 46567 : if ( ism_mode != ISM_SBA_MODE_DISC )
351 : {
352 46567 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
353 46567 : 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 2627620 : else if ( ism_mode != ISM_SBA_MODE_DISC )
361 : {
362 1934939 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
363 :
364 1934939 : if ( ism_imp[ch] == ISM_NO_META )
365 : {
366 : /* signal low-rate ISM_NO_META frame */
367 374002 : 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 374002 : 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 692681 : push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 );
377 : }
378 : }
379 : }
380 :
381 :
382 1138184 : if ( ism_metadata_flag_global )
383 : {
384 : /*----------------------------------------------------------------*
385 : * Metadata quantization and coding, loop over all objects
386 : *----------------------------------------------------------------*/
387 :
388 1132067 : int16_t total_bits_metadata = 0;
389 1132067 : int16_t bits_metadata_ism = 0;
390 : int16_t nb_bits_objcod_written;
391 :
392 1132067 : if ( ism_mode == ISM_MODE_PARAM )
393 : {
394 153869 : nb_bits_start = hBstr->nb_bits_tot;
395 : }
396 :
397 4395245 : for ( ch = 0; ch < nchan_ism; ch++ )
398 : {
399 3263178 : hIsmMetaData = hIsmMeta[ch];
400 3263178 : 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 2699852 : nb_bits_start = hBstr->nb_bits_tot;
403 : }
404 :
405 3263178 : if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
406 : {
407 : /*----------------------------------------------------------------*
408 : * Quantize and encode azimuth and elevation
409 : *----------------------------------------------------------------*/
410 :
411 3147826 : if ( ism_extended_metadata_flag && non_diegetic_flag_global )
412 : {
413 : /* Write non-diegetic flag for each object */
414 34420 : push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS );
415 : }
416 :
417 3147826 : if ( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag )
418 : {
419 : /* Map azimuth to panning range [-90:90] */
420 20640 : if ( hIsmMetaData->azimuth > 90.0f )
421 : {
422 6586 : hIsmMetaData->azimuth = 180.0f - hIsmMetaData->azimuth;
423 : }
424 :
425 20640 : if ( hIsmMetaData->azimuth < -90.0f )
426 : {
427 6864 : hIsmMetaData->azimuth = -180.0f - hIsmMetaData->azimuth;
428 : }
429 :
430 20640 : 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 20640 : 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 3127186 : 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 2563860 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
439 2563860 : 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 563326 : idx_angle1_abs = hParamIsm->azi_index[ch];
444 563326 : idx_angle2_abs = hParamIsm->ele_index[ch];
445 : }
446 :
447 3127186 : 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 3127186 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_extended_metadata_flag )
453 : {
454 211166 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
455 211166 : idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
456 211166 : idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS );
457 :
458 211166 : 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 211166 : 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 3147826 : 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 2584500 : nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start;
467 : }
468 :
469 : /* Updates */
470 3147826 : hIsmMeta[ch]->last_true_azimuth = hIsmMeta[ch]->azimuth;
471 3147826 : hIsmMeta[ch]->last_true_elevation = hIsmMeta[ch]->elevation;
472 3147826 : 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 1132067 : i = 0;
482 2264134 : 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 1132067 : num = min( INTER_OBJECT_PARAM_CHECK, nchan_ism - i * INTER_OBJECT_PARAM_CHECK );
488 1132067 : i++;
489 :
490 1132067 : set_s( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
491 :
492 3897276 : for ( ch = 0; ch < num; ch++ )
493 : {
494 2765209 : if ( flag_abs_azimuth[ch] == 1 )
495 : {
496 1084248 : abs_matrice[ch * ISM_NUM_PARAM] = 1;
497 : }
498 :
499 2765209 : if ( flag_abs_elevation[ch] == 1 )
500 : {
501 188254 : abs_matrice[ch * ISM_NUM_PARAM + 1] = 1;
502 : }
503 : }
504 1132067 : abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
505 :
506 1132067 : abs_first = 0;
507 1545332 : while ( abs_num > 1 )
508 : {
509 : /* find first "1" entry */
510 1457523 : while ( abs_matrice[abs_first] == 0 )
511 : {
512 1044258 : abs_first++;
513 : }
514 :
515 : /* find next "1" entry */
516 413265 : abs_next = abs_first + 1;
517 2569527 : while ( abs_matrice[abs_next] == 0 )
518 : {
519 2156262 : abs_next++;
520 : }
521 :
522 : /* find "0" position */
523 413265 : pos_zero = 0;
524 623704 : while ( abs_matrice[pos_zero] == 1 )
525 : {
526 210439 : pos_zero++;
527 : }
528 :
529 413265 : ch = abs_next / ISM_NUM_PARAM;
530 :
531 413265 : if ( abs_next % ISM_NUM_PARAM == 0 )
532 : {
533 385999 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1;
534 : }
535 :
536 413265 : if ( abs_next % ISM_NUM_PARAM == 1 )
537 : {
538 27266 : 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 413265 : abs_first++;
543 413265 : abs_num--;
544 : }
545 : }
546 :
547 1132067 : if ( ism_mode == ISM_SBA_MODE_DISC )
548 : {
549 : int16_t md_diff_flag[MAX_NUM_OBJECTS];
550 :
551 223853 : set_s( md_diff_flag, 1, nchan_ism );
552 916534 : for ( ch = 0; ch < nchan_ism; ch++ )
553 : {
554 692681 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
555 :
556 692681 : 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 692681 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
564 : }
565 692681 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
566 692681 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
567 : }
568 :
569 223853 : update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag );
570 :
571 223853 : pop_wmops();
572 223853 : return error;
573 : }
574 908214 : 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 153869 : push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 );
579 :
580 : /* Loop over multiwave to write the object indices into bitstream */
581 461607 : for ( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
582 : {
583 3692856 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
584 : {
585 6770236 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
586 : {
587 3385118 : 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 1846428 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
594 : {
595 3385118 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
596 : {
597 1692559 : push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS );
598 : }
599 : }
600 :
601 : /* total metadata bits */
602 153869 : total_bits_metadata = hBstr->nb_bits_tot - nb_bits_start;
603 :
604 : /* bits per ISM*/
605 153869 : bits_metadata_ism = (int16_t) ( total_bits_metadata / nchan_transport );
606 :
607 : /* Divide the metadata bits into n_Isms*/
608 153869 : nb_bits_objcod_written = 0;
609 461607 : for ( ch = 0; ch < nchan_transport; ch++ )
610 : {
611 307738 : if ( ch == nchan_transport - 1 )
612 : {
613 153869 : nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_written;
614 : }
615 : else
616 : {
617 153869 : nb_bits_metadata[ch] = bits_metadata_ism;
618 153869 : nb_bits_objcod_written += bits_metadata_ism;
619 : }
620 : }
621 : }
622 : }
623 6117 : 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 914331 : 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 164566 : ism_total_brate_ref = *ism_total_brate;
639 164566 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism );
640 :
641 164566 : bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC );
642 164566 : set_s( bits_element, bits_ism / nchan_ism, nchan_ism );
643 164566 : bits_element[nchan_ism - 1] += bits_ism % nchan_ism;
644 164566 : bitbudget_to_brate( bits_element, element_brate, nchan_ism );
645 :
646 164566 : *ism_total_brate = 0;
647 507830 : for ( ch = 0; ch < nchan_ism; ch++ )
648 : {
649 343264 : *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag );
650 :
651 343264 : if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 )
652 : {
653 4708 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
654 : }
655 :
656 343264 : if ( brate_limit_flag == -1 && ism_imp[ch] >= 1 && nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
657 : {
658 2791 : *ism_total_brate += ADJUST_ISM_BRATE_POS;
659 : }
660 : }
661 164566 : ism_metadata_flag_global = 1;
662 :
663 164566 : if ( ism_mode == ISM_MASA_MODE_DISC )
664 : {
665 99812 : brate_limit_flag = 0;
666 378322 : for ( int16_t n = 0; n < nchan_ism; n++ )
667 : {
668 278510 : brate_limit_flag += ism_imp[n];
669 : }
670 :
671 99812 : if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 )
672 : {
673 87807 : *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 914331 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
683 : {
684 164566 : 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 749765 : 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 3494689 : for ( ch = 0; ch < nchan_ism; ch++ )
698 : {
699 2580358 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
700 :
701 2580358 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
702 : {
703 434445 : hIsmMeta[ch]->ism_md_fec_cnt_enc++;
704 434445 : 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 2145913 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
709 : }
710 2580358 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
711 2580358 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
712 : }
713 :
714 3239101 : for ( ch = 0; ch < nchan_transport; ch++ )
715 : {
716 2324770 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
717 2324770 : if ( ism_mode == ISM_MODE_DISC )
718 : {
719 1673768 : if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
720 325146 : ( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
721 : {
722 251381 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
723 : }
724 :
725 1673768 : hSCE[ch]->element_brate = element_brate[ch];
726 : }
727 651002 : else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
728 : {
729 343264 : if ( ism_imp[ch] == ISM_INACTIVE_IMP )
730 : {
731 13876 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
732 : }
733 : }
734 :
735 2324770 : hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
736 :
737 : /* write metadata only in active frames */
738 2324770 : 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 914331 : pop_wmops();
745 :
746 914331 : 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 2192 : 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 2192 : nchan_transport = st_ivas->nchan_transport;
766 2192 : if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
767 : {
768 429 : nchan_transport = MAX_PARAM_ISM_WAVE;
769 429 : ivas_set_omasa_TC( st_ivas->ism_mode, n_ISms, &st_ivas->nSCE, &st_ivas->nCPE );
770 : }
771 1763 : else if ( st_ivas->hEncoderConfig->ivas_format == SBA_ISM_FORMAT )
772 : {
773 1087 : nchan_transport = n_ISms;
774 : }
775 : else
776 : {
777 676 : 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 676 : else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
793 : {
794 90 : nchan_transport = 2;
795 : }
796 : else
797 : {
798 586 : nchan_transport = n_ISms;
799 : }
800 :
801 676 : st_ivas->nchan_transport = nchan_transport;
802 676 : st_ivas->nSCE = nchan_transport;
803 676 : st_ivas->nCPE = 0;
804 : }
805 :
806 : /* allocate ISM metadata handles */
807 7902 : for ( ch = 0; ch < n_ISms; ch++ )
808 : {
809 5710 : 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 5710 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0;
814 5710 : st_ivas->hIsmMetaData[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
815 5710 : st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 0;
816 5710 : st_ivas->hIsmMetaData[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX - 1;
817 5710 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0;
818 5710 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle1_diff_cnt = ISM_FEC_MAX - 2;
819 5710 : st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 0;
820 5710 : st_ivas->hIsmMetaData[ch]->orientation_angle.angle2_diff_cnt = ISM_FEC_MAX - 2;
821 5710 : st_ivas->hIsmMetaData[ch]->last_radius_idx = 0;
822 5710 : st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2;
823 5710 : st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
824 :
825 5710 : st_ivas->hIsmMetaData[ch]->ism_imp = -1;
826 5710 : st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
827 5710 : st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
828 5710 : st_ivas->hIsmMetaData[ch]->q_azimuth_old = 0.0f;
829 5710 : st_ivas->hIsmMetaData[ch]->q_elevation_old = 0.0f;
830 :
831 5710 : ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
832 :
833 5710 : st_ivas->hIsmMetaData[ch]->last_azimuth = 0.0f;
834 5710 : st_ivas->hIsmMetaData[ch]->last_elevation = 0.0f;
835 :
836 5710 : st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0.0f;
837 5710 : st_ivas->hIsmMetaData[ch]->last_true_elevation = 0.0f;
838 5710 : st_ivas->hIsmMetaData[ch]->ism_md_fec_cnt_enc = 0;
839 5710 : st_ivas->hIsmMetaData[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
840 5710 : st_ivas->hIsmMetaData[ch]->last_true_radius = 1.0f;
841 : }
842 :
843 2192 : if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
844 : {
845 429 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
846 : {
847 103 : 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 326 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
853 : {
854 221 : 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 1763 : 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 2192 : return IVAS_ERR_OK;
869 : }
870 :
871 :
872 : /*-------------------------------------------------------------------------
873 : * encode_radius()
874 : *
875 : * Radius index encoding
876 : *-------------------------------------------------------------------------*/
877 :
878 211166 : 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 211166 : idx_radius = idx_radius_abs;
890 211166 : nbits_diff_radius = 0;
891 211166 : *flag_abs_radius = 0; /* differential coding by default */
892 :
893 211166 : 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 199104 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
895 : )
896 : {
897 51701 : *flag_abs_radius = 1;
898 : }
899 :
900 211166 : diff = idx_radius_abs - *last_radius_idx;
901 :
902 : /* try differential coding */
903 211166 : if ( *flag_abs_radius == 0 )
904 : {
905 159465 : if ( diff == 0 )
906 : {
907 116149 : idx_radius = 0;
908 116149 : nbits_diff_radius = 1;
909 : }
910 43316 : else if ( ABSVAL( diff ) <= ISM_MAX_RADIUS_DIFF_IDX )
911 : {
912 8326 : idx_radius = 1 << 1;
913 8326 : nbits_diff_radius = 1;
914 :
915 8326 : if ( diff < 0 )
916 : {
917 3890 : idx_radius += 1; /* negative sign */
918 3890 : diff *= -1;
919 : }
920 : else
921 : {
922 4436 : idx_radius += 0; /* positive sign */
923 : }
924 :
925 8326 : idx_radius = idx_radius << diff;
926 8326 : nbits_diff_radius++;
927 :
928 : /* unary coding of "diff */
929 8326 : idx_radius += ( ( 1 << diff ) - 1 );
930 8326 : nbits_diff_radius += diff;
931 :
932 8326 : if ( nbits_diff_radius < ISM_RADIUS_NBITS )
933 : {
934 : /* add stop bit */
935 7126 : idx_radius = idx_radius << 1;
936 7126 : nbits_diff_radius++;
937 : }
938 : }
939 : else
940 : {
941 34990 : *flag_abs_radius = 1;
942 : }
943 : }
944 :
945 : /* update counter */
946 211166 : if ( *flag_abs_radius == 0 )
947 : {
948 124475 : ( *radius_diff_cnt )++;
949 124475 : *radius_diff_cnt = min( *radius_diff_cnt, ISM_FEC_MAX );
950 : }
951 : else
952 : {
953 86691 : *radius_diff_cnt = 0;
954 : }
955 :
956 : /* Write radius */
957 211166 : push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 );
958 :
959 211166 : if ( *flag_abs_radius )
960 : {
961 86691 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS );
962 : }
963 : else
964 : {
965 124475 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius );
966 : }
967 :
968 : /* Updates */
969 211166 : *last_radius_idx = idx_radius_abs;
970 :
971 211166 : return;
972 : }
973 :
974 :
975 : /*----------------------------------------------------------------*
976 : * encode_angle_indices()
977 : *
978 : * Encoding of an angle
979 : *----------------------------------------------------------------*/
980 :
981 3358992 : 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 3358992 : idx_angle1 = idx_angle1_abs;
1000 :
1001 3358992 : nbits_diff_angle1 = 0;
1002 :
1003 3358992 : *flag_abs_angle1 = 0; /* differential coding by default */
1004 3358992 : 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 3065129 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1006 : )
1007 : {
1008 573982 : *flag_abs_angle1 = 1;
1009 : }
1010 :
1011 : /* try differential coding */
1012 3358992 : if ( *flag_abs_angle1 == 0 )
1013 : {
1014 2785010 : 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 2785010 : if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX )
1018 : {
1019 30490 : if ( diff > 0 )
1020 : {
1021 10691 : diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1022 : }
1023 : else
1024 : {
1025 19799 : diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1026 : }
1027 : }
1028 :
1029 2785010 : if ( diff == 0 )
1030 : {
1031 532784 : idx_angle1 = 0;
1032 532784 : nbits_diff_angle1 = 1;
1033 : }
1034 2252226 : else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */
1035 : {
1036 1555794 : idx_angle1 = 1 << 1;
1037 1555794 : nbits_diff_angle1 = 1;
1038 :
1039 1555794 : if ( diff < 0 )
1040 : {
1041 527884 : idx_angle1 += 1; /* negative sign */
1042 527884 : diff *= -1;
1043 : }
1044 : else
1045 : {
1046 1027910 : idx_angle1 += 0; /* positive sign */
1047 : }
1048 :
1049 1555794 : idx_angle1 = idx_angle1 << diff;
1050 1555794 : nbits_diff_angle1++;
1051 :
1052 : /* unary coding of "diff */
1053 1555794 : idx_angle1 += ( ( 1 << diff ) - 1 );
1054 1555794 : nbits_diff_angle1 += diff;
1055 :
1056 1555794 : if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 )
1057 : {
1058 : /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */
1059 1428670 : idx_angle1 = idx_angle1 << 1;
1060 1428670 : nbits_diff_angle1++;
1061 : }
1062 : }
1063 : else
1064 : {
1065 696432 : *flag_abs_angle1 = 1;
1066 : }
1067 : }
1068 :
1069 : /* update counter */
1070 3358992 : if ( *flag_abs_angle1 == 0 )
1071 : {
1072 2088578 : angle->angle1_diff_cnt++;
1073 2088578 : angle->angle1_diff_cnt = min( angle->angle1_diff_cnt, ISM_FEC_MAX );
1074 : }
1075 : else
1076 : {
1077 1270414 : angle->angle1_diff_cnt = 0;
1078 : }
1079 :
1080 : /* Write azimuth/yaw */
1081 3358992 : push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 );
1082 :
1083 3358992 : if ( *flag_abs_angle1 )
1084 : {
1085 1270414 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS );
1086 : }
1087 : else
1088 : {
1089 2088578 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 );
1090 : }
1091 :
1092 : /*----------------------------------------------------------------*
1093 : * Elevation/pitch index encoding
1094 : *----------------------------------------------------------------*/
1095 :
1096 3358992 : if ( flag_abs_angle2 )
1097 : {
1098 3338352 : idx_angle2 = idx_angle2_abs;
1099 3338352 : nbits_diff_angle2 = 0;
1100 3338352 : *flag_abs_angle2 = 0; /* differential coding by default */
1101 3338352 : 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 2182664 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1103 : )
1104 : {
1105 1164328 : *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 3338352 : if ( ini_frame == 0 )
1110 : {
1111 25810 : *flag_abs_angle2 = 1;
1112 25810 : angle->last_angle2_idx = idx_angle2_abs;
1113 : }
1114 :
1115 3338352 : 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 3338352 : if ( *flag_abs_angle1 == 1 )
1119 : {
1120 1262515 : int16_t diff_orig = diff;
1121 :
1122 1262515 : *flag_abs_angle2 = 0;
1123 :
1124 :
1125 1262515 : if ( diff >= 0 )
1126 : {
1127 810341 : diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX );
1128 : }
1129 : else
1130 : {
1131 452174 : diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX );
1132 : }
1133 :
1134 1262515 : if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX )
1135 : {
1136 673423 : angle->angle2_diff_cnt = ISM_FEC_MAX - 1;
1137 : }
1138 : }
1139 :
1140 : /* try differential coding */
1141 3338352 : if ( *flag_abs_angle2 == 0 )
1142 : {
1143 3108464 : if ( diff == 0 )
1144 : {
1145 1223189 : idx_angle2 = 0;
1146 1223189 : nbits_diff_angle2 = 1;
1147 : }
1148 1885275 : else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX )
1149 : {
1150 1845242 : idx_angle2 = 1 << 1;
1151 1845242 : nbits_diff_angle2 = 1;
1152 :
1153 1845242 : if ( diff < 0 )
1154 : {
1155 928627 : idx_angle2 += 1; /* negative sign */
1156 928627 : diff *= -1;
1157 : }
1158 : else
1159 : {
1160 916615 : idx_angle2 += 0; /* positive sign */
1161 : }
1162 :
1163 1845242 : idx_angle2 = idx_angle2 << diff;
1164 1845242 : nbits_diff_angle2++;
1165 :
1166 : /* unary coding of "diff */
1167 1845242 : idx_angle2 += ( ( 1 << diff ) - 1 );
1168 1845242 : nbits_diff_angle2 += diff;
1169 :
1170 1845242 : if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS )
1171 : {
1172 : /* add stop bit */
1173 1225743 : idx_angle2 = idx_angle2 << 1;
1174 1225743 : nbits_diff_angle2++;
1175 : }
1176 : }
1177 : else
1178 : {
1179 40033 : *flag_abs_angle2 = 1;
1180 : }
1181 : }
1182 :
1183 : /* update counter */
1184 3338352 : if ( *flag_abs_angle2 == 0 )
1185 : {
1186 3068431 : angle->angle2_diff_cnt++;
1187 3068431 : angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX );
1188 : }
1189 : else
1190 : {
1191 269921 : angle->angle2_diff_cnt = 0;
1192 : }
1193 :
1194 : /* Write elevation */
1195 3338352 : if ( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */
1196 : {
1197 2075837 : push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 );
1198 : }
1199 :
1200 3338352 : if ( *flag_abs_angle2 )
1201 : {
1202 269921 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS );
1203 : }
1204 : else
1205 : {
1206 3068431 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 );
1207 : }
1208 : }
1209 :
1210 : /*----------------------------------------------------------------*
1211 : * Updates
1212 : *----------------------------------------------------------------*/
1213 :
1214 3358992 : angle->last_angle1_idx = idx_angle1_abs;
1215 3358992 : angle->last_angle2_idx = idx_angle2_abs;
1216 :
1217 3358992 : return;
1218 : }
1219 :
1220 :
1221 : /*-------------------------------------------------------------------*
1222 : * ivas_ism_metadata_sid_enc()
1223 : *
1224 : * Quantize and encode ISM metadata in SID frame
1225 : *-------------------------------------------------------------------*/
1226 :
1227 14536 : 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 14536 : if ( sid_flag )
1248 : {
1249 2819 : nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
1250 2819 : nBits -= SID_FORMAT_NBITS;
1251 2819 : nBits_start = hBstr->nb_bits_tot;
1252 :
1253 : /*----------------------------------------------------------------*
1254 : * Write ISm common signaling
1255 : *----------------------------------------------------------------*/
1256 :
1257 : /* write number of objects - unary coding */
1258 7510 : for ( ch = 1; ch < nchan_ism; ch++ )
1259 : {
1260 4691 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
1261 : }
1262 2819 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
1263 :
1264 : /* write SID metadata flag (one per object) */
1265 10329 : for ( ch = 0; ch < nchan_ism; ch++ )
1266 : {
1267 7510 : 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 2819 : 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 2819 : if ( nchan_ism > 2 )
1282 : {
1283 1491 : if ( ism_mode == ISM_MODE_DISC )
1284 : {
1285 946 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 );
1286 : }
1287 : else
1288 : {
1289 545 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 );
1290 : }
1291 :
1292 1491 : if ( ism_mode == ISM_MODE_PARAM )
1293 : {
1294 : /* write noisy speech flag */
1295 545 : push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 );
1296 545 : nBits_sce_id = 1;
1297 : }
1298 : }
1299 :
1300 2819 : if ( nchan_transport > 1 )
1301 : {
1302 : /* write sce id */
1303 1806 : push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id );
1304 :
1305 : /* quantize and write coherence */
1306 7277 : for ( ch = 0; ch < nchan_transport; ch++ )
1307 : {
1308 5471 : if ( ch == hISMDTX->sce_id_dtx )
1309 : {
1310 1806 : continue;
1311 : }
1312 :
1313 3665 : idx = (int16_t) ( hISMDTX->coh[ch] * ( ( 1 << nBits_coh ) - 1 ) + 0.5f );
1314 3665 : assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) );
1315 3665 : 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 10329 : for ( ch = 0; ch < nchan_ism; ch++ )
1324 : {
1325 7510 : if ( md_diff_flag[ch] == 1 )
1326 : {
1327 3194 : hIsmMetaData = hIsmMeta[ch];
1328 :
1329 3194 : idx_azimuth = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth );
1330 3194 : idx_elevation = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation );
1331 :
1332 3194 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth );
1333 3194 : push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation );
1334 :
1335 : /* update last indexes to correspond to active frames coding */
1336 3194 : if ( nBits_azimuth > ISM_AZIMUTH_NBITS )
1337 : {
1338 1424 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS );
1339 1424 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS );
1340 : }
1341 : else
1342 : {
1343 1770 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth );
1344 1770 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation );
1345 : }
1346 :
1347 3194 : hIsmMetaData->ism_md_fec_cnt_enc = 0;
1348 3194 : hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
1349 : }
1350 : }
1351 :
1352 : /* Write unused (padding) bits */
1353 2819 : nBits_unused = nBits - hBstr->nb_bits_tot;
1354 9096 : while ( nBits_unused > 0 )
1355 : {
1356 6277 : i = min( nBits_unused, 16 );
1357 6277 : push_indice( hBstr, IND_UNUSED, 0, i );
1358 6277 : nBits_unused -= i;
1359 : }
1360 :
1361 2819 : nb_bits_metadata[0] = hBstr->nb_bits_tot - nBits_start;
1362 : }
1363 :
1364 14536 : return;
1365 : }
|