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 "options.h"
35 : #include <math.h>
36 : #include "ivas_prot_fx.h"
37 : #include "prot_fx.h"
38 : #include "cnst.h"
39 : #include "isar_cnst.h"
40 : #include "ivas_rom_rend.h"
41 : #include "ivas_rom_com.h"
42 : #include "isar_rom_post_rend.h"
43 : #include "ivas_rom_binauralRenderer.h"
44 : #include "lib_isar_post_rend.h"
45 : #include "isar_prot.h"
46 : #ifdef DEBUGGING
47 : #include "debug.h"
48 : #endif
49 : #include "wmc_auto.h"
50 : #include "basop_settings.h"
51 : #include "prot_fx.h"
52 :
53 : #include "basop_util.h"
54 :
55 :
56 : /*-------------------------------------------------------------------------
57 : * Function ivas_cmult_fix()
58 : *
59 : *
60 : *------------------------------------------------------------------------*/
61 :
62 0 : void ivas_cmult_fix(
63 : Word32 in1_re_fx,
64 : Word16 exp_re1,
65 : Word32 in1_im_fx,
66 : Word16 exp_im1,
67 : Word32 in2_re_fx,
68 : Word16 exp_re2,
69 : Word32 in2_im_fx,
70 : Word16 exp_im2,
71 : Word32 *out1_re_fx,
72 : Word32 *out1_im_fx,
73 : Word16 *exp_out1_re,
74 : Word16 *exp_out1_im )
75 : {
76 0 : Word16 shift_1 = W_norm( W_mult_32_32( in1_re_fx, in2_re_fx ) );
77 0 : Word16 shift_2 = W_norm( W_mult_32_32( in1_im_fx, in2_im_fx ) );
78 0 : Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_re_fx ), shift_1 ) );
79 0 : Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( in1_im_fx, in2_im_fx ), shift_2 ) );
80 0 : Word16 exp_tmp1 = 0;
81 0 : move16();
82 0 : *out1_re_fx = BASOP_Util_Add_Mant32Exp( tmp1, exp_re1 + exp_re2 - shift_1, L_negate( tmp2 ), exp_im1 + exp_im2 - shift_2, &exp_tmp1 );
83 0 : *exp_out1_re = exp_tmp1;
84 0 : Word16 shift_3 = W_norm( W_mult_32_32( in1_re_fx, in2_im_fx ) );
85 0 : Word16 shift_4 = W_norm( W_mult_32_32( in2_re_fx, in1_im_fx ) );
86 0 : Word32 tmp3 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_im_fx ), shift_3 ) );
87 0 : Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( in2_re_fx, in1_im_fx ), shift_4 ) );
88 0 : Word16 exp_tmp2 = 0;
89 0 : move16();
90 0 : *out1_im_fx = BASOP_Util_Add_Mant32Exp( tmp3, exp_re1 + exp_im2 - shift_3, tmp4, exp_re2 + exp_im1 - shift_4, &exp_tmp2 );
91 0 : *exp_out1_im = exp_tmp2;
92 0 : move16();
93 :
94 0 : return;
95 : }
96 :
97 :
98 0 : void ivas_calculate_abs_fx(
99 : Word32 re_fx,
100 : Word16 exp_re,
101 : Word32 im_fx,
102 : Word16 exp_im,
103 : Word32 *out_fx,
104 : Word16 *exp_out )
105 : {
106 0 : Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) );
107 0 : Word16 shift_2 = W_norm( W_mult_32_32( im_fx, im_fx ) );
108 0 : Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) );
109 0 : Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( im_fx, im_fx ), shift_2 ) );
110 0 : Word16 exp_tmp1 = 0;
111 0 : Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1, exp_re + exp_re - shift_1, tmp2, exp_im + exp_im - shift_2, &exp_tmp1 );
112 0 : *out_fx = Sqrt32( tmp3, &exp_tmp1 );
113 0 : *exp_out = exp_tmp1;
114 :
115 0 : return;
116 : }
117 :
118 :
119 0 : void ivas_calculate_rabs_fx(
120 : Word32 re_fx,
121 : Word16 exp_re,
122 : Word32 *out_fx,
123 : Word16 *exp_out )
124 : {
125 0 : Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) );
126 0 : Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) );
127 0 : Word16 exp_tmp1 = exp_re + exp_re - shift_1;
128 0 : Word32 tmp2 = Sqrt32( tmp1, &exp_tmp1 );
129 0 : *out_fx = tmp2;
130 0 : *exp_out = exp_tmp1;
131 :
132 0 : return;
133 : }
134 :
135 :
136 0 : void isar_mat_mult_2by2_complex_fx(
137 : Word32 in_re1_fx[2][2],
138 : Word16 exp_re1,
139 : Word32 in_im1_fx[2][2],
140 : Word16 exp_im1,
141 : Word32 in_re2_fx[2][2],
142 : Word16 exp_re2,
143 : Word32 in_im2_fx[2][2],
144 : Word16 exp_im2,
145 : Word32 out_re2_fx[2][2],
146 : Word16 *final_exp_re_1,
147 : Word32 out_im2_fx[2][2],
148 : Word16 *final_exp_im_1 )
149 : {
150 : Word16 i, j;
151 : Word32 tmp_re_fx, tmp_im_fx;
152 :
153 0 : Word16 exp_tmp1 = 0, exp_tmp2 = 0, exp_tmp3 = 0, exp_tmp4 = 0;
154 0 : Word16 final_exp_re = 0, final_exp_im = 0;
155 : Word16 BuffExp_re[2][2];
156 : Word16 BuffExp_im[2][2];
157 :
158 0 : FOR( i = 0; i < 2; i++ )
159 : {
160 0 : FOR( j = 0; j < 2; j++ )
161 : {
162 0 : ivas_cmult_fix( in_re1_fx[i][0], exp_re1, in_im1_fx[i][0], exp_im1, in_re2_fx[0][j], exp_re2, in_im2_fx[0][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 );
163 :
164 0 : out_re2_fx[i][j] = tmp_re_fx;
165 0 : move32();
166 0 : out_im2_fx[i][j] = tmp_im_fx;
167 0 : move32();
168 :
169 0 : ivas_cmult_fix( in_re1_fx[i][1], exp_re1, in_im1_fx[i][1], exp_im1, in_re2_fx[1][j], exp_re2, in_im2_fx[1][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp3, &exp_tmp4 );
170 :
171 0 : out_re2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_re2_fx[i][j], exp_tmp1, tmp_re_fx, exp_tmp3, &final_exp_re );
172 0 : move32();
173 0 : out_im2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_im2_fx[i][j], exp_tmp2, tmp_im_fx, exp_tmp4, &final_exp_im );
174 0 : move32();
175 :
176 0 : BuffExp_re[i][j] = final_exp_re;
177 0 : move16();
178 0 : BuffExp_im[i][j] = final_exp_im;
179 0 : move16();
180 : }
181 : }
182 :
183 0 : Word16 max_exp_re = 0;
184 0 : Word16 max_exp_im = 0;
185 0 : move16();
186 0 : move16();
187 0 : FOR( i = 0; i < 2; i++ )
188 : {
189 0 : FOR( j = 0; j < 2; j++ )
190 : {
191 0 : max_exp_re = s_max( max_exp_re, BuffExp_re[i][j] );
192 0 : max_exp_im = s_max( max_exp_im, BuffExp_im[i][j] );
193 : }
194 : }
195 :
196 0 : FOR( i = 0; i < 2; i++ )
197 : {
198 0 : FOR( j = 0; j < 2; j++ )
199 : {
200 0 : out_re2_fx[i][j] = L_shr( out_re2_fx[i][j], max_exp_re - BuffExp_re[i][j] );
201 0 : move32();
202 0 : out_im2_fx[i][j] = L_shr( out_im2_fx[i][j], max_exp_im - BuffExp_im[i][j] );
203 0 : move32();
204 : }
205 : }
206 0 : *final_exp_re_1 = max_exp_re;
207 0 : move16();
208 0 : *final_exp_im_1 = max_exp_im;
209 0 : move16();
210 :
211 0 : return;
212 : }
213 :
214 :
215 : /*-------------------------------------------------------------------------
216 : * Function ISAR_SPLIT_REND_BITStream_init()
217 : *
218 : *
219 : *------------------------------------------------------------------------*/
220 :
221 0 : void ISAR_SPLIT_REND_BITStream_init(
222 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
223 : const Word32 buf_len_bytes,
224 : UWord8 *pbuf )
225 : {
226 0 : pBits->bits_buf = pbuf;
227 0 : pBits->buf_len = buf_len_bytes;
228 0 : move32();
229 0 : pBits->bits_read = 0;
230 0 : move32();
231 0 : pBits->bits_written = 0;
232 0 : move32();
233 :
234 0 : return;
235 : }
236 :
237 :
238 : /*-------------------------------------------------------------------------
239 : * Function isar_split_rend_huffman_dec_init_min_max_len()
240 : *
241 : *
242 : *------------------------------------------------------------------------*/
243 :
244 0 : static void isar_split_rend_huffman_dec_init_min_max_len(
245 : isar_split_rend_huffman_cfg_t *p_huff_cfg )
246 : {
247 : Word16 i, code_len;
248 : const Word32 *codebook;
249 :
250 0 : codebook = p_huff_cfg->codebook;
251 :
252 0 : p_huff_cfg->min_len = p_huff_cfg->sym_len;
253 0 : move16();
254 0 : p_huff_cfg->max_len = 0;
255 0 : move16();
256 :
257 0 : FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
258 : {
259 0 : code_len = extract_l( codebook[1] );
260 0 : IF( GT_16( p_huff_cfg->min_len, code_len ) )
261 : {
262 0 : p_huff_cfg->min_len = code_len;
263 0 : move16();
264 : }
265 0 : IF( LT_16( p_huff_cfg->max_len, code_len ) )
266 : {
267 0 : p_huff_cfg->max_len = code_len;
268 0 : move16();
269 : }
270 0 : codebook = codebook + 3;
271 : }
272 :
273 0 : return;
274 : }
275 :
276 :
277 : /*-------------------------------------------------------------------------
278 : * Function is_idx_present()
279 : *
280 : *
281 : *------------------------------------------------------------------------*/
282 :
283 0 : static Word16 is_idx_present(
284 : Word16 *idx_list,
285 : const Word16 idx,
286 : const Word16 len )
287 : {
288 : Word16 i;
289 :
290 0 : FOR( i = 0; i < len; i++ )
291 : {
292 0 : IF( EQ_16( idx_list[i], idx ) )
293 : {
294 0 : return 1;
295 : }
296 : }
297 :
298 0 : return 0;
299 : }
300 :
301 :
302 : /*-------------------------------------------------------------------------
303 : * Function ivas_split_huff_get_idx_trav_list()
304 : *
305 : *
306 : *------------------------------------------------------------------------*/
307 :
308 0 : static void ivas_split_huff_get_idx_trav_list(
309 : Word16 *idx_list,
310 : isar_split_rend_huffman_cfg_t *p_huff_cfg )
311 : {
312 : Word16 i, j, min_idx;
313 : Word32 min_bits;
314 : const Word32 *codebook;
315 :
316 0 : FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
317 : {
318 0 : idx_list[i] = -1;
319 0 : move16();
320 : }
321 :
322 0 : FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
323 : {
324 0 : codebook = p_huff_cfg->codebook;
325 0 : min_bits = p_huff_cfg->max_len;
326 0 : move16();
327 0 : min_idx = -1;
328 0 : move16();
329 0 : FOR( j = 0; j < p_huff_cfg->sym_len; j++ )
330 : {
331 0 : test();
332 0 : IF( GE_32( min_bits, codebook[1] ) && EQ_16( is_idx_present( idx_list, j, i + 1 ), 0 ) )
333 : {
334 0 : min_bits = codebook[1];
335 0 : move16();
336 0 : min_idx = j;
337 0 : move16();
338 : }
339 0 : codebook += 3;
340 : }
341 0 : idx_list[i] = min_idx;
342 0 : move16();
343 : }
344 :
345 0 : return;
346 : }
347 :
348 :
349 : /*-------------------------------------------------------------------------
350 : * Function isar_split_rend_init_huff_cfg()
351 : *
352 : *
353 : *------------------------------------------------------------------------*/
354 :
355 0 : void isar_split_rend_init_huff_cfg(
356 : ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg )
357 : {
358 0 : pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0];
359 0 : pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
360 0 : move16();
361 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] );
362 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] );
363 0 : pHuff_cfg->pred_base2_code_len[0] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL;
364 0 : move16();
365 :
366 0 : pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0];
367 0 : pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
368 0 : move16();
369 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] );
370 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] );
371 0 : pHuff_cfg->pred_base2_code_len[1] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL;
372 0 : move16();
373 :
374 :
375 0 : pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0];
376 0 : pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS;
377 0 : move16();
378 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll );
379 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll );
380 0 : pHuff_cfg->pred_roll_base2_code_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL;
381 0 : move16();
382 :
383 0 : pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0];
384 0 : pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
385 0 : move16();
386 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd );
387 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd );
388 0 : pHuff_cfg->gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
389 0 : move16();
390 :
391 0 : pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0];
392 0 : pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
393 0 : move16();
394 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd );
395 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd );
396 0 : pHuff_cfg->p_gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
397 0 : move16();
398 :
399 0 : pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0];
400 0 : pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
401 0 : move16();
402 0 : isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff );
403 0 : ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff );
404 0 : pHuff_cfg->p_gd_diff_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
405 0 : move16();
406 :
407 0 : return;
408 : }
409 :
410 :
411 : /*-------------------------------------------------------------------------
412 : * Function set_fix_rotation_mat()
413 : *
414 : *
415 : *------------------------------------------------------------------------*/
416 :
417 0 : void set_fix_rotation_mat_fx(
418 : Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
419 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
420 : {
421 : Word32 cos_yaw, sin_yaw;
422 : Word16 pos_idx;
423 0 : Word16 ind = 0;
424 :
425 : // pMultiBinPoseData->relative_head_poses can take only take -30, -22.5, -15, 0, 15, 22.5 and 30 degrees.
426 : // cos(180 - theta) = cos(theta).
427 : // Need only 4 values in LUT
428 :
429 0 : FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ )
430 : {
431 0 : ind = extract_l( L_shr( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), Q22 ) );
432 :
433 0 : ind = shr( ind, 3 ); /* Values: 0, 1, 2 and 3 */
434 0 : cos_yaw = ivas_split_rend_fix_pos_rot_mat_cos_fx[ind]; /* Q31 */
435 0 : sin_yaw = 0;
436 :
437 0 : fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; /* Q31 */
438 0 : fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; /* Q31 */
439 0 : fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; /* Q31 */
440 0 : fix_pos_rot_mat[pos_idx][1][0] = L_negate( sin_yaw ); /* Q31 */
441 : }
442 :
443 0 : return;
444 : }
445 :
446 : /*-------------------------------------------------------------------------
447 : * Function set_pose_types()
448 : *
449 : *
450 : *------------------------------------------------------------------------*/
451 :
452 0 : void set_pose_types_fx(
453 : ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
454 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
455 : {
456 : Word16 pos_idx;
457 :
458 0 : FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
459 : {
460 0 : IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), EPSILON_FX ) )
461 : {
462 0 : pose_type[pos_idx] = ANY_YAW;
463 0 : move32();
464 : }
465 0 : ELSE IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][2] ), EPSILON_FX ) )
466 : {
467 0 : pose_type[pos_idx] = ANY_ROLL;
468 0 : move32();
469 : }
470 : ELSE
471 : {
472 0 : pose_type[pos_idx] = PITCH_ONLY;
473 0 : move32();
474 : }
475 : }
476 :
477 0 : return;
478 : }
479 :
480 :
481 : /*-------------------------------------------------------------------------
482 : * Function wrap_a()
483 : *
484 : *
485 : *------------------------------------------------------------------------*/
486 :
487 0 : Word16 wrap_a(
488 : Word16 val,
489 : const Word16 min_val,
490 : const Word16 max_val )
491 : {
492 0 : IF( LT_16( val, min_val ) )
493 : {
494 0 : val = add( add( sub( max_val, min_val ), val ), 1 );
495 : }
496 :
497 0 : IF( GT_16( val, max_val ) )
498 : {
499 0 : val = sub( sub( add( min_val, val ), max_val ), 1 );
500 : }
501 :
502 0 : return val;
503 : }
504 :
505 :
506 : /*-------------------------------------------------------------------------
507 : * Function isar_SplitRenderer_getdiagdiff()
508 : *
509 : *
510 : *------------------------------------------------------------------------*/
511 :
512 0 : void isar_SplitRenderer_getdiagdiff(
513 : Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
514 : Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
515 : const Word16 sign,
516 : const Word16 min_val,
517 : const Word16 max_val )
518 : {
519 0 : out_idx[0][0] = in_idx[0][0];
520 0 : move16();
521 0 : out_idx[0][1] = in_idx[0][1];
522 0 : move16();
523 : // DEPR_i_mult used instead of i_mult becuase it is not available
524 0 : out_idx[1][1] = add( in_idx[1][1], DEPR_i_mult( sign, out_idx[0][0] ) );
525 0 : move16();
526 0 : out_idx[1][1] = wrap_a( out_idx[1][1], min_val, max_val );
527 0 : move16();
528 0 : out_idx[1][0] = add( in_idx[1][0], DEPR_i_mult( sign, out_idx[0][1] ) );
529 0 : move16();
530 0 : out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val );
531 0 : move16();
532 :
533 0 : return;
534 : }
535 :
536 :
537 : /*-------------------------------------------------------------------------
538 : * Function ISAR_SPLIT_REND_BITStream_read_int32()
539 : *
540 : *
541 : *------------------------------------------------------------------------*/
542 :
543 0 : Word32 ISAR_SPLIT_REND_BITStream_read_int32(
544 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
545 : const Word32 bits )
546 : {
547 : Word32 val, k, bit_val;
548 :
549 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
550 : assert( ( pBits->bits_written - pBits->bits_read ) >= bits );
551 : assert( bits <= 32 );
552 : #endif
553 :
554 : /* write bit by bit */
555 0 : val = 0;
556 0 : move32();
557 0 : FOR( k = L_sub( bits, 1 ); k >= 0; k-- )
558 : {
559 0 : bit_val = NE_32( L_and( pBits->bits_buf[L_shr( pBits->bits_read, 3 )], ( L_shl( 1, (Word16) ( L_and( pBits->bits_read, 7 ) ) ) ) ), 0 );
560 0 : val = L_or( val, L_shl( bit_val, (Word16) k ) );
561 0 : pBits->bits_read = L_add( pBits->bits_read, 1 );
562 : }
563 :
564 0 : return val;
565 : }
566 :
567 :
568 : /*-------------------------------------------------------------------------
569 : * Function ISAR_SPLIT_REND_BITStream_write_int32()
570 : *
571 : *
572 : *------------------------------------------------------------------------*/
573 :
574 0 : void ISAR_SPLIT_REND_BITStream_write_int32(
575 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
576 : const Word32 val,
577 : const Word32 bits )
578 : {
579 : Word32 mask, k;
580 :
581 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
582 : /*protection check*/
583 : if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) )
584 : {
585 : assert( 0 );
586 : }
587 : #endif
588 :
589 0 : mask = L_shl( 1, extract_l( L_sub( bits, 1 ) ) );
590 : /* write bit by bit */
591 0 : FOR( k = 0; k < bits; k++ )
592 : {
593 0 : IF( L_and( val, mask ) )
594 : {
595 0 : pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_or( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) );
596 : }
597 : ELSE
598 : {
599 0 : pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_and( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], ~L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) );
600 : }
601 0 : pBits->bits_written++;
602 0 : mask = L_shr( mask, 1 );
603 : }
604 :
605 0 : return;
606 : }
607 :
608 :
609 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
610 : /*-------------------------------------------------------------------------
611 : * isar_log_cldfb2wav_data()
612 : *
613 : *
614 : *------------------------------------------------------------------------*/
615 :
616 : void isar_log_cldfb2wav_data(
617 : float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
618 : float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
619 : HANDLE_CLDFB_FILTER_BANK *cldfbSyn,
620 : const int16_t num_chs,
621 : const int16_t num_freq_bands,
622 : const int32_t output_Fs,
623 : const int16_t num_slots,
624 : const int16_t start_slot_idx,
625 : const char *filename )
626 : {
627 : float *RealBuffer[CLDFB_NO_COL_MAX];
628 : float *ImagBuffer[CLDFB_NO_COL_MAX];
629 : float pcm_out[BINAURAL_CHANNELS][L_FRAME48k];
630 : float *pPcm[BINAURAL_CHANNELS];
631 : float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
632 : float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
633 : int16_t sf, ch;
634 :
635 : assert( num_chs <= BINAURAL_CHANNELS );
636 : for ( ch = 0; ch < num_chs; ch++ )
637 : {
638 : for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
639 : {
640 : mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands );
641 : mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands );
642 : RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf];
643 : ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf];
644 : }
645 : cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] );
646 : pPcm[ch] = pcm_out[ch];
647 : }
648 : dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs );
649 :
650 : return;
651 : }
652 : #endif
653 :
654 :
655 : /*-------------------------------------------------------------------------
656 : * Function isar_get_split_rend_md_target_brate()
657 : *
658 : *
659 : *------------------------------------------------------------------------*/
660 :
661 0 : Word32 isar_get_split_rend_md_target_brate(
662 : const Word32 SplitRendBitRate,
663 : const Word16 pcm_out_flag )
664 : {
665 : Word32 md_bitrate;
666 :
667 0 : IF( EQ_16( pcm_out_flag, 1 ) )
668 : {
669 0 : md_bitrate = SplitRendBitRate;
670 0 : move32();
671 : }
672 : ELSE
673 : {
674 0 : SWITCH( SplitRendBitRate )
675 : {
676 0 : case SPLIT_REND_768k:
677 : {
678 0 : md_bitrate = 256000;
679 0 : move32();
680 0 : BREAK;
681 : }
682 0 : case SPLIT_REND_512k:
683 : {
684 0 : md_bitrate = 128000;
685 0 : move32();
686 0 : BREAK;
687 : }
688 0 : case SPLIT_REND_384k:
689 : {
690 0 : md_bitrate = 128000;
691 0 : move32();
692 0 : BREAK;
693 : }
694 0 : default:
695 : {
696 0 : return -1;
697 : }
698 : }
699 : }
700 :
701 0 : return md_bitrate;
702 : }
703 :
704 :
705 : /*-------------------------------------------------------------------------
706 : * Function isar_get_lcld_bitrate()
707 : *
708 : *
709 : *------------------------------------------------------------------------*/
710 :
711 0 : Word32 isar_get_lcld_bitrate(
712 : const Word32 SplitRendBitRate,
713 : const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode )
714 : {
715 0 : IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
716 : {
717 0 : SWITCH( SplitRendBitRate )
718 : {
719 0 : case SPLIT_REND_768k:
720 : {
721 0 : return IVAS_512k;
722 : }
723 0 : case SPLIT_REND_512k:
724 : {
725 0 : return IVAS_384k;
726 : }
727 0 : case SPLIT_REND_384k:
728 : {
729 0 : return IVAS_256k;
730 : }
731 0 : default:
732 : {
733 0 : assert( 0 );
734 : }
735 : }
736 : }
737 : ELSE
738 : {
739 0 : return SplitRendBitRate;
740 : }
741 :
742 : return -1;
743 : }
744 :
745 : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
746 : /*-------------------------------------------------------------------------
747 : * Function isar_get_lc3plus_bitrate()
748 : *
749 : *
750 : *------------------------------------------------------------------------*/
751 :
752 0 : Word32 isar_get_lc3plus_bitrate(
753 : const Word32 SplitRendBitRate,
754 : const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
755 : const Word32 nChannels,
756 : const Word32 codecFrameDurationUs )
757 : {
758 : Word32 bitrate;
759 0 : bitrate = isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode );
760 : /* Check for LC3plus LEA 48_6 LC3 compatibility mode signalling */
761 0 : test();
762 0 : test();
763 0 : test();
764 0 : if ( EQ_32( ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE, poseCorrectionMode ) && EQ_32( bitrate, 256000 ) && EQ_32( nChannels, 2 ) && EQ_32( codecFrameDurationUs, 10000 ) )
765 : {
766 0 : bitrate = 2 * 126000;
767 0 : move32();
768 : }
769 :
770 0 : return bitrate;
771 : }
772 :
773 : #endif
774 :
775 : /*-------------------------------------------------------------------------
776 : * Function isar_split_rend_validate_config()
777 : *
778 : *
779 : *------------------------------------------------------------------------*/
780 :
781 0 : ivas_error isar_split_rend_validate_config(
782 : const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
783 : const Word16 is_pcm_out )
784 : {
785 : /* Valid DOF range is 0-3 */
786 0 : test();
787 0 : IF( LT_16( pSplitRendConfig->dof, 0 ) || GT_16( pSplitRendConfig->dof, 3 ) )
788 : {
789 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Valid DOF range is 0-3" );
790 : }
791 :
792 : /* Only CLDFB pose correction supports HQ mode */
793 0 : test();
794 0 : IF( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) && NE_16( pSplitRendConfig->hq_mode, 0 ) )
795 : {
796 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" );
797 : }
798 :
799 : /* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */
800 0 : test();
801 0 : test();
802 0 : test();
803 0 : IF( ( EQ_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && NE_16( pSplitRendConfig->dof, 0 ) ) ||
804 : ( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && EQ_16( pSplitRendConfig->dof, 0 ) ) )
805 : {
806 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" );
807 : }
808 :
809 0 : IF( NE_16( pSplitRendConfig->codec_frame_size_ms, 0 ) ) /* 0 means "default for current codec", will be set to actual value at a later stage */
810 : {
811 0 : test();
812 0 : test();
813 0 : test();
814 0 : IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LCLD ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 20 ) )
815 : {
816 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" );
817 : }
818 :
819 0 : test();
820 0 : test();
821 0 : IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) )
822 : {
823 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" );
824 : }
825 : }
826 :
827 : /* Validate bitrate */
828 0 : IF( EQ_16( is_pcm_out, 0 ) )
829 : {
830 0 : SWITCH( pSplitRendConfig->splitRendBitRate )
831 : {
832 0 : case SPLIT_REND_256k:
833 0 : IF( NE_16( pSplitRendConfig->dof, 0 ) )
834 : {
835 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" );
836 : }
837 0 : BREAK;
838 0 : case SPLIT_REND_320k:
839 : /* Only valid with 0 DOF */
840 0 : IF( NE_16( pSplitRendConfig->dof, 0 ) )
841 : {
842 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" );
843 : }
844 0 : BREAK;
845 0 : case SPLIT_REND_384k:
846 : case SPLIT_REND_512k:
847 : case SPLIT_REND_768k:
848 : /* Always valid */
849 0 : BREAK;
850 0 : default:
851 0 : return IVAS_ERR_LC3PLUS_INVALID_BITRATE;
852 : }
853 : }
854 : ELSE
855 : {
856 0 : IF( EQ_16( pSplitRendConfig->dof, 1 ) )
857 : {
858 0 : IF( LT_32( pSplitRendConfig->splitRendBitRate, 34000 ) )
859 : {
860 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" );
861 : }
862 : }
863 0 : ELSE IF( EQ_16( pSplitRendConfig->dof, 2 ) )
864 : {
865 0 : IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) )
866 : {
867 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" );
868 : }
869 : }
870 0 : ELSE IF( EQ_16( pSplitRendConfig->dof, 3 ) )
871 : {
872 0 : IF( LT_32( pSplitRendConfig->splitRendBitRate, 82000 ) )
873 : {
874 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" );
875 : }
876 : }
877 : }
878 :
879 0 : return IVAS_ERR_OK;
880 : }
881 :
882 :
883 : /*-------------------------------------------------------------------------
884 : * Function isar_split_rend_get_quant_params()
885 : *
886 : *
887 : *------------------------------------------------------------------------*/
888 :
889 0 : void isar_split_rend_get_quant_params_fx(
890 : const Word16 num_md_bands,
891 : Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
892 : Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
893 : Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
894 : Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
895 : Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
896 : Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
897 : Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
898 : Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
899 : Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
900 : const Word16 ro_flag,
901 : Word16 *num_quant_strats )
902 : {
903 : Word16 q;
904 :
905 0 : *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS;
906 0 : move16();
907 :
908 0 : pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
909 0 : move16();
910 0 : pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31;
911 0 : move32();
912 0 : pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26;
913 0 : move32();
914 0 : FOR( q = 1; q < *num_quant_strats; q++ )
915 : {
916 0 : pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
917 0 : move16();
918 0 : pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31;
919 0 : move32();
920 0 : pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26;
921 0 : move32();
922 : }
923 :
924 0 : FOR( q = 0; q < *num_quant_strats; q++ )
925 : {
926 0 : pred_real_bands_yaw[q] = num_md_bands;
927 0 : move16();
928 0 : pred_real_bands_roll[q] = num_md_bands;
929 0 : move16();
930 : }
931 :
932 0 : IF( ro_flag )
933 : {
934 0 : FOR( q = 0; q < *num_quant_strats; q++ )
935 : {
936 0 : pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH;
937 0 : move16();
938 : }
939 : }
940 : ELSE
941 : {
942 0 : FOR( q = 0; q < *num_quant_strats - 2; q++ )
943 : {
944 0 : pred_imag_bands_yaw[q] = num_md_bands;
945 0 : move16();
946 : }
947 0 : pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH;
948 0 : move16();
949 0 : pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW;
950 0 : move16();
951 : }
952 :
953 0 : FOR( q = 0; q < *num_quant_strats; q++ )
954 : {
955 0 : pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH;
956 0 : move16();
957 : }
958 :
959 0 : FOR( q = 0; q < *num_quant_strats; q++ )
960 : {
961 0 : d_bands_yaw[q] = 0;
962 0 : move16();
963 0 : bands_pitch[q] = num_md_bands;
964 0 : move16();
965 : }
966 :
967 0 : return;
968 : }
969 :
970 : /*-------------------------------------------------------------------------
971 : * Function isar_renderSplitGetRot_axisNumBits()
972 : *
973 : *
974 : *------------------------------------------------------------------------*/
975 :
976 0 : Word16 isar_renderSplitGetRot_axisNumBits(
977 : const Word16 dof )
978 : {
979 : Word16 num_bits;
980 0 : IF( dof < 3 )
981 : {
982 0 : num_bits = 2;
983 : }
984 : ELSE
985 : {
986 0 : num_bits = 0;
987 : }
988 0 : return num_bits;
989 : }
990 :
991 : /*-------------------------------------------------------------------------
992 : * Function isar_renderSplitGetRot_axisFromCode()
993 : *
994 : *
995 : *------------------------------------------------------------------------*/
996 :
997 0 : ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
998 : const Word16 dof,
999 : const Word16 code )
1000 : {
1001 : ISAR_SPLIT_REND_ROT_AXIS rot_axis;
1002 :
1003 0 : IF( dof == 1 )
1004 : {
1005 0 : rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
1006 : }
1007 0 : else if ( dof == 2 )
1008 : {
1009 0 : IF( code == 0 )
1010 : {
1011 0 : rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
1012 : }
1013 : ELSE
1014 : {
1015 0 : rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH;
1016 : }
1017 : }
1018 : ELSE
1019 : {
1020 0 : rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS;
1021 : }
1022 :
1023 0 : return rot_axis;
1024 : }
1025 :
1026 : /*-------------------------------------------------------------------------
1027 : * Function isar_renderSplitGetCodeFromRot_axis()
1028 : *
1029 : *
1030 : *------------------------------------------------------------------------*/
1031 :
1032 0 : Word16 isar_renderSplitGetCodeFromRot_axis(
1033 : const Word16 dof,
1034 : const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
1035 : Word16 *num_bits )
1036 : {
1037 0 : Word16 code = 0;
1038 0 : IF( dof == 1 )
1039 : {
1040 0 : code = (Word16) rot_axis;
1041 : }
1042 0 : else if ( dof == 2 )
1043 : {
1044 0 : IF( rot_axis == DEFAULT_AXIS )
1045 : {
1046 0 : code = (Word16) rot_axis;
1047 : }
1048 : ELSE
1049 : {
1050 0 : code = (Word16) ( rot_axis - YAW_PITCH ) + 1;
1051 : }
1052 : }
1053 : ELSE
1054 : {
1055 0 : code = (Word16) DEFAULT_AXIS;
1056 : }
1057 0 : *num_bits = isar_renderSplitGetRot_axisNumBits( dof );
1058 :
1059 0 : return code;
1060 : }
1061 :
1062 : /*-------------------------------------------------------------------------
1063 : * Function isar_renderSplitGetMultiBinPoseData()
1064 : *
1065 : *
1066 : *------------------------------------------------------------------------*/
1067 :
1068 0 : void isar_renderSplitGetMultiBinPoseData_fx(
1069 : const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
1070 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1071 : const ISAR_SPLIT_REND_ROT_AXIS rot_axis )
1072 : {
1073 : Word16 pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses;
1074 : const Word32 *relative_yaw_angles;
1075 : const Word32 *relative_pitch_angles;
1076 : const Word32 *relative_roll_angles;
1077 :
1078 0 : FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
1079 : {
1080 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
1081 0 : move32();
1082 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
1083 0 : move32();
1084 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
1085 0 : move32();
1086 : }
1087 :
1088 : /* 0 DOF defaults */
1089 0 : num_yaw_poses = 0;
1090 0 : move16();
1091 0 : num_pitch_poses = 0;
1092 0 : move16();
1093 0 : num_roll_poses = 0;
1094 0 : move16();
1095 :
1096 : /* defaults for all DOF except 3DOF HQ */
1097 0 : relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx;
1098 0 : relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx;
1099 0 : relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx;
1100 :
1101 0 : IF( EQ_16( pSplit_rend_config->dof, 1 ) )
1102 : {
1103 0 : SWITCH( rot_axis )
1104 : {
1105 0 : case DEFAULT_AXIS:
1106 : case YAW:
1107 : {
1108 0 : num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
1109 0 : move16();
1110 0 : BREAK;
1111 : }
1112 0 : case PITCH:
1113 : {
1114 0 : num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
1115 0 : move16();
1116 0 : BREAK;
1117 : }
1118 0 : case ROLL:
1119 : {
1120 0 : num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
1121 0 : move16();
1122 0 : BREAK;
1123 : }
1124 0 : default:
1125 : {
1126 0 : assert( 0 && "unsupported rotation axis value" );
1127 : }
1128 : }
1129 : }
1130 0 : ELSE IF( EQ_16( pSplit_rend_config->dof, 2 ) )
1131 : {
1132 0 : SWITCH( rot_axis )
1133 : {
1134 0 : case DEFAULT_AXIS:
1135 : case YAW_PITCH:
1136 : {
1137 0 : num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
1138 0 : move16();
1139 0 : num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
1140 0 : move16();
1141 0 : BREAK;
1142 : }
1143 0 : case YAW_ROLL:
1144 : {
1145 0 : num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
1146 0 : move16();
1147 0 : num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
1148 0 : move16();
1149 0 : BREAK;
1150 : }
1151 0 : case PITCH_ROLL:
1152 : {
1153 0 : num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
1154 0 : move16();
1155 0 : num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
1156 0 : move16();
1157 0 : BREAK;
1158 : }
1159 0 : default:
1160 : {
1161 0 : assert( 0 && "unsupported rotation axis value" );
1162 : }
1163 : }
1164 : }
1165 0 : ELSE IF( EQ_16( pSplit_rend_config->dof, 3 ) )
1166 : {
1167 0 : IF( EQ_16( pSplit_rend_config->hq_mode, 1 ) )
1168 : {
1169 0 : relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx;
1170 0 : relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx;
1171 0 : relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx;
1172 0 : num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
1173 0 : move16();
1174 0 : num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
1175 0 : move16();
1176 0 : num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
1177 0 : move16();
1178 : }
1179 : ELSE
1180 : {
1181 0 : relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_fx;
1182 0 : relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_fx;
1183 0 : relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_fx;
1184 0 : num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
1185 0 : move16();
1186 0 : num_pitch_poses = 1;
1187 0 : move16();
1188 0 : num_roll_poses = 1;
1189 0 : move16();
1190 : }
1191 : }
1192 :
1193 0 : pMultiBinPoseData->num_poses = add( add( num_yaw_poses, num_pitch_poses ), add( num_roll_poses, 1 ) );
1194 0 : assert( LE_16( pMultiBinPoseData->num_poses, MAX_HEAD_ROT_POSES ) );
1195 :
1196 0 : FOR( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ )
1197 : {
1198 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] = relative_yaw_angles[pos_idx];
1199 0 : move32();
1200 : }
1201 :
1202 0 : FOR( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ )
1203 : {
1204 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx];
1205 0 : move32();
1206 : }
1207 :
1208 0 : FOR( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ )
1209 : {
1210 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx];
1211 0 : move32();
1212 : }
1213 0 : pMultiBinPoseData->dof = pSplit_rend_config->dof;
1214 0 : move16();
1215 0 : pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode;
1216 0 : move16();
1217 0 : pMultiBinPoseData->rot_axis = rot_axis;
1218 0 : move32();
1219 0 : pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode;
1220 0 : move32();
1221 :
1222 0 : return;
1223 : }
1224 :
1225 : /*-------------------------------------------------------------------------
1226 : * Function isar_renderSplitUpdateNoCorrectionPoseData()
1227 : *
1228 : *
1229 : *------------------------------------------------------------------------*/
1230 :
1231 0 : void isar_renderSplitUpdateNoCorrectionPoseData(
1232 : const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
1233 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
1234 : {
1235 0 : pMultiBinPoseData->num_poses = 1;
1236 0 : move16();
1237 0 : assert( pSplit_rend_config->dof == 0 );
1238 0 : pMultiBinPoseData->dof = pSplit_rend_config->dof;
1239 0 : move16();
1240 0 : assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE );
1241 0 : pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode;
1242 0 : move32();
1243 :
1244 0 : return;
1245 : }
1246 :
1247 :
1248 : /*-------------------------------------------------------------------------
1249 : * Function isar_init_multi_bin_pose_data()
1250 : *
1251 : *
1252 : *------------------------------------------------------------------------*/
1253 :
1254 0 : void isar_init_multi_bin_pose_data_fx(
1255 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
1256 : {
1257 : Word16 pos_idx;
1258 :
1259 0 : FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
1260 : {
1261 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
1262 0 : move32();
1263 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
1264 0 : move32();
1265 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
1266 0 : move32();
1267 : }
1268 0 : pMultiBinPoseData->num_poses = 1;
1269 0 : move16();
1270 0 : pMultiBinPoseData->dof = 3;
1271 0 : move16();
1272 0 : pMultiBinPoseData->hq_mode = 0;
1273 0 : move16();
1274 0 : pMultiBinPoseData->rot_axis = DEFAULT_AXIS;
1275 0 : move32();
1276 :
1277 0 : return;
1278 : }
1279 :
1280 : /* Copy for encoder, to be removed */
1281 0 : void isar_init_multi_bin_pose_data_fx_enc(
1282 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
1283 : {
1284 : Word16 pos_idx;
1285 :
1286 0 : FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
1287 : {
1288 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
1289 0 : move32();
1290 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
1291 0 : move32();
1292 0 : pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
1293 0 : move32();
1294 : }
1295 0 : pMultiBinPoseData->num_poses = 1;
1296 0 : move16();
1297 0 : pMultiBinPoseData->dof = 3;
1298 0 : move16();
1299 0 : pMultiBinPoseData->hq_mode = 0;
1300 0 : move16();
1301 0 : pMultiBinPoseData->rot_axis = DEFAULT_AXIS;
1302 0 : move32();
1303 :
1304 0 : return;
1305 : }
1306 :
1307 0 : ivas_error isar_framesize_to_ms(
1308 : const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
1309 : Word16 *ms /* o : frame size in ms */
1310 : )
1311 : {
1312 0 : switch ( frame_size )
1313 : {
1314 0 : case IVAS_RENDER_FRAMESIZE_5MS:
1315 0 : *ms = 5;
1316 0 : break;
1317 0 : case IVAS_RENDER_FRAMESIZE_10MS:
1318 0 : *ms = 10;
1319 0 : break;
1320 0 : case IVAS_RENDER_FRAMESIZE_20MS:
1321 0 : *ms = 20;
1322 0 : break;
1323 0 : default:
1324 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" );
1325 : }
1326 :
1327 0 : return IVAS_ERR_OK;
1328 : }
1329 :
1330 :
1331 : /*-------------------------------------------------------------------------
1332 : * Function isar_split_rend_choose_default_codec()
1333 : *
1334 : *
1335 : *------------------------------------------------------------------------*/
1336 :
1337 0 : ivas_error isar_split_rend_choose_default_codec(
1338 : ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
1339 : Word16 *pIsar_frame_size_ms, /* i/o: pointer to ISAR frame size setting */
1340 : Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */
1341 : const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */
1342 : const Word16 pcm_out_flag, /* i : flag to indicate PCM output */
1343 : const Word16 num_subframes /* i : number of subframes */
1344 : )
1345 : {
1346 0 : IF( EQ_16( pcm_out_flag, 0 ) )
1347 : {
1348 0 : IF( EQ_32( *pCodec, ISAR_SPLIT_REND_CODEC_DEFAULT ) )
1349 : {
1350 0 : *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS;
1351 0 : move32();
1352 : }
1353 : }
1354 : ELSE
1355 : {
1356 0 : *pCodec = ISAR_SPLIT_REND_CODEC_NONE;
1357 0 : move32();
1358 : }
1359 :
1360 0 : IF( EQ_16( *pCodec_frame_size_ms, 0 ) ) /* codec frame size hasn't been set yet - use default for current configuration */
1361 : {
1362 0 : SWITCH( *pCodec )
1363 : {
1364 0 : case ISAR_SPLIT_REND_CODEC_LCLD:
1365 0 : *pCodec_frame_size_ms = DEPR_i_mult( num_subframes, 5 );
1366 0 : BREAK;
1367 0 : case ISAR_SPLIT_REND_CODEC_LC3PLUS:
1368 : case ISAR_SPLIT_REND_CODEC_NONE:
1369 0 : *pCodec_frame_size_ms = 5;
1370 0 : move16();
1371 0 : BREAK;
1372 0 : default:
1373 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" );
1374 : }
1375 0 : }
1376 :
1377 0 : IF( *pIsar_frame_size_ms == 0 ) /* ISAR frame size hasn't been set yet - use default for current configuration */
1378 : {
1379 0 : *pIsar_frame_size_ms = 20;
1380 : }
1381 :
1382 0 : return IVAS_ERR_OK;
1383 : }
1384 :
1385 :
1386 : /*-------------------------------------------------------------------*
1387 : * Function get_bit()
1388 : *
1389 : *
1390 : *-------------------------------------------------------------------*/
1391 :
1392 0 : Word32 get_bit(
1393 : const Word32 state,
1394 : const Word32 bit_id )
1395 : {
1396 0 : return L_and( state, ( L_shl( 1, (Word16) bit_id ) ) );
1397 : }
|