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.h"
40 : #include "prot.h"
41 : #include "isar_rom_post_rend.h"
42 : #include "lib_isar_pre_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 :
52 : /*---------------------------------------------------------------------*
53 : * Local function declarations
54 : *---------------------------------------------------------------------*/
55 :
56 : static void isar_SplitRenderer_GetRotMd( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
57 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
58 : float *Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX],
59 : float *Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX],
60 : #else
61 : float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
62 : float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
63 : #endif
64 : const int16_t low_res,
65 : const int16_t ro_md_flag );
66 :
67 :
68 : /*-------------------------------------------------------------------------
69 : * Local functions
70 : *
71 : *
72 : *------------------------------------------------------------------------*/
73 :
74 0 : static void isar_calc_mat_det_2by2_complex(
75 : float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
76 : float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
77 : float *det_re,
78 : float *det_im )
79 : {
80 : float re1, im1, re2, im2;
81 :
82 0 : IVAS_CMULT_FLOAT( in_re[0][0], in_im[0][0], in_re[1][1], in_im[1][1], re1, im1 );
83 0 : IVAS_CMULT_FLOAT( in_re[0][1], in_im[0][1], in_re[1][0], in_im[1][0], re2, im2 );
84 0 : *det_re = re1 - re2;
85 0 : *det_im = im1 - im2;
86 :
87 0 : return;
88 : }
89 :
90 :
91 0 : static int16_t isar_is_mat_inv_2by2_complex(
92 : float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
93 : float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] )
94 : {
95 0 : int16_t is_det_zero = 1;
96 : float det, det_re, det_im;
97 :
98 0 : isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
99 :
100 0 : det = ( ( det_re * det_re ) + ( det_im * det_im ) );
101 :
102 0 : if ( det < EPSILON )
103 : {
104 0 : is_det_zero = 0;
105 : }
106 :
107 0 : return is_det_zero;
108 : }
109 :
110 :
111 0 : static void isar_calc_mat_inv_2by2_complex(
112 : float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
113 : float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
114 : float out_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
115 : float out_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] )
116 : {
117 : float det_re, det_im;
118 : float re, im, det;
119 :
120 0 : isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
121 :
122 0 : det = ( det_re * det_re ) + ( det_im * det_im );
123 :
124 : #ifdef DEBUGGING
125 : /* assert to catch cases when input is singular matrix */
126 : assert( det > 0 );
127 : #endif
128 0 : det = 1 / det;
129 :
130 0 : IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][1], in_im[1][1], re, im );
131 0 : out_re[0][0] = re * det;
132 0 : out_im[0][0] = im * det;
133 :
134 0 : IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][1], in_im[0][1], re, im );
135 0 : out_re[0][1] = -re * det;
136 0 : out_im[0][1] = -im * det;
137 :
138 0 : IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][0], in_im[1][0], re, im );
139 0 : out_re[1][0] = -re * det;
140 0 : out_im[1][0] = -im * det;
141 :
142 0 : IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][0], in_im[0][0], re, im );
143 0 : out_re[1][1] = re * det;
144 0 : out_im[1][1] = im * det;
145 :
146 0 : return;
147 : }
148 :
149 :
150 0 : static void ComputePredMat(
151 : float cov_ii_re[][BINAURAL_CHANNELS],
152 : float cov_ii_im[][BINAURAL_CHANNELS],
153 : float cov_io_re[][BINAURAL_CHANNELS],
154 : float cov_io_im[][BINAURAL_CHANNELS],
155 : float pred_mat_re[][BINAURAL_CHANNELS],
156 : float pred_mat_im[][BINAURAL_CHANNELS],
157 : const int16_t num_chs,
158 : const int16_t real_only )
159 : {
160 : float cov_ii_local_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
161 : float cov_ii_inv_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
162 : float cov_ii_inv_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
163 : float trace_cov;
164 : int16_t i, j;
165 :
166 0 : trace_cov = 0.0f;
167 0 : for ( i = 0; i < num_chs; i++ )
168 : {
169 0 : trace_cov += cov_ii_re[i][i];
170 : }
171 :
172 0 : trace_cov = max( 0.0f, trace_cov );
173 :
174 0 : if ( trace_cov < EPSILON )
175 : {
176 0 : for ( i = 0; i < num_chs; i++ )
177 : {
178 : /* protection from cases when variance of ref channels is very small */
179 0 : set_zero( pred_mat_re[i], BINAURAL_CHANNELS );
180 0 : set_zero( pred_mat_im[i], BINAURAL_CHANNELS );
181 : }
182 0 : return;
183 : }
184 :
185 0 : for ( i = 0; i < num_chs; i++ )
186 : {
187 0 : mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs );
188 : }
189 :
190 0 : for ( i = 0; i < num_chs; i++ )
191 : {
192 0 : cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f );
193 : }
194 :
195 0 : if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) )
196 : {
197 0 : isar_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im );
198 0 : isar_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im );
199 : }
200 : else
201 : {
202 : int16_t max_var_idx;
203 0 : for ( i = 0; i < num_chs; i++ )
204 : {
205 0 : set_zero( pred_mat_re[i], BINAURAL_CHANNELS );
206 0 : set_zero( pred_mat_im[i], BINAURAL_CHANNELS );
207 : }
208 :
209 0 : max_var_idx = 0;
210 0 : if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] )
211 : {
212 0 : max_var_idx = 1;
213 : }
214 :
215 0 : if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON )
216 : {
217 0 : for ( j = 0; j < num_chs; j++ )
218 : {
219 0 : pred_mat_re[max_var_idx][j] = cov_io_re[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx];
220 0 : pred_mat_im[max_var_idx][j] = cov_io_im[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx];
221 : }
222 : }
223 : }
224 :
225 0 : if ( real_only )
226 : {
227 0 : for ( i = 0; i < num_chs; i++ )
228 : {
229 0 : set_zero( pred_mat_im[i], BINAURAL_CHANNELS );
230 : }
231 : }
232 :
233 0 : return;
234 : }
235 :
236 :
237 0 : static void ComputePostPredCov(
238 : float cov_ii_re[][BINAURAL_CHANNELS],
239 : float cov_ii_im[][BINAURAL_CHANNELS],
240 : float pred_mat_re[][BINAURAL_CHANNELS],
241 : float pred_mat_im[][BINAURAL_CHANNELS],
242 : float postpred_cov_re[][BINAURAL_CHANNELS],
243 : const int16_t num_chs )
244 : {
245 : int16_t i, j;
246 : float dmx_mat_conj_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
247 : float dmx_mat_conj_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
248 : float temp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
249 : float temp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
250 : float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
251 :
252 0 : assert( num_chs == BINAURAL_CHANNELS );
253 0 : for ( i = 0; i < num_chs; i++ )
254 : {
255 0 : for ( j = 0; j < num_chs; j++ )
256 : {
257 0 : dmx_mat_conj_re[i][j] = pred_mat_re[j][i];
258 0 : dmx_mat_conj_im[i][j] = -pred_mat_im[j][i];
259 :
260 0 : temp_mat_re[i][j] = pred_mat_re[i][j];
261 0 : temp_mat_im[i][j] = pred_mat_im[i][j];
262 : }
263 0 : set_zero( postpred_cov_re[i], BINAURAL_CHANNELS );
264 : }
265 :
266 : /* 2x2 mult */
267 0 : isar_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im );
268 0 : isar_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im );
269 :
270 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
271 : {
272 0 : for ( j = 0; j < i; j++ )
273 : {
274 0 : postpred_cov_re[i][j] = postpred_cov_re[j][i];
275 : }
276 : }
277 :
278 0 : return;
279 : }
280 :
281 :
282 0 : static void ComputeBandedCrossCov(
283 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
284 : float *Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX],
285 : float *Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX],
286 : #else
287 : float Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
288 : float Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
289 : #endif
290 : const int16_t ch_start_idx1,
291 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
292 : float *Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX],
293 : float *Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX],
294 : #else
295 : float Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
296 : float Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
297 : #endif
298 : const int16_t ch_start_idx2,
299 : float out_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
300 : float out_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
301 : const int16_t num_chs,
302 : const int16_t *pBand_grouping,
303 : const int16_t num_slots,
304 : const int16_t start_slot_idx,
305 : const int16_t md_band_idx,
306 : const int16_t real_only )
307 : {
308 : int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2;
309 : int16_t brange[2];
310 :
311 0 : for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
312 : {
313 0 : set_f( out_cov_re[ch_idx1], 0.0f, num_chs );
314 0 : set_f( out_cov_im[ch_idx1], 0.0f, num_chs );
315 : }
316 :
317 0 : brange[0] = pBand_grouping[md_band_idx];
318 0 : brange[1] = pBand_grouping[md_band_idx + 1];
319 :
320 0 : for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
321 : {
322 0 : for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ )
323 : {
324 0 : if ( real_only == 0 )
325 : {
326 0 : for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
327 : {
328 0 : for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
329 : {
330 0 : out_cov_re[ch_idx1][ch_idx2] +=
331 0 : Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] +
332 0 : Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx];
333 :
334 0 : out_cov_im[ch_idx1][ch_idx2] +=
335 0 : Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] -
336 0 : Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx];
337 : }
338 : }
339 : }
340 : else
341 : {
342 0 : for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
343 : {
344 0 : for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
345 : {
346 0 : out_cov_re[ch_idx1][ch_idx2] +=
347 0 : Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] +
348 0 : Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx];
349 :
350 0 : out_cov_im[ch_idx1][ch_idx2] = 0.0f;
351 : }
352 : }
353 : }
354 : }
355 : }
356 :
357 0 : return;
358 : }
359 :
360 :
361 0 : static void ComputeBandedCov(
362 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
363 : float *Cldfb_RealBuffer[][CLDFB_NO_COL_MAX],
364 : float *Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX],
365 : #else
366 : float Cldfb_RealBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
367 : float Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
368 : #endif
369 : const int16_t ch_start_idx,
370 : float out_cov_re[][BINAURAL_CHANNELS],
371 : float out_cov_im[][BINAURAL_CHANNELS],
372 : const int16_t num_chs,
373 : const int16_t *pBand_grouping,
374 : const int16_t num_slots,
375 : const int16_t start_slot_idx,
376 : const int16_t md_band_idx,
377 : const int16_t real_only )
378 : {
379 : int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2;
380 : int16_t brange[2];
381 :
382 0 : for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
383 : {
384 0 : set_f( out_cov_re[ch_idx1], 0.0f, num_chs );
385 0 : set_f( out_cov_im[ch_idx1], 0.0f, num_chs );
386 : }
387 :
388 0 : brange[0] = pBand_grouping[md_band_idx];
389 0 : brange[1] = pBand_grouping[md_band_idx + 1];
390 :
391 0 : for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
392 : {
393 0 : for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ )
394 : {
395 0 : if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) )
396 : {
397 0 : for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
398 : {
399 0 : for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
400 : {
401 0 : out_cov_re[ch_idx1][ch_idx2] +=
402 0 : Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] +
403 0 : Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx];
404 :
405 0 : out_cov_im[ch_idx1][ch_idx2] +=
406 0 : Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] -
407 0 : Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx];
408 : }
409 : }
410 : }
411 : else
412 : {
413 0 : for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
414 : {
415 0 : for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
416 : {
417 0 : out_cov_re[ch_idx1][ch_idx2] +=
418 0 : Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] +
419 0 : Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx];
420 :
421 0 : out_cov_im[ch_idx1][ch_idx2] = 0.0f;
422 : }
423 : }
424 : }
425 : }
426 : }
427 :
428 0 : for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
429 : {
430 0 : for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ )
431 : {
432 0 : out_cov_re[ch_idx1][ch_idx2] = out_cov_re[ch_idx2][ch_idx1];
433 0 : out_cov_im[ch_idx1][ch_idx2] = -out_cov_im[ch_idx2][ch_idx1];
434 : }
435 : }
436 :
437 0 : return;
438 : }
439 :
440 :
441 0 : static float GetNormFact(
442 : float cov_ii_re[][BINAURAL_CHANNELS],
443 : float cov_ii_im[][BINAURAL_CHANNELS],
444 : float cov_io_re[][BINAURAL_CHANNELS],
445 : float cov_io_im[][BINAURAL_CHANNELS],
446 : float cov_oo_re[][BINAURAL_CHANNELS] )
447 : {
448 : int16_t i, j;
449 : float norm_fact, abs_val;
450 :
451 0 : norm_fact = 0.0f;
452 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
453 : {
454 0 : for ( j = 0; j < BINAURAL_CHANNELS; j++ )
455 : {
456 0 : IVAS_CALCULATE_ABS( cov_ii_re[i][j], cov_ii_im[i][j], abs_val );
457 0 : norm_fact = max( norm_fact, abs_val );
458 :
459 0 : IVAS_CALCULATE_ABS( cov_io_re[i][j], cov_io_im[i][j], abs_val );
460 0 : norm_fact = max( norm_fact, abs_val );
461 :
462 0 : IVAS_CALCULATE_RABS( cov_oo_re[i][j], abs_val );
463 0 : norm_fact = max( norm_fact, abs_val );
464 : }
465 : }
466 :
467 0 : norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f;
468 :
469 0 : norm_fact = PCM16_TO_FLT_FAC / norm_fact;
470 :
471 0 : return norm_fact;
472 : }
473 :
474 :
475 0 : static void isar_split_rend_huffman_encode(
476 : isar_split_rend_huffman_cfg_t *huff_cfg,
477 : const int16_t in,
478 : int32_t *hcode,
479 : int32_t *hlen )
480 : {
481 : int32_t min_sym_val;
482 : const int32_t *codebook;
483 :
484 0 : min_sym_val = huff_cfg->codebook[0];
485 :
486 0 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
487 0 : *hlen = codebook[1];
488 0 : *hcode = codebook[2];
489 :
490 0 : return;
491 : }
492 :
493 :
494 0 : static void isar_split_rend_quant_md(
495 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
496 : const ISAR_SPLIT_REND_POSE_TYPE pose_type,
497 : const int16_t real_only,
498 : float fix_pos_rot_mat[][BINAURAL_CHANNELS],
499 : const float pred_1byquantstep )
500 : {
501 : int16_t ch1, ch2;
502 : int16_t gd_idx_min;
503 : float quant_val;
504 :
505 0 : if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY )
506 0 : {
507 : float onebyquantstep;
508 :
509 0 : onebyquantstep = pred_1byquantstep;
510 0 : if ( real_only == 1 )
511 : {
512 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
513 : {
514 0 : hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1];
515 : }
516 :
517 0 : hMd->pred_mat_re[1][0] = 0.0f;
518 0 : hMd->pred_mat_re[0][1] = 0.0f;
519 :
520 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
521 : {
522 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
523 : {
524 0 : quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f );
525 0 : quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
526 0 : hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
527 : }
528 : }
529 : }
530 : else
531 : {
532 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
533 : {
534 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
535 : {
536 0 : quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2];
537 0 : quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
538 0 : hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
539 : }
540 : }
541 : }
542 :
543 0 : if ( real_only == 0 )
544 : {
545 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
546 : {
547 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
548 : {
549 0 : quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) );
550 0 : hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
551 : }
552 : }
553 : }
554 : }
555 0 : else if ( pose_type == COM_GAIN_ONLY )
556 : {
557 0 : quant_val = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) );
558 0 : gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL );
559 0 : hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val );
560 0 : hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP;
561 0 : hMd->gd_idx = hMd->gd_idx - gd_idx_min;
562 : }
563 0 : else if ( pose_type == LR_GAIN_ONLY )
564 : {
565 0 : quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
566 0 : gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL );
567 0 : hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
568 0 : hMd->gd_idx = hMd->gd_idx - gd_idx_min;
569 :
570 0 : quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
571 0 : hMd->gd2_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
572 0 : hMd->gd2_idx = hMd->gd2_idx - gd_idx_min;
573 : }
574 :
575 0 : return;
576 : }
577 :
578 :
579 0 : static void get_lr_gains(
580 : float cov_in[][BINAURAL_CHANNELS],
581 : float cov_out[][BINAURAL_CHANNELS],
582 : float gains[BINAURAL_CHANNELS] )
583 : {
584 : int16_t i;
585 :
586 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
587 : {
588 0 : gains[i] = cov_in[i][i];
589 0 : if ( gains[i] < EPSILON )
590 : {
591 0 : gains[i] = 1.0f;
592 : }
593 : else
594 : {
595 0 : gains[i] = ( cov_out[i][i] ) / gains[i];
596 0 : gains[i] = sqrtf( gains[i] );
597 : }
598 : }
599 :
600 0 : return;
601 : }
602 :
603 :
604 0 : static void ComputeCoeffs(
605 : float cov_ii_re[][BINAURAL_CHANNELS],
606 : float cov_ii_im[][BINAURAL_CHANNELS],
607 : float cov_io_re[][BINAURAL_CHANNELS],
608 : float cov_io_im[][BINAURAL_CHANNELS],
609 : float cov_oo_re[][BINAURAL_CHANNELS],
610 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
611 : const ISAR_SPLIT_REND_POSE_TYPE pose_type,
612 : const int16_t real_only )
613 : {
614 : float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
615 : float cov_ii_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
616 : float cov_ii_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
617 : float cov_io_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
618 : float cov_io_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
619 : float cov_oo_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
620 : float sigma_d, gd, gd2, gl2, gr2, cov_norm_fact;
621 : int16_t i, j;
622 :
623 0 : if ( pose_type == PITCH_ONLY )
624 : {
625 : float gd_tmp[BINAURAL_CHANNELS];
626 :
627 0 : get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
628 :
629 0 : hMd->gd = gd_tmp[0];
630 0 : hMd->gd2 = gd_tmp[1];
631 : }
632 : else
633 : {
634 0 : if ( real_only )
635 : {
636 : float gd_tmp[BINAURAL_CHANNELS];
637 :
638 0 : get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
639 :
640 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
641 : {
642 0 : hMd->pred_mat_re[i][i] = gd_tmp[i];
643 0 : hMd->pred_mat_re2[i] = gd_tmp[i];
644 0 : set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS );
645 : }
646 :
647 0 : hMd->pred_mat_re[1][0] = 0.0f;
648 0 : hMd->pred_mat_re[0][1] = 0.0f;
649 : }
650 : else
651 : {
652 0 : get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 );
653 :
654 0 : cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re );
655 :
656 : /* normalize the covariance */
657 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
658 : {
659 0 : for ( j = 0; j < BINAURAL_CHANNELS; j++ )
660 : {
661 0 : cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact;
662 0 : cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact;
663 0 : cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact;
664 0 : cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact;
665 0 : cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact;
666 : }
667 : }
668 :
669 0 : ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only );
670 :
671 0 : ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, BINAURAL_CHANNELS );
672 :
673 : /* normalize everything to +-1 range */
674 0 : gd = 1.0f / ( PCM16_TO_FLT_FAC );
675 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
676 : {
677 0 : for ( j = 0; j < BINAURAL_CHANNELS; j++ )
678 : {
679 0 : postpred_cov_re[i][j] *= gd;
680 0 : cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd;
681 0 : cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd;
682 : }
683 : }
684 :
685 0 : gd2 = 0.0f;
686 0 : sigma_d = 0.0f;
687 0 : hMd->gd = 0.0f;
688 :
689 0 : if ( postpred_cov_re[0][0] > EPSILON )
690 : {
691 0 : gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] );
692 0 : gl2 = max( gl2, 1.0f );
693 0 : gl2 = sqrtf( gl2 );
694 : }
695 : else
696 : {
697 0 : gl2 = 1.0f;
698 : }
699 :
700 0 : if ( postpred_cov_re[1][1] > EPSILON )
701 : {
702 0 : gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] );
703 0 : gr2 = max( gr2, 1.0f );
704 0 : gr2 = sqrtf( gr2 );
705 : }
706 : else
707 : {
708 0 : gr2 = 1.0f;
709 : }
710 :
711 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
712 : {
713 0 : hMd->pred_mat_re[i][0] *= gl2;
714 0 : hMd->pred_mat_re[i][1] *= gr2;
715 : }
716 :
717 0 : if ( real_only == 0 )
718 : {
719 0 : for ( i = 0; i < BINAURAL_CHANNELS; i++ )
720 : {
721 0 : hMd->pred_mat_im[i][0] *= gl2;
722 0 : hMd->pred_mat_im[i][1] *= gr2;
723 : }
724 : }
725 : }
726 : }
727 :
728 0 : return;
729 : }
730 :
731 :
732 0 : static void get_base2_bits(
733 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
734 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
735 : const int16_t num_subframes,
736 : const int16_t num_quant_strats,
737 : const int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
738 : const int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
739 : int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
740 : const int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
741 : const int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
742 : const int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
743 : const int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
744 : int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] )
745 : {
746 : int16_t pred_roll_bits;
747 : int16_t d_gain_bits, pitch_gain_bits, pose_idx, q;
748 : int16_t pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
749 :
750 : ISAR_SPLIT_REND_POSE_TYPE pose_type;
751 :
752 0 : for ( q = 0; q < num_quant_strats; q++ )
753 : {
754 0 : pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) );
755 : }
756 0 : pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) );
757 :
758 0 : d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) );
759 0 : pitch_gain_bits = d_gain_bits;
760 :
761 0 : for ( q = 0; q < num_quant_strats; q++ )
762 : {
763 0 : base2bits[q] = 0;
764 : }
765 :
766 0 : for ( q = 0; q < num_quant_strats; q++ )
767 : {
768 0 : for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ )
769 : {
770 0 : pose_type = hBinHrSplitPreRend->pose_type[pose_idx];
771 0 : if ( pose_type == ANY_YAW )
772 : {
773 0 : base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
774 0 : base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
775 0 : base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
776 0 : base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes;
777 : }
778 0 : else if ( pose_type == PITCH_ONLY )
779 : {
780 0 : base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes;
781 0 : base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes;
782 : }
783 : else
784 : {
785 0 : base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
786 0 : base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
787 0 : base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
788 : }
789 : }
790 : }
791 :
792 0 : return;
793 : }
794 :
795 :
796 0 : static void isar_SplitRenderer_code_md_base2(
797 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
798 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
799 : const int16_t num_subframes,
800 : const int16_t pred_real_bands_yaw,
801 : const int16_t pred_imag_bands_yaw,
802 : const int16_t pred_quant_pnts_yaw,
803 : const int16_t d_bands_yaw,
804 : const int16_t bands_pitch,
805 : const int16_t pred_real_bands_roll,
806 : const int16_t pred_imag_bands_roll,
807 : ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */
808 : )
809 : {
810 : int16_t pos_idx, b, ch1, ch2, sf_idx;
811 : int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses;
812 : int16_t min_pred_roll_idx, pred_roll_code_len;
813 : int16_t pred_cb_idx;
814 : int32_t code;
815 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
816 : ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
817 :
818 0 : pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
819 0 : if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
820 : {
821 0 : pred_cb_idx = 1;
822 : }
823 : else
824 : {
825 0 : pred_cb_idx = 0;
826 : }
827 0 : min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0];
828 0 : min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
829 0 : min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0];
830 0 : min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0];
831 :
832 0 : pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx];
833 0 : pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len;
834 0 : gd_code_len = pHuff_cfg->gd_base2_code_len;
835 0 : p_gd_code_len = pHuff_cfg->p_gd_base2_code_len;
836 :
837 0 : num_poses = pMultiBinPoseData->num_poses;
838 :
839 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
840 : {
841 0 : for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
842 : {
843 0 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
844 : {
845 0 : for ( b = 0; b < pred_imag_bands_yaw; b++ )
846 : {
847 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
848 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
849 : {
850 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
851 : {
852 0 : code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx;
853 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
854 : }
855 : }
856 :
857 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
858 : {
859 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
860 : {
861 0 : code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx;
862 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
863 : }
864 : }
865 : }
866 :
867 0 : for ( ; b < pred_real_bands_yaw; b++ )
868 : {
869 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
870 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
871 : {
872 0 : code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_idx;
873 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
874 : }
875 : }
876 :
877 0 : for ( b = 0; b < d_bands_yaw; b++ )
878 : {
879 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
880 0 : code = hMd->gd_idx - min_gd_idx;
881 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len );
882 : }
883 : }
884 0 : else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
885 : {
886 0 : for ( b = 0; b < bands_pitch; b++ )
887 : {
888 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
889 0 : code = hMd->gd_idx - min_p_gd_idx;
890 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
891 :
892 0 : code = hMd->gd2_idx - min_p_gd_idx;
893 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
894 : }
895 : }
896 : else
897 : {
898 0 : for ( b = 0; b < pred_imag_bands_roll; b++ )
899 : {
900 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
901 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
902 : {
903 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
904 : {
905 0 : code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx;
906 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
907 : }
908 : }
909 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
910 : {
911 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
912 : {
913 0 : code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx;
914 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
915 : }
916 : }
917 : }
918 :
919 0 : for ( ; b < pred_real_bands_roll; b++ )
920 : {
921 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
922 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
923 : {
924 0 : code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx;
925 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
926 : }
927 : }
928 : }
929 : }
930 : }
931 :
932 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
933 : {
934 : static int16_t num_bits = 0;
935 : static int16_t cntr = 0;
936 : float fnum_bits;
937 :
938 : cntr++;
939 :
940 : num_bits += pBits->bits_written;
941 : /* collect bits for every second */
942 : if ( cntr == 50 )
943 : {
944 : cntr = 0;
945 : fnum_bits = (float) num_bits / 1000.0f;
946 : dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
947 : num_bits = 0;
948 : }
949 : }
950 : #endif
951 0 : return;
952 : }
953 :
954 :
955 0 : static void isar_SplitRenderer_code_md_huff(
956 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
957 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
958 : const int16_t num_subframes,
959 : const int16_t pred_real_bands_yaw,
960 : const int16_t pred_imag_bands_yaw,
961 : const int16_t pred_quant_pnts_yaw,
962 : const int16_t d_bands_yaw,
963 : const int16_t bands_pitch,
964 : const int16_t pred_real_bands_roll,
965 : const int16_t pred_imag_bands_roll,
966 : ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */
967 : )
968 : {
969 : int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses;
970 : int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
971 : int16_t min_pred_idx, max_pred_idx;
972 : int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
973 : int32_t code, len;
974 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
975 : ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
976 :
977 0 : pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
978 :
979 0 : if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
980 : {
981 0 : pred_cb_idx = 1;
982 : }
983 : else
984 : {
985 0 : pred_cb_idx = 0;
986 : }
987 :
988 0 : min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0];
989 0 : max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3];
990 0 : min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
991 0 : max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
992 :
993 0 : num_poses = pMultiBinPoseData->num_poses;
994 :
995 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
996 : {
997 0 : for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
998 : {
999 0 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
1000 : {
1001 0 : for ( b = 0; b < pred_imag_bands_yaw; b++ )
1002 : {
1003 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1004 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
1005 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1006 : {
1007 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1008 : {
1009 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
1010 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1011 : }
1012 : }
1013 :
1014 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
1015 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1016 : {
1017 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1018 : {
1019 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
1020 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1021 : }
1022 : }
1023 : }
1024 :
1025 0 : for ( ; b < pred_real_bands_yaw; b++ )
1026 : {
1027 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1028 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
1029 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1030 : {
1031 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len );
1032 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1033 : }
1034 : }
1035 0 : for ( b = 0; b < d_bands_yaw; b++ )
1036 : {
1037 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1038 0 : isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len );
1039 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1040 : }
1041 : }
1042 0 : else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
1043 : {
1044 0 : for ( b = 0; b < bands_pitch; b++ )
1045 : {
1046 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1047 0 : isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
1048 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1049 :
1050 0 : isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
1051 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1052 : }
1053 : }
1054 : else
1055 : {
1056 0 : for ( b = 0; b < pred_imag_bands_roll; b++ )
1057 : {
1058 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1059 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
1060 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1061 : {
1062 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1063 : {
1064 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
1065 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1066 : }
1067 : }
1068 :
1069 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
1070 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1071 : {
1072 0 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1073 : {
1074 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
1075 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1076 : }
1077 : }
1078 : }
1079 :
1080 0 : for ( ; b < pred_real_bands_roll; b++ )
1081 : {
1082 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1083 0 : isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
1084 0 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1085 : {
1086 0 : isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len );
1087 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
1088 : }
1089 : }
1090 : }
1091 : }
1092 : }
1093 :
1094 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1095 : {
1096 : static int16_t num_bits = 0;
1097 : static int16_t cntr = 0;
1098 : float fnum_bits;
1099 :
1100 : cntr++;
1101 : num_bits += pBits->bits_written;
1102 : /* collect bits for every second */
1103 : if ( cntr == 50 )
1104 : {
1105 : cntr = 0;
1106 : fnum_bits = (float) num_bits / 1000.0f;
1107 : dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
1108 : num_bits = 0;
1109 : }
1110 : }
1111 : #endif
1112 0 : return;
1113 : }
1114 :
1115 :
1116 0 : static void isar_SplitRenderer_quant_code(
1117 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
1118 : const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
1119 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
1120 : ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
1121 : const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
1122 : const int16_t ro_md_flag, /* i : real only metadata for yaw flag */
1123 : const int32_t target_md_bits /* i : ISAR MD bitrate */
1124 : )
1125 : {
1126 : int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
1127 : int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit;
1128 : int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1129 : int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1130 : int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1131 : int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1132 : int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1133 : float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1134 : float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
1135 : ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
1136 : int16_t rot_axis_code, num_bits;
1137 :
1138 0 : if ( low_res_pre_rend_rot )
1139 : {
1140 0 : num_subframes = 1;
1141 : }
1142 : else
1143 : {
1144 0 : num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
1145 : }
1146 :
1147 0 : overhead_bits = pBits->bits_written;
1148 :
1149 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS );
1150 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS );
1151 :
1152 0 : rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits );
1153 0 : if ( num_bits > 0 )
1154 : {
1155 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits );
1156 : }
1157 :
1158 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS );
1159 :
1160 : /* code ref pose*/
1161 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1162 : {
1163 : int16_t angle;
1164 : IVAS_QUATERNION head_pos_euler;
1165 :
1166 0 : Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
1167 0 : angle = (int16_t) roundf( head_pos_euler.x );
1168 0 : angle += 180;
1169 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1170 :
1171 0 : angle = (int16_t) roundf( head_pos_euler.y );
1172 0 : angle += 180;
1173 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1174 :
1175 0 : angle = (int16_t) roundf( head_pos_euler.z );
1176 0 : angle += 180;
1177 :
1178 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
1179 : }
1180 :
1181 0 : isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
1182 : pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw,
1183 : d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats );
1184 :
1185 0 : quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) );
1186 :
1187 0 : overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */
1188 :
1189 0 : get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw,
1190 : pred_quant_pnts_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits );
1191 :
1192 0 : for ( q = 0; q < num_quant_strats; q++ )
1193 : {
1194 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1195 : {
1196 0 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
1197 : {
1198 0 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
1199 : {
1200 0 : for ( b = 0; b < pred_imag_bands_yaw[q]; b++ )
1201 : {
1202 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1203 :
1204 0 : isar_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
1205 : }
1206 0 : for ( ; b < pred_real_bands_yaw[q]; b++ )
1207 : {
1208 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1209 :
1210 0 : isar_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
1211 : }
1212 :
1213 0 : for ( b = 0; b < d_bands_yaw[q]; b++ )
1214 : {
1215 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1216 :
1217 0 : isar_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
1218 : }
1219 : }
1220 0 : else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
1221 : {
1222 0 : for ( b = 0; b < bands_pitch[q]; b++ )
1223 : {
1224 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1225 0 : isar_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
1226 : }
1227 : }
1228 : else
1229 : {
1230 0 : for ( b = 0; b < pred_imag_bands_roll[q]; b++ )
1231 : {
1232 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1233 0 : isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
1234 : }
1235 0 : for ( ; b < pred_real_bands_roll[q]; b++ )
1236 : {
1237 0 : hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1238 0 : isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
1239 : }
1240 : }
1241 : }
1242 : }
1243 :
1244 : /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/
1245 0 : start_bit = pBits->bits_written;
1246 :
1247 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
1248 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
1249 :
1250 0 : huff_bits = pBits->bits_written;
1251 0 : isar_SplitRenderer_code_md_huff(
1252 : hBinHrSplitPreRend,
1253 : pMultiBinPoseData,
1254 : num_subframes,
1255 0 : pred_real_bands_yaw[q],
1256 0 : pred_imag_bands_yaw[q],
1257 0 : pred_quant_pnts_yaw[q],
1258 0 : d_bands_yaw[q],
1259 0 : bands_pitch[q],
1260 0 : pred_real_bands_roll[q],
1261 0 : pred_imag_bands_roll[q],
1262 : pBits );
1263 :
1264 0 : huff_bits = pBits->bits_written - huff_bits;
1265 :
1266 0 : if ( ( target_md_bits >= ( base2bits[q] + overhead_bits ) ) || ( target_md_bits >= ( huff_bits + overhead_bits ) ) || ( q == ( num_quant_strats - 1 ) ) )
1267 : {
1268 0 : if ( huff_bits > base2bits[q] )
1269 : {
1270 0 : pBits->bits_written = start_bit;
1271 :
1272 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
1273 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
1274 :
1275 0 : isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
1276 0 : pred_quant_pnts_yaw[q], d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits );
1277 : }
1278 0 : break;
1279 : }
1280 :
1281 0 : pBits->bits_written = start_bit;
1282 : }
1283 :
1284 : #ifdef SPLIT_MD_CODING_DEBUG
1285 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1286 : {
1287 : int16_t val, quant_strat, ch1, ch2;
1288 : char filename[200] = "split_md_debug_indices.bin";
1289 : quant_strat = q;
1290 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
1291 : {
1292 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
1293 : {
1294 : for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ )
1295 : {
1296 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1297 : {
1298 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1299 : {
1300 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
1301 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1302 : }
1303 : }
1304 : }
1305 : for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
1306 : {
1307 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1308 : {
1309 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1310 : {
1311 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
1312 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1313 : }
1314 : }
1315 : }
1316 : for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
1317 : {
1318 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
1319 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1320 : }
1321 : }
1322 : else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
1323 : {
1324 : for ( b = 0; b < bands_pitch[quant_strat]; b++ )
1325 : {
1326 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
1327 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1328 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx;
1329 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1330 : }
1331 : }
1332 : else
1333 : {
1334 : for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ )
1335 : {
1336 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1337 : {
1338 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1339 : {
1340 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
1341 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1342 : }
1343 : }
1344 : }
1345 : for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
1346 : {
1347 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1348 : {
1349 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1350 : {
1351 : val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
1352 : dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
1353 : }
1354 : }
1355 : }
1356 : }
1357 : }
1358 : }
1359 :
1360 : #endif
1361 0 : return;
1362 : }
1363 :
1364 :
1365 : /*-------------------------------------------------------------------------
1366 : * Function isar_SplitRenderer_GetRotMd()
1367 : *
1368 : *
1369 : *------------------------------------------------------------------------*/
1370 :
1371 0 : static void isar_SplitRenderer_GetRotMd(
1372 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
1373 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
1374 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
1375 : float *Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX], /* o : Reference Binaural signals */
1376 : float *Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX], /* o : Reference Binaural signals */
1377 : #else
1378 : float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
1379 : float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
1380 : #endif
1381 : const int16_t low_res,
1382 : const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */
1383 : )
1384 : {
1385 : float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1386 : float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1387 : float cov_io_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1388 : float cov_ii_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1389 : float cov_oo_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1390 : float cov_io_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
1391 0 : int16_t real_only = 0;
1392 : int16_t pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2;
1393 : int16_t num_md_bands, num_poses;
1394 0 : const int16_t *pBand_grouping = isar_split_rend_band_grouping;
1395 :
1396 0 : push_wmops( "isar_SplitRenderer_GetRotMd" );
1397 :
1398 0 : num_md_bands = MAX_SPLIT_REND_MD_BANDS;
1399 0 : num_poses = pMultiBinPoseData->num_poses;
1400 :
1401 0 : if ( low_res )
1402 : {
1403 0 : num_slots = CLDFB_NO_COL_MAX;
1404 0 : num_subframes = 1;
1405 : }
1406 : else
1407 : {
1408 0 : num_slots = MAX_PARAM_SPATIAL_SUBFRAMES;
1409 0 : num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
1410 : }
1411 :
1412 : /* compute reference signal covariance */
1413 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1414 : {
1415 0 : start_slot_idx = sf_idx * num_slots;
1416 0 : for ( b = 0; b < num_md_bands; b++ )
1417 : {
1418 0 : if ( ( b < SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) )
1419 : {
1420 0 : real_only = 0;
1421 : }
1422 : else
1423 : {
1424 0 : real_only = 1;
1425 : }
1426 :
1427 0 : ch_s_idx1 = 0;
1428 0 : ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, cov_ii_re, cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
1429 :
1430 : /* compute rotated signal covariance */
1431 0 : for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
1432 : {
1433 0 : if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL )
1434 : {
1435 0 : if ( b >= SPLIT_REND_RO_MD_BAND_THRESH )
1436 : {
1437 0 : real_only = 1;
1438 : }
1439 : }
1440 0 : ch_s_idx2 = ( pos_idx + 1 ) * BINAURAL_CHANNELS;
1441 0 : ComputeBandedCrossCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_io_re, cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
1442 :
1443 0 : ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_oo_re, cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
1444 :
1445 0 : ComputeCoeffs( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only );
1446 : }
1447 : }
1448 : }
1449 :
1450 0 : pop_wmops();
1451 0 : return;
1452 : }
1453 :
1454 :
1455 : /*-------------------------------------------------------------------------
1456 : * Function isar_rend_CldfbSplitPreRendProcess()
1457 : *
1458 : *
1459 : *------------------------------------------------------------------------*/
1460 :
1461 0 : void isar_rend_CldfbSplitPreRendProcess(
1462 : const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
1463 : const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
1464 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
1465 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
1466 : float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i : Binaural signals, real part */
1467 : float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i : Binaural signals, imag. part */
1468 : #else
1469 : float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */
1470 : float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */
1471 : #endif
1472 : ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
1473 : const int32_t target_md_bits, /* i : ISAR MD bitrate */
1474 : const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
1475 : const int16_t ro_md_flag /* i : real only metadata for yaw flag */
1476 : )
1477 : {
1478 0 : push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
1479 :
1480 0 : isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag );
1481 :
1482 0 : isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits );
1483 :
1484 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
1485 : float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv;
1486 : IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler;
1487 : float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1488 : float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1489 : int16_t sf_idx, pos_idx, b, ch1, ch2;
1490 : int32_t read_off, write_off;
1491 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
1492 : {
1493 : QuaternionsPost[sf_idx].w = -3.0f;
1494 : QuaternionsPost[sf_idx].x = 0.0f;
1495 : QuaternionsPost[sf_idx].y = 0.0f;
1496 : QuaternionsPost[sf_idx].z = 0.0f;
1497 : }
1498 :
1499 : hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1;
1500 : set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData );
1501 : set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData );
1502 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
1503 : {
1504 : Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
1505 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f;
1506 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x );
1507 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y );
1508 : hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z );
1509 : }
1510 : for ( sf_idx = 0; sf_idx < 1; sf_idx++ )
1511 : {
1512 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
1513 : {
1514 : for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ )
1515 : {
1516 : hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
1517 : BIN_HR_SPLIT_REND_MD_HANDLE hMd;
1518 : hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
1519 : minv = -1.4f;
1520 : maxv = 1.4f;
1521 : step = ( maxv - minv ) / 62.0f;
1522 : if ( b >= 20 )
1523 : {
1524 : float sign;
1525 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1526 : {
1527 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1528 : {
1529 : sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f;
1530 : IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] );
1531 : hMd->pred_mat_re[ch1][ch2] *= sign;
1532 : hMd->pred_mat_im[ch1][ch2] = 0.0f;
1533 : }
1534 : }
1535 : }
1536 :
1537 : for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
1538 : {
1539 : for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
1540 : {
1541 : quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
1542 : quant_val = min( maxv, max( quant_val, minv ) );
1543 : quant_val = (int16_t) roundf( quant_val / step );
1544 : hMd->pred_mat_re[ch1][ch2] = quant_val * step;
1545 : hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
1546 :
1547 : quant_val = hMd->pred_mat_im[ch1][ch2];
1548 : quant_val = min( maxv, max( quant_val, minv ) );
1549 : quant_val = (int16_t) roundf( quant_val / step );
1550 : hMd->pred_mat_im[ch1][ch2] = quant_val * step;
1551 : }
1552 : }
1553 : }
1554 : }
1555 : }
1556 :
1557 : for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
1558 : {
1559 : 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 );
1560 : 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 );
1561 : 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 );
1562 : 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 );
1563 : isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 );
1564 :
1565 : {
1566 : float *pOut[2];
1567 : char fname[200] = "ref_act_pos.wav";
1568 : pOut[0] = tmpCrendBuffer[0];
1569 : pOut[1] = tmpCrendBuffer[1];
1570 : dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 );
1571 : }
1572 : }
1573 : #endif
1574 :
1575 0 : pop_wmops();
1576 0 : return;
1577 : }
1578 :
1579 :
1580 : /*-------------------------------------------------------------------------
1581 : * Function isar_splitBinPreRendOpen()
1582 : *
1583 : *
1584 : *------------------------------------------------------------------------*/
1585 :
1586 0 : ivas_error isar_splitBinPreRendOpen(
1587 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, /* i/o: binaural pre-renderer handle */
1588 : MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* o : pose correction data handle */
1589 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1590 : ,
1591 : const int32_t output_Fs
1592 : #endif
1593 : )
1594 : {
1595 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend;
1596 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1597 : ivas_error error;
1598 : int16_t ch;
1599 : #endif
1600 : int16_t pos_idx, sf_idx, bandIdx;
1601 :
1602 0 : if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL )
1603 : {
1604 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) );
1605 : }
1606 :
1607 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1608 : for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
1609 : {
1610 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
1611 : {
1612 : hBinRend->cldfbSynRotBinDec[i][ch] = NULL;
1613 : }
1614 : }
1615 :
1616 : for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
1617 : {
1618 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
1619 : {
1620 : if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
1621 : {
1622 : return error;
1623 : }
1624 : }
1625 : }
1626 :
1627 : #endif
1628 0 : for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
1629 : {
1630 0 : for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ )
1631 : {
1632 0 : for ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ )
1633 : {
1634 0 : hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f;
1635 : }
1636 : }
1637 : }
1638 :
1639 0 : set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData );
1640 :
1641 0 : set_pose_types( hBinRend->pose_type, pMultiBinPoseData );
1642 :
1643 0 : isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
1644 :
1645 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
1646 : ivas_error error;
1647 : if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK )
1648 : {
1649 : return error;
1650 : }
1651 :
1652 : #endif
1653 0 : *hBinHrSplitPreRend = hBinRend;
1654 :
1655 0 : return IVAS_ERR_OK;
1656 : }
1657 :
1658 :
1659 : /*-------------------------------------------------------------------------
1660 : * Function isar_splitBinPreRendClose()
1661 : *
1662 : *
1663 : *------------------------------------------------------------------------*/
1664 :
1665 0 : void isar_splitBinPreRendClose(
1666 : ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */
1667 : )
1668 : {
1669 0 : if ( ( *hBinHrSplitPreRend ) != NULL )
1670 : {
1671 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1672 : {
1673 : int16_t i, n;
1674 : for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
1675 : {
1676 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
1677 : {
1678 : if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL )
1679 : {
1680 : deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) );
1681 : ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL;
1682 : }
1683 : }
1684 : }
1685 : }
1686 : #endif
1687 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
1688 : isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend );
1689 : #endif
1690 :
1691 0 : free( ( *hBinHrSplitPreRend ) );
1692 0 : ( *hBinHrSplitPreRend ) = NULL;
1693 : }
1694 :
1695 0 : return;
1696 : }
1697 :
1698 :
1699 : /*-------------------------------------------------------------------------*
1700 : * isar_set_split_rend_ht_setup()
1701 : *
1702 : *
1703 : *-------------------------------------------------------------------------*/
1704 :
1705 0 : void isar_set_split_rend_ht_setup(
1706 : SPLIT_REND_WRAPPER *hSplitrend, /* i/o: Split renderer pre-renderer handle */
1707 : IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], /* i/o: External orientation in quaternions */
1708 : float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] /* o : real-space rotation matrix */
1709 : )
1710 : {
1711 : int16_t sf, i, j;
1712 :
1713 0 : if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
1714 : {
1715 0 : for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1716 : {
1717 0 : Quaternions[sf] = Quaternions[0];
1718 :
1719 0 : for ( i = 0; i < 3; i++ )
1720 : {
1721 0 : for ( j = 0; j < 3; j++ )
1722 : {
1723 0 : Rmat[sf][i][j] = Rmat[0][i][j];
1724 : }
1725 : }
1726 : }
1727 : }
1728 :
1729 0 : return;
1730 : }
1731 :
1732 :
1733 : /*-------------------------------------------------------------------------
1734 : * Function isar_init_split_rend_handles()
1735 : *
1736 : *
1737 : *------------------------------------------------------------------------*/
1738 :
1739 0 : void isar_init_split_rend_handles(
1740 : SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */
1741 : )
1742 : {
1743 : int16_t i;
1744 :
1745 0 : hSplitRendWrapper->hBinHrSplitPreRend = NULL;
1746 0 : hSplitRendWrapper->hCldfbHandles = NULL;
1747 0 : hSplitRendWrapper->hSplitBinLCLDEnc = NULL;
1748 0 : hSplitRendWrapper->hLc3plusEnc = NULL;
1749 :
1750 0 : for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
1751 : {
1752 0 : hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL;
1753 : }
1754 0 : hSplitRendWrapper->lc3plusDelaySamples = 0;
1755 :
1756 0 : isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
1757 :
1758 0 : return;
1759 : }
1760 :
1761 :
1762 : /*-------------------------------------------------------------------------
1763 : * Function split_renderer_open_lc3plus()
1764 : *
1765 : *
1766 : *------------------------------------------------------------------------*/
1767 :
1768 0 : ivas_error split_renderer_open_lc3plus(
1769 : SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i/o: Split renderer pre-renderer handle */
1770 : const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */
1771 : const int32_t output_Fs, /* i : output sampling rate */
1772 : const IVAS_RENDER_FRAMESIZE isar_frame_size /* i : IVAS frame size */
1773 : )
1774 : {
1775 : ivas_error error;
1776 : int16_t i, delayBufferLength;
1777 : LC3PLUS_CONFIG config;
1778 : int16_t isar_frame_size_ms;
1779 :
1780 0 : if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK )
1781 : {
1782 0 : return error;
1783 : }
1784 :
1785 : /* Check configuration validity */
1786 0 : if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms )
1787 : {
1788 0 : return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" );
1789 : }
1790 :
1791 0 : config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000;
1792 0 : config.samplerate = output_Fs;
1793 :
1794 0 : config.isar_frame_duration_us = isar_frame_size_ms * 1000;
1795 :
1796 0 : config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 );
1797 0 : config.channels = BINAURAL_CHANNELS;
1798 :
1799 0 : if ( ( error = ISAR_LC3PLUS_ENC_Open( config, isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK )
1800 : {
1801 0 : return error;
1802 : }
1803 :
1804 : /* This returns delay of entire LC3plus chain (enc + dec) */
1805 0 : if ( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK )
1806 : {
1807 0 : return error;
1808 : }
1809 :
1810 : /* Alocate buffers for delay compensation */
1811 0 : if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
1812 : {
1813 0 : delayBufferLength = (int16_t) ( output_Fs / (int32_t) FRAMES_PER_SEC + hSplitRendWrapper->lc3plusDelaySamples );
1814 0 : for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
1815 : {
1816 0 : if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL )
1817 : {
1818 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
1819 : }
1820 :
1821 0 : set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength );
1822 : }
1823 : }
1824 : else
1825 : {
1826 : /* Delay is always expected to be exactly 2 CLDFB columns */
1827 0 : assert( hSplitRendWrapper->lc3plusDelaySamples % ( output_Fs / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 );
1828 0 : assert( hSplitRendWrapper->lc3plusDelaySamples / ( output_Fs / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 );
1829 :
1830 0 : delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX;
1831 0 : for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
1832 : {
1833 0 : if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL )
1834 : {
1835 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
1836 : }
1837 :
1838 0 : set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength );
1839 : }
1840 : }
1841 :
1842 0 : return IVAS_ERR_OK;
1843 : }
1844 :
1845 :
1846 : /*-------------------------------------------------------------------------
1847 : * Function splitRendLc3plusEncodeAndWrite()
1848 : *
1849 : *
1850 : *------------------------------------------------------------------------*/
1851 :
1852 0 : ivas_error splitRendLc3plusEncodeAndWrite(
1853 : SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
1854 : ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
1855 : const int32_t available_bits, /* i : available bit-budget */
1856 : float *in[] /* i/o: PCM in/out buffer */
1857 : )
1858 : {
1859 : ivas_error error;
1860 : int16_t i;
1861 : int32_t lc3plusBitstreamSize;
1862 : float *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
1863 0 : assert( hSplitBin->hLc3plusEnc != NULL );
1864 :
1865 : /* Find next byte boundary and zero-pad to it */
1866 0 : while ( pBits->bits_written % 8 != 0 )
1867 : {
1868 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
1869 : }
1870 :
1871 0 : for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
1872 : {
1873 0 : channel_ptrs[i] = in[i];
1874 : }
1875 :
1876 0 : if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK )
1877 : {
1878 0 : return error;
1879 : }
1880 :
1881 0 : if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
1882 : {
1883 0 : return error;
1884 : }
1885 :
1886 : /* Write bitstream */
1887 0 : if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
1888 : {
1889 0 : return error;
1890 : }
1891 :
1892 0 : pBits->bits_written += 8 * lc3plusBitstreamSize;
1893 0 : pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
1894 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
1895 0 : pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 );
1896 0 : pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 );
1897 :
1898 0 : return IVAS_ERR_OK;
1899 : }
1900 :
1901 :
1902 : /*-------------------------------------------------------------------------
1903 : * Function isar_renderMultiTDBinToSplitBinaural()
1904 : *
1905 : *
1906 : *------------------------------------------------------------------------*/
1907 :
1908 0 : ivas_error isar_renderMultiTDBinToSplitBinaural(
1909 : SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
1910 : const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
1911 : const int32_t SplitRendBitRate, /* i : ISAR bitrate */
1912 : const int16_t isar_frame_size_ms, /* i : ISAR bit stream frame size in ms */
1913 : const int16_t codec_frame_size_ms, /* i : ISAR frame length in ms */
1914 : ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
1915 : const int16_t max_bands, /* i : CLDFB bands */
1916 : float *in[], /* i/o: PCM in/out buffer */
1917 : const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
1918 : const int16_t pcm_out_flag, /* i : flag to indicate PCM output */
1919 : const int16_t ro_md_flag /* i : real only metadata for yaw flag */
1920 : )
1921 : {
1922 : ivas_error error;
1923 : int32_t bit_len, available_bits, target_md_bits;
1924 : int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses;
1925 : float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1926 : float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1927 : uint8_t useLc3plus;
1928 : float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
1929 : int16_t i;
1930 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
1931 : int16_t j;
1932 : float *p_Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
1933 : float *p_Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
1934 : #endif
1935 : int32_t num_slots;
1936 :
1937 0 : push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
1938 :
1939 0 : error = IVAS_ERR_OK;
1940 0 : num_poses = hSplitBin->multiBinPoseData.num_poses;
1941 :
1942 0 : useLc3plus = hSplitBin->hLc3plusEnc != NULL;
1943 :
1944 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
1945 0 : for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
1946 : {
1947 0 : for ( j = 0; j < CLDFB_NO_COL_MAX; ++j )
1948 : {
1949 0 : p_Cldfb_In_BinReal[i][j] = Cldfb_In_BinReal[i][j];
1950 0 : p_Cldfb_In_BinImag[i][j] = Cldfb_In_BinImag[i][j];
1951 : }
1952 : }
1953 : #endif
1954 :
1955 0 : if ( useLc3plus )
1956 : {
1957 : /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/
1958 0 : int16_t frame_size = (int16_t) ( hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SEC );
1959 :
1960 0 : for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
1961 : {
1962 : /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */
1963 0 : mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples );
1964 0 : in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i];
1965 0 : mvr2r( in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, frame_size );
1966 : }
1967 : }
1968 : else
1969 : {
1970 0 : for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
1971 : {
1972 0 : in_delayed[i] = in[i];
1973 : }
1974 : }
1975 :
1976 0 : if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
1977 : {
1978 0 : num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
1979 0 : num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels;
1980 :
1981 : /* CLDFB Analysis*/
1982 0 : for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
1983 : {
1984 : #ifdef SPLIT_POSE_CORRECTION_DEBUG
1985 : {
1986 : float *pOut[2];
1987 : char fname[200] = "ref_out_pos";
1988 : char tag[2];
1989 : tag[0] = (char) ( '0' + pos_idx );
1990 : tag[1] = '\0';
1991 : strcat( fname, tag );
1992 : strcat( fname, ".wav" );
1993 :
1994 : pOut[0] = in_delayed[2 * pos_idx];
1995 : pOut[1] = in_delayed[2 * pos_idx + 1];
1996 : dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 );
1997 : }
1998 :
1999 : #endif
2000 0 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
2001 : {
2002 0 : for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
2003 : {
2004 0 : cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ),
2005 0 : Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
2006 0 : max_bands, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch] );
2007 : }
2008 : }
2009 : }
2010 : }
2011 :
2012 0 : if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
2013 : {
2014 0 : target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
2015 :
2016 0 : isar_rend_CldfbSplitPreRendProcess(
2017 : hSplitBin->hBinHrSplitPreRend,
2018 : headPosition,
2019 : &hSplitBin->multiBinPoseData,
2020 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
2021 : p_Cldfb_In_BinReal,
2022 : p_Cldfb_In_BinImag,
2023 : #else
2024 : Cldfb_In_BinReal,
2025 : Cldfb_In_BinImag,
2026 : #endif
2027 : pBits,
2028 : target_md_bits,
2029 : low_res_pre_rend_rot,
2030 : ro_md_flag );
2031 : }
2032 :
2033 0 : if ( pcm_out_flag == 0 )
2034 : {
2035 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
2036 0 : pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD;
2037 :
2038 0 : if ( !useLc3plus )
2039 : {
2040 0 : available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
2041 0 : available_bits -= pBits->bits_written;
2042 0 : pBits->codec_frame_size_ms = codec_frame_size_ms;
2043 0 : pBits->isar_frame_size_ms = isar_frame_size_ms;
2044 :
2045 0 : isar_splitBinLCLDEncProcess(
2046 : hSplitBin->hSplitBinLCLDEnc,
2047 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
2048 : p_Cldfb_In_BinReal,
2049 : p_Cldfb_In_BinImag,
2050 : #else
2051 : Cldfb_In_BinReal,
2052 : Cldfb_In_BinImag,
2053 : #endif
2054 : available_bits,
2055 : pBits );
2056 : }
2057 : else
2058 : {
2059 0 : if ( pBits->pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
2060 : {
2061 0 : available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us ) / FRAMES_PER_SEC;
2062 : }
2063 : else
2064 : {
2065 0 : available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
2066 : }
2067 :
2068 0 : if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK )
2069 : {
2070 0 : return error;
2071 : }
2072 : }
2073 : }
2074 : else
2075 : {
2076 0 : pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
2077 0 : pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
2078 : }
2079 :
2080 : /*zero pad*/
2081 0 : if ( pcm_out_flag )
2082 : {
2083 0 : bit_len = SplitRendBitRate / FRAMES_PER_SEC;
2084 : }
2085 : else
2086 : {
2087 0 : if ( !useLc3plus )
2088 : {
2089 0 : bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
2090 : }
2091 : else
2092 : {
2093 0 : bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000;
2094 0 : bit_len = SplitRendBitRate * bit_len / 1000;
2095 : }
2096 : }
2097 :
2098 0 : while ( pBits->bits_written < bit_len )
2099 : {
2100 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
2101 : }
2102 :
2103 0 : pop_wmops();
2104 :
2105 0 : return error;
2106 : }
2107 :
2108 :
2109 : /*-------------------------------------------------------------------------
2110 : * Function lc3plusTimeAlignCldfbPoseCorr()
2111 : *
2112 : *
2113 : *------------------------------------------------------------------------*/
2114 :
2115 0 : void lc3plusTimeAlignCldfbPoseCorr(
2116 : SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
2117 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
2118 : float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */
2119 : float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX] /* i/o: Binaural signals, imag. part */
2120 : #else
2121 : float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: Binaural signals, real part */
2122 : float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* ii/: Binaural signals, imag. part */
2123 : #endif
2124 : )
2125 : {
2126 : float Cldfb_In_BinReal_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
2127 : float Cldfb_In_BinImag_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
2128 : int16_t pose, ch, slot_idx;
2129 : float *bufRead, *bufWrite;
2130 :
2131 0 : for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose )
2132 : {
2133 0 : for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch )
2134 : {
2135 0 : bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch];
2136 0 : bufWrite = bufRead;
2137 :
2138 : /* Save last 2 columns for next frame */
2139 0 : for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
2140 : {
2141 0 : mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
2142 0 : mvr2r( Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
2143 : }
2144 :
2145 : /* Delay existing columns by 2 slots */
2146 0 : for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx )
2147 : {
2148 0 : mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
2149 0 : mvr2r( Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
2150 : }
2151 :
2152 : /* Fill 2 first columns from buffer */
2153 0 : for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
2154 : {
2155 0 : mvr2r( bufRead, Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
2156 0 : bufRead += CLDFB_NO_CHANNELS_MAX;
2157 0 : mvr2r( bufRead, Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
2158 0 : bufRead += CLDFB_NO_CHANNELS_MAX;
2159 : }
2160 :
2161 : /* Copy last 2 columns to buffer */
2162 0 : for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
2163 : {
2164 0 : mvr2r( Cldfb_In_BinReal_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX );
2165 0 : bufWrite += CLDFB_NO_CHANNELS_MAX;
2166 0 : mvr2r( Cldfb_In_BinImag_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX );
2167 0 : bufWrite += CLDFB_NO_CHANNELS_MAX;
2168 : }
2169 : }
2170 : }
2171 :
2172 0 : return;
2173 : }
|