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