LCOV - code coverage report
Current view: top level - lib_isar - lib_isar_pre_rend.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 228 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 4 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             : #include "ivas_prot_fx.h"
      37             : #include "prot_fx.h"
      38             : #include "isar_cnst.h"
      39             : #include "isar_rom_post_rend.h"
      40             : #include "lib_isar_pre_rend.h"
      41             : #include "isar_prot.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Function ISAR_PRE_REND_open()
      50             :  *
      51             :  *
      52             :  *------------------------------------------------------------------------*/
      53             : 
      54           0 : ivas_error ISAR_PRE_REND_open(
      55             :     SPLIT_REND_WRAPPER *hSplitRendWrapper,
      56             :     ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
      57             :     const Word32 OutSampleRate,
      58             :     const Word16 cldfb_in_flag,
      59             :     const Word16 pcm_out_flag,
      60             :     const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size      */
      61             :     const Word16 mixed_td_cldfb_flag )
      62             : {
      63             :     ivas_error error, ch, num_ch;
      64           0 :     UWord8 isCldfbNeeded = 0;
      65           0 :     Word16 cldfb_in_flag_local = cldfb_in_flag;
      66             : 
      67           0 :     IF( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ),
      68             :                                                         &pSplitRendConfig->isar_frame_size_ms,
      69             :                                                         &pSplitRendConfig->codec_frame_size_ms,
      70             :                                                         cldfb_in_flag_local,
      71             :                                                         pcm_out_flag, (Word16) ivas_frame_size ) ) != IVAS_ERR_OK )
      72             :     {
      73           0 :         return error;
      74             :     }
      75             : 
      76           0 :     if ( mixed_td_cldfb_flag )
      77             :     {
      78           0 :         cldfb_in_flag_local = 0;
      79             :     }
      80             : 
      81           0 :     IF( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK )
      82             :     {
      83           0 :         return error;
      84             :     }
      85             : 
      86           0 :     IF( EQ_16( cldfb_in_flag_local, 0 ) )
      87             :     {
      88           0 :         isCldfbNeeded = 1;
      89             :     }
      90           0 :     ELSE IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag_local )
      91             :     {
      92           0 :         isCldfbNeeded = 1;
      93             :     }
      94           0 :     ELSE IF( pcm_out_flag && cldfb_in_flag_local )
      95             :     {
      96           0 :         isCldfbNeeded = 1;
      97             :     }
      98             : 
      99           0 :     hSplitRendWrapper->hCldfbHandles = NULL;
     100             : 
     101           0 :     IF( isCldfbNeeded )
     102             :     {
     103           0 :         IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL )
     104             :         {
     105           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) );
     106             :         }
     107           0 :         num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
     108           0 :         FOR( ch = 0; ch < num_ch; ch++ )
     109             :         {
     110           0 :             hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL;
     111             :         }
     112             : 
     113           0 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     114             :         {
     115           0 :             hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL;
     116             :         }
     117             : 
     118           0 :         num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS;
     119             : 
     120           0 :         FOR( ch = 0; ch < num_ch; ch++ )
     121             :         {
     122           0 :             if ( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ),
     123             :                                               CLDFB_ANALYSIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK )
     124             :             {
     125           0 :                 return error;
     126             :             }
     127             :         }
     128             : 
     129           0 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     130             :         {
     131           0 :             IF( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK )
     132             :             {
     133           0 :                 return error;
     134             :             }
     135             :         }
     136             :     }
     137             : 
     138           0 :     IF( EQ_16( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
     139             :     {
     140           0 :         if ( ( error = isar_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData
     141             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
     142             :                                                  ,
     143             :                                                  OutSampleRate
     144             : #endif
     145             :                                                  ) ) != IVAS_ERR_OK )
     146             :         {
     147           0 :             return error;
     148             :         }
     149             :     }
     150             : 
     151           0 :     IF( EQ_16( pcm_out_flag, 0 ) )
     152             :     {
     153           0 :         IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) )
     154             :         {
     155           0 :             if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, ivas_frame_size ) ) != IVAS_ERR_OK )
     156             :             {
     157           0 :                 return error;
     158             :             }
     159             :         }
     160             :         ELSE
     161             :         {
     162             :             Word16 iNumBlocksPerFrame;
     163           0 :             iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20;
     164             : 
     165           0 :             IF( ( error = isar_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK )
     166             :             {
     167           0 :                 return error;
     168             :             }
     169             :         }
     170             :     }
     171             : 
     172           0 :     return IVAS_ERR_OK;
     173             : }
     174             : 
     175             : 
     176             : /*-------------------------------------------------------------------------
     177             :  * Function ISAR_PRE_REND_close()
     178             :  *
     179             :  *
     180             :  *------------------------------------------------------------------------*/
     181             : 
     182           0 : void ISAR_PRE_REND_close(
     183             :     SPLIT_REND_WRAPPER *hSplitBinRend,         /* i/o: Split renderer pre-renerer handle    */
     184             :     IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer           */
     185             : )
     186             : {
     187             :     Word16 i;
     188             : 
     189           0 :     IF( hSplitBinRend->hBinHrSplitPreRend != NULL )
     190             :     {
     191           0 :         isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend );
     192             :     }
     193             : 
     194           0 :     IF( hSplitBinRend->hSplitBinLCLDEnc != NULL )
     195             :     {
     196           0 :         isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc );
     197             :     }
     198             : 
     199           0 :     IF( hSplitBinRend->hCldfbHandles != NULL )
     200             :     {
     201             :         Word16 num_ch, ch;
     202           0 :         num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
     203           0 :         FOR( ch = 0; ch < num_ch; ch++ )
     204             :         {
     205           0 :             IF( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL )
     206             :             {
     207           0 :                 deleteCldfb_ivas_fx( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] );
     208           0 :                 hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL;
     209             :             }
     210             :         }
     211             : 
     212           0 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     213             :         {
     214           0 :             IF( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL )
     215             :             {
     216           0 :                 deleteCldfb_ivas_fx( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] );
     217           0 :                 hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL;
     218             :             }
     219             :         }
     220             : 
     221           0 :         free( hSplitBinRend->hCldfbHandles );
     222           0 :         hSplitBinRend->hCldfbHandles = NULL;
     223             :     }
     224             : 
     225           0 :     IF( hSplitBinRend->hLc3plusEnc != NULL )
     226             :     {
     227           0 :         ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc );
     228             :     }
     229             : 
     230           0 :     FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
     231             :     {
     232           0 :         if ( hSplitBinRend->lc3plusDelayBuffers_fx[i] != NULL )
     233             :         {
     234           0 :             free( hSplitBinRend->lc3plusDelayBuffers_fx[i] );
     235           0 :             hSplitBinRend->lc3plusDelayBuffers_fx[i] = NULL;
     236             :         }
     237             :     }
     238             : 
     239           0 :     IF( pSplitRendEncBuffer != NULL )
     240             :     {
     241             : 
     242           0 :         IF( pSplitRendEncBuffer->data_fx != NULL )
     243             :         {
     244           0 :             free( pSplitRendEncBuffer->data_fx );
     245           0 :             pSplitRendEncBuffer->data_fx = NULL;
     246             :         }
     247             : 
     248           0 :         pSplitRendEncBuffer->config.numChannels = 0;
     249           0 :         pSplitRendEncBuffer->config.numSamplesPerChannel = 0;
     250             :     }
     251             : 
     252           0 :     return;
     253             : }
     254             : 
     255             : 
     256             : /*-------------------------------------------------------------------------*
     257             :  * ISAR_PRE_REND_GetMultiBinPoseData()
     258             :  *
     259             :  *
     260             :  *-------------------------------------------------------------------------*/
     261             : 
     262           0 : void ISAR_PRE_REND_GetMultiBinPoseData(
     263             :     const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i  : Split renderer pre-renerer config    */
     264             :     MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,           /* i/o: pose correction data handle          */
     265             :     const ISAR_SPLIT_REND_ROT_AXIS rot_axis                /* i  : Rotation axis                        */
     266             : )
     267             : {
     268           0 :     isar_renderSplitGetMultiBinPoseData_fx( pSplit_rend_config, pMultiBinPoseData, rot_axis );
     269             : 
     270           0 :     return;
     271             : }
     272             : 
     273             : 
     274             : /*-------------------------------------------------------------------------
     275             :  * Function ISAR_PRE_REND_MultiBinToSplitBinaural()
     276             :  *
     277             :  *
     278             :  *------------------------------------------------------------------------*/
     279             : 
     280           0 : ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
     281             :     SPLIT_REND_WRAPPER *hSplitBin,
     282             :     const IVAS_QUATERNION headPosition,
     283             :     const Word32 SplitRendBitRate,
     284             :     ISAR_SPLIT_REND_CODEC splitCodec,
     285             :     const Word16 isar_frame_size_ms, /* i: ISAR framesize   */
     286             :     Word16 codec_frame_size_ms,
     287             :     ISAR_SPLIT_REND_BITS_HANDLE pBits,
     288             :     Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
     289             :     Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
     290             :     const Word16 max_bands,
     291             :     Word32 *pOutput_fx[],
     292             :     const Word16 low_res_pre_rend_rot,
     293             :     const Word16 cldfb_in_flag,
     294             :     const Word16 pcm_out_flag,
     295             :     const Word16 ro_md_flag,
     296             :     Word16 Q_buff,
     297             :     Word16 *Q_out )
     298             : {
     299             :     ivas_error error;
     300             :     Word32 bit_len, target_md_bits, available_bits, tmp_32;
     301           0 :     Word16 q1 = 31, q2 = 31, q_final, Q_cldfb, tmp, tmp_e;
     302             :     Word16 i, j;
     303           0 :     error = IVAS_ERR_OK;
     304             :     Word16 Q_buff_re, Q_buff_im;
     305             : 
     306           0 :     push_wmops( "ISAR_PRE_REND_MultiBinToSplitBinaural" );
     307             : 
     308           0 :     Q_buff_re = Q_buff;
     309           0 :     move16();
     310           0 :     Q_buff_im = Q_buff;
     311           0 :     move16();
     312           0 :     IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
     313             :     {
     314           0 :         set_fix_rotation_mat_fx( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat_fx, &hSplitBin->multiBinPoseData );
     315           0 :         set_pose_types_fx( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData );
     316             :     }
     317             : 
     318           0 :     IF( EQ_16( cldfb_in_flag, 0 ) )
     319             :     {
     320           0 :         error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, isar_frame_size_ms, codec_frame_size_ms, pBits, max_bands, pOutput_fx, Q_out[0], low_res_pre_rend_rot, pcm_out_flag, ro_md_flag );
     321             : 
     322           0 :         Q_out[1] = Q_out[0];
     323           0 :         move16();
     324           0 :         pop_wmops();
     325           0 :         return error;
     326             :     }
     327             : 
     328           0 :     IF( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
     329             :     {
     330             :         /* Time-align pose correction to delay of LC3plus */
     331           0 :         lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, &Q_buff );
     332           0 :         Q_buff_re = Q_buff;
     333           0 :         move16();
     334           0 :         Q_buff_im = Q_buff;
     335           0 :         move16();
     336             :     }
     337             : 
     338           0 :     IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
     339             :     {
     340           0 :         target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
     341             : 
     342             :         /*float2fix, to be removed*/
     343           0 :         Word16 Q_Cldfb_re = 31, Q_Cldfb_im = 31;
     344           0 :         move16();
     345           0 :         move16();
     346           0 :         FOR( i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ )
     347             :         {
     348           0 :             FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     349             :             {
     350           0 :                 Q_Cldfb_re = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_re );
     351           0 :                 Q_Cldfb_im = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_im );
     352             :             }
     353             :         }
     354           0 :         FOR( i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ )
     355             :         {
     356           0 :             FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     357             :             {
     358           0 :                 Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_re );
     359           0 :                 Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_im );
     360             :             }
     361             :         }
     362           0 :         Q_buff_re = add( Q_Cldfb_re, Q_buff );
     363           0 :         Q_buff_im = add( Q_Cldfb_im, Q_buff );
     364           0 :         Word16 exp_cldfb_re = sub( 31, Q_buff_re );
     365           0 :         Word16 exp_cldfb_im = sub( 31, Q_buff_im );
     366           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 );
     367             :     }
     368             : 
     369           0 :     IF( EQ_16( pcm_out_flag, 0 ) )
     370             :     {
     371           0 :         pBits->codec = splitCodec;
     372           0 :         pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
     373             : 
     374           0 :         IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
     375             :         {
     376             :             // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
     377           0 :             available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
     378           0 :             tmp_e = 0;
     379           0 :             tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
     380           0 :             available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
     381           0 :             available_bits = L_sub( available_bits, pBits->bits_written );
     382           0 :             pBits->codec_frame_size_ms = codec_frame_size_ms;
     383           0 :             q_final = sub( s_min( Q_buff_re, Q_buff_im ), 2 );
     384           0 :             FOR( i = 0; i < hSplitBin->hSplitBinLCLDEnc->iChannels; i++ )
     385             :             {
     386           0 :                 FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     387             :                 {
     388           0 :                     Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
     389           0 :                     Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
     390             :                 }
     391             :             }
     392           0 :             isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final );
     393           0 :             Q_buff_re = q_final;
     394           0 :             move16();
     395           0 :             Q_buff_im = q_final;
     396           0 :             move16();
     397             :         }
     398             :         ELSE
     399             :         {
     400             :             Word16 ch, slot_idx, num_slots, ivas_fs;
     401           0 :             tmp_e = 0;
     402           0 :             tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
     403           0 :             ivas_fs = shr( tmp, sub( 15, tmp_e ) ); // Q0
     404             :             // ivas_fs = (Word16) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
     405             : 
     406           0 :             tmp_e = 0;
     407           0 :             tmp = BASOP_Util_Divide3232_Scale( L_mult0( CLDFB_NO_COL_MAX, ivas_fs ), 20, &tmp_e );
     408           0 :             num_slots = shr( tmp, sub( 15, tmp_e ) ); // Q0
     409             :                                                       // num_slots = (Word16) CLDFB_NO_COL_MAX * ivas_fs  / 20;
     410             :             /* CLDFB synthesis of main pose */
     411             :             {
     412           0 :                 q1 = 31;
     413           0 :                 q2 = 31;
     414           0 :                 move16();
     415           0 :                 move16();
     416           0 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     417             :                 {
     418           0 :                     FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     419             :                     {
     420           0 :                         q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 );
     421           0 :                         q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 );
     422             :                     }
     423             :                 }
     424             : 
     425           0 :                 q_final = s_min( q1, q2 );
     426           0 :                 q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) );
     427           0 :                 q_final = sub( q_final, 6 ); // guard bits
     428           0 :                 q_final = s_min( q_final, Q25 );
     429             : 
     430           0 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     431             :                 {
     432           0 :                     FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     433             :                     {
     434           0 :                         Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
     435           0 :                         Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
     436             :                     }
     437             :                 }
     438             :             }
     439             : 
     440           0 :             FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     441             :             {
     442             :                 Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX];
     443             :                 Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX];
     444             : 
     445             : 
     446           0 :                 FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
     447             :                 {
     448           0 :                     Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx];
     449           0 :                     move32();
     450           0 :                     Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx];
     451           0 :                     move32();
     452             :                 }
     453             : 
     454           0 :                 Q_cldfb = q_final;
     455           0 :                 move16();
     456           0 :                 Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state ) );
     457           0 :                 cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, 0, 0, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1
     458           0 :                 Q_out[ch] = sub( Q_cldfb, 1 );
     459           0 :                 move16();
     460           0 :                 hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state = Q_out[ch];
     461           0 :                 move16();
     462             :             }
     463           0 :             assert( Q_out[0] == Q_out[1] );
     464             : 
     465             : 
     466             : #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6
     467           0 :             IF( EQ_32( pBits->pose_correction, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) )
     468             :             {
     469           0 :                 available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us );
     470           0 :                 available_bits = Mpy_32_32( available_bits, ONE_BY_FRAMES_PER_SEC_Q31 );
     471             :             }
     472             :             ELSE
     473             :             {
     474           0 :                 available_bits = L_sub( Mpy_32_32( SplitRendBitRate, ONE_BY_FRAMES_PER_SEC_Q31 ), pBits->bits_written );
     475             :             }
     476             : #else
     477             :             available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
     478             : #endif
     479           0 :             IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, pOutput_fx, Q_out[0] ) ) != IVAS_ERR_OK )
     480             :             {
     481           0 :                 return error;
     482             :             }
     483             :         }
     484             :     }
     485             :     ELSE
     486             :     {
     487             :         Word16 ch, slot_idx;
     488             :         /* CLDFB synthesis of main pose */
     489           0 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     490             :         {
     491             :             Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX];
     492             :             Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX];
     493           0 :             q1 = 31;
     494           0 :             move16();
     495           0 :             q2 = 31;
     496           0 :             move16();
     497           0 :             FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     498             :             {
     499           0 :                 q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 );
     500           0 :                 q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 );
     501             :             }
     502           0 :             q_final = s_min( q1, q2 );
     503           0 :             q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) );
     504           0 :             q_final = sub( q_final, 6 ); // guard bits
     505           0 :             q_final = s_min( q_final, Q25 );
     506           0 :             FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
     507             :             {
     508           0 :                 Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
     509           0 :                 Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
     510             :             }
     511             : 
     512           0 :             FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
     513             :             {
     514           0 :                 Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx];
     515           0 :                 move32();
     516           0 :                 Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx];
     517           0 :                 move32();
     518             :             }
     519             : 
     520           0 :             Q_cldfb = q_final;
     521           0 :             move16();
     522           0 :             Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state ) );
     523           0 :             cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, 0, 0, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1
     524           0 :             Q_out[ch] = sub( Q_cldfb, 1 );
     525           0 :             move16();
     526           0 :             hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state = Q_out[ch];
     527           0 :             move16();
     528             :         }
     529             : 
     530           0 :         pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
     531           0 :         pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
     532             :     }
     533             : 
     534             :     /*zero pad*/
     535           0 :     IF( pcm_out_flag )
     536             :     {
     537           0 :         tmp_e = 0;
     538           0 :         tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e );
     539           0 :         bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
     540             :         // bit_len = SplitRendBitRate / FRAMES_PER_SEC;
     541             :     }
     542             :     ELSE
     543             :     {
     544           0 :         IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
     545             :         {
     546             :             // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
     547             : 
     548           0 :             bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
     549           0 :             tmp_e = 0;
     550           0 :             tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
     551           0 :             bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
     552             :         }
     553             :         ELSE
     554             :         {
     555           0 :             tmp_e = 0;
     556           0 :             tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
     557           0 :             bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
     558             :                                                                    // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
     559             :                                                                    // bit_len = SplitRendBitRate * bit_len / 1000;
     560           0 :             tmp_e = 0;
     561           0 :             tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e );
     562           0 :             bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
     563             :         }
     564             :     }
     565             : 
     566           0 :     WHILE( LT_32( pBits->bits_written, bit_len ) )
     567             :     {
     568           0 :         ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
     569             :     }
     570             : 
     571           0 :     pop_wmops();
     572           0 :     return error;
     573             : }

Generated by: LCOV version 1.14