LCOV - code coverage report
Current view: top level - lib_enc - ivas_ism_dtx_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 216 217 99.5 %
Date: 2025-05-03 01:55:50 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <math.h>
      35             : #include "options.h"
      36             : #include "ivas_cnst.h"
      37             : #include "prot_fx.h"
      38             : #include "wmc_auto.h"
      39             : #include "ivas_prot_fx.h"
      40             : #include "prot_fx_enc.h"
      41             : 
      42             : 
      43             : /*-----------------------------------------------------------------------*
      44             :  * Local constants
      45             :  *-----------------------------------------------------------------------*/
      46             : #define MD_MAX_DIFF_AZIMUTH_FX   41943040
      47             : #define MD_MAX_DIFF_ELEVATION_FX 41943040
      48             : 
      49             : #define MD_MAX_DIFF_AZIMUTH   10
      50             : #define MD_MAX_DIFF_ELEVATION 10
      51             : 
      52             : 
      53             : /*-------------------------------------------------------------------*
      54             :  * ivas_ism_dtx_open()
      55             :  *
      56             :  * Open ISM DTX handle
      57             :  *-------------------------------------------------------------------*/
      58             : 
      59          14 : ivas_error ivas_ism_dtx_open(
      60             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure          */
      61             : )
      62             : {
      63             :     ivas_error error;
      64             :     ISM_DTX_HANDLE hISMDTX;
      65             :     Word16 i;
      66             : 
      67          14 :     error = IVAS_ERR_OK;
      68          14 :     move32();
      69             : 
      70             :     /* Assign memory to DirAC handle  */
      71          14 :     IF( ( hISMDTX = (ISM_DTX_HANDLE) malloc( sizeof( ISM_DTX_DATA ) ) ) == NULL )
      72             :     {
      73           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM DTX Handle \n" ) );
      74             :     }
      75             : 
      76          14 :     hISMDTX->dtx_flag = 0;
      77          14 :     move16();
      78          14 :     hISMDTX->sce_id_dtx = 0;
      79          14 :     move16();
      80          14 :     hISMDTX->cnt_SID_ISM = -1;
      81          14 :     move16();
      82             : 
      83          70 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
      84             :     {
      85          56 :         set32_fx( hISMDTX->long_term_energy_stereo_dmx_enc_fx[i], 0, PARAM_ISM_HYS_BUF_SIZE );
      86             :     }
      87          14 :     hISMDTX->long_term_energy_stereo_dmx_enc_e = 0;
      88          14 :     move16();
      89             : 
      90          14 :     set16_fx( hISMDTX->coh_fx, 0, MAX_NUM_OBJECTS );
      91             : 
      92          14 :     st_ivas->hISMDTX = hISMDTX;
      93             : 
      94          14 :     return error;
      95             : }
      96             : 
      97             : 
      98             : /*-------------------------------------------------------------------*
      99             :  * ivas_ism_get_dtx_enc()
     100             :  *
     101             :  * Analysis and decision about DTX in ISM format
     102             :  *-------------------------------------------------------------------*/
     103             : 
     104             : /*! r: indication of DTX frame */
     105       14826 : Word16 ivas_ism_dtx_enc_fx(
     106             :     ISM_DTX_HANDLE hISMDTX,           /* i/o: ISM DTX handle               */
     107             :     SCE_ENC_HANDLE hSCE[MAX_SCE],     /* i/o: SCE encoder structure        */
     108             :     const Word32 ivas_total_brate,    /* i  : IVAS total bitrate           Q0*/
     109             :     const Word16 nchan_ism,           /* i  : number of objects            Q0*/
     110             :     const Word16 nchan_transport,     /* i  : number of transport channels Q0*/
     111             :     Word16 vad_flag[MAX_NUM_OBJECTS], /* i  : VAD flag                     Q0*/
     112             :     ISM_METADATA_HANDLE hIsmMeta[],   /* i/o: ISM metadata handles         */
     113             :     Word16 md_diff_flag[],            /* o  : metadata differential flag   Q0*/
     114             :     Word16 *sid_flag                  /* o  : indication of SID frame      Q0*/
     115             : )
     116             : {
     117             :     Word16 ch, dtx_flag;
     118             :     Word16 nBits, nBits_MD_max;
     119             :     Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
     120             :     Word16 lp_noise_fx[MAX_NUM_OBJECTS], lp_noise_variation_fx, lp_noise_mean_fx;
     121             :     Word16 lp_noise_max_fx;
     122             :     Word32 tmp1_fx, tmp2_fx;
     123             :     /* initialization */
     124       52942 :     FOR( ch = 0; ch < nchan_transport; ch++ )
     125             :     {
     126       38116 :         hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
     127       38116 :         move16();
     128             :     }
     129             : 
     130             :     /*------------------------------------------------------------------*
     131             :      * compute global ISM DTX flag
     132             :      *-----------------------------------------------------------------*/
     133             : 
     134             :     /* compute global ISM based on localVAD */
     135       14826 :     dtx_flag = 1;
     136       14826 :     move16();
     137       52942 :     FOR( ch = 0; ch < nchan_transport; ch++ )
     138             :     {
     139       38116 :         dtx_flag = s_and( dtx_flag, !vad_flag[ch] ); /* Q0 */
     140             :     }
     141             : 
     142             :     /* compute global ISM based on long-term background noise */
     143             :     /* one of the channels is active -> no DTX */
     144       52942 :     FOR( ch = 0; ch < nchan_transport; ch++ )
     145             :     {
     146       38116 :         lp_noise_fx[ch] = hSCE[ch]->hCoreCoder[0]->lp_noise_fx; /*Q8*/
     147       38116 :         move16();
     148             :     }
     149             : 
     150       14826 :     lp_noise_variation_fx = var_fx( lp_noise_fx, Q8, nchan_transport ); /*Q8*/
     151       14826 :     lp_noise_mean_fx = mean_fx( lp_noise_fx, nchan_transport );         /*Q8*/
     152             : 
     153       14826 :     test();
     154       14826 :     test();
     155       14826 :     if ( GT_16( lp_noise_mean_fx, ( 50 << 8 ) ) || ( GT_16( lp_noise_mean_fx, ( 25 << 8 ) ) && GT_16( lp_noise_variation_fx, ( 32 << 8 ) ) ) )
     156             :     {
     157         134 :         dtx_flag = 0;
     158         134 :         move16();
     159             :     }
     160             : 
     161             : 
     162             :     /* default DTX is applied at lower bitrates; otherwise DTX is applied only in silence */
     163       14826 :     maximum_fx( lp_noise_fx, nchan_transport, &lp_noise_max_fx ); /*Q8*/
     164             : 
     165       14826 :     test();
     166       14826 :     test();
     167       14826 :     test();
     168       14826 :     test();
     169       14826 :     test();
     170       14826 :     test();
     171       14826 :     test();
     172       14826 :     test();
     173       33218 :     if ( !( ( EQ_16( nchan_ism, 1 ) && LE_32( ivas_total_brate, IVAS_24k4 ) ) ||
     174       28052 :             ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) ||
     175       22552 :             ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) ||
     176       16776 :             ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) ||
     177        4916 :             LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) )
     178             :     {
     179        3960 :         dtx_flag = 0;
     180        3960 :         move16();
     181             :     }
     182             : 
     183             :     /*------------------------------------------------------------------*
     184             :      * Reset the bitstream
     185             :      *-----------------------------------------------------------------*/
     186             : 
     187       14826 :     IF( dtx_flag )
     188             :     {
     189             :         /* reset the bitstream (IVAS format signaling was already written) */
     190        2437 :         reset_indices_enc_fx( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot );
     191             :     }
     192             : 
     193             :     /*------------------------------------------------------------------*
     194             :      * decide about SID metadata to be sent or not (per object)
     195             :      * estimate the MD bit-budget consumption
     196             :      *-----------------------------------------------------------------*/
     197             : 
     198       14826 :     IF( dtx_flag )
     199             :     {
     200        2437 :         ivas_get_ism_sid_quan_bitbudget_fx( nchan_ism, &nBits_azimuth, &nBits_elevation, &tmp1_fx, &tmp2_fx, &nBits_coh, &nBits_sce_id );
     201             : 
     202        2437 :         nBits = 0;
     203        2437 :         move16();
     204        9543 :         FOR( ch = 0; ch < nchan_ism; ch++ )
     205             :         {
     206             :             /* check difference between current and last metadata */
     207        7106 :             md_diff_flag[ch] = 0;
     208        7106 :             move16();
     209        7106 :             if ( GT_32( L_abs( L_sub( hIsmMeta[ch]->azimuth_fx, hIsmMeta[ch]->last_azimuth_fx ) ), MD_MAX_DIFF_AZIMUTH_FX ) )
     210             :             {
     211        3484 :                 md_diff_flag[ch] = 1;
     212        3484 :                 move16();
     213             :             }
     214             : 
     215        7106 :             if ( GT_32( L_abs( L_sub( hIsmMeta[ch]->elevation_fx, hIsmMeta[ch]->last_elevation_fx ) ), MD_MAX_DIFF_ELEVATION_FX ) )
     216             :             {
     217        1608 :                 md_diff_flag[ch] = 1;
     218        1608 :                 move16();
     219             :             }
     220             : 
     221             :             /* estimate SID metadata bit-budget */
     222        7106 :             nBits = add( nBits, 1 ); /* number of objects       Q0*/
     223        7106 :             nBits = add( nBits, 1 ); /* SID metadata flag       Q0*/
     224        7106 :             IF( EQ_16( md_diff_flag[ch], 1 ) )
     225             :             {
     226        3860 :                 nBits = add( nBits, nBits_azimuth );   /* Q0 */
     227        3860 :                 nBits = add( nBits, nBits_elevation ); /* Q0 */
     228             :             }
     229             :         }
     230             : 
     231             :         /* calculate maximum available MD bit-budget */
     232        2437 :         nBits_MD_max = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
     233        2437 :         move16();
     234        2437 :         nBits_MD_max = sub( nBits_MD_max, SID_FORMAT_NBITS ); /* Q0 */
     235             : 
     236        2437 :         if ( GT_16( nchan_transport, 1 ) )
     237             :         {
     238        2069 :             nBits_MD_max = sub( nBits_MD_max, nBits_sce_id ); /* Q0 */
     239             :         }
     240             : 
     241        6362 :         FOR( ch = 0; ch < nchan_transport - 1; ch++ )
     242             :         {
     243        3925 :             nBits_MD_max = sub( nBits_MD_max, nBits_coh ); /* coherence         Q0*/
     244             :         }
     245             : 
     246        2437 :         if ( GT_16( nchan_ism, 3 ) )
     247             :         {
     248        1300 :             nBits_MD_max = sub( nBits_MD_max, 1 ); /* ism_mode flag             Q0*/
     249             :         }
     250             : 
     251             :         /* too many metadata bits -> switch to active coding */
     252        2437 :         if ( GT_16( nBits, nBits_MD_max ) )
     253             :         {
     254         322 :             dtx_flag = 0;
     255         322 :             move16();
     256             :         }
     257             :     }
     258             : 
     259             :     /*------------------------------------------------------------------*
     260             :      * set core_brate for all channels
     261             :      * get 'sid_flag' value
     262             :      *-----------------------------------------------------------------*/
     263             : 
     264       14826 :     *sid_flag = 0;
     265       14826 :     move16();
     266             : 
     267       14826 :     IF( !dtx_flag )
     268             :     {
     269             :         /* at least one of the channels is active -> no DTX */
     270       45621 :         FOR( ch = 0; ch < nchan_transport; ch++ )
     271             :         {
     272       32910 :             hSCE[ch]->hCoreCoder[0]->core_brate = -1;
     273       32910 :             move32();
     274       32910 :             set_bw_fx( IVAS_SCE, hSCE[ch]->element_brate, hSCE[ch]->hCoreCoder[0], MODE1 );
     275             :         }
     276             : 
     277       12711 :         hISMDTX->cnt_SID_ISM = -1;
     278       12711 :         move16();
     279             : 
     280             :         /* IVAS format signaling was erased in dtx() */
     281       12711 :         IF( EQ_16( hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot, 0 ) )
     282             :         {
     283             :             /* replicate ivas_write_format() */
     284        1844 :             Word16 ind = 2;
     285        1844 :             nBits = IVAS_FORMAT_SIGNALING_NBITS;
     286        1844 :             move16();
     287        1844 :             move16();
     288        1844 :             IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
     289             :             {
     290        1844 :                 ind = 4;
     291        1844 :                 nBits = IVAS_FORMAT_SIGNALING_NBITS_EXTENDED;
     292        1844 :                 move16();
     293        1844 :                 move16();
     294             :             }
     295             : 
     296        1844 :             push_indice( hSCE[0]->hCoreCoder[0]->hBstr, IND_IVAS_FORMAT, ind, nBits );
     297             :         }
     298             :     }
     299             :     ELSE /* ism_dtx_flag == 1 */
     300             :     {
     301        7321 :         FOR( ch = 0; ch < nchan_transport; ch++ )
     302             :         {
     303        5206 :             hSCE[ch]->hCoreCoder[0]->cng_type = FD_CNG;
     304        5206 :             move16();
     305             :         }
     306             : 
     307             :         /* * update the global SID counter */
     308        2115 :         hISMDTX->cnt_SID_ISM = add( hISMDTX->cnt_SID_ISM, 1 ); /* Q0 */
     309        2115 :         move16();
     310        2115 :         IF( GE_16( hISMDTX->cnt_SID_ISM, hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID ) )
     311             :         {
     312             :             /* adaptive SID update interval */
     313         145 :             hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID = hSCE[0]->hCoreCoder[0]->hDtxEnc->interval_SID; /* Q0 */
     314         145 :             hISMDTX->cnt_SID_ISM = 0;
     315         145 :             move16();
     316         145 :             move16();
     317             :         }
     318             : 
     319             :         /* encode SID in one channel only */
     320        7321 :         FOR( ch = 0; ch < nchan_transport; ch++ )
     321             :         {
     322        5206 :             hSCE[ch]->hCoreCoder[0]->core_brate = FRAME_NO_DATA;
     323        5206 :             move32();
     324             :         }
     325             : 
     326        2115 :         IF( hISMDTX->cnt_SID_ISM == 0 )
     327             :         {
     328         535 :             hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate = SID_2k40;
     329         535 :             *sid_flag = 1;
     330         535 :             move32();
     331         535 :             move16();
     332             :         }
     333             :     }
     334             : 
     335       14826 :     test();
     336       14826 :     IF( EQ_16( dtx_flag, 1 ) && *sid_flag == 0 )
     337             :     {
     338        1580 :         set16_fx( md_diff_flag, 0, nchan_transport );
     339             :     }
     340             : 
     341       14826 :     return dtx_flag;
     342             : }
     343             : 
     344             : /*-------------------------------------------------------------------*
     345             :  * ivas_ism_get_sce_id_dtx()
     346             :  *
     347             :  *
     348             :  *-------------------------------------------------------------------*/
     349       14826 : void ivas_ism_get_sce_id_dtx_fx(
     350             :     ISM_DTX_HANDLE hISMDTX,       /* i/o: ISM DTX handle                   */
     351             :     SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure            */
     352             :     const Word16 nchan_transport, /* i  : number of transport channels     Q0*/
     353             :     const Word16 input_frame      /* i  : input frame length per channel   Q0*/
     354             : )
     355             : {
     356             :     Word32 tmp_energy[MAX_NUM_OBJECTS];
     357             :     Word16 tmp_energy_e[MAX_NUM_OBJECTS];
     358             :     Word16 i, j;
     359             :     Word16 long_term_energy_stereo_dmx_enc_e[MAX_NUM_OBJECTS];
     360             :     Word16 max_exp;
     361             : 
     362       14826 :     set16_fx( long_term_energy_stereo_dmx_enc_e, hISMDTX->long_term_energy_stereo_dmx_enc_e, nchan_transport );
     363       14826 :     IF( EQ_16( nchan_transport, 1 ) )
     364             :     {
     365        3026 :         hISMDTX->sce_id_dtx = 0;
     366        3026 :         move16();
     367             : 
     368        3026 :         return;
     369             :     }
     370             : 
     371             :     /* Initialize*/
     372       11800 :     set32_fx( tmp_energy, 0, MAX_NUM_OBJECTS );
     373       11800 :     set16_fx( tmp_energy_e, 0, MAX_NUM_OBJECTS );
     374             : 
     375             :     /* compute long term energy parameter */
     376       46890 :     FOR( j = 0; j < nchan_transport; j++ )
     377             :     {
     378      350900 :         FOR( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ )
     379             :         {
     380      315810 :             hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i + 1]; /* exp(hISMDTX->long_term_energy_stereo_dmx_enc_e) */
     381      315810 :             move32();
     382             :         }
     383       35090 :         long_term_energy_stereo_dmx_enc_e[j] = 20;
     384       35090 :         move16();
     385       35090 :         hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = sum2_32_fx( hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, &long_term_energy_stereo_dmx_enc_e[j] ); /*Resultant Q_lte=2*Q(input_fx)+1=2*-5+1=>-9*/
     386       35090 :         move32();
     387       35090 :         tmp_energy[j] = L_deposit_l( 0 );
     388       35090 :         move32();
     389      350900 :         FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE - 1; i++ )
     390             :         {
     391      315810 :             tmp_energy[j] = BASOP_Util_Add_Mant32Exp( tmp_energy[j], tmp_energy_e[j], hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], hISMDTX->long_term_energy_stereo_dmx_enc_e, &tmp_energy_e[j] ); /*Resultant Q(tmp_energy)=Q_lte*/
     392      315810 :             move32();
     393             :         }
     394       35090 :         tmp_energy[j] = BASOP_Util_Add_Mant32Exp( tmp_energy[j], tmp_energy_e[j], hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], long_term_energy_stereo_dmx_enc_e[j], &tmp_energy_e[j] ); /*Resultant Q(tmp_energy)=Q_lte*/
     395       35090 :         move32();
     396             :     }
     397             : 
     398       11800 :     maximum_fx( long_term_energy_stereo_dmx_enc_e, nchan_transport, &max_exp );
     399       11800 :     max_exp = s_max( max_exp, hISMDTX->long_term_energy_stereo_dmx_enc_e );
     400       46890 :     FOR( j = 0; j < nchan_transport; j++ )
     401             :     {
     402      350900 :         FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE - 1; i++ )
     403             :         {
     404      315810 :             hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], max_exp - hISMDTX->long_term_energy_stereo_dmx_enc_e ); /* exp(max_exp) */
     405      315810 :             move32();
     406             :         }
     407       35090 :         hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], max_exp - long_term_energy_stereo_dmx_enc_e[j] ); /* exp(max_exp) */
     408       35090 :         move32();
     409             :     }
     410       11800 :     hISMDTX->long_term_energy_stereo_dmx_enc_e = max_exp;
     411       11800 :     move16();
     412             :     /* determine the sce_id */
     413       11800 :     hISMDTX->sce_id_dtx = 0;
     414       11800 :     move16();
     415       35090 :     FOR( j = 1; j < nchan_transport; j++ )
     416             :     {
     417       23290 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_energy[j], tmp_energy_e[j], tmp_energy[hISMDTX->sce_id_dtx], tmp_energy_e[hISMDTX->sce_id_dtx] ), 1 ) )
     418             :         {
     419       12161 :             hISMDTX->sce_id_dtx = j;
     420       12161 :             move16();
     421             :         }
     422             :     }
     423             : 
     424       11800 :     return;
     425             : }
     426             : 
     427             : /*-------------------------------------------------------------------*
     428             :  * ivas_ism_coh_estim_dtx_enc()
     429             :  *
     430             :  *
     431             :  *-------------------------------------------------------------------*/
     432         535 : void ivas_ism_coh_estim_dtx_enc_fx(
     433             :     ISM_DTX_HANDLE hISMDTX,       /* i/o: ISM DTX handle                                */
     434             :     SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure                 */
     435             :     const Word16 nchan_transport, /* i  : number of transport channels  Q0*/
     436             :     const Word16 input_frame      /* i  : input frame length                    Q0*/
     437             : )
     438             : {
     439             :     Encoder_State *st, *st_id0;
     440             :     Word16 sce_id, i;
     441             :     Word32 acorr_ene_fx[MAX_NUM_OBJECTS], xcorr_ene_fx;
     442             :     Word16 acorr_ene_e[MAX_NUM_OBJECTS], xcorr_ene_e;
     443             :     Word16 norm_inp, norm_inp0;
     444             :     Word16 tot_exp, tot_exp2;
     445             :     Word32 scaled_inp, scaled_inp0;
     446         535 :     set16_fx( acorr_ene_e, 0, MAX_NUM_OBJECTS );
     447             : 
     448         535 :     IF( EQ_16( nchan_transport, 1 ) )
     449             :     {
     450          55 :         hISMDTX->coh_fx[0] = 0;
     451          55 :         move16();
     452          55 :         return;
     453             :     }
     454             : 
     455             :     /* Compute Coherence */
     456         480 :     acorr_ene_fx[hISMDTX->sce_id_dtx] = 0;
     457         480 :     move32();
     458         480 :     st_id0 = hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0];
     459             : 
     460      461280 :     FOR( i = 0; i < input_frame; i++ )
     461             :     {
     462      460800 :         norm_inp = norm_l( st_id0->input32_fx[i] );
     463      460800 :         scaled_inp = L_shl( st_id0->input32_fx[i], norm_inp );
     464      460800 :         tot_exp = shl( sub( 20, norm_inp ), 1 );
     465      460800 :         acorr_ene_fx[hISMDTX->sce_id_dtx] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_e[hISMDTX->sce_id_dtx], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[hISMDTX->sce_id_dtx] ); /* exp(acorr_ene_e) */
     466      460800 :         move32();
     467             :     }
     468             : 
     469        2004 :     FOR( sce_id = 0; sce_id < nchan_transport; sce_id++ )
     470             :     {
     471        1524 :         IF( EQ_16( sce_id, hISMDTX->sce_id_dtx ) )
     472             :         {
     473         480 :             hISMDTX->coh_fx[sce_id] = 32767; /* 1 in Q15 */
     474         480 :             move16();
     475         480 :             CONTINUE;
     476             :         }
     477             : 
     478        1044 :         st = hSCE[sce_id]->hCoreCoder[0];
     479             : 
     480        1044 :         acorr_ene_fx[sce_id] = 0;
     481        1044 :         xcorr_ene_fx = 0;
     482        1044 :         xcorr_ene_e = 0;
     483        1044 :         move32();
     484        1044 :         move32();
     485        1044 :         move16();
     486             : 
     487     1003284 :         FOR( i = 0; i < input_frame; i++ )
     488             :         {
     489     1002240 :             norm_inp = norm_l( st->input32_fx[i] );
     490     1002240 :             scaled_inp = L_shl( st->input32_fx[i], norm_inp );
     491     1002240 :             tot_exp = shl( sub( sub( 31, st->q_inp32 ), norm_inp ), 1 );
     492     1002240 :             acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); /* exp(acorr_ene_e) */
     493     1002240 :             move32();
     494     1002240 :             norm_inp0 = norm_l( st_id0->input32_fx[i] );
     495     1002240 :             scaled_inp0 = L_shl( st_id0->input32_fx[i], norm_inp0 );
     496     1002240 :             tot_exp2 = add( sub( sub( 31, st_id0->q_inp32 ), norm_inp0 ), sub( sub( 31, st->q_inp32 ), norm_inp ) );
     497     1002240 :             xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp0 ), tot_exp2, &xcorr_ene_e ); /* exp(xcorr_ene_e) */
     498             :         }
     499             :         Word16 coh_e;
     500        1044 :         Word16 temp_e = acorr_ene_e[hISMDTX->sce_id_dtx] + acorr_ene_e[sce_id];
     501        1044 :         Word32 temp = Sqrt32( L_add( Mult_32_32( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_fx[sce_id] ), EPSILON_FX ), &temp_e ); /*fabsf( xcorr_ene ) / ( sqrtf( ( acorr_ene[hISMDTX->sce_id_dtx] * acorr_ene[sce_id] ) + EPSILON ) );*/
     502        1044 :         hISMDTX->coh_fx[sce_id] = BASOP_Util_Divide3232_Scale( L_abs( xcorr_ene_fx ), temp, &coh_e );                                /* coh_e + (xcorr_ene_e - temp_e) */
     503        1044 :         move16();
     504        1044 :         coh_e = add( coh_e, sub( xcorr_ene_e, temp_e ) );
     505        1044 :         IF( coh_e < 0 )
     506             :         {
     507         673 :             hISMDTX->coh_fx[sce_id] = shl( hISMDTX->coh_fx[sce_id], coh_e );
     508         673 :             move16();
     509         673 :             coh_e = 0;
     510             :         }
     511             :         /* ensure value of coherence is between [0,1] */
     512        1044 :         hISMDTX->coh_fx[sce_id] = check_bounds_s_fx( hISMDTX->coh_fx[sce_id], 0, shl_sat( 1, 15 - coh_e ) ); /* Q0 */
     513        1044 :         hISMDTX->coh_fx[sce_id] = shl_sat( hISMDTX->coh_fx[sce_id], coh_e );
     514        1044 :         move16();
     515        1044 :         move16();
     516             :     }
     517             : 
     518         480 :     return;
     519             : }

Generated by: LCOV version 1.14