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 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
37 : #include <string.h>
38 : #endif
39 : #include "ivas_prot_fx.h"
40 : #include "prot_fx.h"
41 : #include "lib_isar_pre_rend.h"
42 : #include "isar_rom_post_rend.h"
43 : #include "isar_prot.h"
44 : #ifdef DEBUGGING
45 : #include "debug.h"
46 : #endif
47 : #include "wmc_auto.h"
48 : #ifdef DBG_WAV_WRITER
49 : #include "string.h"
50 : #endif
51 : #include "basop_util.h"
52 :
53 :
54 : /*-------------------------------------------------------------------------
55 : * Local functions
56 : *
57 : *
58 : *------------------------------------------------------------------------*/
59 :
60 0 : static void isar_calc_mat_det_2by2_complex_fx(
61 : Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
62 : Word16 exp_in_re,
63 : Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
64 : Word16 exp_in_im,
65 : Word32 *det_re,
66 : Word16 *exp_det_re,
67 : Word32 *det_im,
68 : Word16 *exp_det_im )
69 : {
70 : Word32 re1_fx, im1_fx, re2_fx, im2_fx;
71 :
72 0 : Word16 exp_re_1 = 0, exp_re_2 = 0;
73 0 : Word16 exp_im_1 = 0, exp_im_2 = 0;
74 0 : ivas_cmult_fix( in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re1_fx, &im1_fx, &exp_re_1, &exp_im_1 );
75 0 : ivas_cmult_fix( in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re2_fx, &im2_fx, &exp_re_2, &exp_im_2 );
76 :
77 0 : Word16 exp_re_final = 0, exp_im_final = 0;
78 0 : *det_re = BASOP_Util_Add_Mant32Exp( re1_fx, exp_re_1, L_negate( re2_fx ), exp_re_2, &exp_re_final );
79 0 : *det_im = BASOP_Util_Add_Mant32Exp( im1_fx, exp_im_1, L_negate( im2_fx ), exp_im_2, &exp_im_final );
80 0 : *exp_det_re = exp_re_final;
81 0 : *exp_det_im = exp_im_final;
82 :
83 0 : return;
84 : }
85 :
86 :
87 0 : static Word16 isar_is_mat_inv_2by2_complex_fx(
88 : Word32 in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
89 : Word16 exp_in_re,
90 : Word32 in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
91 : Word16 exp_in_im )
92 : {
93 0 : Word16 is_det_zero = 1;
94 : Word32 det, det_re, det_im;
95 0 : Word16 exp_det = 0, exp_det_re = 0, exp_det_im = 0;
96 0 : isar_calc_mat_det_2by2_complex_fx( in_re, exp_in_re, in_im, exp_in_im, &det_re, &exp_det_re, &det_im, &exp_det_im );
97 :
98 0 : Word64 det_re_sq = W_mult_32_32( det_re, det_re );
99 0 : Word16 det_sq_re_nrm = W_norm( det_re_sq );
100 0 : Word32 tmp1 = W_extract_h( W_shl( det_re_sq, det_sq_re_nrm ) );
101 :
102 0 : Word64 det_im_sq = W_mult_32_32( det_im, det_im );
103 0 : Word16 det_im_nrm = W_norm( det_im_sq );
104 0 : Word32 tmp2 = W_extract_h( W_shl( det_im_sq, det_im_nrm ) );
105 :
106 0 : det = BASOP_Util_Add_Mant32Exp( tmp1, exp_det_re + exp_det_re - det_sq_re_nrm, tmp2, exp_det_im + exp_det_im - det_im_nrm, &exp_det );
107 :
108 0 : Word16 res = BASOP_Util_Cmp_Mant32Exp( det, exp_det, EPSILON_FX, 31 );
109 0 : IF( EQ_16( res, -1 ) )
110 : {
111 0 : is_det_zero = 0;
112 : }
113 :
114 0 : return is_det_zero;
115 : }
116 :
117 :
118 0 : static void isar_calc_mat_inv_2by2_complex_fx(
119 : Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
120 : Word16 exp_in_re,
121 : Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
122 : Word16 exp_in_im,
123 : Word32 out_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
124 : Word16 *exp_out_re,
125 : Word32 out_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
126 : Word16 *exp_out_im )
127 : {
128 : Word16 exp_buffer_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buffer_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
129 :
130 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
131 : {
132 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
133 : {
134 0 : exp_buffer_re[i][j] = MIN16B;
135 0 : move16();
136 0 : exp_buffer_im[i][j] = MIN16B;
137 0 : move16();
138 : }
139 : }
140 : Word32 det_re_fx, det_im_fx;
141 0 : Word16 exp_det_re = 0, exp_det_im = 0;
142 0 : move16();
143 0 : move16();
144 : Word32 re_fx, im_fx, det_fx;
145 0 : Word16 exp_re = 0, exp_im = 0;
146 0 : move16();
147 0 : move16();
148 :
149 0 : isar_calc_mat_det_2by2_complex_fx( in_re_fx, exp_in_re, in_im_fx, exp_in_im, &det_re_fx, &exp_det_re, &det_im_fx, &exp_det_im );
150 :
151 0 : Word16 tmp1 = W_norm( W_mult_32_32( det_re_fx, det_re_fx ) );
152 0 : Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( det_re_fx, det_re_fx ), tmp1 ) ); // 2*exp_det_re - tmp1
153 0 : Word16 tmp3 = W_norm( W_mult_32_32( det_im_fx, det_im_fx ) );
154 0 : Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( det_im_fx, det_im_fx ), tmp3 ) ); // 2*exp_im_re - tmp3
155 0 : Word16 exp_det = 0;
156 0 : det_fx = BASOP_Util_Add_Mant32Exp( tmp2, 2 * exp_det_re - tmp1, tmp4, 2 * exp_det_im - tmp3, &exp_det );
157 :
158 0 : Word16 exp_tmp5 = 0;
159 0 : Word16 tmp5 = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, det_fx, &exp_tmp5 );
160 0 : exp_det = add( exp_tmp5, sub( 1, exp_det ) );
161 0 : det_fx = L_deposit_h( tmp5 );
162 :
163 : #ifdef DEBUGGING
164 : /* assert to catch cases when input is singular matrix */
165 : assert( GT_32( det_fx, 0 ) );
166 : #endif
167 :
168 0 : exp_re = 0;
169 0 : exp_im = 0;
170 0 : move16();
171 0 : move16();
172 0 : ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
173 :
174 0 : Word64 tmp7 = W_mult_32_32( re_fx, det_fx );
175 0 : Word16 tmp7_nrm = W_norm( tmp7 );
176 0 : out_re_fx[0][0] = W_extract_h( W_shl( tmp7, tmp7_nrm ) ); // exp_re + exp_det - tmp7_nrm
177 0 : move32();
178 0 : Word64 tmp8 = W_mult_32_32( im_fx, det_fx );
179 0 : Word16 tmp8_nrm = W_norm( tmp8 );
180 0 : out_im_fx[0][0] = W_extract_h( W_shl( tmp8, tmp8_nrm ) ); // exp_im + exp_det - tmp8_nrm
181 0 : move32();
182 :
183 0 : exp_buffer_re[0][0] = add( exp_re, sub( exp_det, tmp7_nrm ) );
184 0 : move16();
185 0 : exp_buffer_im[0][0] = add( exp_im, sub( exp_det, tmp8_nrm ) );
186 0 : move16();
187 :
188 0 : ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
189 :
190 0 : Word64 tmp9 = W_mult_32_32( L_negate( re_fx ), det_fx );
191 0 : Word16 tmp9_nrm = W_norm( tmp9 );
192 0 : out_re_fx[0][1] = W_extract_h( W_shl( tmp9, tmp9_nrm ) );
193 0 : Word64 tmp10 = W_mult_32_32( L_negate( im_fx ), det_fx );
194 0 : Word16 tmp10_nrm = W_norm( tmp10 );
195 0 : out_im_fx[0][1] = W_extract_h( W_shl( tmp10, tmp10_nrm ) );
196 :
197 0 : exp_buffer_re[0][1] = add( exp_re, sub( exp_det, tmp9_nrm ) );
198 0 : exp_buffer_im[0][1] = add( exp_im, sub( exp_det, tmp10_nrm ) );
199 :
200 0 : ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
201 :
202 0 : Word64 tmp11 = W_mult_32_32( L_negate( re_fx ), det_fx );
203 0 : Word16 tmp11_nrm = W_norm( tmp11 );
204 0 : out_re_fx[1][0] = W_extract_h( W_shl( tmp11, tmp11_nrm ) );
205 0 : Word64 tmp12 = W_mult_32_32( L_negate( im_fx ), det_fx );
206 0 : Word16 tmp12_nrm = W_norm( tmp12 );
207 0 : out_im_fx[1][0] = W_extract_h( W_shl( tmp12, tmp12_nrm ) );
208 :
209 0 : exp_buffer_re[1][0] = add( exp_re, sub( exp_det, tmp11_nrm ) );
210 0 : move16();
211 0 : exp_buffer_im[1][0] = add( exp_im, sub( exp_det, tmp12_nrm ) );
212 0 : move16();
213 :
214 0 : ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
215 :
216 0 : Word64 tmp13 = W_mult_32_32( re_fx, det_fx );
217 0 : Word16 tmp13_nrm = W_norm( tmp13 );
218 0 : out_re_fx[1][1] = W_extract_h( W_shl( tmp13, tmp13_nrm ) );
219 0 : move32();
220 :
221 0 : Word64 tmp14 = W_mult_32_32( im_fx, det_fx );
222 0 : Word16 tmp14_nrm = W_norm( tmp14 );
223 0 : out_im_fx[1][1] = W_extract_h( W_shl( tmp14, tmp14_nrm ) );
224 0 : move32();
225 :
226 0 : exp_buffer_re[1][1] = add( exp_re, sub( exp_det, tmp13_nrm ) );
227 0 : move16();
228 0 : exp_buffer_im[1][1] = add( exp_im, sub( exp_det, tmp14_nrm ) );
229 0 : move16();
230 :
231 0 : Word16 max_exp_re = MIN16B, max_exp_im = MIN16B;
232 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
233 : {
234 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
235 : {
236 0 : max_exp_re = s_max( max_exp_re, exp_buffer_re[i][j] );
237 0 : max_exp_im = s_max( max_exp_im, exp_buffer_im[i][j] );
238 : }
239 : }
240 :
241 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
242 : {
243 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
244 : {
245 0 : out_re_fx[i][j] = L_shr( out_re_fx[i][j], max_exp_re - exp_buffer_re[i][j] );
246 0 : move32();
247 0 : out_im_fx[i][j] = L_shr( out_im_fx[i][j], max_exp_im - exp_buffer_im[i][j] );
248 0 : move32();
249 : }
250 : }
251 :
252 0 : *exp_out_re = max_exp_re;
253 0 : move16();
254 0 : *exp_out_im = max_exp_im;
255 0 : move16();
256 :
257 0 : return;
258 : }
259 :
260 :
261 0 : static void ComputePredMat_fx(
262 : Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
263 : Word16 exp_cov_ii_re,
264 : Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
265 : Word16 exp_cov_ii_im,
266 : Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
267 : Word16 exp_cov_io_re,
268 : Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
269 : Word16 exp_cov_io_im,
270 : Word32 pred_mat_re_fx[][BINAURAL_CHANNELS],
271 : Word16 *exp_pred_mat_re,
272 : Word32 pred_mat_im_fx[][BINAURAL_CHANNELS],
273 : Word16 *exp_pred_mat_im,
274 : const Word16 num_chs,
275 : const Word16 real_only )
276 : {
277 : Word32 cov_ii_local_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
278 : Word32 cov_ii_inv_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
279 : Word32 cov_ii_inv_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
280 0 : Word16 exp_cov_ii_local_re = 0, exp_cov_ii_inv_re = 0, exp_cov_ii_inv_im = 0;
281 : Word32 trace_cov_fx;
282 :
283 : Word16 i, j;
284 :
285 0 : trace_cov_fx = 0;
286 0 : Word16 exp_trace_cov = 0;
287 0 : FOR( i = 0; i < num_chs; i++ )
288 : {
289 0 : trace_cov_fx = L_add( trace_cov_fx, L_shr( cov_ii_re_fx[i][i], 1 ) );
290 : }
291 0 : exp_trace_cov = add( exp_cov_ii_re, 1 );
292 :
293 0 : trace_cov_fx = L_max( 0, trace_cov_fx );
294 0 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( trace_cov_fx, exp_cov_ii_re, EPSILON_FX, 0 );
295 0 : IF( EQ_16( flag, negate( 1 ) ) )
296 : {
297 0 : FOR( i = 0; i < num_chs; i++ )
298 : {
299 : /* protection from cases when variance of ref channels is very small */
300 0 : set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS );
301 0 : set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
302 : }
303 0 : return;
304 : }
305 :
306 : Word16 buff_exp[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
307 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
308 : {
309 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
310 : {
311 0 : buff_exp[i][j] = 0;
312 0 : move16();
313 : }
314 : }
315 :
316 0 : FOR( i = 0; i < num_chs; i++ )
317 : {
318 0 : Copy32( cov_ii_re_fx[i], cov_ii_local_re_fx[i], num_chs );
319 0 : set16_fx( buff_exp[i], exp_cov_ii_re, num_chs );
320 : }
321 :
322 0 : Word32 tmp = 0;
323 0 : FOR( i = 0; i < num_chs; i++ )
324 : {
325 0 : tmp = Mpy_32_32( trace_cov_fx, 214748 ); // exp_trace_cov
326 0 : Word16 exp_tmp = 0;
327 0 : cov_ii_local_re_fx[i][i] = BASOP_Util_Add_Mant32Exp( cov_ii_re_fx[i][i], exp_cov_ii_re, tmp, exp_trace_cov, &exp_tmp );
328 0 : move32();
329 0 : buff_exp[i][i] = exp_tmp;
330 0 : move16();
331 : }
332 :
333 0 : Word16 max_exp = MIN16B;
334 0 : FOR( i = 0; i < 2; i++ )
335 : {
336 0 : FOR( j = 0; j < 2; j++ )
337 : {
338 0 : max_exp = max( max_exp, buff_exp[i][j] );
339 : }
340 : }
341 :
342 0 : FOR( i = 0; i < num_chs; i++ )
343 : {
344 0 : FOR( j = 0; j < num_chs; j++ )
345 : {
346 0 : cov_ii_local_re_fx[i][j] = L_shr( cov_ii_local_re_fx[i][j], max_exp - buff_exp[i][j] );
347 0 : move32();
348 : }
349 : }
350 :
351 0 : exp_cov_ii_local_re = max_exp;
352 0 : move16();
353 :
354 0 : IF( isar_is_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im ) )
355 : {
356 0 : isar_calc_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im, cov_ii_inv_re_fx, &exp_cov_ii_inv_re, cov_ii_inv_im_fx, &exp_cov_ii_inv_im );
357 0 : isar_mat_mult_2by2_complex_fx( cov_ii_inv_re_fx, exp_cov_ii_inv_re, cov_ii_inv_im_fx, exp_cov_ii_inv_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im );
358 : }
359 : ELSE
360 : {
361 : Word16 max_var_idx;
362 0 : FOR( i = 0; i < num_chs; i++ )
363 : {
364 0 : set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS );
365 0 : set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
366 : }
367 :
368 0 : max_var_idx = 0;
369 0 : move16();
370 0 : IF( GT_32( cov_ii_local_re_fx[1][1], cov_ii_local_re_fx[0][0] ) )
371 : {
372 0 : max_var_idx = 1;
373 : }
374 :
375 0 : Word16 tmp1 = 0, exp_tmp1 = 0;
376 0 : move16();
377 0 : move16();
378 0 : Word16 tmp2 = 0, exp_tmp2 = 0;
379 0 : move16();
380 0 : move16();
381 0 : Word16 flag1 = BASOP_Util_Cmp_Mant32Exp( cov_ii_local_re_fx[max_var_idx][max_var_idx], exp_cov_ii_local_re, EPSILON_FX, 0 );
382 0 : IF( EQ_16( flag1, 1 ) )
383 : {
384 : Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
385 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
386 : {
387 0 : set16_fx( pred_mat_buf_re[i], *exp_pred_mat_re, BINAURAL_CHANNELS );
388 0 : set16_fx( pred_mat_buf_im[i], *exp_pred_mat_im, BINAURAL_CHANNELS );
389 : }
390 0 : FOR( j = 0; j < num_chs; j++ )
391 : {
392 0 : tmp1 = BASOP_Util_Divide3232_Scale( cov_io_re_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp1 );
393 0 : exp_tmp1 = exp_tmp1 + ( exp_cov_io_re - exp_cov_ii_local_re );
394 0 : tmp2 = BASOP_Util_Divide3232_Scale( cov_io_im_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp2 );
395 0 : exp_tmp2 = exp_tmp2 + ( exp_cov_io_im - exp_cov_ii_local_re );
396 0 : pred_mat_re_fx[max_var_idx][j] = tmp1;
397 0 : move32();
398 0 : pred_mat_im_fx[max_var_idx][j] = tmp2;
399 0 : move32();
400 0 : pred_mat_buf_re[max_var_idx][j] = exp_tmp1;
401 0 : move16();
402 0 : pred_mat_buf_im[max_var_idx][j] = exp_tmp2;
403 0 : move16();
404 : }
405 :
406 0 : Word16 max_re = MIN16B, max_im = MIN16B;
407 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
408 : {
409 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
410 : {
411 :
412 0 : max_re = s_max( max_re, pred_mat_buf_re[i][j] );
413 0 : move16();
414 0 : max_im = s_max( max_im, pred_mat_buf_im[i][j] );
415 0 : move16();
416 : }
417 : }
418 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
419 : {
420 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
421 : {
422 :
423 0 : pred_mat_re_fx[i][j] = L_shr( pred_mat_re_fx[i][j], max_re - pred_mat_buf_re[i][j] );
424 0 : move32();
425 0 : pred_mat_im_fx[i][j] = L_shr( pred_mat_im_fx[i][j], max_im - pred_mat_buf_im[i][j] );
426 0 : move32();
427 : }
428 : }
429 :
430 0 : *exp_pred_mat_re = max_re;
431 0 : move16();
432 0 : *exp_pred_mat_im = max_im;
433 0 : move16();
434 : }
435 : }
436 :
437 0 : IF( real_only )
438 : {
439 0 : FOR( i = 0; i < num_chs; i++ )
440 : {
441 0 : set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
442 : }
443 : }
444 :
445 0 : return;
446 : }
447 :
448 :
449 0 : static void ComputePostPredCov_fx(
450 : Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
451 : Word16 exp_cov_ii_re,
452 : Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
453 : Word16 exp_cov_ii_im,
454 : Word32 pred_mat_re_fx[][BINAURAL_CHANNELS],
455 : Word16 exp_pred_mat_re,
456 : Word32 pred_mat_im_fx[][BINAURAL_CHANNELS],
457 : Word16 exp_pred_mat_im,
458 : Word32 postpred_cov_re_fx[][BINAURAL_CHANNELS],
459 : Word16 *exp_postpred_cov_re,
460 : Word16 num_chs )
461 : {
462 : Word16 i, j;
463 : Word32 dmx_mat_conj_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
464 : Word32 dmx_mat_conj_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
465 : Word32 temp_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
466 : Word32 temp_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
467 : Word32 postpred_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
468 0 : Word16 exp_postpred_cov_im = 0;
469 0 : Word16 exp_temp_mat_re = 0, exp_temp_mat_im = 0;
470 :
471 0 : assert( num_chs == BINAURAL_CHANNELS );
472 :
473 0 : FOR( i = 0; i < num_chs; i++ )
474 : {
475 0 : FOR( j = 0; j < num_chs; j++ )
476 : {
477 0 : dmx_mat_conj_re_fx[i][j] = pred_mat_re_fx[j][i];
478 0 : move32();
479 0 : dmx_mat_conj_im_fx[i][j] = L_negate( pred_mat_im_fx[j][i] );
480 0 : move32();
481 :
482 0 : temp_mat_re_fx[i][j] = pred_mat_re_fx[i][j];
483 0 : move32();
484 0 : temp_mat_im_fx[i][j] = pred_mat_im_fx[i][j];
485 0 : move32();
486 : }
487 0 : set32_fx( postpred_cov_re_fx[i], 0, BINAURAL_CHANNELS );
488 : }
489 0 : isar_mat_mult_2by2_complex_fx( dmx_mat_conj_re_fx, exp_pred_mat_re, dmx_mat_conj_im_fx, exp_pred_mat_im, cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, temp_mat_re_fx, &exp_temp_mat_re, temp_mat_im_fx, &exp_temp_mat_im );
490 0 : isar_mat_mult_2by2_complex_fx( temp_mat_re_fx, exp_temp_mat_re, temp_mat_im_fx, exp_temp_mat_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im, postpred_cov_re_fx, exp_postpred_cov_re, postpred_cov_im_fx, &exp_postpred_cov_im );
491 :
492 : /* 2x2 mult */
493 :
494 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
495 : {
496 0 : FOR( j = 0; j < i; j++ )
497 : {
498 0 : postpred_cov_re_fx[i][j] = postpred_cov_re_fx[j][i];
499 0 : move32();
500 : }
501 : }
502 :
503 0 : return;
504 : }
505 :
506 :
507 0 : static void ComputeBandedCrossCov_fx(
508 : Word32 Cldfb_RealBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
509 : Word16 exp_cldfb_re_1,
510 : Word32 Cldfb_ImagBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
511 : Word16 exp_cldfb_im_1,
512 : const Word16 ch_start_idx1,
513 : Word32 Cldfb_RealBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
514 : Word16 exp_cldfb_re_2,
515 : Word32 Cldfb_ImagBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
516 : Word16 exp_cldfb_im_2,
517 : const Word16 ch_start_idx2,
518 : Word32 out_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
519 : Word16 *exp_out_cov_re,
520 : Word32 out_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
521 : Word16 *exp_out_cov_im,
522 : const Word16 num_chs,
523 : const Word16 *pBand_grouping,
524 : const Word16 num_slots,
525 : const Word16 start_slot_idx,
526 : const Word16 md_band_idx,
527 : const Word16 real_only )
528 : {
529 : Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2;
530 : Word16 brange[2];
531 :
532 0 : FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
533 : {
534 0 : set_l( out_cov_re_fx[ch_idx1], 0, num_chs );
535 0 : set_l( out_cov_im_fx[ch_idx1], 0, num_chs );
536 : }
537 :
538 0 : brange[0] = pBand_grouping[md_band_idx];
539 0 : move16();
540 0 : brange[1] = pBand_grouping[md_band_idx + 1];
541 0 : move16();
542 : Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
543 0 : FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
544 : {
545 0 : FOR( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ )
546 : {
547 0 : Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2], tmp_b = out_cov_im_fx[ch_idx1][ch_idx2];
548 0 : Word16 exp_tmp_a = 0, exp_tmp_b = 0;
549 0 : IF( EQ_16( real_only, 0 ) )
550 : {
551 0 : FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
552 : {
553 0 : FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
554 : {
555 0 : Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
556 0 : Word16 tmp1_nrm = W_norm( tmp1 );
557 0 : Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) );
558 :
559 0 : Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
560 0 : Word16 tmp2_nrm = W_norm( tmp2 );
561 0 : Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) );
562 :
563 0 : Word16 exp_tmp3 = 0;
564 0 : Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 );
565 0 : Word16 exp_tmp_a_tmp = 0;
566 0 : tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
567 0 : exp_tmp_a = exp_tmp_a_tmp;
568 :
569 0 : Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
570 0 : Word16 tmp4_nrm = W_norm( tmp4 );
571 0 : Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm
572 :
573 0 : Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
574 0 : Word16 tmp5_nrm = W_norm( tmp5 );
575 0 : Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm
576 :
577 0 : Word16 exp_tmp6 = 0;
578 0 : Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm, &exp_tmp6 );
579 0 : Word16 exp_tmp_b_tmp = 0;
580 0 : tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp );
581 0 : exp_tmp_b = exp_tmp_b_tmp;
582 : }
583 : }
584 : }
585 : ELSE
586 : {
587 0 : FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
588 : {
589 0 : FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
590 : {
591 0 : Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
592 0 : Word16 tmp1_nrm = W_norm( tmp1 );
593 0 : Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) );
594 :
595 0 : Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
596 0 : Word16 tmp2_nrm = W_norm( tmp2 );
597 0 : Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) );
598 :
599 0 : Word16 exp_tmp3 = 0;
600 0 : Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 );
601 0 : Word16 exp_tmp_a_tmp = 0;
602 0 : tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
603 0 : exp_tmp_a = exp_tmp_a_tmp;
604 :
605 0 : tmp_b = 0;
606 0 : exp_tmp_b = 0;
607 : }
608 : }
609 : }
610 0 : out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a;
611 0 : move32();
612 0 : out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b;
613 0 : move32();
614 0 : exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a;
615 0 : move32();
616 0 : exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b;
617 0 : move32();
618 : }
619 : }
620 : /*make common exponent*/
621 0 : Word16 max_cov_re = 0, max_cov_im = 0;
622 0 : FOR( Word16 i = 0; i < num_chs; i++ )
623 : {
624 0 : FOR( Word16 j = 0; j < num_chs; j++ )
625 : {
626 0 : max_cov_re = max( max_cov_re, exp_buff_re[i][j] );
627 0 : max_cov_im = max( max_cov_im, exp_buff_im[i][j] );
628 : }
629 : }
630 0 : FOR( Word16 i = 0; i < num_chs; i++ )
631 : {
632 0 : FOR( Word16 j = 0; j < num_chs; j++ )
633 : {
634 0 : out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], max_cov_re - exp_buff_re[i][j] );
635 0 : move32();
636 0 : out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], max_cov_im - exp_buff_im[i][j] );
637 0 : move32();
638 : }
639 : }
640 :
641 0 : *exp_out_cov_re = max_cov_re;
642 0 : *exp_out_cov_im = max_cov_im;
643 :
644 0 : return;
645 : }
646 :
647 :
648 0 : static void ComputeBandedCov_fx(
649 : Word32 Cldfb_RealBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
650 : Word16 exp_cldfb_re,
651 : Word32 Cldfb_ImagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
652 : Word16 exp_cldfb_im,
653 : const Word16 ch_start_idx,
654 : Word32 out_cov_re_fx[][BINAURAL_CHANNELS],
655 : Word16 *exp_cov_re,
656 : Word32 out_cov_im_fx[][BINAURAL_CHANNELS],
657 : Word16 *exp_cov_im,
658 : const Word16 num_chs,
659 : const Word16 *pBand_grouping,
660 : const Word16 num_slots,
661 : const Word16 start_slot_idx,
662 : const Word16 md_band_idx,
663 : const Word16 real_only )
664 : {
665 : Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2;
666 : Word16 brange[2];
667 :
668 0 : FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
669 : {
670 0 : set32_fx( out_cov_re_fx[ch_idx1], 0, num_chs );
671 0 : set32_fx( out_cov_im_fx[ch_idx1], 0, num_chs );
672 : }
673 :
674 0 : brange[0] = pBand_grouping[md_band_idx];
675 0 : move16();
676 0 : brange[1] = pBand_grouping[md_band_idx + 1];
677 0 : move16();
678 :
679 : Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
680 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
681 : {
682 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
683 : {
684 0 : exp_buff_re[i][j] = 0;
685 0 : move16();
686 0 : exp_buff_im[i][j] = 0;
687 0 : move16();
688 : }
689 : }
690 :
691 0 : FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
692 : {
693 0 : FOR( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ )
694 : {
695 0 : Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2];
696 0 : Word32 tmp_b = out_cov_im_fx[ch_idx1][ch_idx2];
697 0 : Word16 exp_tmp_a = 0, exp_tmp_b = 0;
698 0 : test();
699 0 : IF( ( NE_16( ch_idx2, ch_idx1 ) ) && ( EQ_16( real_only, 0 ) ) )
700 : {
701 0 : FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
702 : {
703 0 : FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
704 : {
705 0 : Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
706 0 : Word16 tmp1_nrm = W_norm( tmp1 );
707 0 : Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm
708 :
709 0 : Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
710 0 : Word16 tmp2_nrm = W_norm( tmp2 );
711 0 : Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm
712 :
713 0 : Word16 exp_tmp3 = 0;
714 0 : Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 );
715 0 : Word16 exp_tmp_a_tmp = 0;
716 0 : tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
717 0 : exp_tmp_a = exp_tmp_a_tmp;
718 :
719 0 : Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
720 0 : Word16 tmp4_nrm = W_norm( tmp4 );
721 0 : Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re + exp_cldfb_im - tmp4_nrm
722 :
723 0 : Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
724 0 : Word16 tmp5_nrm = W_norm( tmp5 );
725 0 : Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im + exp_cldfb_re - tmp5_nrm
726 :
727 0 : Word16 exp_tmp6 = 0;
728 0 : Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re + exp_cldfb_im - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im + exp_cldfb_re - tmp5_nrm, &exp_tmp6 );
729 0 : Word16 exp_tmp_b_tmp = 0;
730 0 : tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp );
731 0 : exp_tmp_b = exp_tmp_b_tmp;
732 : }
733 : }
734 : }
735 : ELSE
736 : {
737 0 : FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
738 : {
739 0 : FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
740 : {
741 0 : Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
742 0 : Word16 tmp1_nrm = W_norm( tmp1 );
743 0 : Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm
744 :
745 0 : Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
746 0 : Word16 tmp2_nrm = W_norm( tmp2 );
747 0 : Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm
748 :
749 0 : Word16 exp_tmp3 = 0;
750 0 : Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 );
751 :
752 0 : Word16 exp_tmp_a_tmp = 0;
753 0 : tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
754 0 : exp_tmp_a = exp_tmp_a_tmp;
755 :
756 0 : tmp_b = 0;
757 0 : exp_tmp_b = 0;
758 : }
759 : }
760 : }
761 0 : out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a;
762 0 : move32();
763 0 : exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a;
764 0 : move32();
765 :
766 0 : out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b;
767 0 : move32();
768 0 : exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b;
769 0 : move32();
770 : }
771 : }
772 :
773 0 : Word16 exp_max_re = MIN16B, exp_max_im = MIN16B;
774 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
775 : {
776 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
777 : {
778 0 : exp_max_re = max( exp_max_re, exp_buff_re[i][j] );
779 0 : exp_max_im = max( exp_max_im, exp_buff_im[i][j] );
780 : }
781 : }
782 :
783 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
784 : {
785 0 : FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
786 : {
787 0 : out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], exp_max_re - exp_buff_re[i][j] );
788 0 : move32();
789 0 : out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], exp_max_im - exp_buff_im[i][j] );
790 0 : move32();
791 : }
792 : }
793 :
794 0 : FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
795 : {
796 0 : FOR( ch_idx2 = add( ch_idx1, 1 ); ch_idx2 < num_chs; ch_idx2++ )
797 : {
798 0 : out_cov_re_fx[ch_idx1][ch_idx2] = out_cov_re_fx[ch_idx2][ch_idx1];
799 0 : move32();
800 0 : out_cov_im_fx[ch_idx1][ch_idx2] = L_negate( out_cov_im_fx[ch_idx2][ch_idx1] );
801 0 : move32();
802 : }
803 : }
804 :
805 0 : *exp_cov_re = exp_max_re;
806 0 : *exp_cov_im = exp_max_im;
807 :
808 0 : return;
809 : }
810 :
811 :
812 0 : static Word32 GetNormFact_fx(
813 : Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
814 : Word16 exp_cov_ii_re,
815 : Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
816 : Word16 exp_cov_ii_im,
817 : Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
818 : Word16 exp_cov_io_re,
819 : Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
820 : Word16 exp_cov_io_im,
821 : Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
822 : Word16 exp_cov_oo_re,
823 : Word16 *exp_norm_fact_fx )
824 : {
825 : Word16 i, j;
826 0 : Word32 norm_fact_fx = 0, abs_val_fx;
827 0 : Word16 exp_abs_val = 0, exp_norm_fact = 0;
828 :
829 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
830 : {
831 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
832 : {
833 0 : ivas_calculate_abs_fx( cov_ii_re_fx[i][j], exp_cov_ii_re, cov_ii_im_fx[i][j], exp_cov_ii_im, &abs_val_fx, &exp_abs_val );
834 0 : Word16 res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
835 0 : IF( EQ_16( res_1, negate( 1 ) ) )
836 : {
837 0 : norm_fact_fx = abs_val_fx;
838 0 : exp_norm_fact = exp_abs_val;
839 : }
840 :
841 0 : ivas_calculate_abs_fx( cov_io_re_fx[i][j], exp_cov_io_re, cov_io_im_fx[i][j], exp_cov_io_im, &abs_val_fx, &exp_abs_val );
842 0 : res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
843 0 : IF( EQ_16( res_1, negate( 1 ) ) )
844 : {
845 0 : norm_fact_fx = abs_val_fx;
846 0 : exp_norm_fact = exp_abs_val;
847 : }
848 0 : ivas_calculate_rabs_fx( cov_oo_re_fx[i][j], exp_cov_oo_re, &abs_val_fx, &exp_abs_val );
849 0 : res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
850 0 : IF( EQ_16( res_1, negate( 1 ) ) )
851 : {
852 0 : norm_fact_fx = abs_val_fx;
853 0 : exp_norm_fact = exp_abs_val;
854 : }
855 : }
856 : }
857 :
858 0 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, EPSILON_FX, 0 );
859 0 : IF( EQ_16( flag, negate( 1 ) ) )
860 : {
861 0 : norm_fact_fx = ONE_IN_Q30;
862 0 : exp_norm_fact = 1;
863 : }
864 :
865 0 : Word16 exp_tmp = 0;
866 0 : Word16 tmp = BASOP_Util_Divide3232_Scale( PCM16_TO_FLT_FAC_FX_Q15, norm_fact_fx, &exp_tmp );
867 0 : exp_tmp = add( exp_tmp, sub( 16, exp_norm_fact ) );
868 0 : norm_fact_fx = L_deposit_h( tmp );
869 0 : exp_norm_fact = exp_tmp;
870 :
871 0 : *exp_norm_fact_fx = exp_norm_fact;
872 :
873 0 : return norm_fact_fx;
874 : }
875 :
876 0 : static void isar_split_rend_huffman_encode(
877 : isar_split_rend_huffman_cfg_t *huff_cfg,
878 : const Word16 in,
879 : Word32 *hcode,
880 : Word32 *hlen )
881 : {
882 : Word32 min_sym_val;
883 : const Word32 *codebook;
884 :
885 0 : min_sym_val = huff_cfg->codebook[0];
886 0 : move32();
887 :
888 0 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
889 0 : *hlen = codebook[1];
890 0 : move32();
891 0 : *hcode = codebook[2];
892 0 : move32();
893 :
894 0 : return;
895 : }
896 :
897 :
898 0 : static void isar_split_rend_quant_md_fx(
899 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
900 : const ISAR_SPLIT_REND_POSE_TYPE pose_type,
901 : const Word16 real_only,
902 : Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS],
903 : const Word32 pred_1byquantstep, // Q26
904 : const Word16 Q_frame
905 : #ifdef DEBUG_QUANT_MD_FX
906 : ,
907 : float fix_pos_rot_mat_flt[][BINAURAL_CHANNELS],
908 : const float pred_1byquantstep_flt // Q26
909 : #endif
910 : )
911 : {
912 : Word16 ch1, ch2;
913 : Word16 gd_idx_min;
914 : Word32 quant_val;
915 : #ifdef DEBUG_QUANT_MD_FX
916 : float quant_val_flt;
917 : Word16 tmp;
918 : #endif
919 :
920 0 : if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY )
921 0 : {
922 : Word32 onebyquantstep;
923 :
924 0 : onebyquantstep = pred_1byquantstep;
925 : #ifdef DEBUG_QUANT_MD_FX
926 : float onebyquantstep_flt = pred_1byquantstep_flt;
927 : #endif
928 0 : IF( real_only == 1 )
929 : {
930 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
931 : {
932 0 : hMd->pred_mat_re_fx[ch1][ch1] = hMd->pred_mat_re2[ch1];
933 : }
934 0 : hMd->pred_mat_re_fx[1][0] = 0;
935 0 : hMd->pred_mat_re_fx[0][1] = 0;
936 :
937 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
938 : {
939 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
940 : {
941 0 : quant_val = L_sub_sat( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, sub( Q31, Q_frame ) ) );
942 0 : quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
943 0 : hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0
944 : }
945 : }
946 : }
947 : else
948 : {
949 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
950 : {
951 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
952 : {
953 0 : quant_val = L_sub_sat( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( fix_pos_rot_mat[ch1][ch2], sub( Q31, Q_frame ) ) );
954 0 : quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
955 0 : hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0
956 :
957 : #ifdef DEBUG_QUANT_MD_FX
958 : quant_val_flt = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat_flt[ch1][ch2];
959 : quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val_flt, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
960 : tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt );
961 : if ( hMd->pred_mat_re_idx[ch1][ch2] != tmp )
962 : {
963 : printf( "\nUNEQUAL INDEX\n" );
964 : }
965 : #endif
966 : }
967 : }
968 : }
969 :
970 0 : if ( real_only == 0 )
971 : {
972 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
973 : {
974 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
975 : {
976 0 : quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( hMd->pred_mat_im_fx[ch1][ch2], L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
977 0 : hMd->pred_mat_im_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) );
978 : // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP;
979 :
980 :
981 : #ifdef DEBUG_QUANT_MD_FX
982 : quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) );
983 : tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt );
984 : if ( hMd->pred_mat_im_idx[ch1][ch2] != tmp )
985 : {
986 : printf( "\nUNEQUAL INDEX\n" );
987 : }
988 : #endif
989 : }
990 : }
991 : }
992 : }
993 0 : else if ( pose_type == COM_GAIN_ONLY )
994 : {
995 0 : quant_val = L_min( L_shl_r( 1, Q_frame ) /*ISAR_SPLIT_REND_D_MAX_VAL_FX*/, L_max( hMd->gd_fx, ISAR_SPLIT_REND_D_MIN_VAL_FX ) ); //_frame
996 0 : gd_idx_min = 0; //(int16_t)roundf(ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL)
997 0 : hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_D_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
998 0 : hMd->gd_fx = W_extract_l( W_shr( W_mult0_32_32( hMd->gd_idx, ISAR_SPLIT_REND_D_Q_STEP_Q31 ), sub( Q31, Q_frame ) ) );
999 0 : hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min );
1000 :
1001 : #ifdef DEBUG_QUANT_MD_FX
1002 : quant_val_flt = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) );
1003 : gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL );
1004 : tmp = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val_flt );
1005 : tmp = tmp - gd_idx_min;
1006 : if ( hMd->gd_idx != tmp )
1007 : {
1008 : printf( "\nUNEQUAL INDEX\n" );
1009 : }
1010 : #endif
1011 : }
1012 0 : else if ( pose_type == LR_GAIN_ONLY )
1013 : {
1014 0 : quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25
1015 0 : gd_idx_min = 7; // (int16_t)roundf(ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL)
1016 0 : hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
1017 0 : hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min );
1018 :
1019 : #ifdef DEBUG_QUANT_MD_FX
1020 : quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PRED_MAX_VAL ) );
1021 : gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL );
1022 : tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt );
1023 : tmp = tmp - gd_idx_min;
1024 : if ( hMd->gd_idx != tmp )
1025 : {
1026 : printf( "\nUNEQUAL INDEX\n" );
1027 : }
1028 : #endif
1029 0 : quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd2_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25
1030 0 : hMd->gd2_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
1031 0 : hMd->gd2_idx = sub( hMd->gd2_idx, gd_idx_min );
1032 :
1033 : #ifdef DEBUG_QUANT_MD_FX
1034 : quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PRED_MAX_VAL ) );
1035 : tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt );
1036 : tmp = tmp - gd_idx_min;
1037 : if ( hMd->gd2_idx != tmp )
1038 : {
1039 : printf( "\nUNEQUAL INDEX\n" );
1040 : }
1041 : #endif
1042 : }
1043 :
1044 0 : return;
1045 : }
1046 :
1047 :
1048 0 : static void get_lr_gains(
1049 : Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
1050 : const Word16 exp_cov_ii_re,
1051 : Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
1052 : const Word16 exp_cov_oo_re,
1053 : Word32 gains_fx[BINAURAL_CHANNELS],
1054 : Word16 *exp_gains_fx )
1055 : {
1056 0 : Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 };
1057 0 : Word16 exp_gd_tmp = 0, i;
1058 :
1059 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1060 : {
1061 0 : gains_fx[i] = cov_ii_re_fx[i][i];
1062 0 : move32();
1063 0 : exp_gd_tmp_buf[i] = exp_cov_ii_re;
1064 0 : move16();
1065 :
1066 0 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( gains_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 );
1067 0 : IF( EQ_16( flag, negate( 1 ) ) )
1068 : {
1069 0 : gains_fx[i] = ONE_IN_Q25;
1070 0 : move32();
1071 0 : exp_gd_tmp_buf[i] = 6;
1072 0 : move16();
1073 : }
1074 : ELSE
1075 : {
1076 0 : Word16 tmp, tmp_sqrt, exp_tmp = 0;
1077 0 : tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gains_fx[i], &exp_tmp );
1078 0 : exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] );
1079 0 : tmp_sqrt = Sqrt16( tmp, &exp_tmp );
1080 0 : gains_fx[i] = L_deposit_h( tmp_sqrt );
1081 0 : move32();
1082 0 : exp_gd_tmp_buf[i] = exp_tmp;
1083 0 : move16();
1084 : }
1085 : }
1086 :
1087 0 : Word16 max_gd_exp = MIN16B;
1088 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1089 : {
1090 0 : max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] );
1091 : }
1092 0 : exp_gd_tmp = max_gd_exp;
1093 :
1094 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1095 : {
1096 0 : gains_fx[i] = L_shr( gains_fx[i], max_gd_exp - exp_gd_tmp_buf[i] );
1097 0 : move32();
1098 : }
1099 :
1100 0 : *exp_gains_fx = exp_gd_tmp;
1101 0 : move16();
1102 :
1103 0 : return;
1104 : }
1105 :
1106 :
1107 0 : static void ComputeCoeffs_fx(
1108 : Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
1109 : Word16 exp_cov_ii_re,
1110 : Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
1111 : Word16 exp_cov_ii_im,
1112 : Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
1113 : Word16 exp_cov_io_re,
1114 : Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
1115 : Word16 exp_cov_io_im,
1116 : Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
1117 : Word16 exp_cov_oo_re,
1118 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
1119 : const ISAR_SPLIT_REND_POSE_TYPE pose_type,
1120 : const Word16 real_only )
1121 : {
1122 : Word16 i, j;
1123 : Word32 gd_fx, gl2_fx, gr2_fx, cov_norm_fact_fx;
1124 0 : Word16 exp_gd = 0;
1125 :
1126 : Word32 postpred_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1127 0 : Word16 exp_postpred_cov_re = 0;
1128 :
1129 : Word32 cov_ii_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1130 : Word32 cov_ii_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1131 : Word32 cov_io_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1132 : Word32 cov_io_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1133 : Word32 cov_oo_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1134 :
1135 0 : Word16 exp_cov_ii_norm_re = 0, exp_cov_ii_norm_im = 0, exp_cov_io_norm_re = 0, exp_cov_io_norm_im = 0, exp_cov_oo_norm_re = 0;
1136 0 : Word16 exp_pred_re = 0, exp_pred_im = 0;
1137 :
1138 0 : IF( EQ_16( pose_type, PITCH_ONLY ) )
1139 : {
1140 : Word32 gd_tmp_fx[BINAURAL_CHANNELS];
1141 0 : Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 };
1142 0 : Word16 exp_gd_tmp = 0;
1143 :
1144 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1145 : {
1146 0 : gd_tmp_fx[i] = cov_ii_re_fx[i][i];
1147 0 : move32();
1148 0 : exp_gd_tmp_buf[i] = exp_cov_ii_re;
1149 0 : move16();
1150 0 : exp_gd_tmp = exp_cov_ii_re;
1151 :
1152 0 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp, EPSILON_FX, 0 );
1153 0 : IF( EQ_16( flag, negate( 1 ) ) )
1154 : {
1155 0 : gd_tmp_fx[i] = ONE_IN_Q25;
1156 0 : move32();
1157 0 : exp_gd_tmp_buf[i] = 6;
1158 0 : move16();
1159 : }
1160 : ELSE
1161 : {
1162 0 : Word16 tmp, tmp_sqrt, exp_tmp = 0;
1163 0 : tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp );
1164 0 : exp_tmp = add( exp_tmp, sub( exp_cov_oo_re, exp_gd_tmp ) );
1165 0 : tmp_sqrt = Sqrt16( tmp, &exp_tmp );
1166 0 : gd_tmp_fx[i] = L_deposit_h( tmp_sqrt );
1167 0 : move32();
1168 0 : exp_gd_tmp_buf[i] = exp_tmp;
1169 0 : move16();
1170 : }
1171 : }
1172 :
1173 0 : Word16 max_gd_exp = MIN16B;
1174 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1175 : {
1176 0 : max_gd_exp = s_max( max_gd_exp, exp_gd_tmp_buf[i] );
1177 : }
1178 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1179 : {
1180 0 : gd_tmp_fx[i] = L_shr( gd_tmp_fx[i], max_gd_exp - exp_gd_tmp_buf[i] );
1181 0 : move32();
1182 : }
1183 0 : exp_gd_tmp = max_gd_exp;
1184 0 : move16();
1185 0 : hMd->gd_fx = gd_tmp_fx[0];
1186 0 : move16();
1187 0 : hMd->gd2_fx = gd_tmp_fx[1];
1188 0 : move16();
1189 0 : hMd->exp_gd = exp_gd_tmp;
1190 0 : move16();
1191 0 : hMd->exp_gd2 = exp_gd_tmp;
1192 0 : move16();
1193 : }
1194 : ELSE
1195 : {
1196 0 : IF( real_only )
1197 : {
1198 : Word32 gd_tmp_fx[BINAURAL_CHANNELS];
1199 0 : get_lr_gains( cov_ii_re_fx, exp_cov_ii_re,
1200 : cov_oo_re_fx, exp_cov_oo_re,
1201 : gd_tmp_fx, &hMd->exp_pred_mat_re2 );
1202 0 : hMd->pred_mat_re_fx[1][0] = 0;
1203 0 : move32();
1204 0 : hMd->pred_mat_re_fx[0][1] = 0;
1205 0 : move32();
1206 0 : hMd->exp_pred_mat_re = hMd->exp_pred_mat_re2;
1207 0 : move16();
1208 0 : hMd->exp_pred_mat_im = hMd->exp_pred_mat_re;
1209 0 : move16();
1210 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1211 : {
1212 0 : hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i];
1213 0 : hMd->pred_mat_re2[i] = gd_tmp_fx[i];
1214 0 : set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
1215 : }
1216 : }
1217 : ELSE
1218 : {
1219 0 : get_lr_gains( cov_ii_re_fx, exp_cov_ii_re,
1220 : cov_oo_re_fx, exp_cov_oo_re,
1221 0 : hMd->pred_mat_re2, &hMd->exp_pred_mat_re2 );
1222 0 : Word16 exp_norm_fact = 0;
1223 0 : cov_norm_fact_fx = GetNormFact_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &exp_norm_fact );
1224 :
1225 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1226 : {
1227 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1228 : {
1229 0 : cov_ii_norm_re_fx[i][j] = Mpy_32_32( cov_ii_re_fx[i][j], cov_norm_fact_fx );
1230 0 : move32();
1231 0 : cov_ii_norm_im_fx[i][j] = Mpy_32_32( cov_ii_im_fx[i][j], cov_norm_fact_fx );
1232 0 : move32();
1233 0 : cov_io_norm_re_fx[i][j] = Mpy_32_32( cov_io_re_fx[i][j], cov_norm_fact_fx );
1234 0 : move32();
1235 0 : cov_io_norm_im_fx[i][j] = Mpy_32_32( cov_io_im_fx[i][j], cov_norm_fact_fx );
1236 0 : move32();
1237 0 : cov_oo_norm_re_fx[i][j] = Mpy_32_32( cov_oo_re_fx[i][j], cov_norm_fact_fx );
1238 0 : move32();
1239 : }
1240 : }
1241 :
1242 0 : exp_cov_ii_norm_re = add( exp_cov_ii_re, exp_norm_fact );
1243 0 : exp_cov_ii_norm_im = add( exp_cov_ii_im, exp_norm_fact );
1244 0 : exp_cov_io_norm_re = add( exp_cov_io_re, exp_norm_fact );
1245 0 : exp_cov_io_norm_im = add( exp_cov_io_im, exp_norm_fact );
1246 0 : exp_cov_oo_norm_re = add( exp_cov_oo_re, exp_norm_fact );
1247 :
1248 0 : ComputePredMat_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, cov_io_norm_re_fx, exp_cov_io_norm_re, cov_io_norm_im_fx, exp_cov_io_norm_im, hMd->pred_mat_re_fx, &exp_pred_re, hMd->pred_mat_im_fx, &exp_pred_im, BINAURAL_CHANNELS, real_only );
1249 0 : hMd->exp_pred_mat_re = exp_pred_re;
1250 0 : move16();
1251 0 : hMd->exp_pred_mat_im = exp_pred_im;
1252 0 : move16();
1253 :
1254 : /*TODO : change this function to real only as thats what is needed*/
1255 0 : ComputePostPredCov_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, hMd->pred_mat_re_fx, exp_pred_re, hMd->pred_mat_im_fx, exp_pred_im, postpred_cov_re_fx, &exp_postpred_cov_re, BINAURAL_CHANNELS );
1256 :
1257 : /* normalize everything to +-1 range */
1258 0 : Word16 gd_16_fx = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, PCM16_TO_FLT_FAC_FX_Q15, &exp_gd );
1259 0 : gd_fx = L_deposit_h( gd_16_fx );
1260 0 : exp_gd = add( exp_gd, sub( 1, 16 ) );
1261 :
1262 : Word16 tmp_buff_2[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmp_buff_3[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1263 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1264 : {
1265 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1266 : {
1267 0 : Word64 tmp_2 = W_mult_32_32( cov_ii_norm_re_fx[i][j], gd_fx );
1268 0 : Word64 tmp_3 = W_mult_32_32( cov_oo_norm_re_fx[i][j], gd_fx );
1269 0 : Word16 shift_2 = W_norm( tmp_2 );
1270 0 : Word16 shift_3 = W_norm( tmp_3 );
1271 :
1272 0 : postpred_cov_re_fx[i][j] = Mpy_32_32( postpred_cov_re_fx[i][j], gd_fx );
1273 0 : move32();
1274 0 : cov_ii_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_2, shift_2 ) );
1275 0 : move32();
1276 0 : cov_oo_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_3, shift_3 ) );
1277 0 : move32();
1278 :
1279 0 : tmp_buff_2[i][j] = exp_cov_ii_norm_re + exp_gd - shift_2;
1280 0 : move16();
1281 0 : tmp_buff_3[i][j] = exp_cov_oo_norm_re + exp_gd - shift_3;
1282 0 : move16();
1283 : }
1284 : }
1285 0 : Word16 max_2 = MIN16B, max_3 = MIN16B;
1286 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1287 : {
1288 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1289 : {
1290 0 : max_2 = s_max( max_2, tmp_buff_2[i][j] );
1291 0 : max_3 = s_max( max_3, tmp_buff_3[i][j] );
1292 : }
1293 : }
1294 :
1295 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1296 : {
1297 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1298 : {
1299 0 : cov_ii_norm_re_fx[i][j] = L_shr( cov_ii_norm_re_fx[i][j], max_2 - tmp_buff_2[i][j] );
1300 0 : move32();
1301 0 : cov_oo_norm_re_fx[i][j] = L_shr( cov_oo_norm_re_fx[i][j], max_3 - tmp_buff_3[i][j] );
1302 0 : move32();
1303 : }
1304 : }
1305 :
1306 0 : exp_postpred_cov_re = add( exp_postpred_cov_re, exp_gd );
1307 0 : exp_cov_ii_norm_re = max_2;
1308 0 : move16();
1309 0 : exp_cov_oo_norm_re = max_3;
1310 0 : move16();
1311 :
1312 0 : hMd->gd_fx = 0;
1313 0 : move16();
1314 0 : Word16 exp_gl2 = 0;
1315 0 : move16();
1316 0 : Word16 check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[0][0], exp_postpred_cov_re, EPSILON_FX, 0 );
1317 0 : IF( EQ_16( check_postPred, 1 ) )
1318 : {
1319 0 : Word16 exp_div_res = 0;
1320 0 : Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[0][0], postpred_cov_re_fx[0][0], &exp_div_res );
1321 0 : exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re );
1322 0 : gl2_fx = L_deposit_h( div_res );
1323 0 : exp_gl2 = exp_div_res;
1324 0 : move16();
1325 :
1326 0 : Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gl2_fx, exp_gl2, ONE_IN_Q30, 1 );
1327 0 : IF( EQ_16( Cmp1, negate( 1 ) ) )
1328 : {
1329 0 : gl2_fx = ONE_IN_Q30;
1330 0 : exp_gl2 = 1;
1331 0 : move16();
1332 0 : move16();
1333 : }
1334 :
1335 0 : gl2_fx = Sqrt32( gl2_fx, &exp_gl2 );
1336 : }
1337 : ELSE
1338 : {
1339 0 : gl2_fx = ONE_IN_Q30;
1340 0 : exp_gl2 = 1;
1341 0 : move16();
1342 0 : move16();
1343 : }
1344 :
1345 0 : Word16 exp_gr2 = 0;
1346 0 : check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[1][1], exp_postpred_cov_re, EPSILON_FX, 0 );
1347 0 : IF( EQ_16( check_postPred, 1 ) )
1348 : {
1349 0 : Word16 exp_div_res = 0;
1350 0 : Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[1][1], postpred_cov_re_fx[1][1], &exp_div_res );
1351 0 : exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re );
1352 0 : gr2_fx = L_deposit_h( div_res );
1353 0 : exp_gr2 = exp_div_res;
1354 :
1355 0 : Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gr2_fx, exp_gr2, ONE_IN_Q30, 1 );
1356 0 : IF( EQ_16( Cmp1, negate( 1 ) ) )
1357 : {
1358 0 : gr2_fx = ONE_IN_Q30;
1359 0 : move16();
1360 0 : exp_gr2 = 1;
1361 0 : move16();
1362 : }
1363 :
1364 0 : gr2_fx = Sqrt32( gr2_fx, &exp_gr2 );
1365 : }
1366 : ELSE
1367 : {
1368 0 : gr2_fx = ONE_IN_Q30;
1369 0 : move16();
1370 0 : exp_gr2 = 1;
1371 0 : move16();
1372 : }
1373 :
1374 : Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1375 : Word16 pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1376 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1377 : {
1378 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1379 : {
1380 0 : pred_mat_buf_re[i][j] = exp_pred_re;
1381 0 : move16();
1382 0 : pred_mat_buf_im[i][j] = exp_pred_im;
1383 0 : move16();
1384 : }
1385 : }
1386 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1387 : {
1388 0 : hMd->pred_mat_re_fx[i][0] = Mpy_32_32( hMd->pred_mat_re_fx[i][0], gl2_fx );
1389 0 : move32();
1390 0 : hMd->pred_mat_re_fx[i][1] = Mpy_32_32( hMd->pred_mat_re_fx[i][1], gr2_fx );
1391 0 : move32();
1392 0 : pred_mat_buf_re[i][0] = add( exp_pred_re, exp_gl2 );
1393 0 : move16();
1394 0 : pred_mat_buf_re[i][1] = add( exp_pred_re, exp_gr2 );
1395 0 : move16();
1396 : }
1397 :
1398 0 : IF( EQ_16( real_only, 0 ) )
1399 : {
1400 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1401 : {
1402 0 : hMd->pred_mat_im_fx[i][0] = Mpy_32_32( hMd->pred_mat_im_fx[i][0], gl2_fx );
1403 0 : move32();
1404 0 : hMd->pred_mat_im_fx[i][1] = Mpy_32_32( hMd->pred_mat_im_fx[i][1], gr2_fx );
1405 0 : move32();
1406 :
1407 0 : pred_mat_buf_im[i][0] = add( exp_pred_im, exp_gl2 );
1408 0 : move16();
1409 0 : pred_mat_buf_im[i][1] = add( exp_pred_im, exp_gr2 );
1410 0 : move16();
1411 : }
1412 : }
1413 :
1414 0 : Word16 max_exp_pred_re = MIN16B, max_exp_pred_im = MIN16B;
1415 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1416 : {
1417 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1418 : {
1419 0 : max_exp_pred_re = s_max( max_exp_pred_re, pred_mat_buf_re[i][j] );
1420 0 : max_exp_pred_im = s_max( max_exp_pred_im, pred_mat_buf_im[i][j] );
1421 : }
1422 : }
1423 :
1424 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1425 : {
1426 0 : FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
1427 : {
1428 0 : hMd->pred_mat_re_fx[i][j] = L_shr( hMd->pred_mat_re_fx[i][j], max_exp_pred_re - pred_mat_buf_re[i][j] );
1429 0 : move32();
1430 0 : hMd->pred_mat_im_fx[i][j] = L_shr( hMd->pred_mat_im_fx[i][j], max_exp_pred_im - pred_mat_buf_im[i][j] );
1431 0 : move32();
1432 : }
1433 : }
1434 :
1435 0 : hMd->exp_pred_mat_re = max_exp_pred_re;
1436 0 : move16();
1437 0 : hMd->exp_pred_mat_im = max_exp_pred_im;
1438 0 : move16();
1439 : }
1440 : }
1441 :
1442 0 : return;
1443 : }
1444 :
1445 :
1446 0 : static void get_base2_bits(
1447 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
1448 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1449 : const Word16 num_subframes,
1450 : const Word16 num_quant_strats,
1451 : const Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1452 : const Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1453 : Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1454 : const Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1455 : const Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1456 : const Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1457 : const Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
1458 : Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] )
1459 : {
1460 : Word16 pred_roll_bits;
1461 : Word16 d_gain_bits, pitch_gain_bits, pose_idx, q;
1462 : Word16 pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1463 : Word16 bin_ch_2, bin_ch_2_num_sf, bin_ch_num_sf;
1464 :
1465 : ISAR_SPLIT_REND_POSE_TYPE pose_type;
1466 :
1467 0 : FOR( q = 0; q < num_quant_strats; q++ )
1468 : {
1469 0 : pred_yaw_bits[q] = ceil_log_2( pred_quant_pnts_yaw[q] );
1470 0 : move16();
1471 : }
1472 0 : pred_roll_bits = ceil_log_2( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS );
1473 :
1474 0 : d_gain_bits = ceil_log_2( ISAR_SPLIT_REND_D_QUANT_PNTS );
1475 0 : pitch_gain_bits = d_gain_bits;
1476 0 : move16();
1477 :
1478 0 : FOR( q = 0; q < num_quant_strats; q++ )
1479 : {
1480 0 : base2bits[q] = 0;
1481 0 : move32();
1482 : }
1483 :
1484 0 : bin_ch_2 = DEPR_i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
1485 0 : bin_ch_2_num_sf = DEPR_i_mult( bin_ch_2, num_subframes );
1486 0 : bin_ch_num_sf = DEPR_i_mult( BINAURAL_CHANNELS, num_subframes );
1487 :
1488 0 : FOR( q = 0; q < num_quant_strats; q++ )
1489 : {
1490 0 : FOR( pose_idx = 0; pose_idx < sub( pMultiBinPoseData->num_poses, 1 ); pose_idx++ )
1491 : {
1492 0 : pose_type = hBinHrSplitPreRend->pose_type[pose_idx];
1493 0 : IF( EQ_32( pose_type, ANY_YAW ) )
1494 : {
1495 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_num_sf ) );
1496 0 : move32();
1497 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_num_sf ) );
1498 0 : move32();
1499 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) );
1500 0 : move32();
1501 :
1502 :
1503 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( d_gain_bits, d_bands_yaw[q] ), num_subframes ) );
1504 0 : move32();
1505 : }
1506 0 : ELSE IF( EQ_32( pose_type, PITCH_ONLY ) )
1507 : {
1508 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) );
1509 0 : move32();
1510 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) );
1511 0 : move32();
1512 : }
1513 : ELSE
1514 : {
1515 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_num_sf ) );
1516 0 : move32();
1517 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_num_sf ) );
1518 0 : move32();
1519 0 : base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) );
1520 0 : move32();
1521 : }
1522 : }
1523 : }
1524 :
1525 0 : return;
1526 : }
1527 :
1528 :
1529 0 : static void isar_SplitRenderer_code_md_base2(
1530 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
1531 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1532 : const Word16 num_subframes,
1533 : const Word16 pred_real_bands_yaw,
1534 : const Word16 pred_imag_bands_yaw,
1535 : const Word16 pred_quant_pnts_yaw,
1536 : const Word16 d_bands_yaw,
1537 : const Word16 bands_pitch,
1538 : const Word16 pred_real_bands_roll,
1539 : const Word16 pred_imag_bands_roll,
1540 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1541 : {
1542 : Word16 pos_idx, b, ch1, ch2, sf_idx;
1543 : Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses;
1544 : Word16 min_pred_roll_idx, pred_roll_code_len;
1545 : Word16 pred_cb_idx;
1546 : Word32 code;
1547 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
1548 : ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
1549 :
1550 0 : pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
1551 0 : IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
1552 : {
1553 0 : pred_cb_idx = 1;
1554 0 : move16();
1555 : }
1556 : ELSE
1557 : {
1558 0 : pred_cb_idx = 0;
1559 0 : move16();
1560 : }
1561 0 : min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
1562 0 : min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
1563 0 : min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] );
1564 0 : min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] );
1565 :
1566 0 : pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx];
1567 0 : move16();
1568 0 : pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len;
1569 0 : move16();
1570 0 : gd_code_len = pHuff_cfg->gd_base2_code_len;
1571 0 : move16();
1572 0 : p_gd_code_len = pHuff_cfg->p_gd_base2_code_len;
1573 0 : move16();
1574 :
1575 0 : num_poses = pMultiBinPoseData->num_poses;
1576 0 : move16();
1577 :
1578 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1579 : {
1580 0 : FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ )
1581 : {
1582 0 : IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) )
1583 : {
1584 0 : FOR( b = 0; b < pred_imag_bands_yaw; b++ )
1585 : {
1586 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1587 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1588 : {
1589 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1590 : {
1591 0 : code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx );
1592 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
1593 : }
1594 : }
1595 :
1596 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1597 : {
1598 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1599 : {
1600 0 : code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx );
1601 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
1602 : }
1603 : }
1604 : }
1605 0 : FOR( ; b < pred_real_bands_yaw; b++ )
1606 : {
1607 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1608 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1609 : {
1610 0 : code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_idx );
1611 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
1612 : }
1613 : }
1614 0 : FOR( b = 0; b < d_bands_yaw; b++ )
1615 : {
1616 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1617 0 : code = L_sub( hMd->gd_idx, min_gd_idx );
1618 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len );
1619 : }
1620 : }
1621 0 : ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) )
1622 : {
1623 0 : FOR( b = 0; b < bands_pitch; b++ )
1624 : {
1625 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1626 0 : code = L_sub( hMd->gd_idx, min_p_gd_idx );
1627 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
1628 :
1629 0 : code = L_sub( hMd->gd2_idx, min_p_gd_idx );
1630 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
1631 : }
1632 : }
1633 : ELSE
1634 : {
1635 0 : FOR( b = 0; b < pred_imag_bands_roll; b++ )
1636 : {
1637 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1638 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1639 : {
1640 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1641 : {
1642 0 : code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx );
1643 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
1644 : }
1645 : }
1646 :
1647 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1648 : {
1649 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1650 : {
1651 0 : code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx );
1652 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
1653 : }
1654 : }
1655 : }
1656 0 : FOR( ; b < pred_real_bands_roll; b++ )
1657 : {
1658 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1659 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1660 : {
1661 0 : code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_roll_idx );
1662 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
1663 : }
1664 : }
1665 : }
1666 : }
1667 : }
1668 :
1669 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1670 : {
1671 : static int16_t num_bits = 0;
1672 : static int16_t cntr = 0;
1673 : float fnum_bits;
1674 :
1675 : cntr++;
1676 :
1677 : num_bits += pBits->bits_written;
1678 : /* collect bits for every second */
1679 : if ( cntr == 50 )
1680 : {
1681 : cntr = 0;
1682 : fnum_bits = (float) num_bits / 1000.0f;
1683 : dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
1684 : num_bits = 0;
1685 : }
1686 : }
1687 : #endif
1688 0 : return;
1689 : }
1690 :
1691 :
1692 0 : static void isar_SplitRenderer_code_md_huff(
1693 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
1694 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1695 : const Word16 num_subframes,
1696 : const Word16 pred_real_bands_yaw,
1697 : const Word16 pred_imag_bands_yaw,
1698 : const Word16 pred_quant_pnts_yaw,
1699 : const Word16 d_bands_yaw,
1700 : const Word16 bands_pitch,
1701 : const Word16 pred_real_bands_roll,
1702 : const Word16 pred_imag_bands_roll,
1703 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1704 : {
1705 : Word16 pos_idx, b, ch1, ch2, sf_idx, num_poses;
1706 : Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1707 : Word16 min_pred_idx, max_pred_idx;
1708 : Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
1709 : Word32 code, len;
1710 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
1711 : ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
1712 :
1713 0 : pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
1714 :
1715 0 : IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
1716 : {
1717 0 : pred_cb_idx = 1;
1718 0 : move16();
1719 : }
1720 : ELSE
1721 : {
1722 0 : pred_cb_idx = 0;
1723 0 : move16();
1724 : }
1725 :
1726 0 : min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
1727 0 : max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[DEPR_i_mult( sub( pred_quant_pnts_yaw, 1 ), 3 )] );
1728 0 : min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
1729 0 : max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[DEPR_i_mult( sub( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS, 1 ), 3 )] );
1730 :
1731 0 : num_poses = pMultiBinPoseData->num_poses;
1732 0 : move16();
1733 :
1734 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1735 : {
1736 0 : FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ )
1737 : {
1738 0 : IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) )
1739 : {
1740 0 : FOR( b = 0; b < pred_imag_bands_yaw; b++ )
1741 : {
1742 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1743 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
1744 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1745 : {
1746 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1747 : {
1748 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
1749 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1750 : }
1751 : }
1752 :
1753 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
1754 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1755 : {
1756 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1757 : {
1758 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
1759 :
1760 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1761 : }
1762 : }
1763 : }
1764 0 : FOR( ; b < pred_real_bands_yaw; b++ )
1765 : {
1766 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1767 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
1768 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1769 : {
1770 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len );
1771 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1772 : }
1773 : }
1774 0 : FOR( b = 0; b < d_bands_yaw; b++ )
1775 : {
1776 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1777 0 : isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len );
1778 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1779 : }
1780 : }
1781 0 : ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) )
1782 : {
1783 0 : FOR( b = 0; b < bands_pitch; b++ )
1784 : {
1785 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1786 0 : isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
1787 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1788 :
1789 0 : isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
1790 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1791 : }
1792 : }
1793 : ELSE
1794 : {
1795 0 : FOR( b = 0; b < pred_imag_bands_roll; b++ )
1796 : {
1797 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1798 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
1799 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1800 : {
1801 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1802 : {
1803 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
1804 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1805 : }
1806 : }
1807 :
1808 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
1809 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1810 : {
1811 0 : FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1812 : {
1813 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
1814 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1815 : }
1816 : }
1817 : }
1818 0 : FOR( ; b < pred_real_bands_roll; b++ )
1819 : {
1820 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1821 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
1822 0 : FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1823 : {
1824 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len );
1825 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1826 : }
1827 : }
1828 : }
1829 : }
1830 : }
1831 :
1832 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1833 : {
1834 : static int16_t num_bits = 0;
1835 : static int16_t cntr = 0;
1836 : float fnum_bits;
1837 :
1838 : cntr++;
1839 : num_bits += pBits->bits_written;
1840 : /* collect bits for every second */
1841 : IF( cntr == 50 )
1842 : {
1843 : cntr = 0;
1844 : fnum_bits = (float) num_bits / 1000.0f;
1845 : dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
1846 : num_bits = 0;
1847 : }
1848 : }
1849 : #endif
1850 0 : return;
1851 : }
1852 :
1853 :
1854 0 : static void isar_SplitRenderer_quant_code(
1855 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
1856 : const IVAS_QUATERNION headPosition,
1857 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1858 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
1859 : const Word16 low_res_pre_rend_rot,
1860 : const Word16 ro_md_flag,
1861 : const Word32 target_md_bits,
1862 : const Word16 Q_frame )
1863 : {
1864 : Word16 q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
1865 : Word32 overhead_bits, quant_strat_bits, huff_bits, start_bit;
1866 : Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1867 : Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1868 : Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1869 : Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1870 : Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1871 : Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1872 : Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1873 : #ifdef DEBUG_QUANT_MD_FX
1874 : float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1875 : float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1876 : #endif
1877 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
1878 : Word16 rot_axis_code, num_bits;
1879 :
1880 0 : IF( low_res_pre_rend_rot )
1881 : {
1882 0 : num_subframes = 1;
1883 : }
1884 : ELSE
1885 : {
1886 0 : num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
1887 : }
1888 :
1889 0 : overhead_bits = pBits->bits_written;
1890 :
1891 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS );
1892 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS );
1893 0 : rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits );
1894 0 : if ( num_bits > 0 )
1895 : {
1896 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, (Word32) rot_axis_code, num_bits );
1897 : }
1898 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, (Word32) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS );
1899 :
1900 : /* code ref pose*/
1901 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1902 : {
1903 : Word16 angle;
1904 : IVAS_QUATERNION head_pos_euler, headPosition_q22;
1905 :
1906 0 : modify_Quat_q_fx( &headPosition, &headPosition_q22, Q22 );
1907 0 : Quat2EulerDegree_fx( headPosition_q22, &head_pos_euler.z_fx, &head_pos_euler.y_fx, &head_pos_euler.x_fx );
1908 0 : angle = (Word16) L_shr_r( head_pos_euler.x_fx, Q22 );
1909 0 : angle = add( angle, 180 );
1910 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1911 :
1912 0 : angle = (Word16) L_shr_r( head_pos_euler.y_fx, Q22 );
1913 0 : angle = add( angle, 180 );
1914 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1915 :
1916 0 : angle = (Word16) L_shr_r( head_pos_euler.z_fx, Q22 );
1917 0 : angle = add( angle, 180 );
1918 :
1919 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1920 : }
1921 :
1922 0 : isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
1923 : pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx,
1924 : d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats );
1925 : #ifdef DEBUG_QUANT_MD_FX
1926 : fixedToFloat_arrL( pred_quantstep_yaw_fx, pred_quantstep_yaw, Q31, ISAR_SPLIT_REND_NUM_QUANT_STRATS );
1927 : fixedToFloat_arrL( pred_1byquantstep_yaw_fx, pred_1byquantstep_yaw, Q26, ISAR_SPLIT_REND_NUM_QUANT_STRATS );
1928 : #endif
1929 :
1930 0 : quant_strat_bits = ceil_log_2( num_quant_strats );
1931 :
1932 0 : overhead_bits = L_add( L_add( L_sub( pBits->bits_written, overhead_bits ), quant_strat_bits ), 1 ); /* 1 for base2 vs huff */
1933 :
1934 0 : get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw,
1935 : pred_quant_pnts_yaw,
1936 : d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits );
1937 :
1938 0 : FOR( q = 0; q < num_quant_strats; q++ )
1939 : {
1940 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1941 : {
1942 0 : FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
1943 : {
1944 0 : IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
1945 : {
1946 0 : FOR( b = 0; b < pred_imag_bands_yaw[q]; b++ )
1947 : {
1948 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1949 0 : isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame
1950 : #ifdef DEBUG_QUANT_MD_FX
1951 : ,
1952 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q]
1953 : #endif
1954 : );
1955 : }
1956 0 : FOR( ; b < pred_real_bands_yaw[q]; b++ )
1957 : {
1958 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1959 0 : isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame
1960 : #ifdef DEBUG_QUANT_MD_FX
1961 : ,
1962 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q]
1963 : #endif
1964 : );
1965 : }
1966 :
1967 0 : FOR( b = 0; b < d_bands_yaw[q]; b++ )
1968 : {
1969 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1970 0 : isar_split_rend_quant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame
1971 : #ifdef DEBUG_QUANT_MD_FX
1972 : ,
1973 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f
1974 : #endif
1975 : );
1976 : }
1977 : }
1978 0 : ELSE IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
1979 : {
1980 0 : FOR( b = 0; b < bands_pitch[q]; b++ )
1981 : {
1982 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1983 0 : isar_split_rend_quant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame
1984 : #ifdef DEBUG_QUANT_MD_FX
1985 : ,
1986 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f
1987 : #endif
1988 : );
1989 : }
1990 : }
1991 : ELSE
1992 : {
1993 0 : FOR( b = 0; b < pred_imag_bands_roll[q]; b++ )
1994 : {
1995 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1996 0 : isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame
1997 : #ifdef DEBUG_QUANT_MD_FX
1998 : ,
1999 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP
2000 : #endif
2001 : );
2002 : }
2003 0 : FOR( ; b < pred_real_bands_roll[q]; b++ )
2004 : {
2005 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
2006 0 : isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame
2007 : #ifdef DEBUG_QUANT_MD_FX
2008 : ,
2009 : hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP
2010 : #endif
2011 : );
2012 : }
2013 : }
2014 : }
2015 : }
2016 :
2017 : /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/
2018 0 : start_bit = pBits->bits_written;
2019 :
2020 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
2021 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
2022 :
2023 0 : huff_bits = pBits->bits_written;
2024 0 : isar_SplitRenderer_code_md_huff(
2025 : hBinHrSplitPreRend,
2026 : pMultiBinPoseData,
2027 : num_subframes,
2028 0 : pred_real_bands_yaw[q],
2029 0 : pred_imag_bands_yaw[q],
2030 0 : pred_quant_pnts_yaw[q],
2031 0 : d_bands_yaw[q],
2032 0 : bands_pitch[q],
2033 0 : pred_real_bands_roll[q],
2034 0 : pred_imag_bands_roll[q],
2035 : pBits );
2036 :
2037 0 : huff_bits = L_sub( pBits->bits_written, huff_bits );
2038 0 : test();
2039 0 : test();
2040 0 : test();
2041 0 : IF( GE_32( target_md_bits, ( base2bits[q] + overhead_bits ) ) || GE_32( target_md_bits, ( huff_bits + overhead_bits ) ) || EQ_16( q, sub( num_quant_strats, 1 ) ) )
2042 : {
2043 0 : IF( GT_32( huff_bits, base2bits[q] ) )
2044 : {
2045 0 : pBits->bits_written = start_bit;
2046 :
2047 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
2048 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
2049 :
2050 0 : isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
2051 0 : pred_quant_pnts_yaw[q], d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits );
2052 : }
2053 0 : BREAK;
2054 : }
2055 :
2056 0 : pBits->bits_written = start_bit;
2057 : }
2058 :
2059 : #ifdef SPLIT_MD_CODING_DEBUG
2060 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2061 : {
2062 : int16_t val, quant_strat, ch1, ch2;
2063 : char filename[200] = "split_md_debug_indices.bin";
2064 : quant_strat = q;
2065 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
2066 : {
2067 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
2068 : {
2069 : for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ )
2070 : {
2071 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2072 : {
2073 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2074 : {
2075 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
2076 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2077 : }
2078 : }
2079 : }
2080 : for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
2081 : {
2082 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2083 : {
2084 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2085 : {
2086 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
2087 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2088 : }
2089 : }
2090 : }
2091 : for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
2092 : {
2093 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
2094 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2095 : }
2096 : }
2097 : else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
2098 : {
2099 : for ( b = 0; b < bands_pitch[quant_strat]; b++ )
2100 : {
2101 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
2102 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2103 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx;
2104 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2105 : }
2106 : }
2107 : else
2108 : {
2109 : for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ )
2110 : {
2111 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2112 : {
2113 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2114 : {
2115 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
2116 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2117 : }
2118 : }
2119 : }
2120 : for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
2121 : {
2122 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2123 : {
2124 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2125 : {
2126 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
2127 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
2128 : }
2129 : }
2130 : }
2131 : }
2132 : }
2133 : }
2134 : #endif
2135 :
2136 0 : return;
2137 : }
2138 :
2139 :
2140 : /*-------------------------------------------------------------------------
2141 : * Function isar_SplitRenderer_GetRotMd()
2142 : *
2143 : *
2144 : *------------------------------------------------------------------------*/
2145 :
2146 0 : static void isar_SplitRenderer_GetRotMd_fx(
2147 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
2148 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
2149 : Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
2150 : Word16 exp_cldfb_re,
2151 : Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
2152 : Word16 exp_cldfb_im,
2153 : const Word16 low_res,
2154 : const Word16 ro_md_flag )
2155 : {
2156 0 : Word32 cov_ii_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2157 0 : Word32 cov_oo_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2158 0 : Word32 cov_io_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2159 0 : Word32 cov_ii_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2160 0 : Word32 cov_oo_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2161 0 : Word32 cov_io_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
2162 0 : Word16 exp_cov_io_re = 0, exp_cov_io_im = 0;
2163 0 : Word16 exp_cov_ii_re = 0, exp_cov_ii_im = 0;
2164 0 : Word16 exp_cov_oo_re = 0, exp_cov_oo_im = 0;
2165 :
2166 0 : Word16 real_only = 0;
2167 : Word16 pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2;
2168 : Word16 num_md_bands, num_poses;
2169 0 : const Word16 *pBand_grouping = isar_split_rend_band_grouping;
2170 :
2171 0 : push_wmops( "isar_SplitRenderer_GetRotMd_fx" );
2172 :
2173 0 : num_md_bands = MAX_SPLIT_REND_MD_BANDS;
2174 0 : move16();
2175 0 : num_poses = pMultiBinPoseData->num_poses;
2176 0 : move16();
2177 :
2178 0 : IF( low_res )
2179 : {
2180 0 : num_slots = CLDFB_NO_COL_MAX;
2181 0 : move16();
2182 0 : num_subframes = 1;
2183 0 : move16();
2184 : }
2185 : ELSE
2186 : {
2187 0 : num_slots = MAX_PARAM_SPATIAL_SUBFRAMES;
2188 0 : move16();
2189 0 : num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
2190 0 : move16();
2191 : }
2192 :
2193 : /* compute reference signal covariance */
2194 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2195 : {
2196 0 : start_slot_idx = imult1616( sf_idx, num_slots );
2197 0 : FOR( b = 0; b < num_md_bands; b++ )
2198 : {
2199 0 : test();
2200 0 : IF( LT_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) )
2201 : {
2202 0 : real_only = 0;
2203 0 : move16();
2204 : }
2205 : ELSE
2206 : {
2207 0 : real_only = 1;
2208 0 : move16();
2209 : }
2210 :
2211 0 : ch_s_idx1 = 0;
2212 :
2213 0 : ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, cov_ii_re_fx, &exp_cov_ii_re, cov_ii_im_fx, &exp_cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
2214 :
2215 : /* compute rotated signal covariance */
2216 0 : FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
2217 : {
2218 0 : IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL )
2219 : {
2220 0 : IF( GE_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) )
2221 : {
2222 0 : real_only = 1;
2223 : }
2224 : }
2225 0 : ch_s_idx2 = imult1616( add( pos_idx, 1 ), BINAURAL_CHANNELS );
2226 :
2227 0 : ComputeBandedCrossCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_io_re_fx, &exp_cov_io_re, cov_io_im_fx, &exp_cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
2228 :
2229 0 : ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_oo_re_fx, &exp_cov_oo_re, cov_oo_im_fx, &exp_cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
2230 :
2231 0 : ComputeCoeffs_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only );
2232 : }
2233 : }
2234 : }
2235 :
2236 0 : pop_wmops();
2237 0 : return;
2238 : }
2239 :
2240 :
2241 : /*-------------------------------------------------------------------------
2242 : * Function isar_rend_CldfbSplitPreRendProcess()
2243 : *
2244 : *
2245 : *------------------------------------------------------------------------*/
2246 :
2247 0 : void isar_rend_CldfbSplitPreRendProcess(
2248 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
2249 : const IVAS_QUATERNION headPosition,
2250 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
2251 : Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
2252 : Word16 exp_cldfb_re,
2253 : Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
2254 : Word16 exp_cldfb_im,
2255 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
2256 : const Word32 target_md_bits,
2257 : const Word16 low_res_pre_rend_rot,
2258 : const Word16 ro_md_flag )
2259 : {
2260 0 : push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
2261 :
2262 0 : isar_SplitRenderer_GetRotMd_fx( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, low_res_pre_rend_rot, ro_md_flag );
2263 :
2264 : Word16 num_md_bands, num_poses;
2265 : Word16 pos_idx, b, sf_idx, num_subframes;
2266 :
2267 0 : num_md_bands = MAX_SPLIT_REND_MD_BANDS;
2268 0 : num_poses = pMultiBinPoseData->num_poses;
2269 :
2270 0 : IF( low_res_pre_rend_rot )
2271 : {
2272 0 : num_subframes = 1;
2273 : }
2274 : ELSE
2275 : {
2276 0 : num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
2277 : }
2278 :
2279 : /*FILE *filePointer_gd, *filePointer_gd2;
2280 : FILE *filePointer_re, *filePointer_im;
2281 : filePointer_gd = fopen("Fixed_code_cov_gd_complete.txt", "a");
2282 : filePointer_gd2 = fopen("Fixed_code_cov_gd2_complete.txt", "a");
2283 : filePointer_re = fopen("Fixed_code_re_complete.txt", "a");
2284 : filePointer_im = fopen("Fixed_code_im_complete.txt", "a");*/
2285 :
2286 : #ifdef DUMP_GETROTMD_OUTPUT
2287 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2288 : {
2289 : for ( b = 0; b < num_md_bands; b++ )
2290 : {
2291 : for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
2292 : {
2293 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
2294 : {
2295 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd );
2296 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 );
2297 : /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
2298 : fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
2299 : }
2300 : else
2301 : {
2302 : for ( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
2303 : {
2304 : for ( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
2305 : {
2306 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re );
2307 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im );
2308 : /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]);
2309 : fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/
2310 : }
2311 : }
2312 : }
2313 : }
2314 : }
2315 : }
2316 : #endif
2317 :
2318 : /*fclose(filePointer_gd);
2319 : fclose(filePointer_gd2);
2320 : fclose(filePointer_re);
2321 : fclose(filePointer_im);*/
2322 :
2323 : /* Check if rescaling can be simplified/avoid */
2324 :
2325 0 : Word16 exp_frame = 0;
2326 : // Word32 L_temp_max = 0;
2327 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2328 : {
2329 0 : FOR( b = 0; b < num_md_bands; b++ )
2330 : {
2331 0 : FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
2332 : {
2333 0 : IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
2334 : {
2335 0 : exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd );
2336 0 : exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 );
2337 : }
2338 : ELSE
2339 : {
2340 0 : exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re );
2341 0 : exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2 );
2342 0 : exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im );
2343 : }
2344 : }
2345 : }
2346 : }
2347 : // exp_frame = s_min( exp_frame, sub( 31, norm_l( L_temp_max ) ) );
2348 0 : exp_frame = s_min( exp_frame, 15 ); // Considering the max value as of prediction matrices as 300
2349 :
2350 0 : Word16 Q_frame = sub( Q31, exp_frame );
2351 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2352 : {
2353 0 : FOR( b = 0; b < num_md_bands; b++ )
2354 : {
2355 0 : FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
2356 : {
2357 0 : IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
2358 : {
2359 0 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ) );
2360 0 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ) );
2361 : /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
2362 : fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
2363 : }
2364 : ELSE
2365 : {
2366 0 : FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
2367 : {
2368 0 : Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re, exp_frame ) );
2369 0 : Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im, exp_frame ) );
2370 : }
2371 0 : Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re2, BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2, exp_frame ) );
2372 : }
2373 : }
2374 : }
2375 : }
2376 :
2377 0 : isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits, Q_frame );
2378 : #ifdef DEBUG_QUANT_CODE_OUT
2379 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
2380 : {
2381 : for ( b = 0; b < num_md_bands; b++ )
2382 : {
2383 : for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
2384 : {
2385 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
2386 : {
2387 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, Q_frame );
2388 : hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, Q_frame );
2389 : /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
2390 : fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
2391 : }
2392 : else
2393 : {
2394 : for ( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
2395 : {
2396 : fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i], Q_frame, BINAURAL_CHANNELS );
2397 : fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i], Q_frame, BINAURAL_CHANNELS );
2398 : // for ( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
2399 : //{
2400 : // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], Q6 );
2401 : // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], Q6 );
2402 : // /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]);
2403 : // fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/
2404 : // }
2405 : }
2406 : }
2407 : }
2408 : }
2409 : }
2410 : #endif
2411 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
2412 : float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv;
2413 : IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler;
2414 : float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
2415 : float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
2416 : int16_t sf_idx, pos_idx, b, ch1, ch2;
2417 : int32_t read_off, write_off;
2418 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
2419 : {
2420 : QuaternionsPost[sf_idx].w = -3.0f;
2421 : QuaternionsPost[sf_idx].x = 0.0f;
2422 : QuaternionsPost[sf_idx].y = 0.0f;
2423 : QuaternionsPost[sf_idx].z = 0.0f;
2424 : }
2425 :
2426 : hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1;
2427 : set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData );
2428 : set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData );
2429 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
2430 : {
2431 : Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
2432 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f;
2433 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x );
2434 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y );
2435 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z );
2436 : }
2437 : for ( sf_idx = 0; sf_idx < 1; sf_idx++ )
2438 : {
2439 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
2440 : {
2441 : for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ )
2442 : {
2443 : hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
2444 : BIN_HR_SPLIT_REND_MD_HANDLE hMd;
2445 : hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
2446 : minv = -1.4f;
2447 : maxv = 1.4f;
2448 : step = ( maxv - minv ) / 62.0f;
2449 : if ( b >= 20 )
2450 : {
2451 : float sign;
2452 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2453 : {
2454 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2455 : {
2456 : sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f;
2457 : IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] );
2458 : hMd->pred_mat_re[ch1][ch2] *= sign;
2459 : hMd->pred_mat_im[ch1][ch2] = 0.0f;
2460 : }
2461 : }
2462 : }
2463 :
2464 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
2465 : {
2466 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
2467 : {
2468 : quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
2469 : quant_val = min( maxv, max( quant_val, minv ) );
2470 : quant_val = (int16_t) roundf( quant_val / step );
2471 : hMd->pred_mat_re[ch1][ch2] = quant_val * step;
2472 : hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
2473 :
2474 : quant_val = hMd->pred_mat_im[ch1][ch2];
2475 : quant_val = min( maxv, max( quant_val, minv ) );
2476 : quant_val = (int16_t) roundf( quant_val / step );
2477 : hMd->pred_mat_im[ch1][ch2] = quant_val * step;
2478 : }
2479 : }
2480 : }
2481 : }
2482 : }
2483 :
2484 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
2485 : {
2486 : mvr2r( (float *) Cldfb_In_BinReal[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
2487 : mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
2488 : mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
2489 : mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
2490 : isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 );
2491 :
2492 : {
2493 : float *pOut[2];
2494 : char fname[200] = "ref_act_pos.wav";
2495 : pOut[0] = tmpCrendBuffer[0];
2496 : pOut[1] = tmpCrendBuffer[1];
2497 : dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 );
2498 : }
2499 : }
2500 : #endif
2501 :
2502 0 : pop_wmops();
2503 0 : return;
2504 : }
2505 :
2506 :
2507 : /*-------------------------------------------------------------------------
2508 : * Function isar_splitBinPreRendOpen()
2509 : *
2510 : *
2511 : *------------------------------------------------------------------------*/
2512 :
2513 0 : ivas_error isar_splitBinPreRendOpen(
2514 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
2515 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
2516 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
2517 : ,
2518 : const int32_t output_Fs
2519 : #endif
2520 : )
2521 : {
2522 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend;
2523 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
2524 : ivas_error error;
2525 : int16_t ch;
2526 : #endif
2527 : Word16 pos_idx, sf_idx, bandIdx;
2528 :
2529 0 : IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL )
2530 : {
2531 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) );
2532 : }
2533 :
2534 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
2535 : for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
2536 : {
2537 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2538 : {
2539 : hBinRend->cldfbSynRotBinDec[i][ch] = NULL;
2540 : }
2541 : }
2542 :
2543 : for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
2544 : {
2545 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2546 : {
2547 : if ( ( error = openCldfb_ivas_fx( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
2548 : {
2549 : return error;
2550 : }
2551 : }
2552 : }
2553 : #endif
2554 :
2555 0 : FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
2556 : {
2557 0 : FOR( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ )
2558 : {
2559 0 : FOR( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ )
2560 : {
2561 0 : hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd_fx = 0;
2562 : }
2563 : }
2564 : }
2565 0 : set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData );
2566 0 : set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData );
2567 :
2568 0 : isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
2569 :
2570 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
2571 : ivas_error error;
2572 : if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK )
2573 : {
2574 : return error;
2575 : }
2576 : #endif
2577 :
2578 0 : *hBinHrSplitPreRend = hBinRend;
2579 :
2580 0 : return IVAS_ERR_OK;
2581 : }
2582 :
2583 :
2584 : /*-------------------------------------------------------------------------
2585 : * Function isar_splitBinPreRendClose()
2586 : *
2587 : *
2588 : *------------------------------------------------------------------------*/
2589 :
2590 0 : void isar_splitBinPreRendClose(
2591 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend )
2592 : {
2593 0 : IF( ( *hBinHrSplitPreRend ) != NULL )
2594 : {
2595 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
2596 : {
2597 : Word16 i, n;
2598 : FOR( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
2599 : {
2600 : FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
2601 : {
2602 : IF( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL )
2603 : {
2604 : deleteCldfb_ivas_fx( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) );
2605 : ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL;
2606 : }
2607 : }
2608 : }
2609 : }
2610 : #endif
2611 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
2612 : isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend );
2613 : #endif
2614 :
2615 0 : free( ( *hBinHrSplitPreRend ) );
2616 0 : ( *hBinHrSplitPreRend ) = NULL;
2617 : }
2618 :
2619 0 : return;
2620 : }
2621 :
2622 :
2623 : /*-------------------------------------------------------------------------*
2624 : * isar_set_split_rend_ht_setup()
2625 : *
2626 : *
2627 : *-------------------------------------------------------------------------*/
2628 :
2629 0 : void isar_set_split_rend_ht_setup_fx(
2630 : SPLIT_REND_WRAPPER *hSplitrend,
2631 : IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
2632 : Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] )
2633 : {
2634 : Word16 sf, i, j;
2635 :
2636 0 : IF( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
2637 : {
2638 0 : FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
2639 : {
2640 0 : Quaternions[sf] = Quaternions[0];
2641 :
2642 0 : FOR( i = 0; i < 3; i++ )
2643 : {
2644 0 : FOR( j = 0; j < 3; j++ )
2645 : {
2646 0 : Rmat_fx[sf][i][j] = Rmat_fx[0][i][j];
2647 0 : move32();
2648 : }
2649 : }
2650 : }
2651 : }
2652 :
2653 0 : return;
2654 : }
2655 :
2656 :
2657 : /*-------------------------------------------------------------------------
2658 : * Function isar_init_split_rend_handles()
2659 : *
2660 : *
2661 : *------------------------------------------------------------------------*/
2662 :
2663 0 : void isar_init_split_rend_handles(
2664 : SPLIT_REND_WRAPPER *hSplitRendWrapper )
2665 : {
2666 : Word16 i;
2667 :
2668 0 : hSplitRendWrapper->hBinHrSplitPreRend = NULL;
2669 0 : hSplitRendWrapper->hCldfbHandles = NULL;
2670 0 : hSplitRendWrapper->hSplitBinLCLDEnc = NULL;
2671 0 : hSplitRendWrapper->hLc3plusEnc = NULL;
2672 :
2673 0 : FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
2674 : {
2675 0 : hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = NULL;
2676 : }
2677 0 : hSplitRendWrapper->lc3plusDelaySamples = 0;
2678 0 : move32();
2679 :
2680 0 : isar_init_multi_bin_pose_data_fx_enc( &hSplitRendWrapper->multiBinPoseData );
2681 :
2682 0 : return;
2683 : }
2684 :
2685 :
2686 : /*-------------------------------------------------------------------------
2687 : * Function split_renderer_open_lc3plus()
2688 : *
2689 : *
2690 : *------------------------------------------------------------------------*/
2691 :
2692 0 : ivas_error split_renderer_open_lc3plus(
2693 : SPLIT_REND_WRAPPER *hSplitRendWrapper,
2694 : const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
2695 : const Word32 OutSampleRate,
2696 : const IVAS_RENDER_FRAMESIZE isar_frame_size )
2697 : {
2698 : ivas_error error;
2699 : Word16 i, delayBufferLength;
2700 : LC3PLUS_CONFIG config;
2701 : Word16 isar_frame_size_ms;
2702 :
2703 0 : IF( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK )
2704 : {
2705 0 : return error;
2706 : }
2707 :
2708 : /* Check configuration validity */
2709 0 : IF( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms )
2710 : {
2711 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" );
2712 : }
2713 :
2714 0 : config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000;
2715 0 : config.samplerate = OutSampleRate;
2716 0 : config.isar_frame_duration_us = isar_frame_size_ms * 1000;
2717 0 : config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 );
2718 0 : config.channels = BINAURAL_CHANNELS;
2719 :
2720 0 : if ( ( error = ISAR_LC3PLUS_ENC_Open( config,
2721 : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
2722 0 : isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ),
2723 : #else
2724 : isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ),
2725 : #endif
2726 : &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK )
2727 : {
2728 0 : return error;
2729 : }
2730 :
2731 : /* This returns delay of entire LC3plus chain (enc + dec) */
2732 0 : IF( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK )
2733 : {
2734 0 : return error;
2735 : }
2736 :
2737 : /* Alocate buffers for delay compensation */
2738 0 : IF( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
2739 : {
2740 0 : delayBufferLength = (Word16) ( OutSampleRate / (Word32) FRAMES_PER_SEC + hSplitRendWrapper->lc3plusDelaySamples );
2741 0 : FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
2742 : {
2743 0 : IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL )
2744 : {
2745 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
2746 : }
2747 :
2748 0 : set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength );
2749 : }
2750 0 : hSplitRendWrapper->lc3plusDelayBuffers_q = 31;
2751 : }
2752 : ELSE
2753 : {
2754 : /* Delay is always expected to be exactly 2 CLDFB columns */
2755 0 : assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 );
2756 0 : assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 );
2757 :
2758 0 : delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX;
2759 0 : FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
2760 : {
2761 0 : IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL )
2762 : {
2763 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
2764 : }
2765 :
2766 0 : set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength );
2767 : }
2768 0 : hSplitRendWrapper->lc3plusDelayBuffers_q = 31;
2769 : }
2770 :
2771 0 : return IVAS_ERR_OK;
2772 : }
2773 :
2774 :
2775 : /*-------------------------------------------------------------------------
2776 : * Function splitRendLc3plusEncodeAndWrite()
2777 : *
2778 : *
2779 : *------------------------------------------------------------------------*/
2780 :
2781 0 : ivas_error splitRendLc3plusEncodeAndWrite(
2782 : SPLIT_REND_WRAPPER *hSplitBin,
2783 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
2784 : const Word32 available_bits,
2785 : Word32 *in[],
2786 : Word16 Q_sig )
2787 : {
2788 : ivas_error error;
2789 : Word16 i;
2790 : Word32 lc3plusBitstreamSize;
2791 : Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
2792 : Word16 Q_in[16];
2793 0 : assert( hSplitBin->hLc3plusEnc != NULL );
2794 :
2795 : /* Find next byte boundary and zero-pad to it */
2796 0 : while ( pBits->bits_written % 8 != 0 )
2797 : {
2798 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
2799 : }
2800 :
2801 0 : for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
2802 : {
2803 0 : channel_ptrs[i] = in[i];
2804 : }
2805 :
2806 0 : IF( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK )
2807 : {
2808 0 : return error;
2809 : }
2810 :
2811 0 : IF( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
2812 : {
2813 0 : return error;
2814 : }
2815 :
2816 : /* Write bitstream */
2817 0 : set16_fx( Q_in, Q_sig, 16 );
2818 0 : move16();
2819 0 : IF( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize, Q_in ) ) != IVAS_ERR_OK )
2820 : {
2821 0 : return error;
2822 : }
2823 :
2824 0 : pBits->bits_written += 8 * lc3plusBitstreamSize;
2825 0 : pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
2826 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
2827 0 : pBits->codec_frame_size_ms = (Word16) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 );
2828 0 : pBits->isar_frame_size_ms = (Word16) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 );
2829 :
2830 0 : return IVAS_ERR_OK;
2831 : }
2832 :
2833 :
2834 : /*-------------------------------------------------------------------------
2835 : * Function isar_renderMultiTDBinToSplitBinaural()
2836 : *
2837 : *
2838 : *------------------------------------------------------------------------*/
2839 :
2840 0 : ivas_error isar_renderMultiTDBinToSplitBinaural(
2841 : SPLIT_REND_WRAPPER *hSplitBin,
2842 : const IVAS_QUATERNION headPosition,
2843 : const Word32 SplitRendBitRate,
2844 : const Word16 isar_frame_size_ms,
2845 : const Word16 codec_frame_size_ms,
2846 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
2847 : const Word16 max_bands,
2848 : // float *in[],
2849 : Word32 *in_fx[], // Q11
2850 : Word16 Q_sig,
2851 : const Word16 low_res_pre_rend_rot,
2852 : const Word16 pcm_out_flag,
2853 : const Word16 ro_md_flag )
2854 : {
2855 : ivas_error error;
2856 : Word32 bit_len, available_bits, target_md_bits, tmp_32;
2857 : Word16 num_cldfb_bands, ch, slot_idx, pos_idx, num_poses;
2858 : Word16 tmp, tmp_e;
2859 0 : Word32 Cldfb_In_BinReal_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 };
2860 0 : Word32 Cldfb_In_BinImag_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 };
2861 0 : Word16 Q_in = Q_sig, q_final = 0;
2862 0 : move16();
2863 0 : move16();
2864 : UWord8 useLc3plus;
2865 : Word32 *in_delayed_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
2866 : Word16 i;
2867 : Word32 num_slots;
2868 :
2869 0 : push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
2870 :
2871 0 : error = IVAS_ERR_OK;
2872 0 : num_poses = hSplitBin->multiBinPoseData.num_poses;
2873 :
2874 0 : useLc3plus = hSplitBin->hLc3plusEnc != NULL;
2875 :
2876 0 : IF( useLc3plus )
2877 : {
2878 : /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/
2879 : // Word16 frame_size = (Word16) ( hSplitBin->hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND );
2880 0 : tmp_e = 0;
2881 0 : tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.samplerate, FRAMES_PER_SEC, &tmp_e );
2882 0 : Word16 frame_size = shr( tmp, sub( 15, tmp_e ) ); // Q0
2883 0 : FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
2884 : {
2885 : /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */
2886 0 : mvl2l( hSplitBin->lc3plusDelayBuffers_fx[i] + frame_size, hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples );
2887 0 : in_delayed_fx[i] = hSplitBin->lc3plusDelayBuffers_fx[i];
2888 0 : Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples, sub( Q_in, hSplitBin->lc3plusDelayBuffers_q ) );
2889 0 : mvl2l( in_fx[i], hSplitBin->lc3plusDelayBuffers_fx[i] + hSplitBin->lc3plusDelaySamples, frame_size );
2890 : }
2891 0 : hSplitBin->lc3plusDelayBuffers_q = Q_in;
2892 : }
2893 : ELSE
2894 : {
2895 0 : FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
2896 : {
2897 0 : in_delayed_fx[i] = in_fx[i];
2898 0 : move32();
2899 : }
2900 : }
2901 :
2902 0 : test();
2903 0 : test();
2904 0 : IF( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
2905 : {
2906 0 : Word32 in_delayed_cldfb[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k] = { 0 };
2907 0 : Word16 gd_bits = sub( Q_sig, Q11 );
2908 0 : FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ )
2909 : {
2910 0 : Copy32( in_delayed_fx[i], in_delayed_cldfb[i], L_FRAME48k );
2911 0 : Scale_sig32( in_delayed_cldfb[i], L_FRAME48k, -gd_bits );
2912 : }
2913 0 : Q_sig = sub( Q_sig, gd_bits );
2914 0 : num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
2915 0 : move32();
2916 0 : num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels;
2917 0 : move16();
2918 : /* CLDFB Analysis*/
2919 0 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
2920 : {
2921 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
2922 : {
2923 : float *pOut[2];
2924 : char fname[200] = "ref_out_pos";
2925 : char tag[2];
2926 : tag[0] = (char) ( '0' + pos_idx );
2927 : tag[1] = '\0';
2928 : strcat( fname, tag );
2929 : strcat( fname, ".wav" );
2930 :
2931 : pOut[0] = in_delayed[2 * pos_idx];
2932 : pOut[1] = in_delayed[2 * pos_idx + 1];
2933 : dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 );
2934 : }
2935 :
2936 : #endif
2937 0 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2938 : {
2939 0 : HANDLE_CLDFB_FILTER_BANK temp_cldfbAna = hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch];
2940 0 : Scale_sig32( temp_cldfbAna->cldfb_state_fx,
2941 0 : sub( temp_cldfbAna->p_filter_length, temp_cldfbAna->no_channels ), sub( Q_sig, temp_cldfbAna->Q_cldfb_state ) );
2942 0 : temp_cldfbAna->Q_cldfb_state = Q_sig;
2943 0 : move16();
2944 0 : FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
2945 : {
2946 0 : Word16 Q_cldfb = Q_sig;
2947 : // floatToFixed_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels);
2948 0 : cldfbAnalysis_ts_fx_fixed_q( &( in_delayed_cldfb[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ),
2949 0 : Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
2950 0 : Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
2951 : max_bands,
2952 : temp_cldfbAna,
2953 : &Q_cldfb );
2954 : /*fixedToFloat_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels);
2955 : fixedToFloat_arrL(Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);
2956 : fixedToFloat_arrL(Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);*/
2957 : /*for (int k = 0; k < max_bands; k++) {
2958 : printf("\n%f %f ", Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k]);
2959 : }*/
2960 : }
2961 : }
2962 : }
2963 0 : q_final = sub( Q_sig, 5 );
2964 : }
2965 :
2966 0 : IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
2967 : {
2968 : // target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
2969 0 : target_md_bits = W_extract_l( W_mult0_32_32( isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ), L_FRAME48k ) );
2970 0 : tmp_e = 0;
2971 0 : tmp_32 = BASOP_Util_Divide3232_Scale_cadence( target_md_bits, 48000, &tmp_e );
2972 0 : target_md_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
2973 :
2974 : /*scaling to max Q*/
2975 0 : Word16 scale_factor = 31;
2976 0 : move32();
2977 0 : FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ )
2978 : {
2979 0 : FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
2980 : {
2981 0 : scale_factor = s_min( scale_factor, s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ) );
2982 : }
2983 : }
2984 0 : scale_factor = sub( scale_factor, 2 );
2985 0 : FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ )
2986 : {
2987 0 : FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
2988 : {
2989 0 : Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor );
2990 0 : Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor );
2991 : }
2992 : }
2993 0 : q_final = add( q_final, scale_factor );
2994 0 : Word16 exp_cldfb_re = sub( 31, q_final );
2995 0 : Word16 exp_cldfb_im = sub( 31, q_final );
2996 0 : isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
2997 : }
2998 :
2999 0 : IF( EQ_16( pcm_out_flag, 0 ) )
3000 : {
3001 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
3002 0 : pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD;
3003 :
3004 0 : IF( !useLc3plus )
3005 : {
3006 : // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
3007 0 : available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
3008 0 : tmp_e = 0;
3009 0 : tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
3010 0 : available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
3011 0 : available_bits = L_sub( available_bits, pBits->bits_written );
3012 0 : pBits->codec_frame_size_ms = codec_frame_size_ms;
3013 0 : move16();
3014 0 : pBits->isar_frame_size_ms = isar_frame_size_ms;
3015 0 : move16();
3016 0 : isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final );
3017 : }
3018 : ELSE
3019 : {
3020 : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
3021 0 : IF( EQ_32( pBits->pose_correction, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) )
3022 : {
3023 0 : available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us );
3024 0 : available_bits = Mpy_32_32( available_bits, ONE_BY_FRAMES_PER_SEC_Q31 );
3025 : }
3026 : ELSE
3027 : {
3028 0 : available_bits = L_sub( Mpy_32_32( SplitRendBitRate, ONE_BY_FRAMES_PER_SEC_Q31 ), pBits->bits_written );
3029 : }
3030 : #else
3031 : available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
3032 : #endif
3033 0 : IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in_fx, Q_in ) ) != IVAS_ERR_OK )
3034 : {
3035 0 : return error;
3036 : }
3037 : }
3038 : }
3039 : ELSE
3040 : {
3041 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
3042 0 : pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
3043 : }
3044 :
3045 : /*zero pad*/
3046 0 : IF( pcm_out_flag )
3047 : {
3048 0 : tmp_e = 0;
3049 0 : tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e );
3050 0 : bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
3051 : // bit_len = SplitRendBitRate / FRAMES_PER_SEC;
3052 : }
3053 : ELSE
3054 : {
3055 0 : IF( !useLc3plus )
3056 : {
3057 : // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
3058 :
3059 0 : bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
3060 0 : tmp_e = 0;
3061 0 : tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
3062 0 : bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
3063 : }
3064 : ELSE
3065 : {
3066 0 : tmp_e = 0;
3067 0 : tmp = BASOP_Util_Divide3232_Scale( (Word32) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
3068 0 : bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
3069 : // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
3070 : // bit_len = SplitRendBitRate * bit_len / 1000;
3071 0 : tmp_e = 0;
3072 0 : tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e );
3073 0 : bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
3074 : }
3075 : }
3076 :
3077 :
3078 0 : WHILE( LT_32( pBits->bits_written, bit_len ) )
3079 : {
3080 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
3081 : }
3082 :
3083 0 : pop_wmops();
3084 :
3085 0 : return error;
3086 : }
3087 :
3088 :
3089 : /*-------------------------------------------------------------------------
3090 : * Function lc3plusTimeAlignCldfbPoseCorr()
3091 : *
3092 : *
3093 : *------------------------------------------------------------------------*/
3094 :
3095 0 : void lc3plusTimeAlignCldfbPoseCorr(
3096 : SPLIT_REND_WRAPPER *hSplitBin,
3097 : Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
3098 : Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
3099 : Word16 *Q_in )
3100 : {
3101 : Word32 Cldfb_In_BinReal_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
3102 : Word32 Cldfb_In_BinImag_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
3103 : Word16 pose, ch, slot_idx;
3104 : Word32 *bufRead_fx, *bufWrite_fx;
3105 :
3106 0 : IF( GT_16( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) )
3107 : {
3108 : // hSplitBin->lc3plusDelayBuffers_q[0] = *Q_in;
3109 0 : FOR( Word16 i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ )
3110 : {
3111 :
3112 0 : Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], 4 * CLDFB_NO_CHANNELS_MAX, sub( *Q_in, hSplitBin->lc3plusDelayBuffers_q ) );
3113 : }
3114 0 : hSplitBin->lc3plusDelayBuffers_q = *Q_in;
3115 : }
3116 : ELSE
3117 : {
3118 0 : FOR( Word16 i = 0; i < CLDFB_NO_COL_MAX; i++ )
3119 : {
3120 0 : for ( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
3121 : {
3122 0 : Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) );
3123 0 : Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) );
3124 : }
3125 : }
3126 0 : *Q_in = hSplitBin->lc3plusDelayBuffers_q;
3127 : }
3128 :
3129 0 : FOR( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose )
3130 : {
3131 0 : FOR( ch = 0; ch < BINAURAL_CHANNELS; ++ch )
3132 : {
3133 0 : bufRead_fx = hSplitBin->lc3plusDelayBuffers_fx[pose * BINAURAL_CHANNELS + ch];
3134 0 : bufWrite_fx = bufRead_fx;
3135 :
3136 : /* Save last 2 columns for next frame */
3137 0 : FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
3138 : {
3139 0 : Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
3140 0 : Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
3141 : }
3142 :
3143 : /* Delay existing columns by 2 slots */
3144 : /*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */
3145 0 : FOR( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx )
3146 : {
3147 0 : Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
3148 0 : Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
3149 : }
3150 :
3151 : /* Fill 2 first columns from buffer */
3152 0 : FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
3153 : {
3154 0 : Copy32( bufRead_fx, Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
3155 0 : bufRead_fx += CLDFB_NO_CHANNELS_MAX;
3156 0 : Copy32( bufRead_fx, Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
3157 0 : bufRead_fx += CLDFB_NO_CHANNELS_MAX;
3158 : }
3159 :
3160 : /* Copy last 2 columns to buffer */
3161 0 : FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
3162 : {
3163 0 : Copy32( Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX );
3164 0 : bufWrite_fx += CLDFB_NO_CHANNELS_MAX;
3165 0 : Copy32( Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX );
3166 0 : bufWrite_fx += CLDFB_NO_CHANNELS_MAX;
3167 : }
3168 : }
3169 : }
3170 :
3171 0 : return;
3172 : }
|