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 3417040 : 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 3417040 : if ( hIsmMeta == NULL )
91 : {
92 0 : return IVAS_ERR_UNEXPECTED_NULL_POINTER;
93 : }
94 :
95 3417040 : hIsmMeta->ism_metadata_flag = 1;
96 :
97 : /* save read metadata parameters to the internal codec structure */
98 3417040 : hIsmMeta->azimuth = azimuth;
99 3417040 : hIsmMeta->elevation = elevation;
100 3417040 : hIsmMeta->radius = radius_meta;
101 3417040 : hIsmMeta->yaw = yaw;
102 3417040 : hIsmMeta->pitch = pitch;
103 3417040 : hIsmMeta->non_diegetic_flag = non_diegetic_flag;
104 :
105 3417040 : return IVAS_ERR_OK;
106 : }
107 :
108 :
109 : /*-------------------------------------------------------------------------*
110 : * rate_ism_importance()
111 : *
112 : * Rate importance of particular ISM streams
113 : *-------------------------------------------------------------------------*/
114 :
115 601929 : 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 2210580 : for ( ch = 0; ch < nchan_transport; ch++ )
126 : {
127 1608651 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
128 :
129 1608651 : if ( hSCE[ch]->hCoreCoder[0]->tcxonly )
130 : {
131 573390 : if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
132 : {
133 294663 : ctype = INACTIVE;
134 : }
135 278727 : else if ( ctype == UNVOICED )
136 : {
137 22815 : ctype = GENERIC;
138 : }
139 : }
140 :
141 1608651 : if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
142 : {
143 392491 : ism_imp[ch] = ISM_NO_META;
144 : }
145 1216160 : else if ( ctype == INACTIVE || ctype == UNVOICED )
146 : {
147 332775 : ism_imp[ch] = ISM_LOW_IMP;
148 : }
149 883385 : else if ( ctype == VOICED )
150 : {
151 360606 : ism_imp[ch] = ISM_MEDIUM_IMP;
152 : }
153 : else /* GENERIC */
154 : {
155 522779 : ism_imp[ch] = ISM_HIGH_IMP;
156 : }
157 : }
158 :
159 601929 : return;
160 : }
161 :
162 :
163 : /*-------------------------------------------------------------------------*
164 : * ivas_ism_metadata_enc()
165 : *
166 : * quantize and encode ISM metadata
167 : *-------------------------------------------------------------------------*/
168 :
169 928642 : 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 928642 : 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 928642 : int16_t idx_angle1_abs = 0;
190 928642 : 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 928642 : 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 928642 : error = IVAS_ERR_OK;
206 928642 : push_wmops( "ism_meta_enc" );
207 :
208 : /* initialization */
209 928642 : ism_metadata_flag_global = 0;
210 928642 : non_diegetic_flag_global = 0;
211 928642 : set_s( nb_bits_metadata, 0, nchan_transport );
212 928642 : set_s( flag_abs_azimuth, 0, nchan_ism );
213 928642 : set_s( flag_abs_elevation, 0, nchan_ism );
214 928642 : set_s( flag_abs_yaw, 0, nchan_ism );
215 928642 : set_s( flag_abs_pitch, 0, nchan_ism );
216 928642 : set_s( flag_abs_radius, 0, nchan_ism );
217 928642 : set_s( null_metadata_flag, 0, nchan_ism );
218 928642 : set_s( lowrate_metadata_flag, 0, nchan_ism );
219 :
220 928642 : 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 148000 : 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 3159488 : for ( ch = 0; ch < nchan_ism; ch++ )
235 : {
236 2378846 : if ( ism_mode == ISM_MODE_PARAM )
237 : {
238 448638 : hIsmMeta[ch]->ism_metadata_flag = 1;
239 : }
240 1930208 : else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC )
241 : {
242 1930208 : null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
243 :
244 1930208 : if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
245 : {
246 1888311 : 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 1323290 : 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 1888311 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
254 : {
255 366272 : if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
256 241834 : ( 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 133356 : lowrate_metadata_flag[ch] = 1;
260 :
261 133356 : hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
262 : }
263 232916 : else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
264 : {
265 :
266 159373 : lowrate_metadata_flag[ch] = 1;
267 :
268 159373 : if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
269 : {
270 63287 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
271 : }
272 : else
273 : {
274 96086 : hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
275 : }
276 : }
277 73543 : else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
278 : {
279 9103 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
280 9103 : lowrate_metadata_flag[ch] = 1;
281 :
282 9103 : 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 780642 : if ( ism_mode != ISM_SBA_MODE_DISC )
294 : {
295 601929 : rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
296 : }
297 : }
298 :
299 : /*----------------------------------------------------------------*
300 : * Write ISM common signaling
301 : *----------------------------------------------------------------*/
302 :
303 928642 : 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 1813825 : for ( ch = 1; ch < nchan_ism; ch++ )
307 : {
308 1211896 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
309 : }
310 601929 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
311 : }
312 :
313 3616988 : for ( ch = 0; ch < nchan_ism; ch++ )
314 : {
315 2688346 : ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag;
316 2688346 : ism_metadata_flag_global |= lowrate_metadata_flag[ch];
317 2688346 : non_diegetic_flag_global |= hIsmMeta[ch]->non_diegetic_flag;
318 : }
319 :
320 : /* write extended metadata presence flag */
321 928642 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
322 : {
323 521209 : push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
324 :
325 : /* Write global non-diegetic object flag */
326 521209 : if ( ism_extended_metadata_flag )
327 : {
328 56456 : 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 3411814 : for ( ch = 0; ch < nchan_transport; ch++ )
334 : {
335 2483172 : 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 309500 : hIsmMeta[ch]->ism_imp = ism_imp[ch];
339 309500 : hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
340 309500 : hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
341 : }
342 : else
343 : {
344 2173672 : if ( null_metadata_flag[ch] )
345 : {
346 : /* signal NULL metadata frame */
347 41897 : 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 41897 : if ( ism_mode != ISM_SBA_MODE_DISC )
351 : {
352 41897 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
353 41897 : 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 2131775 : else if ( ism_mode != ISM_SBA_MODE_DISC )
361 : {
362 1566754 : push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
363 :
364 1566754 : if ( ism_imp[ch] == ISM_NO_META )
365 : {
366 : /* signal low-rate ISM_NO_META frame */
367 366272 : 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 366272 : 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 565021 : push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 );
377 : }
378 : }
379 : }
380 :
381 :
382 928642 : if ( ism_metadata_flag_global )
383 : {
384 : /*----------------------------------------------------------------*
385 : * Metadata quantization and coding, loop over all objects
386 : *----------------------------------------------------------------*/
387 :
388 922542 : int16_t total_bits_metadata = 0;
389 922542 : int16_t bits_metadata_ism = 0;
390 : int16_t nb_bits_objcod_written;
391 :
392 922542 : if ( ism_mode == ISM_MODE_PARAM )
393 : {
394 121732 : nb_bits_start = hBstr->nb_bits_tot;
395 : }
396 :
397 3601062 : for ( ch = 0; ch < nchan_ism; ch++ )
398 : {
399 2678520 : hIsmMetaData = hIsmMeta[ch];
400 2678520 : 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 2229882 : nb_bits_start = hBstr->nb_bits_tot;
403 : }
404 :
405 2678520 : if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
406 : {
407 : /*----------------------------------------------------------------*
408 : * Quantize and encode azimuth and elevation
409 : *----------------------------------------------------------------*/
410 :
411 2568133 : if ( ism_extended_metadata_flag && non_diegetic_flag_global )
412 : {
413 : /* Write non-diegetic flag for each object */
414 8785 : push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS );
415 : }
416 :
417 2568133 : if ( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag )
418 : {
419 : /* Map azimuth to panning range [-90:90] */
420 4235 : if ( hIsmMetaData->azimuth > 90.0f )
421 : {
422 1123 : hIsmMetaData->azimuth = 180.0f - hIsmMetaData->azimuth;
423 : }
424 :
425 4235 : if ( hIsmMetaData->azimuth < -90.0f )
426 : {
427 1095 : hIsmMetaData->azimuth = -180.0f - hIsmMetaData->azimuth;
428 : }
429 :
430 4235 : 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 4235 : 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 2563898 : 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 2115260 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
439 2115260 : 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 448638 : idx_angle1_abs = hParamIsm->azi_index[ch];
444 448638 : idx_angle2_abs = hParamIsm->ele_index[ch];
445 : }
446 :
447 2563898 : 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 2563898 : if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_extended_metadata_flag )
453 : {
454 176841 : idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
455 176841 : idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
456 176841 : idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS );
457 :
458 176841 : 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 176841 : 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 2568133 : 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 2119495 : nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start;
467 : }
468 :
469 : /* Updates */
470 2568133 : hIsmMeta[ch]->last_true_azimuth = hIsmMeta[ch]->azimuth;
471 2568133 : hIsmMeta[ch]->last_true_elevation = hIsmMeta[ch]->elevation;
472 2568133 : 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 922542 : i = 0;
482 1845084 : 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 922542 : num = min( INTER_OBJECT_PARAM_CHECK, nchan_ism - i * INTER_OBJECT_PARAM_CHECK );
488 922542 : i++;
489 :
490 922542 : set_s( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
491 :
492 3182066 : for ( ch = 0; ch < num; ch++ )
493 : {
494 2259524 : if ( flag_abs_azimuth[ch] == 1 )
495 : {
496 899540 : abs_matrice[ch * ISM_NUM_PARAM] = 1;
497 : }
498 :
499 2259524 : if ( flag_abs_elevation[ch] == 1 )
500 : {
501 154334 : abs_matrice[ch * ISM_NUM_PARAM + 1] = 1;
502 : }
503 : }
504 922542 : abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
505 :
506 922542 : abs_first = 0;
507 1265443 : while ( abs_num > 1 )
508 : {
509 : /* find first "1" entry */
510 1208437 : while ( abs_matrice[abs_first] == 0 )
511 : {
512 865536 : abs_first++;
513 : }
514 :
515 : /* find next "1" entry */
516 342901 : abs_next = abs_first + 1;
517 2147458 : while ( abs_matrice[abs_next] == 0 )
518 : {
519 1804557 : abs_next++;
520 : }
521 :
522 : /* find "0" position */
523 342901 : pos_zero = 0;
524 514573 : while ( abs_matrice[pos_zero] == 1 )
525 : {
526 171672 : pos_zero++;
527 : }
528 :
529 342901 : ch = abs_next / ISM_NUM_PARAM;
530 :
531 342901 : if ( abs_next % ISM_NUM_PARAM == 0 )
532 : {
533 319344 : hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1;
534 : }
535 :
536 342901 : if ( abs_next % ISM_NUM_PARAM == 1 )
537 : {
538 23557 : 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 342901 : abs_first++;
543 342901 : abs_num--;
544 : }
545 : }
546 :
547 922542 : if ( ism_mode == ISM_SBA_MODE_DISC )
548 : {
549 : int16_t md_diff_flag[MAX_NUM_OBJECTS];
550 :
551 178713 : set_s( md_diff_flag, 1, nchan_ism );
552 743734 : for ( ch = 0; ch < nchan_ism; ch++ )
553 : {
554 565021 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
555 :
556 565021 : 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 565021 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
564 : }
565 565021 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
566 565021 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
567 : }
568 :
569 178713 : update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag );
570 :
571 178713 : pop_wmops();
572 178713 : return error;
573 : }
574 743829 : 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 121732 : push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 );
579 :
580 : /* Loop over multiwave to write the object indices into bitstream */
581 365196 : for ( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
582 : {
583 2921568 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
584 : {
585 5356208 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
586 : {
587 2678104 : 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 1460784 : for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
594 : {
595 2678104 : for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
596 : {
597 1339052 : push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS );
598 : }
599 : }
600 :
601 : /* total metadata bits */
602 121732 : total_bits_metadata = hBstr->nb_bits_tot - nb_bits_start;
603 :
604 : /* bits per ISM*/
605 121732 : bits_metadata_ism = (int16_t) ( total_bits_metadata / nchan_transport );
606 :
607 : /* Divide the metadata bits into n_Isms*/
608 121732 : nb_bits_objcod_written = 0;
609 365196 : for ( ch = 0; ch < nchan_transport; ch++ )
610 : {
611 243464 : if ( ch == nchan_transport - 1 )
612 : {
613 121732 : nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_written;
614 : }
615 : else
616 : {
617 121732 : nb_bits_metadata[ch] = bits_metadata_ism;
618 121732 : nb_bits_objcod_written += bits_metadata_ism;
619 : }
620 : }
621 : }
622 : }
623 6100 : 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 749929 : 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 148000 : ism_total_brate_ref = *ism_total_brate;
639 148000 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism );
640 :
641 148000 : bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC );
642 148000 : set_s( bits_element, bits_ism / nchan_ism, nchan_ism );
643 148000 : bits_element[nchan_ism - 1] += bits_ism % nchan_ism;
644 148000 : bitbudget_to_brate( bits_element, element_brate, nchan_ism );
645 :
646 148000 : *ism_total_brate = 0;
647 457500 : for ( ch = 0; ch < nchan_ism; ch++ )
648 : {
649 309500 : *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag );
650 :
651 309500 : if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 )
652 : {
653 4352 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
654 : }
655 :
656 309500 : 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 148000 : ism_metadata_flag_global = 1;
662 :
663 148000 : if ( ism_mode == ISM_MASA_MODE_DISC )
664 : {
665 86500 : brate_limit_flag = 0;
666 334500 : for ( int16_t n = 0; n < nchan_ism; n++ )
667 : {
668 248000 : brate_limit_flag += ism_imp[n];
669 : }
670 :
671 86500 : if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 )
672 : {
673 75346 : *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 749929 : if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
683 : {
684 148000 : 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 601929 : 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 2873254 : for ( ch = 0; ch < nchan_ism; ch++ )
698 : {
699 2123325 : hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
700 :
701 2123325 : if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
702 : {
703 422045 : hIsmMeta[ch]->ism_md_fec_cnt_enc++;
704 422045 : 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 1701280 : hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
709 : }
710 2123325 : hIsmMeta[ch]->ism_md_inc_diff_cnt++;
711 2123325 : hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
712 : }
713 :
714 2668080 : for ( ch = 0; ch < nchan_transport; ch++ )
715 : {
716 1918151 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
717 1918151 : if ( ism_mode == ISM_MODE_DISC )
718 : {
719 1365187 : if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
720 317451 : ( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
721 : {
722 242974 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
723 : }
724 :
725 1365187 : hSCE[ch]->element_brate = element_brate[ch];
726 : }
727 552964 : else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
728 : {
729 309500 : if ( ism_imp[ch] == ISM_INACTIVE_IMP )
730 : {
731 13876 : hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
732 : }
733 : }
734 :
735 1918151 : hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
736 :
737 : /* write metadata only in active frames */
738 1918151 : 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 749929 : pop_wmops();
745 :
746 749929 : 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 176841 : 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 176841 : idx_radius = idx_radius_abs;
890 176841 : nbits_diff_radius = 0;
891 176841 : *flag_abs_radius = 0; /* differential coding by default */
892 :
893 176841 : 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 167135 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
895 : )
896 : {
897 48629 : *flag_abs_radius = 1;
898 : }
899 :
900 176841 : diff = idx_radius_abs - *last_radius_idx;
901 :
902 : /* try differential coding */
903 176841 : if ( *flag_abs_radius == 0 )
904 : {
905 128212 : if ( diff == 0 )
906 : {
907 93199 : idx_radius = 0;
908 93199 : nbits_diff_radius = 1;
909 : }
910 35013 : else if ( ABSVAL( diff ) <= ISM_MAX_RADIUS_DIFF_IDX )
911 : {
912 5060 : idx_radius = 1 << 1;
913 5060 : nbits_diff_radius = 1;
914 :
915 5060 : if ( diff < 0 )
916 : {
917 2462 : idx_radius += 1; /* negative sign */
918 2462 : diff *= -1;
919 : }
920 : else
921 : {
922 2598 : idx_radius += 0; /* positive sign */
923 : }
924 :
925 5060 : idx_radius = idx_radius << diff;
926 5060 : nbits_diff_radius++;
927 :
928 : /* unary coding of "diff */
929 5060 : idx_radius += ( ( 1 << diff ) - 1 );
930 5060 : nbits_diff_radius += diff;
931 :
932 5060 : if ( nbits_diff_radius < ISM_RADIUS_NBITS )
933 : {
934 : /* add stop bit */
935 4047 : idx_radius = idx_radius << 1;
936 4047 : nbits_diff_radius++;
937 : }
938 : }
939 : else
940 : {
941 29953 : *flag_abs_radius = 1;
942 : }
943 : }
944 :
945 : /* update counter */
946 176841 : if ( *flag_abs_radius == 0 )
947 : {
948 98259 : ( *radius_diff_cnt )++;
949 98259 : *radius_diff_cnt = min( *radius_diff_cnt, ISM_FEC_MAX );
950 : }
951 : else
952 : {
953 78582 : *radius_diff_cnt = 0;
954 : }
955 :
956 : /* Write radius */
957 176841 : push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 );
958 :
959 176841 : if ( *flag_abs_radius )
960 : {
961 78582 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS );
962 : }
963 : else
964 : {
965 98259 : push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius );
966 : }
967 :
968 : /* Updates */
969 176841 : *last_radius_idx = idx_radius_abs;
970 :
971 176841 : return;
972 : }
973 :
974 :
975 : /*----------------------------------------------------------------*
976 : * encode_angle_indices()
977 : *
978 : * Encoding of an angle
979 : *----------------------------------------------------------------*/
980 :
981 2744974 : 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 2744974 : idx_angle1 = idx_angle1_abs;
1000 :
1001 2744974 : nbits_diff_angle1 = 0;
1002 :
1003 2744974 : *flag_abs_angle1 = 0; /* differential coding by default */
1004 2744974 : 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 2492890 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1006 : )
1007 : {
1008 524229 : *flag_abs_angle1 = 1;
1009 : }
1010 :
1011 : /* try differential coding */
1012 2744974 : if ( *flag_abs_angle1 == 0 )
1013 : {
1014 2220745 : 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 2220745 : if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX )
1018 : {
1019 23680 : if ( diff > 0 )
1020 : {
1021 8929 : diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1022 : }
1023 : else
1024 : {
1025 14751 : diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1;
1026 : }
1027 : }
1028 :
1029 2220745 : if ( diff == 0 )
1030 : {
1031 415804 : idx_angle1 = 0;
1032 415804 : nbits_diff_angle1 = 1;
1033 : }
1034 1804941 : else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */
1035 : {
1036 1265266 : idx_angle1 = 1 << 1;
1037 1265266 : nbits_diff_angle1 = 1;
1038 :
1039 1265266 : if ( diff < 0 )
1040 : {
1041 454675 : idx_angle1 += 1; /* negative sign */
1042 454675 : diff *= -1;
1043 : }
1044 : else
1045 : {
1046 810591 : idx_angle1 += 0; /* positive sign */
1047 : }
1048 :
1049 1265266 : idx_angle1 = idx_angle1 << diff;
1050 1265266 : nbits_diff_angle1++;
1051 :
1052 : /* unary coding of "diff */
1053 1265266 : idx_angle1 += ( ( 1 << diff ) - 1 );
1054 1265266 : nbits_diff_angle1 += diff;
1055 :
1056 1265266 : if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 )
1057 : {
1058 : /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */
1059 1159078 : idx_angle1 = idx_angle1 << 1;
1060 1159078 : nbits_diff_angle1++;
1061 : }
1062 : }
1063 : else
1064 : {
1065 539675 : *flag_abs_angle1 = 1;
1066 : }
1067 : }
1068 :
1069 : /* update counter */
1070 2744974 : if ( *flag_abs_angle1 == 0 )
1071 : {
1072 1681070 : angle->angle1_diff_cnt++;
1073 1681070 : angle->angle1_diff_cnt = min( angle->angle1_diff_cnt, ISM_FEC_MAX );
1074 : }
1075 : else
1076 : {
1077 1063904 : angle->angle1_diff_cnt = 0;
1078 : }
1079 :
1080 : /* Write azimuth/yaw */
1081 2744974 : push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 );
1082 :
1083 2744974 : if ( *flag_abs_angle1 )
1084 : {
1085 1063904 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS );
1086 : }
1087 : else
1088 : {
1089 1681070 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 );
1090 : }
1091 :
1092 : /*----------------------------------------------------------------*
1093 : * Elevation/pitch index encoding
1094 : *----------------------------------------------------------------*/
1095 :
1096 2744974 : if ( flag_abs_angle2 )
1097 : {
1098 2740739 : idx_angle2 = idx_angle2_abs;
1099 2740739 : nbits_diff_angle2 = 0;
1100 2740739 : *flag_abs_angle2 = 0; /* differential coding by default */
1101 2740739 : 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 1770014 : || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */
1103 : )
1104 : {
1105 975484 : *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 2740739 : if ( ini_frame == 0 )
1110 : {
1111 21181 : *flag_abs_angle2 = 1;
1112 21181 : angle->last_angle2_idx = idx_angle2_abs;
1113 : }
1114 :
1115 2740739 : 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 2740739 : if ( *flag_abs_angle1 == 1 )
1119 : {
1120 1061891 : int16_t diff_orig = diff;
1121 :
1122 1061891 : *flag_abs_angle2 = 0;
1123 :
1124 :
1125 1061891 : if ( diff >= 0 )
1126 : {
1127 686935 : diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX );
1128 : }
1129 : else
1130 : {
1131 374956 : diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX );
1132 : }
1133 :
1134 1061891 : if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX )
1135 : {
1136 587437 : angle->angle2_diff_cnt = ISM_FEC_MAX - 1;
1137 : }
1138 : }
1139 :
1140 : /* try differential coding */
1141 2740739 : if ( *flag_abs_angle2 == 0 )
1142 : {
1143 2553809 : if ( diff == 0 )
1144 : {
1145 1005621 : idx_angle2 = 0;
1146 1005621 : nbits_diff_angle2 = 1;
1147 : }
1148 1548188 : else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX )
1149 : {
1150 1513841 : idx_angle2 = 1 << 1;
1151 1513841 : nbits_diff_angle2 = 1;
1152 :
1153 1513841 : if ( diff < 0 )
1154 : {
1155 758076 : idx_angle2 += 1; /* negative sign */
1156 758076 : diff *= -1;
1157 : }
1158 : else
1159 : {
1160 755765 : idx_angle2 += 0; /* positive sign */
1161 : }
1162 :
1163 1513841 : idx_angle2 = idx_angle2 << diff;
1164 1513841 : nbits_diff_angle2++;
1165 :
1166 : /* unary coding of "diff */
1167 1513841 : idx_angle2 += ( ( 1 << diff ) - 1 );
1168 1513841 : nbits_diff_angle2 += diff;
1169 :
1170 1513841 : if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS )
1171 : {
1172 : /* add stop bit */
1173 1012766 : idx_angle2 = idx_angle2 << 1;
1174 1012766 : nbits_diff_angle2++;
1175 : }
1176 : }
1177 : else
1178 : {
1179 34347 : *flag_abs_angle2 = 1;
1180 : }
1181 : }
1182 :
1183 : /* update counter */
1184 2740739 : if ( *flag_abs_angle2 == 0 )
1185 : {
1186 2519462 : angle->angle2_diff_cnt++;
1187 2519462 : angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX );
1188 : }
1189 : else
1190 : {
1191 221277 : angle->angle2_diff_cnt = 0;
1192 : }
1193 :
1194 : /* Write elevation */
1195 2740739 : if ( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */
1196 : {
1197 1678848 : push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 );
1198 : }
1199 :
1200 2740739 : if ( *flag_abs_angle2 )
1201 : {
1202 221277 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS );
1203 : }
1204 : else
1205 : {
1206 2519462 : push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 );
1207 : }
1208 : }
1209 :
1210 : /*----------------------------------------------------------------*
1211 : * Updates
1212 : *----------------------------------------------------------------*/
1213 :
1214 2744974 : angle->last_angle1_idx = idx_angle1_abs;
1215 2744974 : angle->last_angle2_idx = idx_angle2_abs;
1216 :
1217 2744974 : return;
1218 : }
1219 :
1220 :
1221 : /*-------------------------------------------------------------------*
1222 : * ivas_ism_metadata_sid_enc()
1223 : *
1224 : * Quantize and encode ISM metadata in SID frame
1225 : *-------------------------------------------------------------------*/
1226 :
1227 11906 : 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 11906 : if ( sid_flag )
1248 : {
1249 2085 : nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
1250 2085 : nBits -= SID_FORMAT_NBITS;
1251 2085 : nBits_start = hBstr->nb_bits_tot;
1252 :
1253 : /*----------------------------------------------------------------*
1254 : * Write ISm common signaling
1255 : *----------------------------------------------------------------*/
1256 :
1257 : /* write number of objects - unary coding */
1258 4961 : for ( ch = 1; ch < nchan_ism; ch++ )
1259 : {
1260 2876 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
1261 : }
1262 2085 : push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
1263 :
1264 : /* write SID metadata flag (one per object) */
1265 7046 : for ( ch = 0; ch < nchan_ism; ch++ )
1266 : {
1267 4961 : 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 2085 : 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 2085 : if ( nchan_ism > 2 )
1282 : {
1283 923 : if ( ism_mode == ISM_MODE_DISC )
1284 : {
1285 655 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 );
1286 : }
1287 : else
1288 : {
1289 268 : push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 );
1290 : }
1291 :
1292 923 : if ( ism_mode == ISM_MODE_PARAM )
1293 : {
1294 : /* write noisy speech flag */
1295 268 : push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 );
1296 268 : nBits_sce_id = 1;
1297 : }
1298 : }
1299 :
1300 2085 : if ( nchan_transport > 1 )
1301 : {
1302 : /* write sce id */
1303 1127 : push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id );
1304 :
1305 : /* quantize and write coherence */
1306 4658 : for ( ch = 0; ch < nchan_transport; ch++ )
1307 : {
1308 3531 : if ( ch == hISMDTX->sce_id_dtx )
1309 : {
1310 1127 : continue;
1311 : }
1312 :
1313 2404 : idx = (int16_t) ( hISMDTX->coh[ch] * ( ( 1 << nBits_coh ) - 1 ) + 0.5f );
1314 2404 : assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) );
1315 2404 : 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 7046 : for ( ch = 0; ch < nchan_ism; ch++ )
1324 : {
1325 4961 : if ( md_diff_flag[ch] == 1 )
1326 : {
1327 2355 : hIsmMetaData = hIsmMeta[ch];
1328 :
1329 2355 : idx_azimuth = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth );
1330 2355 : idx_elevation = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation );
1331 :
1332 2355 : push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth );
1333 2355 : push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation );
1334 :
1335 : /* update last indexes to correspond to active frames coding */
1336 2355 : if ( nBits_azimuth > ISM_AZIMUTH_NBITS )
1337 : {
1338 1214 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS );
1339 1214 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS );
1340 : }
1341 : else
1342 : {
1343 1141 : hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth );
1344 1141 : hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation );
1345 : }
1346 :
1347 2355 : hIsmMetaData->ism_md_fec_cnt_enc = 0;
1348 2355 : hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
1349 : }
1350 : }
1351 :
1352 : /* Write unused (padding) bits */
1353 2085 : nBits_unused = nBits - hBstr->nb_bits_tot;
1354 6956 : while ( nBits_unused > 0 )
1355 : {
1356 4871 : i = min( nBits_unused, 16 );
1357 4871 : push_indice( hBstr, IND_UNUSED, 0, i );
1358 4871 : nBits_unused -= i;
1359 : }
1360 :
1361 2085 : nb_bits_metadata[0] = hBstr->nb_bits_tot - nBits_start;
1362 : }
1363 :
1364 11906 : return;
1365 : }
|