LCOV - code coverage report
Current view: top level - lib_isar - isar_splitRendererPre.c (source / functions) Hit Total Coverage
Test: Coverage on main -- conformance test test_26252.py @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 607 653 93.0 %
Date: 2025-11-01 05:07:43 Functions: 26 26 100.0 %

          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     7600696 : 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     7600696 :     IVAS_CMULT_FLOAT( in_re[0][0], in_im[0][0], in_re[1][1], in_im[1][1], re1, im1 );
      83     7600696 :     IVAS_CMULT_FLOAT( in_re[0][1], in_im[0][1], in_re[1][0], in_im[1][0], re2, im2 );
      84     7600696 :     *det_re = re1 - re2;
      85     7600696 :     *det_im = im1 - im2;
      86             : 
      87     7600696 :     return;
      88             : }
      89             : 
      90             : 
      91     3800348 : 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     3800348 :     int16_t is_det_zero = 1;
      96             :     float det, det_re, det_im;
      97             : 
      98     3800348 :     isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
      99             : 
     100     3800348 :     det = ( ( det_re * det_re ) + ( det_im * det_im ) );
     101             : 
     102     3800348 :     if ( det < EPSILON )
     103             :     {
     104           0 :         is_det_zero = 0;
     105             :     }
     106             : 
     107     3800348 :     return is_det_zero;
     108             : }
     109             : 
     110             : 
     111     3800348 : 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     3800348 :     isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
     121             : 
     122     3800348 :     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     3800348 :     det = 1 / det;
     129             : 
     130     3800348 :     IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][1], in_im[1][1], re, im );
     131     3800348 :     out_re[0][0] = re * det;
     132     3800348 :     out_im[0][0] = im * det;
     133             : 
     134     3800348 :     IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][1], in_im[0][1], re, im );
     135     3800348 :     out_re[0][1] = -re * det;
     136     3800348 :     out_im[0][1] = -im * det;
     137             : 
     138     3800348 :     IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][0], in_im[1][0], re, im );
     139     3800348 :     out_re[1][0] = -re * det;
     140     3800348 :     out_im[1][0] = -im * det;
     141             : 
     142     3800348 :     IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][0], in_im[0][0], re, im );
     143     3800348 :     out_re[1][1] = re * det;
     144     3800348 :     out_im[1][1] = im * det;
     145             : 
     146     3800348 :     return;
     147             : }
     148             : 
     149             : 
     150     3849096 : 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     3849096 :     trace_cov = 0.0f;
     167    11547288 :     for ( i = 0; i < num_chs; i++ )
     168             :     {
     169     7698192 :         trace_cov += cov_ii_re[i][i];
     170             :     }
     171             : 
     172     3849096 :     trace_cov = max( 0.0f, trace_cov );
     173             : 
     174     3849096 :     if ( trace_cov < EPSILON )
     175             :     {
     176      146244 :         for ( i = 0; i < num_chs; i++ )
     177             :         {
     178             :             /* protection from cases when variance of ref channels is very small */
     179       97496 :             set_zero( pred_mat_re[i], BINAURAL_CHANNELS );
     180       97496 :             set_zero( pred_mat_im[i], BINAURAL_CHANNELS );
     181             :         }
     182       48748 :         return;
     183             :     }
     184             : 
     185    11401044 :     for ( i = 0; i < num_chs; i++ )
     186             :     {
     187     7600696 :         mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs );
     188             :     }
     189             : 
     190    11401044 :     for ( i = 0; i < num_chs; i++ )
     191             :     {
     192     7600696 :         cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f );
     193             :     }
     194             : 
     195     3800348 :     if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) )
     196             :     {
     197     3800348 :         isar_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im );
     198     3800348 :         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     3800348 :     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     3800348 :     return;
     234             : }
     235             : 
     236             : 
     237     3849096 : 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     3849096 :     assert( num_chs == BINAURAL_CHANNELS );
     253    11547288 :     for ( i = 0; i < num_chs; i++ )
     254             :     {
     255    23094576 :         for ( j = 0; j < num_chs; j++ )
     256             :         {
     257    15396384 :             dmx_mat_conj_re[i][j] = pred_mat_re[j][i];
     258    15396384 :             dmx_mat_conj_im[i][j] = -pred_mat_im[j][i];
     259             : 
     260    15396384 :             temp_mat_re[i][j] = pred_mat_re[i][j];
     261    15396384 :             temp_mat_im[i][j] = pred_mat_im[i][j];
     262             :         }
     263     7698192 :         set_zero( postpred_cov_re[i], BINAURAL_CHANNELS );
     264             :     }
     265             : 
     266             :     /* 2x2 mult */
     267     3849096 :     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     3849096 :     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    11547288 :     for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     271             :     {
     272    11547288 :         for ( j = 0; j < i; j++ )
     273             :         {
     274     3849096 :             postpred_cov_re[i][j] = postpred_cov_re[j][i];
     275             :         }
     276             :     }
     277             : 
     278     3849096 :     return;
     279             : }
     280             : 
     281             : 
     282    11511600 : 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    34534800 :     for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
     312             :     {
     313    23023200 :         set_f( out_cov_re[ch_idx1], 0.0f, num_chs );
     314    23023200 :         set_f( out_cov_im[ch_idx1], 0.0f, num_chs );
     315             :     }
     316             : 
     317    11511600 :     brange[0] = pBand_grouping[md_band_idx];
     318    11511600 :     brange[1] = pBand_grouping[md_band_idx + 1];
     319             : 
     320    34534800 :     for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
     321             :     {
     322    69069600 :         for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ )
     323             :         {
     324    46046400 :             if ( real_only == 0 )
     325             :             {
     326   402425088 :                 for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
     327             :                 {
     328  1336017408 :                     for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
     329             :                     {
     330   957264384 :                         out_cov_re[ch_idx1][ch_idx2] +=
     331   957264384 :                             Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] +
     332   957264384 :                             Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx];
     333             : 
     334   957264384 :                         out_cov_im[ch_idx1][ch_idx2] +=
     335   957264384 :                             Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] -
     336   957264384 :                             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   380363712 :                 for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
     343             :                 {
     344  1610952192 :                     for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
     345             :                     {
     346  1252962816 :                         out_cov_re[ch_idx1][ch_idx2] +=
     347  1252962816 :                             Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] +
     348  1252962816 :                             Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx];
     349             : 
     350  1252962816 :                         out_cov_im[ch_idx1][ch_idx2] = 0.0f;
     351             :                     }
     352             :                 }
     353             :             }
     354             :         }
     355             :     }
     356             : 
     357    11511600 :     return;
     358             : }
     359             : 
     360             : 
     361    14270420 : 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    42811260 :     for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
     383             :     {
     384    28540840 :         set_f( out_cov_re[ch_idx1], 0.0f, num_chs );
     385    28540840 :         set_f( out_cov_im[ch_idx1], 0.0f, num_chs );
     386             :     }
     387             : 
     388    14270420 :     brange[0] = pBand_grouping[md_band_idx];
     389    14270420 :     brange[1] = pBand_grouping[md_band_idx + 1];
     390             : 
     391    42811260 :     for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
     392             :     {
     393    71352100 :         for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ )
     394             :         {
     395    42811260 :             if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) )
     396             :             {
     397   128965332 :                 for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
     398             :                 {
     399   432042752 :                     for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
     400             :                     {
     401   310663616 :                         out_cov_re[ch_idx1][ch_idx2] +=
     402   310663616 :                             Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] +
     403   310663616 :                             Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx];
     404             : 
     405   310663616 :                         out_cov_im[ch_idx1][ch_idx2] +=
     406   310663616 :                             Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] -
     407   310663616 :                             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   598826088 :                 for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
     414             :                 {
     415  2307877888 :                     for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
     416             :                     {
     417  1744276864 :                         out_cov_re[ch_idx1][ch_idx2] +=
     418  1744276864 :                             Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] +
     419  1744276864 :                             Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx];
     420             : 
     421  1744276864 :                         out_cov_im[ch_idx1][ch_idx2] = 0.0f;
     422             :                     }
     423             :                 }
     424             :             }
     425             :         }
     426             :     }
     427             : 
     428    42811260 :     for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
     429             :     {
     430    42811260 :         for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ )
     431             :         {
     432    14270420 :             out_cov_re[ch_idx1][ch_idx2] = out_cov_re[ch_idx2][ch_idx1];
     433    14270420 :             out_cov_im[ch_idx1][ch_idx2] = -out_cov_im[ch_idx2][ch_idx1];
     434             :         }
     435             :     }
     436             : 
     437    14270420 :     return;
     438             : }
     439             : 
     440             : 
     441     3849096 : 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     3849096 :     norm_fact = 0.0f;
     452    11547288 :     for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     453             :     {
     454    23094576 :         for ( j = 0; j < BINAURAL_CHANNELS; j++ )
     455             :         {
     456    15396384 :             IVAS_CALCULATE_ABS( cov_ii_re[i][j], cov_ii_im[i][j], abs_val );
     457    15396384 :             norm_fact = max( norm_fact, abs_val );
     458             : 
     459    15396384 :             IVAS_CALCULATE_ABS( cov_io_re[i][j], cov_io_im[i][j], abs_val );
     460    15396384 :             norm_fact = max( norm_fact, abs_val );
     461             : 
     462    15396384 :             IVAS_CALCULATE_RABS( cov_oo_re[i][j], abs_val );
     463    15396384 :             norm_fact = max( norm_fact, abs_val );
     464             :         }
     465             :     }
     466             : 
     467     3849096 :     norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f;
     468             : 
     469     3849096 :     norm_fact = PCM16_TO_FLT_FAC / norm_fact;
     470             : 
     471     3849096 :     return norm_fact;
     472             : }
     473             : 
     474             : 
     475    46131792 : 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    46131792 :     min_sym_val = huff_cfg->codebook[0];
     485             : 
     486    46131792 :     codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
     487    46131792 :     *hlen = codebook[1];
     488    46131792 :     *hcode = codebook[2];
     489             : 
     490    46131792 :     return;
     491             : }
     492             : 
     493             : 
     494    11514840 : 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    11514840 :     if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY )
     506     8083480 :     {
     507             :         float onebyquantstep;
     508             : 
     509     8083480 :         onebyquantstep = pred_1byquantstep;
     510     8083480 :         if ( real_only == 1 )
     511             :         {
     512    12699384 :             for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     513             :             {
     514     8466256 :                 hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1];
     515             :             }
     516             : 
     517     4233128 :             hMd->pred_mat_re[1][0] = 0.0f;
     518     4233128 :             hMd->pred_mat_re[0][1] = 0.0f;
     519             : 
     520    12699384 :             for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     521             :             {
     522    25398768 :                 for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     523             :                 {
     524    16932512 :                     quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f );
     525    16932512 :                     quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
     526    16932512 :                     hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
     527             :                 }
     528             :             }
     529             :         }
     530             :         else
     531             :         {
     532    11551056 :             for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     533             :             {
     534    23102112 :                 for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     535             :                 {
     536    15401408 :                     quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2];
     537    15401408 :                     quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
     538    15401408 :                     hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
     539             :                 }
     540             :             }
     541             :         }
     542             : 
     543     8083480 :         if ( real_only == 0 )
     544             :         {
     545    11551056 :             for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     546             :             {
     547    23102112 :                 for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     548             :                 {
     549    15401408 :                     quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) );
     550    15401408 :                     hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
     551             :                 }
     552             :             }
     553             :         }
     554             :     }
     555     3431360 :     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     3431360 :     else if ( pose_type == LR_GAIN_ONLY )
     564             :     {
     565     3431360 :         quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
     566     3431360 :         gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL );
     567     3431360 :         hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
     568     3431360 :         hMd->gd_idx = hMd->gd_idx - gd_idx_min;
     569             : 
     570     3431360 :         quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
     571     3431360 :         hMd->gd2_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
     572     3431360 :         hMd->gd2_idx = hMd->gd2_idx - gd_idx_min;
     573             :     }
     574             : 
     575    11514840 :     return;
     576             : }
     577             : 
     578             : 
     579    11511600 : 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    34534800 :     for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     587             :     {
     588    23023200 :         gains[i] = cov_in[i][i];
     589    23023200 :         if ( gains[i] < EPSILON )
     590             :         {
     591      187768 :             gains[i] = 1.0f;
     592             :         }
     593             :         else
     594             :         {
     595    22835432 :             gains[i] = ( cov_out[i][i] ) / gains[i];
     596    22835432 :             gains[i] = sqrtf( gains[i] );
     597             :         }
     598             :     }
     599             : 
     600    11511600 :     return;
     601             : }
     602             : 
     603             : 
     604    11511600 : 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    11511600 :     if ( pose_type == PITCH_ONLY )
     624             :     {
     625             :         float gd_tmp[BINAURAL_CHANNELS];
     626             : 
     627     3430280 :         get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
     628             : 
     629     3430280 :         hMd->gd = gd_tmp[0];
     630     3430280 :         hMd->gd2 = gd_tmp[1];
     631             :     }
     632             :     else
     633             :     {
     634     8081320 :         if ( real_only )
     635             :         {
     636             :             float gd_tmp[BINAURAL_CHANNELS];
     637             : 
     638     4232224 :             get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
     639             : 
     640    12696672 :             for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     641             :             {
     642     8464448 :                 hMd->pred_mat_re[i][i] = gd_tmp[i];
     643     8464448 :                 hMd->pred_mat_re2[i] = gd_tmp[i];
     644     8464448 :                 set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS );
     645             :             }
     646             : 
     647     4232224 :             hMd->pred_mat_re[1][0] = 0.0f;
     648     4232224 :             hMd->pred_mat_re[0][1] = 0.0f;
     649             :         }
     650             :         else
     651             :         {
     652     3849096 :             get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 );
     653             : 
     654     3849096 :             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    11547288 :             for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     658             :             {
     659    23094576 :                 for ( j = 0; j < BINAURAL_CHANNELS; j++ )
     660             :                 {
     661    15396384 :                     cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact;
     662    15396384 :                     cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact;
     663    15396384 :                     cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact;
     664    15396384 :                     cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact;
     665    15396384 :                     cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact;
     666             :                 }
     667             :             }
     668             : 
     669     3849096 :             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     3849096 :             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     3849096 :             gd = 1.0f / ( PCM16_TO_FLT_FAC );
     675    11547288 :             for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     676             :             {
     677    23094576 :                 for ( j = 0; j < BINAURAL_CHANNELS; j++ )
     678             :                 {
     679    15396384 :                     postpred_cov_re[i][j] *= gd;
     680    15396384 :                     cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd;
     681    15396384 :                     cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd;
     682             :                 }
     683             :             }
     684             : 
     685     3849096 :             gd2 = 0.0f;
     686     3849096 :             sigma_d = 0.0f;
     687     3849096 :             hMd->gd = 0.0f;
     688             : 
     689     3849096 :             if ( postpred_cov_re[0][0] > EPSILON )
     690             :             {
     691     3800348 :                 gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] );
     692     3800348 :                 gl2 = max( gl2, 1.0f );
     693     3800348 :                 gl2 = sqrtf( gl2 );
     694             :             }
     695             :             else
     696             :             {
     697       48748 :                 gl2 = 1.0f;
     698             :             }
     699             : 
     700     3849096 :             if ( postpred_cov_re[1][1] > EPSILON )
     701             :             {
     702     3800348 :                 gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] );
     703     3800348 :                 gr2 = max( gr2, 1.0f );
     704     3800348 :                 gr2 = sqrtf( gr2 );
     705             :             }
     706             :             else
     707             :             {
     708       48748 :                 gr2 = 1.0f;
     709             :             }
     710             : 
     711    11547288 :             for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     712             :             {
     713     7698192 :                 hMd->pred_mat_re[i][0] *= gl2;
     714     7698192 :                 hMd->pred_mat_re[i][1] *= gr2;
     715             :             }
     716             : 
     717     3849096 :             if ( real_only == 0 )
     718             :             {
     719    11547288 :                 for ( i = 0; i < BINAURAL_CHANNELS; i++ )
     720             :                 {
     721     7698192 :                     hMd->pred_mat_im[i][0] *= gl2;
     722     7698192 :                     hMd->pred_mat_im[i][1] *= gr2;
     723             :                 }
     724             :             }
     725             :         }
     726             :     }
     727             : 
     728    11511600 :     return;
     729             : }
     730             : 
     731             : 
     732      137941 : 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      689705 :     for ( q = 0; q < num_quant_strats; q++ )
     753             :     {
     754      551764 :         pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) );
     755             :     }
     756      137941 :     pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) );
     757             : 
     758      137941 :     d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) );
     759      137941 :     pitch_gain_bits = d_gain_bits;
     760             : 
     761      689705 :     for ( q = 0; q < num_quant_strats; q++ )
     762             :     {
     763      551764 :         base2bits[q] = 0;
     764             :     }
     765             : 
     766      689705 :     for ( q = 0; q < num_quant_strats; q++ )
     767             :     {
     768     2854084 :         for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ )
     769             :         {
     770     2302320 :             pose_type = hBinHrSplitPreRend->pose_type[pose_idx];
     771     2302320 :             if ( pose_type == ANY_YAW )
     772             :             {
     773     1103528 :                 base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
     774     1103528 :                 base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
     775     1103528 :                 base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
     776     1103528 :                 base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes;
     777             :             }
     778     1198792 :             else if ( pose_type == PITCH_ONLY )
     779             :             {
     780      686056 :                 base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes;
     781      686056 :                 base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes;
     782             :             }
     783             :             else
     784             :             {
     785      512736 :                 base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
     786      512736 :                 base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
     787      512736 :                 base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
     788             :             }
     789             :         }
     790             :     }
     791             : 
     792      137941 :     return;
     793             : }
     794             : 
     795             : 
     796         242 : 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         242 :     pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
     819         242 :     if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
     820             :     {
     821         240 :         pred_cb_idx = 1;
     822             :     }
     823             :     else
     824             :     {
     825           2 :         pred_cb_idx = 0;
     826             :     }
     827         242 :     min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0];
     828         242 :     min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
     829         242 :     min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0];
     830         242 :     min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0];
     831             : 
     832         242 :     pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx];
     833         242 :     pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len;
     834         242 :     gd_code_len = pHuff_cfg->gd_base2_code_len;
     835         242 :     p_gd_code_len = pHuff_cfg->p_gd_base2_code_len;
     836             : 
     837         242 :     num_poses = pMultiBinPoseData->num_poses;
     838             : 
     839         484 :     for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
     840             :     {
     841        1310 :         for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
     842             :         {
     843        1068 :             if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
     844             :             {
     845        2764 :                 for ( b = 0; b < pred_imag_bands_yaw; b++ )
     846             :                 {
     847        2280 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
     848        6840 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     849             :                     {
     850       13680 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     851             :                         {
     852        9120 :                             code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx;
     853        9120 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
     854             :                         }
     855             :                     }
     856             : 
     857        6840 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     858             :                     {
     859       13680 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     860             :                         {
     861        9120 :                             code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx;
     862        9120 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
     863             :                         }
     864             :                     }
     865             :                 }
     866             : 
     867        7884 :                 for ( ; b < pred_real_bands_yaw; b++ )
     868             :                 {
     869        7400 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
     870       22200 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     871             :                     {
     872       14800 :                         code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_idx;
     873       14800 :                         ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
     874             :                     }
     875             :                 }
     876             : 
     877         484 :                 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         584 :             else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
     885             :             {
     886        7308 :                 for ( b = 0; b < bands_pitch; b++ )
     887             :                 {
     888        6960 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
     889        6960 :                     code = hMd->gd_idx - min_p_gd_idx;
     890        6960 :                     ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
     891             : 
     892        6960 :                     code = hMd->gd2_idx - min_p_gd_idx;
     893        6960 :                     ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
     894             :                 }
     895             :             }
     896             :             else
     897             :             {
     898        1180 :                 for ( b = 0; b < pred_imag_bands_roll; b++ )
     899             :                 {
     900         944 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
     901        2832 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     902             :                     {
     903        5664 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     904             :                         {
     905        3776 :                             code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx;
     906        3776 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
     907             :                         }
     908             :                     }
     909        2832 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     910             :                     {
     911        5664 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
     912             :                         {
     913        3776 :                             code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx;
     914        3776 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
     915             :                         }
     916             :                     }
     917             :                 }
     918             : 
     919        4012 :                 for ( ; b < pred_real_bands_roll; b++ )
     920             :                 {
     921        3776 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
     922       11328 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
     923             :                     {
     924        7552 :                         code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx;
     925        7552 :                         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         242 :     return;
     952             : }
     953             : 
     954             : 
     955      137968 : 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      137968 :     pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
     978             : 
     979      137968 :     if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
     980             :     {
     981      137941 :         pred_cb_idx = 1;
     982             :     }
     983             :     else
     984             :     {
     985          27 :         pred_cb_idx = 0;
     986             :     }
     987             : 
     988      137968 :     min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0];
     989      137968 :     max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3];
     990      137968 :     min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
     991      137968 :     max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
     992             : 
     993      137968 :     num_poses = pMultiBinPoseData->num_poses;
     994             : 
     995      275936 :     for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
     996             :     {
     997      713710 :         for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
     998             :         {
     999      575742 :             if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
    1000             :             {
    1001     3613336 :                 for ( b = 0; b < pred_imag_bands_yaw; b++ )
    1002             :                 {
    1003     3337400 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1004     3337400 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
    1005    10012200 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1006             :                     {
    1007    20024400 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
    1008             :                         {
    1009    13349600 :                             isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
    1010    13349600 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1011             :                         }
    1012             :                     }
    1013             : 
    1014     3337400 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
    1015    10012200 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1016             :                     {
    1017    20024400 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
    1018             :                         {
    1019    13349600 :                             isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
    1020    13349600 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1021             :                         }
    1022             :                     }
    1023             :                 }
    1024             : 
    1025     2457256 :                 for ( ; b < pred_real_bands_yaw; b++ )
    1026             :                 {
    1027     2181320 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1028     2181320 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
    1029     6543960 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1030             :                     {
    1031     4362640 :                         isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len );
    1032     4362640 :                         ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1033             :                     }
    1034             :                 }
    1035      275936 :                 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      299806 :             else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
    1043             :             {
    1044     3602928 :                 for ( b = 0; b < bands_pitch; b++ )
    1045             :                 {
    1046     3431360 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1047     3431360 :                     isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
    1048     3431360 :                     ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1049             : 
    1050     3431360 :                     isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
    1051     3431360 :                     ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1052             :                 }
    1053             :             }
    1054             :             else
    1055             :             {
    1056      641190 :                 for ( b = 0; b < pred_imag_bands_roll; b++ )
    1057             :                 {
    1058      512952 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1059      512952 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
    1060     1538856 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1061             :                     {
    1062     3077712 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
    1063             :                         {
    1064     2051808 :                             isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
    1065     2051808 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1066             :                         }
    1067             :                     }
    1068             : 
    1069      512952 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
    1070     1538856 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1071             :                     {
    1072     3077712 :                         for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
    1073             :                         {
    1074     2051808 :                             isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
    1075     2051808 :                             ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
    1076             :                         }
    1077             :                     }
    1078             :                 }
    1079             : 
    1080     2180046 :                 for ( ; b < pred_real_bands_roll; b++ )
    1081             :                 {
    1082     2051808 :                     hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1083     2051808 :                     isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
    1084     6155424 :                     for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
    1085             :                     {
    1086     4103616 :                         isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len );
    1087     4103616 :                         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      137968 :     return;
    1113             : }
    1114             : 
    1115             : 
    1116      137941 : 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      137941 :     if ( low_res_pre_rend_rot )
    1139             :     {
    1140      137941 :         num_subframes = 1;
    1141             :     }
    1142             :     else
    1143             :     {
    1144           0 :         num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
    1145             :     }
    1146             : 
    1147      137941 :     overhead_bits = pBits->bits_written;
    1148             : 
    1149      137941 :     ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS );
    1150      137941 :     ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS );
    1151             : 
    1152      137941 :     rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits );
    1153      137941 :     if ( num_bits > 0 )
    1154             :     {
    1155       52384 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits );
    1156             :     }
    1157             : 
    1158      137941 :     ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS );
    1159             : 
    1160             :     /* code ref pose*/
    1161      275882 :     for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
    1162             :     {
    1163             :         int16_t angle;
    1164             :         IVAS_QUATERNION head_pos_euler;
    1165             : 
    1166      137941 :         Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
    1167      137941 :         angle = (int16_t) roundf( head_pos_euler.x );
    1168      137941 :         angle += 180;
    1169      137941 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
    1170             : 
    1171      137941 :         angle = (int16_t) roundf( head_pos_euler.y );
    1172      137941 :         angle += 180;
    1173      137941 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
    1174             : 
    1175      137941 :         angle = (int16_t) roundf( head_pos_euler.z );
    1176      137941 :         angle += 180;
    1177             : 
    1178      137941 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
    1179             :     }
    1180             : 
    1181      137941 :     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      137941 :     quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) );
    1186             : 
    1187      137941 :     overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */
    1188             : 
    1189      137941 :     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      137968 :     for ( q = 0; q < num_quant_strats; q++ )
    1193             :     {
    1194      275936 :         for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
    1195             :         {
    1196      713710 :             for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
    1197             :             {
    1198      575742 :                 if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
    1199             :                 {
    1200     3613336 :                     for ( b = 0; b < pred_imag_bands_yaw[q]; b++ )
    1201             :                     {
    1202     3337400 :                         hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1203             : 
    1204     3337400 :                         isar_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
    1205             :                     }
    1206     2457256 :                     for ( ; b < pred_real_bands_yaw[q]; b++ )
    1207             :                     {
    1208     2181320 :                         hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1209             : 
    1210     2181320 :                         isar_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
    1211             :                     }
    1212             : 
    1213      275936 :                     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      299806 :                 else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
    1221             :                 {
    1222     3602928 :                     for ( b = 0; b < bands_pitch[q]; b++ )
    1223             :                     {
    1224     3431360 :                         hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1225     3431360 :                         isar_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
    1226             :                     }
    1227             :                 }
    1228             :                 else
    1229             :                 {
    1230      641190 :                     for ( b = 0; b < pred_imag_bands_roll[q]; b++ )
    1231             :                     {
    1232      512952 :                         hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1233      512952 :                         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     2180046 :                     for ( ; b < pred_real_bands_roll[q]; b++ )
    1236             :                     {
    1237     2051808 :                         hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
    1238     2051808 :                         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      137968 :         start_bit = pBits->bits_written;
    1246             : 
    1247      137968 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
    1248      137968 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
    1249             : 
    1250      137968 :         huff_bits = pBits->bits_written;
    1251      137968 :         isar_SplitRenderer_code_md_huff(
    1252             :             hBinHrSplitPreRend,
    1253             :             pMultiBinPoseData,
    1254             :             num_subframes,
    1255      137968 :             pred_real_bands_yaw[q],
    1256      137968 :             pred_imag_bands_yaw[q],
    1257      137968 :             pred_quant_pnts_yaw[q],
    1258      137968 :             d_bands_yaw[q],
    1259      137968 :             bands_pitch[q],
    1260      137968 :             pred_real_bands_roll[q],
    1261      137968 :             pred_imag_bands_roll[q],
    1262             :             pBits );
    1263             : 
    1264      137968 :         huff_bits = pBits->bits_written - huff_bits;
    1265             : 
    1266      137968 :         if ( ( target_md_bits >= ( base2bits[q] + overhead_bits ) ) || ( target_md_bits >= ( huff_bits + overhead_bits ) ) || ( q == ( num_quant_strats - 1 ) ) )
    1267             :         {
    1268      137941 :             if ( huff_bits > base2bits[q] )
    1269             :             {
    1270         242 :                 pBits->bits_written = start_bit;
    1271             : 
    1272         242 :                 ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
    1273         242 :                 ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
    1274             : 
    1275         242 :                 isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
    1276         242 :                                                   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      137941 :             break;
    1279             :         }
    1280             : 
    1281          27 :         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      137941 :     return;
    1362             : }
    1363             : 
    1364             : 
    1365             : /*-------------------------------------------------------------------------
    1366             :  * Function isar_SplitRenderer_GetRotMd()
    1367             :  *
    1368             :  *
    1369             :  *------------------------------------------------------------------------*/
    1370             : 
    1371      137941 : 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      137941 :     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      137941 :     const int16_t *pBand_grouping = isar_split_rend_band_grouping;
    1395             : 
    1396      137941 :     push_wmops( "isar_SplitRenderer_GetRotMd" );
    1397             : 
    1398      137941 :     num_md_bands = MAX_SPLIT_REND_MD_BANDS;
    1399      137941 :     num_poses = pMultiBinPoseData->num_poses;
    1400             : 
    1401      137941 :     if ( low_res )
    1402             :     {
    1403      137941 :         num_slots = CLDFB_NO_COL_MAX;
    1404      137941 :         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      275882 :     for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
    1414             :     {
    1415      137941 :         start_slot_idx = sf_idx * num_slots;
    1416     2896761 :         for ( b = 0; b < num_md_bands; b++ )
    1417             :         {
    1418     2758820 :             if ( ( b < SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) )
    1419             :             {
    1420     1668180 :                 real_only = 0;
    1421             :             }
    1422             :             else
    1423             :             {
    1424     1090640 :                 real_only = 1;
    1425             :             }
    1426             : 
    1427     2758820 :             ch_s_idx1 = 0;
    1428     2758820 :             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    14270420 :             for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
    1432             :             {
    1433    11511600 :                 if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL )
    1434             :                 {
    1435     2563680 :                     if ( b >= SPLIT_REND_RO_MD_BAND_THRESH )
    1436             :                     {
    1437     2050944 :                         real_only = 1;
    1438             :                     }
    1439             :                 }
    1440    11511600 :                 ch_s_idx2 = ( pos_idx + 1 ) * BINAURAL_CHANNELS;
    1441    11511600 :                 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    11511600 :                 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    11511600 :                 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      137941 :     pop_wmops();
    1451      137941 :     return;
    1452             : }
    1453             : 
    1454             : 
    1455             : /*-------------------------------------------------------------------------
    1456             :  * Function isar_rend_CldfbSplitPreRendProcess()
    1457             :  *
    1458             :  *
    1459             :  *------------------------------------------------------------------------*/
    1460             : 
    1461      137941 : 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      137941 :     push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
    1479             : 
    1480      137941 :     isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag );
    1481             : 
    1482      137941 :     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      137941 :     pop_wmops();
    1576      137941 :     return;
    1577             : }
    1578             : 
    1579             : 
    1580             : /*-------------------------------------------------------------------------
    1581             :  * Function isar_splitBinPreRendOpen()
    1582             :  *
    1583             :  *
    1584             :  *------------------------------------------------------------------------*/
    1585             : 
    1586         694 : 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         694 :     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        3614 :     for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
    1629             :     {
    1630        5840 :         for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ )
    1631             :         {
    1632       61320 :             for ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ )
    1633             :             {
    1634       58400 :                 hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f;
    1635             :             }
    1636             :         }
    1637             :     }
    1638             : 
    1639         694 :     set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData );
    1640             : 
    1641         694 :     set_pose_types( hBinRend->pose_type, pMultiBinPoseData );
    1642             : 
    1643         694 :     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         694 :     *hBinHrSplitPreRend = hBinRend;
    1654             : 
    1655         694 :     return IVAS_ERR_OK;
    1656             : }
    1657             : 
    1658             : 
    1659             : /*-------------------------------------------------------------------------
    1660             :  * Function isar_splitBinPreRendClose()
    1661             :  *
    1662             :  *
    1663             :  *------------------------------------------------------------------------*/
    1664             : 
    1665         694 : void isar_splitBinPreRendClose(
    1666             :     ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle    */
    1667             : )
    1668             : {
    1669         694 :     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         694 :         free( ( *hBinHrSplitPreRend ) );
    1692         694 :         ( *hBinHrSplitPreRend ) = NULL;
    1693             :     }
    1694             : 
    1695         694 :     return;
    1696             : }
    1697             : 
    1698             : 
    1699             : /*-------------------------------------------------------------------------*
    1700             :  * isar_set_split_rend_ht_setup()
    1701             :  *
    1702             :  *
    1703             :  *-------------------------------------------------------------------------*/
    1704             : 
    1705      427505 : 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      427505 :     if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
    1714             :     {
    1715     1102284 :         for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1716             :         {
    1717      826713 :             Quaternions[sf] = Quaternions[0];
    1718             : 
    1719     3306852 :             for ( i = 0; i < 3; i++ )
    1720             :             {
    1721     9920556 :                 for ( j = 0; j < 3; j++ )
    1722             :                 {
    1723     7440417 :                     Rmat[sf][i][j] = Rmat[0][i][j];
    1724             :                 }
    1725             :             }
    1726             :         }
    1727             :     }
    1728             : 
    1729      427505 :     return;
    1730             : }
    1731             : 
    1732             : 
    1733             : /*-------------------------------------------------------------------------
    1734             :  * Function isar_init_split_rend_handles()
    1735             :  *
    1736             :  *
    1737             :  *------------------------------------------------------------------------*/
    1738             : 
    1739        1032 : 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        1032 :     hSplitRendWrapper->hBinHrSplitPreRend = NULL;
    1746        1032 :     hSplitRendWrapper->hCldfbHandles = NULL;
    1747        1032 :     hSplitRendWrapper->hSplitBinLCLDEnc = NULL;
    1748        1032 :     hSplitRendWrapper->hLc3plusEnc = NULL;
    1749             : 
    1750       17544 :     for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
    1751             :     {
    1752       16512 :         hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL;
    1753             :     }
    1754        1032 :     hSplitRendWrapper->lc3plusDelaySamples = 0;
    1755             : 
    1756        1032 :     isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
    1757             : 
    1758        1032 :     return;
    1759             : }
    1760             : 
    1761             : 
    1762             : /*-------------------------------------------------------------------------
    1763             :  * Function split_renderer_open_lc3plus()
    1764             :  *
    1765             :  *
    1766             :  *------------------------------------------------------------------------*/
    1767             : 
    1768         358 : 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         358 :     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         358 :     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         358 :     config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000;
    1792         358 :     config.samplerate = output_Fs;
    1793             : 
    1794         358 :     config.isar_frame_duration_us = isar_frame_size_ms * 1000;
    1795             : 
    1796         358 :     config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 );
    1797         358 :     config.channels = BINAURAL_CHANNELS;
    1798             : 
    1799         358 :     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         358 :     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         358 :     if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
    1812             :     {
    1813         358 :         delayBufferLength = (int16_t) ( output_Fs / (int32_t) FRAMES_PER_SEC + hSplitRendWrapper->lc3plusDelaySamples );
    1814        3410 :         for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
    1815             :         {
    1816        3052 :             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        3052 :             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         358 :     return IVAS_ERR_OK;
    1843             : }
    1844             : 
    1845             : 
    1846             : /*-------------------------------------------------------------------------
    1847             :  * Function splitRendLc3plusEncodeAndWrite()
    1848             :  *
    1849             :  *
    1850             :  *------------------------------------------------------------------------*/
    1851             : 
    1852       84880 : 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       84880 :     assert( hSplitBin->hLc3plusEnc != NULL );
    1864             : 
    1865             :     /* Find next byte boundary and zero-pad to it */
    1866      278271 :     while ( pBits->bits_written % 8 != 0 )
    1867             :     {
    1868      193391 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
    1869             :     }
    1870             : 
    1871      733344 :     for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
    1872             :     {
    1873      648464 :         channel_ptrs[i] = in[i];
    1874             :     }
    1875             : 
    1876       84880 :     if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK )
    1877             :     {
    1878           0 :         return error;
    1879             :     }
    1880             : 
    1881       84880 :     if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
    1882             :     {
    1883           0 :         return error;
    1884             :     }
    1885             : 
    1886             :     /* Write bitstream */
    1887       84880 :     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       84880 :     pBits->bits_written += 8 * lc3plusBitstreamSize;
    1893       84880 :     pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
    1894       84880 :     pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
    1895       84880 :     pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 );
    1896       84880 :     pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 );
    1897             : 
    1898       84880 :     return IVAS_ERR_OK;
    1899             : }
    1900             : 
    1901             : 
    1902             : /*-------------------------------------------------------------------------
    1903             :  * Function isar_renderMultiTDBinToSplitBinaural()
    1904             :  *
    1905             :  *
    1906             :  *------------------------------------------------------------------------*/
    1907             : 
    1908       59275 : 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       59275 :     push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
    1938             : 
    1939       59275 :     error = IVAS_ERR_OK;
    1940       59275 :     num_poses = hSplitBin->multiBinPoseData.num_poses;
    1941             : 
    1942       59275 :     useLc3plus = hSplitBin->hLc3plusEnc != NULL;
    1943             : 
    1944             : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
    1945     1007675 :     for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
    1946             :     {
    1947    16122800 :         for ( j = 0; j < CLDFB_NO_COL_MAX; ++j )
    1948             :         {
    1949    15174400 :             p_Cldfb_In_BinReal[i][j] = Cldfb_In_BinReal[i][j];
    1950    15174400 :             p_Cldfb_In_BinImag[i][j] = Cldfb_In_BinImag[i][j];
    1951             :         }
    1952             :     }
    1953             : #endif
    1954             : 
    1955       59275 :     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       42167 :         int16_t frame_size = (int16_t) ( hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SEC );
    1959             : 
    1960      286733 :         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      244566 :             mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples );
    1964      244566 :             in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i];
    1965      244566 :             mvr2r( in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, frame_size );
    1966             :         }
    1967             :     }
    1968             :     else
    1969             :     {
    1970      157620 :         for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
    1971             :         {
    1972      140512 :             in_delayed[i] = in[i];
    1973             :         }
    1974             :     }
    1975             : 
    1976       59275 :     if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
    1977             :     {
    1978       38646 :         num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
    1979       38646 :         num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels;
    1980             : 
    1981             :         /* CLDFB Analysis*/
    1982      210556 :         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      515730 :             for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2001             :             {
    2002     5764460 :                 for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
    2003             :                 {
    2004     5420640 :                     cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ),
    2005     5420640 :                                       Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
    2006     5420640 :                                       max_bands, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch] );
    2007             :                 }
    2008             :             }
    2009             :         }
    2010             :     }
    2011             : 
    2012       59275 :     if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
    2013             :     {
    2014       33113 :         target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
    2015             : 
    2016       33113 :         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       59275 :     if ( pcm_out_flag == 0 )
    2034             :     {
    2035       58469 :         pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
    2036       58469 :         pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD;
    2037             : 
    2038       58469 :         if ( !useLc3plus )
    2039             :         {
    2040       16302 :             available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
    2041       16302 :             available_bits -= pBits->bits_written;
    2042       16302 :             pBits->codec_frame_size_ms = codec_frame_size_ms;
    2043       16302 :             pBits->isar_frame_size_ms = isar_frame_size_ms;
    2044             : 
    2045       16302 :             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       42167 :             if ( pBits->pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
    2060             :             {
    2061       20629 :                 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       21538 :                 available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
    2066             :             }
    2067             : 
    2068       42167 :             if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK )
    2069             :             {
    2070           0 :                 return error;
    2071             :             }
    2072             :         }
    2073             :     }
    2074             :     else
    2075             :     {
    2076         806 :         pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
    2077         806 :         pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
    2078             :     }
    2079             : 
    2080             :     /*zero pad*/
    2081       59275 :     if ( pcm_out_flag )
    2082             :     {
    2083         806 :         bit_len = SplitRendBitRate / FRAMES_PER_SEC;
    2084             :     }
    2085             :     else
    2086             :     {
    2087       58469 :         if ( !useLc3plus )
    2088             :         {
    2089       16302 :             bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
    2090             :         }
    2091             :         else
    2092             :         {
    2093       42167 :             bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000;
    2094       42167 :             bit_len = SplitRendBitRate * bit_len / 1000;
    2095             :         }
    2096             :     }
    2097             : 
    2098    31313196 :     while ( pBits->bits_written < bit_len )
    2099             :     {
    2100    31253921 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
    2101             :     }
    2102             : 
    2103       59275 :     pop_wmops();
    2104             : 
    2105       59275 :     return error;
    2106             : }
    2107             : 
    2108             : 
    2109             : /*-------------------------------------------------------------------------
    2110             :  * Function lc3plusTimeAlignCldfbPoseCorr()
    2111             :  *
    2112             :  *
    2113             :  *------------------------------------------------------------------------*/
    2114             : 
    2115       33658 : 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      226552 :     for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose )
    2132             :     {
    2133      578682 :         for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch )
    2134             :         {
    2135      385788 :             bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch];
    2136      385788 :             bufWrite = bufRead;
    2137             : 
    2138             :             /* Save last 2 columns for next frame */
    2139     1157364 :             for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
    2140             :             {
    2141      771576 :                 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      771576 :                 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     5786820 :             for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx )
    2147             :             {
    2148     5401032 :                 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     5401032 :                 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     1157364 :             for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
    2154             :             {
    2155      771576 :                 mvr2r( bufRead, Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
    2156      771576 :                 bufRead += CLDFB_NO_CHANNELS_MAX;
    2157      771576 :                 mvr2r( bufRead, Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
    2158      771576 :                 bufRead += CLDFB_NO_CHANNELS_MAX;
    2159             :             }
    2160             : 
    2161             :             /* Copy last 2 columns to buffer */
    2162     1157364 :             for ( slot_idx = 0; slot_idx < 2; ++slot_idx )
    2163             :             {
    2164      771576 :                 mvr2r( Cldfb_In_BinReal_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX );
    2165      771576 :                 bufWrite += CLDFB_NO_CHANNELS_MAX;
    2166      771576 :                 mvr2r( Cldfb_In_BinImag_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX );
    2167      771576 :                 bufWrite += CLDFB_NO_CHANNELS_MAX;
    2168             :             }
    2169             :         }
    2170             :     }
    2171             : 
    2172       33658 :     return;
    2173             : }

Generated by: LCOV version 1.14