LCOV - code coverage report
Current view: top level - lib_dec - ivas_agc_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 119 137 86.9 %
Date: 2025-05-03 01:55:50 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 <math.h>
      35             : #include <assert.h>
      36             : #include "options.h"
      37             : #include "prot_fx.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "rom_com.h"
      40             : #include "wmc_auto.h"
      41             : 
      42             : 
      43             : /*-----------------------------------------------------------------------------------------*
      44             :  * Function ivas_agc_dec_init_fx()
      45             :  *
      46             :  * AGC decoder initialization call
      47             :  *
      48             :  *-----------------------------------------------------------------------------------------*/
      49             : 
      50        1476 : static void ivas_agc_dec_init_fx(
      51             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle   */
      52             :     const Word16 output_frame,
      53             :     const Word16 delay )
      54             : {
      55             :     Word16 i;
      56        1476 :     ivas_agc_dec_chan_state_t *ptrG = hAgcDec->gain_state;
      57        1476 :     ivas_agc_chan_data_t *ptr = hAgcDec->gain_data;
      58             : 
      59        1476 :     hAgcDec->agc_com.in_delay = delay;
      60        1476 :     move16();
      61        1476 :     hAgcDec->agc_com.num_coeff = IVAS_SPAR_MAX_DMX_CHS;
      62        1476 :     move16();
      63        1476 :     ivas_agc_calcGainParams_fx( &hAgcDec->agc_com.absEmin, &hAgcDec->agc_com.betaE, &hAgcDec->agc_com.maxAttExp, hAgcDec->agc_com.num_coeff );
      64             : 
      65        1476 :     ivas_agc_initWindowFunc_fx( hAgcDec->agc_com.winFunc_fx, output_frame - hAgcDec->agc_com.in_delay );
      66             : 
      67        7380 :     FOR( i = 0; i < IVAS_SPAR_MAX_DMX_CHS; i++ )
      68             :     {
      69             :         /* gain_state */
      70        5904 :         ptrG->lastGain_fx = MAX_16;
      71        5904 :         move16();
      72        5904 :         ptrG->gainExpVal = 0;
      73        5904 :         move16();
      74        5904 :         ptrG++;
      75             : 
      76             :         /* gain_data */
      77        5904 :         ptr->absGainExp = hAgcDec->agc_com.absEmin;
      78        5904 :         move16();
      79        5904 :         ptr->absGainExpCurr = hAgcDec->agc_com.absEmin;
      80        5904 :         move16();
      81        5904 :         ptr++;
      82             :     }
      83             : 
      84        1476 :     return;
      85             : }
      86             : 
      87             : 
      88             : /*-------------------------------------------------------------------------
      89             :  * ivas_spar_agc_dec_open_fx()
      90             :  *
      91             :  * Allocate and initialize SPAR AGC decoder handle
      92             :  *------------------------------------------------------------------------*/
      93             : 
      94        1476 : ivas_error ivas_spar_agc_dec_open_fx(
      95             :     ivas_agc_dec_state_t **hAgcDec, /* i/o: SPAR AGC decoder handle      */
      96             :     const Word32 output_Fs          /* i  : output sampling rate         */
      97             : )
      98             : {
      99             :     ivas_agc_dec_state_t *hAgc;
     100             :     Word16 output_frame, delay;
     101             : 
     102        1476 :     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        1476 :     output_frame = extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) );
     108        1476 :     delay = NS2SA_FX2( output_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) );
     109        1476 :     move16();
     110             : 
     111        1476 :     IF( ( hAgc->agc_com.winFunc_fx = (Word16 *) malloc( sizeof( Word16 ) * ( output_frame - delay ) ) ) == NULL )
     112             :     {
     113           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     114             :     }
     115             : 
     116        1476 :     IF( ( hAgc->gain_state = (ivas_agc_dec_chan_state_t *) malloc( sizeof( ivas_agc_dec_chan_state_t ) * FOA_CHANNELS ) ) == NULL )
     117             :     {
     118           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     119             :     }
     120             : 
     121        1476 :     IF( ( hAgc->gain_data = (ivas_agc_chan_data_t *) malloc( sizeof( ivas_agc_chan_data_t ) * FOA_CHANNELS ) ) == NULL )
     122             :     {
     123           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" );
     124             :     }
     125             : 
     126        1476 :     ivas_agc_dec_init_fx( hAgc, output_frame, delay );
     127             : 
     128        1476 :     *hAgcDec = hAgc;
     129             : 
     130        1476 :     return IVAS_ERR_OK;
     131             : }
     132             : 
     133             : 
     134             : /*-------------------------------------------------------------------------
     135             :  * ivas_spar_agc_dec_close_fx()
     136             :  *
     137             :  * Deallocate SPAR AGC decoder handle
     138             :  *------------------------------------------------------------------------*/
     139             : 
     140        1476 : void ivas_spar_agc_dec_close_fx(
     141             :     ivas_agc_dec_state_t **hAgcDec /* i/o: SPAR AGC decoder handle      */
     142             : )
     143             : {
     144             :     ivas_agc_dec_state_t *hAgc;
     145             : 
     146        1476 :     test();
     147        1476 :     IF( hAgcDec == NULL || *hAgcDec == NULL )
     148             :     {
     149           0 :         return;
     150             :     }
     151             : 
     152        1476 :     hAgc = *hAgcDec;
     153             : 
     154        1476 :     free( hAgc->agc_com.winFunc_fx );
     155        1476 :     hAgc->agc_com.winFunc_fx = NULL;
     156             : 
     157        1476 :     free( hAgc->gain_state );
     158        1476 :     hAgc->gain_state = NULL;
     159             : 
     160        1476 :     free( hAgc->gain_data );
     161        1476 :     hAgc->gain_data = NULL;
     162             : 
     163        1476 :     free( *hAgcDec );
     164        1476 :     *hAgcDec = NULL;
     165             : 
     166        1476 :     return;
     167             : }
     168             : 
     169             : 
     170             : /*-----------------------------------------------------------------------------------------*
     171             :  * Function ivas_agc_dec_process_fx()
     172             :  *
     173             :  * AGC decoder
     174             :  *-----------------------------------------------------------------------------------------*/
     175             : 
     176      146387 : void ivas_agc_dec_process_fx(
     177             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle       */
     178             :     Word32 *pcm_in[],              /* i  : input audio channels     Qx*/
     179             :     Word32 *pcm_out[],             /* o  : output audio channels    Q_pcm_in - 3*/
     180             :     const Word16 n_channels,       /* i  : number of channels       */
     181             :     const Word16 output_frame      /* i  : output frame length      */
     182             : )
     183             : {
     184             :     Word16 i, j, idx;
     185             :     Word16 tmp, tmp_2;
     186             :     UWord16 offset;
     187             :     Word16 gainLast, gain;
     188      146387 :     ivas_agc_dec_state_t *pState = hAgcDec;
     189             : 
     190      146387 :     offset = sub( output_frame, pState->agc_com.in_delay );
     191             : 
     192      502645 :     FOR( i = 0; i < n_channels; i++ )
     193             :     {
     194      356258 :         pState->gain_state[i].gainExpVal = sub( pState->gain_data[i].absGainExp, pState->gain_data[i].absGainExpCurr );
     195      356258 :         move16();
     196             : 
     197      356258 :         test();
     198             : 
     199      356258 :         IF( GT_16( pState->gain_state[i].gainExpVal, add( pState->agc_com.maxAttExp, 1 ) ) || LT_16( pState->gain_state[i].gainExpVal, -1 ) )
     200             :         {
     201             :             /* Such conditions indicate packet loss, better reset and do nothing*/
     202           0 :             pState->gain_data[i].absGainExp = pState->agc_com.absEmin;
     203           0 :             move16();
     204           0 :             pState->gain_state[i].gainExpVal = 0;
     205           0 :             move16();
     206             :         }
     207             : 
     208             :         // pState->gain_state[i].lastGain = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ) );
     209             :         // gainLast = 1.f / pState->gain_state[i].lastGain;
     210             : 
     211      356258 :         tmp = negate( sub( pState->gain_data[i].absGainExp, pState->agc_com.absEmin ) );
     212             : 
     213      356258 :         IF( tmp < 0 )
     214             :         {
     215           0 :             tmp_2 = MAX_16;
     216           0 :             move16();
     217           0 :             FOR( idx = 0; idx < -tmp; idx++ )
     218             :             {
     219           0 :                 tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 );
     220             :             }
     221           0 :             tmp_2 = div_l( ONE_IN_Q30, tmp_2 );
     222             :         }
     223             :         ELSE
     224             :         {
     225      356258 :             tmp_2 = MAX_16;
     226      356258 :             move16();
     227      363379 :             FOR( idx = 0; idx < ( tmp ); idx++ )
     228             :             {
     229        7121 :                 tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q15(15+15-15)
     230             :             }
     231             :         }
     232      356258 :         pState->gain_state[i].lastGain_fx = tmp_2; // Q15
     233      356258 :         move16();
     234      356258 :         gainLast = div_l( ONE_IN_Q29, pState->gain_state[i].lastGain_fx ); // Q13
     235             : 
     236      356258 :         IF( pState->gain_state[i].gainExpVal != 0 )
     237             :         {
     238      366005 :             FOR( idx = 0; idx < output_frame; idx++ )
     239             :             {
     240      365440 :                 IF( GE_16( idx, pState->agc_com.in_delay ) )
     241             :                 {
     242             :                     // gain = powf( pState->agc_com.winFunc[idx - pState->agc_com.in_delay], (float) ( -1 * pState->gain_state[i].gainExpVal ) ) * gainLast;
     243             : 
     244      146176 :                     tmp = negate( pState->gain_state[i].gainExpVal );
     245      146176 :                     IF( tmp < 0 )
     246             :                     {
     247       76288 :                         tmp_2 = MAX_16;
     248       76288 :                         move16();
     249      152576 :                         FOR( j = 0; j < -tmp; j++ )
     250             :                         {
     251       76288 :                             tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); // Q14(15+14-15)
     252             :                         }
     253       76288 :                         IF( tmp_2 < 0 )
     254             :                         {
     255           0 :                             tmp_2 = div_l( ONE_IN_Q30, negate( tmp_2 ) ); // Q14
     256           0 :                             tmp_2 = negate( tmp_2 );
     257             :                         }
     258             :                         ELSE
     259             :                         {
     260       76288 :                             tmp_2 = div_l( ONE_IN_Q30, tmp_2 ); // Q14
     261             :                         }
     262             :                     }
     263             :                     ELSE
     264             :                     {
     265       69888 :                         tmp_2 = MAX_16;
     266       69888 :                         move16();
     267      139776 :                         FOR( j = 0; j < ( tmp ); j++ )
     268             :                         {
     269       69888 :                             tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); // Q15 (15+15-15)
     270             :                         }
     271       69888 :                         tmp_2 = shr( tmp_2, 1 ); // Q14
     272             :                     }
     273      146176 :                     gain = mult( tmp_2, gainLast ); // Q12
     274             :                 }
     275             :                 ELSE
     276             :                 {
     277      219264 :                     gain = shr( gainLast, 1 ); // Q12
     278             :                 }
     279             : 
     280      365440 :                 pcm_out[i][idx] = Mpy_32_16_1( pcm_in[i][idx], gain ); // Q_pcm_out = Q_pcm_in - 3
     281      365440 :                 move32();
     282             :             }
     283             : 
     284             :             // pState->gain_state[i].lastGain *= powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal );
     285         565 :             tmp = pState->gain_state[i].gainExpVal;
     286         565 :             move16();
     287         565 :             IF( tmp < 0 )
     288             :             {
     289         270 :                 tmp_2 = MAX_16;
     290         270 :                 move16();
     291         540 :                 FOR( idx = 0; idx < -tmp; idx++ )
     292             :                 {
     293         270 :                     tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q14 (14+15-15)
     294             :                 }
     295         270 :                 tmp_2 = div_l( ONE_IN_Q30, tmp_2 ); // Q14
     296             :             }
     297             :             ELSE
     298             :             {
     299         295 :                 tmp_2 = MAX_16;
     300         295 :                 move16();
     301         590 :                 FOR( idx = 0; idx < ( tmp ); idx++ )
     302             :                 {
     303         295 :                     tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); // Q15
     304             :                 }
     305         295 :                 tmp_2 = shr( tmp_2, 1 ); // Q14
     306             :             }
     307         565 :             pState->gain_state[i].lastGain_fx = mult( pState->gain_state[i].lastGain_fx, tmp_2 ); // Q14
     308         565 :             move16();
     309             :         }
     310             :         ELSE
     311             :         {
     312      355693 :             gain = shr( gainLast, 1 ); // Q12
     313   278969453 :             FOR( idx = 0; idx < output_frame; idx++ )
     314             :             {
     315   278613760 :                 pcm_out[i][idx] = Mpy_32_16_1( pcm_in[i][idx], gain ); // Q_pcm_out = Q_pcm_in - 3
     316   278613760 :                 move32();
     317             :             }
     318             :         }
     319      356258 :         pState->gain_data[i].absGainExp = pState->gain_data[i].absGainExpCurr;
     320      356258 :         move16();
     321             :     }
     322             : 
     323      146387 :     return;
     324             : }
     325             : 
     326             : 
     327             : /*-----------------------------------------------------------------------------------------*
     328             :  * ivas_agc_read_bits_fx()
     329             :  *
     330             :  * decode AGC parameters
     331             :  *-----------------------------------------------------------------------------------------*/
     332             : 
     333      140347 : void ivas_agc_read_bits_fx(
     334             :     ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle                               */
     335             :     Decoder_State *st0,            /* i/o: decoder state structure - for bitstream handling */
     336             :     const Word16 n_channels,       /* i  : number of channels                               */
     337             :     const Word16 AGC_flag          /* i  : AGC on/off flag                                  */
     338             : )
     339             : {
     340             :     Word16 i;
     341             :     Word16 per_ch_bit[FOA_CHANNELS];
     342      140347 :     ivas_agc_dec_state_t *pState = hAgcDec;
     343             : 
     344      140347 :     set16_fx( per_ch_bit, 0, FOA_CHANNELS );
     345             : 
     346             :     /* read AGC parameters */
     347      140347 :     IF( EQ_16( AGC_flag, 1 ) )
     348             :     {
     349        4075 :         per_ch_bit[0] = 1;
     350        4075 :         move16();
     351             : 
     352        4075 :         assert( EQ_16( AGC_BITS_PER_CH, ( pState->agc_com.betaE + 1 ) ) );
     353        8150 :         FOR( i = 0; i < n_channels; i++ )
     354             :         {
     355        4075 :             IF( EQ_16( per_ch_bit[i], 1 ) )
     356             :             {
     357        4075 :                 pState->gain_data[i].absGainExpCurr = get_next_indice_fx( st0, (Word16) pState->agc_com.betaE );
     358        4075 :                 move16();
     359             :             }
     360             :             ELSE
     361             :             {
     362           0 :                 pState->gain_data[i].absGainExpCurr = (Word16) pState->agc_com.absEmin;
     363           0 :                 move16();
     364             :             }
     365             :         }
     366             :     }
     367             :     ELSE
     368             :     {
     369      478932 :         FOR( i = 0; i < n_channels; i++ )
     370             :         {
     371      342660 :             pState->gain_data[i].absGainExpCurr = (Word16) pState->agc_com.absEmin;
     372      342660 :             move16();
     373             :         }
     374             :     }
     375             : 
     376      140347 :     return;
     377             : }

Generated by: LCOV version 1.14