LCOV - code coverage report
Current view: top level - lib_dec - ivas_agc_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 69 77 89.6 %
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 <math.h>
      38             : #include <assert.h>
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : #ifdef DEBUG_AGC
      46             : extern FILE *agcIn;
      47             : #endif
      48             : 
      49             : /*-----------------------------------------------------------------------------------------*
      50             :  * Function ivas_agc_dec_init()
      51             :  *
      52             :  * AGC decoder initialization call
      53             :  *
      54             :  *-----------------------------------------------------------------------------------------*/
      55             : 
      56        4908 : static void ivas_agc_dec_init(
      57             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle   */
      58             :     const int16_t output_frame,
      59             :     const int16_t delay )
      60             : {
      61             :     int16_t i;
      62        4908 :     ivas_agc_dec_chan_state_t *ptrG = hAgcDec->gain_state;
      63        4908 :     ivas_agc_chan_data_t *ptr = hAgcDec->gain_data;
      64             : 
      65        4908 :     hAgcDec->agc_com.in_delay = delay;
      66        4908 :     hAgcDec->agc_com.num_coeff = IVAS_SPAR_MAX_DMX_CHS;
      67        4908 :     ivas_agc_calcGainParams( &hAgcDec->agc_com.absEmin, &hAgcDec->agc_com.betaE, &hAgcDec->agc_com.maxAttExp, hAgcDec->agc_com.num_coeff );
      68             : 
      69        4908 :     ivas_agc_initWindowFunc( hAgcDec->agc_com.winFunc, output_frame - hAgcDec->agc_com.in_delay );
      70             : 
      71       24540 :     for ( i = 0; i < IVAS_SPAR_MAX_DMX_CHS; i++ )
      72             :     {
      73             :         /* gain_state */
      74       19632 :         ptrG->lastGain = 1.f;
      75       19632 :         ptrG->gainExpVal = 0;
      76       19632 :         ptrG++;
      77             : 
      78             :         /* gain_data */
      79       19632 :         ptr->absGainExp = hAgcDec->agc_com.absEmin;
      80       19632 :         ptr->absGainExpCurr = hAgcDec->agc_com.absEmin;
      81       19632 :         ptr++;
      82             :     }
      83             : 
      84        4908 :     return;
      85             : }
      86             : 
      87             : 
      88             : /*-------------------------------------------------------------------------
      89             :  * ivas_spar_agc_dec_open()
      90             :  *
      91             :  * Allocate and initialize SPAR AGC decoder handle
      92             :  *------------------------------------------------------------------------*/
      93             : 
      94        4908 : ivas_error ivas_spar_agc_dec_open(
      95             :     ivas_agc_dec_state_t **hAgcDec, /* i/o: SPAR AGC decoder handle      */
      96             :     const int32_t output_Fs         /* i  : output sampling rate         */
      97             : )
      98             : {
      99             :     ivas_agc_dec_state_t *hAgc;
     100             :     int16_t output_frame, delay;
     101             : 
     102        4908 :     if ( ( hAgc = (ivas_agc_dec_state_t *) malloc( sizeof( ivas_agc_dec_state_t ) ) ) == NULL )
     103             :     {
     104           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     105             :     }
     106             : 
     107        4908 :     output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC );
     108        4908 :     delay = NS2SA( output_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) );
     109             : 
     110        4908 :     if ( ( hAgc->agc_com.winFunc = (float *) malloc( sizeof( float ) * ( output_frame - delay ) ) ) == NULL )
     111             :     {
     112           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     113             :     }
     114             : 
     115        4908 :     if ( ( hAgc->gain_state = (ivas_agc_dec_chan_state_t *) malloc( sizeof( ivas_agc_dec_chan_state_t ) * FOA_CHANNELS ) ) == NULL )
     116             :     {
     117           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     118             :     }
     119             : 
     120        4908 :     if ( ( hAgc->gain_data = (ivas_agc_chan_data_t *) malloc( sizeof( ivas_agc_chan_data_t ) * FOA_CHANNELS ) ) == NULL )
     121             :     {
     122           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     123             :     }
     124             : 
     125        4908 :     ivas_agc_dec_init( hAgc, output_frame, delay );
     126             : 
     127        4908 :     *hAgcDec = hAgc;
     128             : 
     129        4908 :     return IVAS_ERR_OK;
     130             : }
     131             : 
     132             : 
     133             : /*-------------------------------------------------------------------------
     134             :  * ivas_spar_agc_dec_close()
     135             :  *
     136             :  * Deallocate SPAR AGC decoder handle
     137             :  *------------------------------------------------------------------------*/
     138             : 
     139        4908 : void ivas_spar_agc_dec_close(
     140             :     ivas_agc_dec_state_t **hAgcDec /* i/o: SPAR AGC decoder handle      */
     141             : )
     142             : {
     143             :     ivas_agc_dec_state_t *hAgc;
     144             : 
     145        4908 :     if ( hAgcDec == NULL || *hAgcDec == NULL )
     146             :     {
     147           0 :         return;
     148             :     }
     149             : 
     150        4908 :     hAgc = *hAgcDec;
     151             : 
     152        4908 :     free( hAgc->agc_com.winFunc );
     153        4908 :     hAgc->agc_com.winFunc = NULL;
     154             : 
     155        4908 :     free( hAgc->gain_state );
     156        4908 :     hAgc->gain_state = NULL;
     157             : 
     158        4908 :     free( hAgc->gain_data );
     159        4908 :     hAgc->gain_data = NULL;
     160             : 
     161        4908 :     free( *hAgcDec );
     162        4908 :     *hAgcDec = NULL;
     163             : 
     164        4908 :     return;
     165             : }
     166             : 
     167             : 
     168             : /*-----------------------------------------------------------------------------------------*
     169             :  * Function ivas_agc_dec_process()
     170             :  *
     171             :  * AGC decoder
     172             :  *-----------------------------------------------------------------------------------------*/
     173             : 
     174      463122 : void ivas_agc_dec_process(
     175             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle       */
     176             :     float *pcm_in[],               /* i  : input audio channels     */
     177             :     float *pcm_out[],              /* o  : output audio channels    */
     178             :     const int16_t n_channels,      /* i  : number of channels       */
     179             :     const int16_t output_frame     /* i  : output frame length      */
     180             : )
     181             : {
     182             :     int16_t i, idx;
     183             :     uint16_t offset;
     184             :     float gainLast, gain;
     185      463122 :     ivas_agc_dec_state_t *pState = hAgcDec;
     186             : 
     187      463122 :     offset = output_frame - pState->agc_com.in_delay;
     188             : 
     189     1605744 :     for ( i = 0; i < n_channels; i++ )
     190             :     {
     191     1142622 :         pState->gain_state[i].gainExpVal = pState->gain_data[i].absGainExp - pState->gain_data[i].absGainExpCurr;
     192             : 
     193     1142622 :         if ( ( pState->gain_state[i].gainExpVal > (int32_t) ( pState->agc_com.maxAttExp + 1 ) ) || ( pState->gain_state[i].gainExpVal < -1 ) )
     194             :         {
     195             :             /* Such conditions indicate packet loss, better reset and do nothing*/
     196           0 :             pState->gain_data[i].absGainExp = pState->agc_com.absEmin;
     197           0 :             pState->gain_state[i].gainExpVal = 0;
     198             :         }
     199             : 
     200     1142622 :         pState->gain_state[i].lastGain = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ) );
     201     1142622 :         gainLast = 1.f / pState->gain_state[i].lastGain;
     202             : 
     203     1142622 :         if ( pState->gain_state[i].gainExpVal != 0 )
     204             :         {
     205     1098015 :             for ( idx = 0; idx < output_frame; idx++ )
     206             :             {
     207     1096320 :                 if ( idx >= pState->agc_com.in_delay )
     208             :                 {
     209      438528 :                     gain = powf( pState->agc_com.winFunc[idx - pState->agc_com.in_delay], (float) ( -1 * pState->gain_state[i].gainExpVal ) ) * gainLast;
     210             :                 }
     211             :                 else
     212             :                 {
     213      657792 :                     gain = gainLast;
     214             :                 }
     215             : 
     216     1096320 :                 pcm_out[i][idx] = pcm_in[i][idx] * gain;
     217             :             }
     218             : 
     219        1695 :             pState->gain_state[i].lastGain *= powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal );
     220             :         }
     221             :         else
     222             :         {
     223     1140927 :             gain = gainLast;
     224   903444927 :             for ( idx = 0; idx < output_frame; idx++ )
     225             :             {
     226   902304000 :                 pcm_out[i][idx] = pcm_in[i][idx] * gain;
     227             :             }
     228             :         }
     229     1142622 :         pState->gain_data[i].absGainExp = pState->gain_data[i].absGainExpCurr;
     230             :     }
     231             : 
     232      463122 :     return;
     233             : }
     234             : 
     235             : 
     236             : /*-----------------------------------------------------------------------------------------*
     237             :  * ivas_agc_read_bits()
     238             :  *
     239             :  * decode AGC parameters
     240             :  *-----------------------------------------------------------------------------------------*/
     241             : 
     242      443862 : void ivas_agc_read_bits(
     243             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle                               */
     244             :     Decoder_State *st0,            /* i/o: decoder state structure - for bitstream handling */
     245             :     const int16_t n_channels,      /* i  : number of channels                               */
     246             :     const int16_t AGC_flag         /* i  : AGC on/off flag                                  */
     247             : )
     248             : {
     249             :     int16_t i;
     250             :     int16_t per_ch_bit[FOA_CHANNELS];
     251      443862 :     ivas_agc_dec_state_t *pState = hAgcDec;
     252             : 
     253      443862 :     set_s( per_ch_bit, 0, FOA_CHANNELS );
     254             : 
     255             :     /* read AGC parameters */
     256      443862 :     if ( AGC_flag == 1 )
     257             :     {
     258       12225 :         per_ch_bit[0] = 1;
     259             : 
     260       12225 :         assert( AGC_BITS_PER_CH == ( pState->agc_com.betaE + 1 ) );
     261       24450 :         for ( i = 0; i < n_channels; i++ )
     262             :         {
     263       12225 :             if ( per_ch_bit[i] == 1 )
     264             :             {
     265       12225 :                 pState->gain_data[i].absGainExpCurr = get_next_indice( st0, (int16_t) pState->agc_com.betaE );
     266             :             }
     267             :             else
     268             :             {
     269           0 :                 pState->gain_data[i].absGainExpCurr = (int32_t) pState->agc_com.absEmin;
     270             :             }
     271             :         }
     272             :     }
     273             :     else
     274             :     {
     275     1530927 :         for ( i = 0; i < n_channels; i++ )
     276             :         {
     277     1099290 :             pState->gain_data[i].absGainExpCurr = (int32_t) pState->agc_com.absEmin;
     278             :         }
     279             :     }
     280             : 
     281             : #ifdef DEBUG_AGC
     282             :     FILE *stream = agcIn;
     283             :     int16_t num_bits = 0, num_dmx_bits[4] = { 0 };
     284             :     for ( i = 0; i < n_channels; i++ )
     285             :     {
     286             :         fread( &( pState->gain_data[i].absGainExpCurr ), sizeof( int32_t ), 1, stream ); /* n bits */
     287             :         num_bits += pState->agc_com.betaE;
     288             :         num_dmx_bits[i]++;
     289             : 
     290             :         /*fprintf(stdout, "AbsGain[%d]:= %d[%d bits]; ", i, pState->gain_data[i].absGainExp, pState->betaE);*/
     291             :     }
     292             :     /*fprintf(stdout, "AGC bits:= %d ", num_bits);*/
     293             : 
     294             : #endif
     295             : 
     296      443862 :     return;
     297             : }

Generated by: LCOV version 1.14