LCOV - code coverage report
Current view: top level - lib_enc - ivas_enc_cov_handler.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 108 127 85.0 %
Date: 2025-05-23 08:37:30 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "prot.h"
      36             : #include "ivas_prot.h"
      37             : #include "ivas_rom_com.h"
      38             : #ifdef DEBUGGING
      39             : #include "debug.h"
      40             : #endif
      41             : #include "wmc_auto.h"
      42             : 
      43             : /*------------------------------------------------------------------------------------------*
      44             :  * Local constants
      45             :  *------------------------------------------------------------------------------------------*/
      46             : 
      47             : #define MIN_POOL_SIZE       24
      48             : #define MAX_UPDATE_RATE     0.8f
      49             : #define MIN_POOL_SIZE_DTX   40
      50             : #define MAX_UPDATE_RATE_DTX 0.4f
      51             : 
      52             : 
      53             : /*------------------------------------------------------------------------------------------*
      54             :  * Local functions declarations
      55             :  *------------------------------------------------------------------------------------------*/
      56             : 
      57             : static void ivas_band_cov( float **ppIn_FR_real, float **ppIn_FR_imag, const int16_t num_chans, const int16_t num_bins, int16_t stride, float **pFb_bin_to_band, const int16_t *pFb_start_bin_per_band, const int16_t *pFb_active_bins_per_band, const int16_t start_band, const int16_t end_band, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] );
      58             : 
      59             : /*-------------------------------------------------------------------------
      60             :  * ivas_spar_covar_enc_open()
      61             :  *
      62             :  * Allocate and initialize SPAR Covar. encoder handle
      63             :  *------------------------------------------------------------------------*/
      64             : 
      65        1684 : ivas_error ivas_spar_covar_enc_open(
      66             :     ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle      */
      67             :     ivas_filterbank_t *pFb,                 /* i/o: FB handle                       */
      68             :     const int32_t input_Fs,                 /* i  : input sampling rate             */
      69             :     const int16_t nchan_inp,                /* i  : number of input channels        */
      70             :     const COV_SMOOTHING_TYPE smooth_mode,   /* i  : Smooth covariance for SPAR or MC*/
      71             :     const int32_t ivas_total_brate          /* i  : IVAS total bitrate              */
      72             : )
      73             : {
      74             :     ivas_enc_cov_handler_state_t *hCovState;
      75             :     ivas_cov_smooth_cfg_t cov_smooth_cfg;
      76             :     ivas_error error;
      77             : 
      78        1684 :     error = IVAS_ERR_OK;
      79             : 
      80        1684 :     if ( ( hCovState = (ivas_enc_cov_handler_state_t *) malloc( sizeof( ivas_enc_cov_handler_state_t ) ) ) == NULL )
      81             :     {
      82           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder" );
      83             :     }
      84             : 
      85        1684 :     cov_smooth_cfg.max_bands = IVAS_MAX_NUM_BANDS;
      86        1684 :     cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE;
      87        1684 :     cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE;
      88        1684 :     if ( smooth_mode == COV_SMOOTH_MC )
      89             :     {
      90          48 :         cov_smooth_cfg.max_update_rate = 1.0f;
      91          48 :         cov_smooth_cfg.min_pool_size = 20;
      92             :     }
      93             : 
      94        1684 :     if ( ( error = ivas_spar_covar_smooth_enc_open( &hCovState->pCov_state, &cov_smooth_cfg, pFb, nchan_inp, smooth_mode, ivas_total_brate ) ) != IVAS_ERR_OK )
      95             :     {
      96           0 :         return error;
      97             :     }
      98             : 
      99        1684 :     cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE_DTX;
     100        1684 :     cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE_DTX;
     101             : 
     102        1684 :     if ( ( error = ivas_spar_covar_smooth_enc_open( &hCovState->pCov_dtx_state, &cov_smooth_cfg, pFb, nchan_inp, smooth_mode, ivas_total_brate ) ) != IVAS_ERR_OK )
     103             :     {
     104           0 :         return error;
     105             :     }
     106             : 
     107        1684 :     hCovState->num_bins = (int16_t) ( input_Fs / FRAMES_PER_SEC );
     108        1684 :     hCovState->prior_dtx_present = 0;
     109             : 
     110        1684 :     set_zero( hCovState->bb_var_lt, FOA_CHANNELS );
     111        1684 :     hCovState->prior_var_flag = -1;
     112             : 
     113        1684 :     *hCovEnc = hCovState;
     114             : 
     115        1684 :     return error;
     116             : }
     117             : 
     118             : 
     119             : /*-------------------------------------------------------------------------
     120             :  * ivas_spar_covar_enc_close()
     121             :  *
     122             :  * Deallocate SPAR Covar. encoder handle
     123             :  *------------------------------------------------------------------------*/
     124             : 
     125        1684 : void ivas_spar_covar_enc_close(
     126             :     ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle    */
     127             :     const int16_t nchan_inp                 /* i  : number of input channels      */
     128             : )
     129             : {
     130             :     ivas_enc_cov_handler_state_t *hCovState;
     131             : 
     132        1684 :     if ( hCovEnc == NULL || *hCovEnc == NULL )
     133             :     {
     134           0 :         return;
     135             :     }
     136             : 
     137        1684 :     hCovState = *hCovEnc;
     138             : 
     139        1684 :     ivas_spar_covar_smooth_enc_close( &hCovState->pCov_state, nchan_inp );
     140             : 
     141        1684 :     ivas_spar_covar_smooth_enc_close( &hCovState->pCov_dtx_state, nchan_inp );
     142             : 
     143        1684 :     free( *hCovEnc );
     144        1684 :     *hCovEnc = NULL;
     145             : 
     146        1684 :     return;
     147             : }
     148             : 
     149             : 
     150             : /*-----------------------------------------------------------------------------------------*
     151             :  * Function ivas_spar_get_activeW_flag()
     152             :  *
     153             :  *
     154             :  *-----------------------------------------------------------------------------------------*/
     155             : 
     156       74079 : static int16_t ivas_spar_get_activeW_flag(
     157             :     ivas_enc_cov_handler_state_t *hCovEnc,
     158             :     float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
     159             :     float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
     160             :     const int16_t dtx_vad,
     161             :     const int16_t nchan_inp,
     162             :     const int16_t nchan_transport,
     163             :     int16_t *res_ind,
     164             :     const int16_t *dmx_order )
     165             : {
     166             :     int16_t b, ch, num_bands, num_chs, activeW_flag;
     167             :     float bb_var[FOA_CHANNELS], sm_fact, side_ch_var, en_ratio;
     168       74079 :     num_chs = min( nchan_inp, FOA_CHANNELS );
     169       74079 :     num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW );
     170             : 
     171       74079 :     set_zero( bb_var, FOA_CHANNELS );
     172             : 
     173       74079 :     if ( dtx_vad == 1 )
     174             :     {
     175      361975 :         for ( ch = 0; ch < num_chs; ch++ )
     176             :         {
     177     3764540 :             for ( b = 0; b < num_bands; b++ )
     178             :             {
     179     3474960 :                 bb_var[ch] += cov_real[ch][ch][b];
     180             :             }
     181             :         }
     182             :     }
     183             :     else
     184             :     {
     185        8420 :         for ( ch = 0; ch < num_chs; ch++ )
     186             :         {
     187       87568 :             for ( b = 0; b < num_bands; b++ )
     188             :             {
     189       80832 :                 bb_var[ch] += cov_dtx_real[ch][ch][b];
     190             :             }
     191             :         }
     192             :     }
     193             : 
     194       74079 :     if ( hCovEnc->prior_var_flag == -1 )
     195             :     {
     196      370395 :         for ( ch = 0; ch < num_chs; ch++ )
     197             :         {
     198      296316 :             hCovEnc->bb_var_lt[ch] = bb_var[ch];
     199             :         }
     200             :     }
     201             :     else
     202             :     {
     203           0 :         sm_fact = 0.5f;
     204           0 :         for ( ch = 0; ch < num_chs; ch++ )
     205             :         {
     206           0 :             hCovEnc->bb_var_lt[ch] = sm_fact * hCovEnc->bb_var_lt[ch] + ( 1 - sm_fact ) * bb_var[ch];
     207             :         }
     208             :     }
     209             : 
     210       74079 :     side_ch_var = 0.0f;
     211      189498 :     for ( ch = nchan_transport; ch < num_chs; ch++ )
     212             :     {
     213      115419 :         side_ch_var += hCovEnc->bb_var_lt[dmx_order[ch]];
     214             :     }
     215             : 
     216       74079 :     if ( side_ch_var < ( IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH * IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH ) )
     217             :     {
     218        2437 :         activeW_flag = 0;
     219             :     }
     220             :     else
     221             :     {
     222       71642 :         en_ratio = hCovEnc->bb_var_lt[0] / side_ch_var;
     223       71642 :         if ( en_ratio < ( IVAS_SPAR_DYN_ACTIVEW_THRESH * IVAS_SPAR_DYN_ACTIVEW_THRESH ) )
     224             :         {
     225           0 :             activeW_flag = 1;
     226             :         }
     227             :         else
     228             :         {
     229       71642 :             activeW_flag = 0;
     230             :         }
     231             :     }
     232             : 
     233       74079 :     if ( activeW_flag )
     234             :     {
     235           0 :         *res_ind = 0;
     236           0 :         if ( nchan_transport == 2 )
     237             :         {
     238             :             int16_t max_idx;
     239             :             float max_val;
     240           0 :             max_idx = nchan_transport;
     241           0 :             max_val = hCovEnc->bb_var_lt[max_idx];
     242           0 :             for ( ch = nchan_transport + 1; ch < num_chs; ch++ )
     243             :             {
     244           0 :                 if ( hCovEnc->bb_var_lt[ch] > max_val )
     245             :                 {
     246           0 :                     max_idx = ch;
     247           0 :                     max_val = hCovEnc->bb_var_lt[ch];
     248             :                 }
     249             :             }
     250           0 :             *res_ind = max_idx;
     251             :         }
     252           0 :         else if ( nchan_transport == 3 )
     253             :         {
     254           0 :             *res_ind = dmx_order[nchan_transport];
     255             :         }
     256             :     }
     257             : 
     258       74079 :     return activeW_flag;
     259             : }
     260             : 
     261             : 
     262             : /*-----------------------------------------------------------------------------------------*
     263             :  * Function ivas_enc_cov_handler_process()
     264             :  *
     265             :  * Encoder covariance handler process call
     266             :  *-----------------------------------------------------------------------------------------*/
     267             : 
     268      162660 : void ivas_enc_cov_handler_process(
     269             :     ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle      */
     270             :     float **ppIn_FR_real,
     271             :     float **ppIn_FR_imag,
     272             :     float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
     273             :     float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
     274             :     ivas_filterbank_t *pFb, /* i/o: FB handle                       */
     275             :     const int16_t start_band,
     276             :     const int16_t end_band,
     277             :     const int16_t num_ch,
     278             :     const int16_t dtx_vad,
     279             :     const int16_t transient_det[2],
     280             :     const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH],
     281             :     int16_t *res_ind,
     282             :     const int16_t *remix_order,
     283             :     int16_t *dyn_active_w_flag,
     284             :     const int16_t nchan_transport,
     285             :     const int16_t is_sba
     286             : 
     287             : )
     288             : {
     289             :     int16_t i, j;
     290             :     int16_t dtx_cov_flag;
     291             : 
     292      162660 :     dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1;
     293             : 
     294      162660 :     ivas_band_cov( ppIn_FR_real, ppIn_FR_imag, num_ch, hCovEnc->num_bins,
     295      162660 :                    pFb->fb_bin_to_band.short_stride,
     296      162660 :                    pFb->fb_bin_to_band.pp_short_stride_bin_to_band,
     297      162660 :                    pFb->fb_bin_to_band.p_short_stride_start_bin_per_band,
     298      162660 :                    pFb->fb_bin_to_band.p_short_stride_num_bins_per_band,
     299             :                    start_band, end_band, cov_real, HOA_md_ind );
     300             : 
     301      162660 :     if ( is_sba )
     302             :     {
     303      159500 :         *res_ind = 0;
     304      159500 :         if ( nchan_transport > 1 && nchan_transport <= ( FOA_CHANNELS - 1 ) )
     305             :         {
     306       74079 :             *dyn_active_w_flag = ivas_spar_get_activeW_flag( hCovEnc, cov_real, cov_real, dtx_vad, num_ch, nchan_transport, res_ind, remix_order );
     307             :         }
     308             :         else
     309             :         {
     310       85421 :             *dyn_active_w_flag = 0;
     311             :         }
     312             :     }
     313             : 
     314             : #ifdef DEBUG_SPAR_WRITE_OUT_COV
     315             :     {
     316             :         static FILE *fid = 0;
     317             :         int16_t k = 0;
     318             :         float tmp_buf[10];
     319             :         if ( !fid )
     320             :         {
     321             :             fid = fopen( "cov_real.txt", "wt" );
     322             :         }
     323             : 
     324             :         for ( i = 0; i < num_ch; i++ )
     325             :         {
     326             :             for ( j = 0; j < num_ch; j++ )
     327             :             {
     328             :                 for ( k = start_band; k < end_band; k++ )
     329             :                 {
     330             :                     fprintf( fid, "%.6f\n", cov_real[i][j][k] );
     331             :                 }
     332             :             }
     333             :         }
     334             :         fprintf( fid, "\n" );
     335             :     }
     336             : #endif
     337      909180 :     for ( i = 0; i < num_ch; i++ )
     338             :     {
     339     4687620 :         for ( j = 0; j < num_ch; j++ )
     340             :         {
     341     3941100 :             mvr2r( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands );
     342             :         }
     343             :     }
     344             : 
     345      162660 :     ivas_cov_smooth_process( hCovEnc->pCov_state, cov_real, pFb, start_band, end_band, num_ch, transient_det );
     346             : 
     347      162660 :     if ( dtx_cov_flag == 0 )
     348             :     {
     349      880565 :         for ( i = 0; i < num_ch; i++ )
     350             :         {
     351     4592120 :             for ( j = 0; j < num_ch; j++ )
     352             :             {
     353     3867228 :                 mvr2r( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands );
     354     3867228 :                 mvr2r( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands );
     355             :             }
     356             :         }
     357             : 
     358      155673 :         hCovEnc->prior_dtx_present = 1;
     359             :     }
     360             :     else
     361             :     {
     362        6987 :         if ( ( transient_det[0] == 0 ) && ( transient_det[1] == 0 ) )
     363             :         {
     364        5875 :             ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det );
     365        5875 :             hCovEnc->prior_dtx_present = 1;
     366             :         }
     367             :         else
     368             :         {
     369        1112 :             if ( hCovEnc->prior_dtx_present == 0 )
     370             :             {
     371          48 :                 ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det );
     372          48 :                 hCovEnc->prior_dtx_present = 1;
     373             :             }
     374             :             else
     375             :             {
     376        4296 :                 for ( i = 0; i < num_ch; i++ )
     377             :                 {
     378       14112 :                     for ( j = 0; j < num_ch; j++ )
     379             :                     {
     380       10880 :                         mvr2r( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands );
     381             :                     }
     382             :                 }
     383             : 
     384        1064 :                 hCovEnc->prior_dtx_present = 1;
     385             :             }
     386             :         }
     387             :     }
     388             : 
     389      162660 :     return;
     390             : }
     391             : 
     392             : 
     393      162660 : static void ivas_band_cov(
     394             :     float **ppIn_FR_real,
     395             :     float **ppIn_FR_imag,
     396             :     const int16_t num_chans,
     397             :     const int16_t num_bins,
     398             :     int16_t stride,
     399             :     float **pFb_bin_to_band,
     400             :     const int16_t *pFb_start_bin_per_band,
     401             :     const int16_t *pFb_active_bins_per_band,
     402             :     const int16_t start_band,
     403             :     const int16_t end_band,
     404             :     float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
     405             :     const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] )
     406             : {
     407             :     int16_t i, j, k;
     408             :     float pV_re[L_FRAME48k];
     409             :     int16_t m, start_bin, active_bins;
     410             : 
     411      909180 :     for ( i = 0; i < num_chans; i++ )
     412             :     {
     413     3090330 :         for ( j = i; j < num_chans; j++ )
     414             :         {
     415     2343810 :             int16_t i1 = HOA_md_ind[i];
     416     2343810 :             int16_t j1 = HOA_md_ind[j];
     417             : 
     418  1927038210 :             for ( k = 0; k < num_bins; k++ )
     419             :             {
     420  1924694400 :                 pV_re[k] = ppIn_FR_real[i1][k] * ppIn_FR_real[j1][k] + ppIn_FR_imag[i1][k] * ppIn_FR_imag[j1][k];
     421             :             }
     422             : 
     423    30207530 :             for ( k = start_band; k < end_band; k++ )
     424             :             {
     425    27863720 :                 float temp = 0.0f;
     426    27863720 :                 const float *p_bin_to_band = pFb_bin_to_band[k];
     427    27863720 :                 float *cov_ptr = pV_re;
     428             :                 int16_t num_blocks;
     429             : 
     430    27863720 :                 num_blocks = num_bins / stride;
     431    27863720 :                 start_bin = pFb_start_bin_per_band[k];
     432    27863720 :                 active_bins = pFb_active_bins_per_band[k];
     433             : 
     434   139318600 :                 for ( int16_t blk = 0; blk < num_blocks; blk++ )
     435             :                 {
     436             :                     /* optional: add temporal weight here */
     437  2150523680 :                     for ( m = start_bin; m < start_bin + active_bins; m++ )
     438             :                     {
     439  2039068800 :                         temp += cov_ptr[m] * ( p_bin_to_band[m - start_bin] );
     440             :                     }
     441   111454880 :                     cov_ptr += stride;
     442             :                 }
     443    27863720 :                 cov_real[i][j][k] = temp * (float) num_blocks;
     444             :             }
     445             :         }
     446             :     }
     447             : 
     448      909180 :     for ( i = 0; i < num_chans; i++ )
     449             :     {
     450     2343810 :         for ( j = 0; j < i; j++ )
     451             :         {
     452    20602770 :             for ( k = start_band; k < end_band; k++ )
     453             :             {
     454    19005480 :                 cov_real[i][j][k] = cov_real[j][i][k];
     455             :             }
     456             :         }
     457             :     }
     458             : 
     459      162660 :     return;
     460             : }

Generated by: LCOV version 1.14