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

Generated by: LCOV version 1.14