LCOV - code coverage report
Current view: top level - lib_rend - ivas_reverb_utils_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 43 45 95.6 %
Date: 2025-08-23 01:22:27 Functions: 2 2 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_fx.h"
      36             : #include "ivas_prot_rend_fx.h"
      37             : #include "ivas_rom_rend.h"
      38             : #include <math.h>
      39             : #include "wmc_auto.h"
      40             : #include "options_warnings.h"
      41             : 
      42             : /*-----------------------------------------------------------------------------------------*
      43             :  * Local constants
      44             :  *-----------------------------------------------------------------------------------------*/
      45             : 
      46             : #define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) )
      47             : 
      48             : /*-----------------------------------------------------------------------------------------*
      49             :  * Local function prototypes
      50             :  *-----------------------------------------------------------------------------------------*/
      51             : 
      52             : static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, const Word32 sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out );
      53             : 
      54             : /*-----------------------------------------------------------------------------------------*
      55             :  * Function ivas_reverb_prepare_cldfb_params()
      56             :  *
      57             :  * Prepares reverb parameters for CLDFB-based reverberator
      58             :  *-----------------------------------------------------------------------------------------*/
      59             : 
      60         245 : ivas_error ivas_reverb_prepare_cldfb_params(
      61             :     const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params,
      62             :     const HRTFS_STATISTICS_HANDLE hHrtfStatistics,
      63             :     const Word32 output_Fs,
      64             :     Word32 *pOutput_t60,
      65             :     Word32 *pOutput_ene )
      66             : {
      67             :     Word16 idx;
      68             : 
      69             :     Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX];
      70             :     Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX];
      71             :     Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX];
      72             : 
      73             :     Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp;
      74         245 :     const Word32 dmx_gain_2_fx = 1852986624;  // Q16
      75         245 :     const Word32 cldfb_band_width = 26214400; // 400 in Q16
      76             :     Word16 pow_exp, tmp_exp;
      77             :     Word32 tmp, exp_argument_fx;
      78             : 
      79             :     Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX];
      80             :     Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX];
      81             : 
      82       14945 :     FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
      83             :     {
      84       14700 :         output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) );
      85             :     }
      86             : 
      87         245 :     ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx ); // Q26
      88         245 :     ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_ene_fx );  // Q30
      89             : 
      90             :     /* adjust DSR for the delay difference */
      91         245 :     delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); // Q27
      92             : 
      93         245 :     ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */
      94             : 
      95       14945 :     FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
      96             :     {
      97       14700 :         L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // Q26
      98             : 
      99       14700 :         exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );
     100       14700 :         exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); // Q26
     101             : 
     102             :         /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */
     103       14700 :         IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26
     104             :         {
     105           0 :             exp_argument_fx = 1543503872;
     106             :         }
     107       14700 :         IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26
     108             :         {
     109           0 :             exp_argument_fx = -1543503872;
     110             :         }
     111             : 
     112       14700 :         tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21
     113             : 
     114       14700 :         L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );
     115       14700 :         L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] );
     116       14700 :         L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31
     117             : 
     118       14700 :         pOutput_ene[idx] = L_tmp; // Q31
     119       14700 :         move32();
     120             : 
     121       14700 :         pOutput_t60[idx] = output_t60_fx[idx]; // Q26
     122             :     }
     123             : 
     124         245 :     ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); // Q28
     125             : 
     126       14945 :     FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
     127             :     {
     128             :         Word32 tmp_ene;
     129             : 
     130       14700 :         tmp_ene = L_shr( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ), 1 ); // Q28
     131       14700 :         tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx );                              // Q13
     132       14700 :         pOutput_ene[idx] = Mpy_32_32( pOutput_ene[idx], tmp_ene );                  // Q13
     133       14700 :         pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 );                       // Q31
     134             :     }
     135             : 
     136         245 :     return IVAS_ERR_OK;
     137             : }
     138             : 
     139             : 
     140             : /*-----------------------------------------------------------------------------------------*
     141             :  * Function ivas_reverb_set_energies()
     142             :  *
     143             :  * Function gets the precalculated left/right energies and computes average
     144             :  * left/right energies to CLDFB bin center frequencies.
     145             :  *-----------------------------------------------------------------------------------------*/
     146             : 
     147         245 : static void ivas_reverb_set_energies(
     148             :     const Word32 *avg_pwr_l,
     149             :     const Word32 *avg_pwr_r,
     150             :     const Word32 sampling_rate,
     151             :     Word32 *avg_pwr_left,
     152             :     Word32 *avg_pwr_right )
     153             : {
     154             :     Word16 freq_idx;
     155             :     Word32 input_fc_fx[FFT_SPECTRUM_SIZE];
     156             :     Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX];
     157             :     Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX];  // Q28
     158             :     Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; // Q28
     159         245 :     const Word32 cldfb_band_width = 26214400;       // 400 in Q16
     160             :     Word16 s;
     161             :     Word16 temp;
     162             : 
     163         245 :     const Word16 avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC;
     164         245 :     temp = BASOP_Util_Divide3216_Scale( sampling_rate, sub( avg_pwr_len, 1 ), &s );
     165             : 
     166       50794 :     FOR( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ )
     167             :     {
     168       50549 :         input_fc_fx[freq_idx] = L_shl( L_mult( temp, freq_idx ), add( 15, s ) );
     169             :     }
     170             : 
     171       14945 :     FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ )
     172             :     {
     173       14700 :         output_fc_fx[freq_idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, freq_idx ), 15 ) );
     174             :     }
     175             : 
     176             :     // Avg Energy Left
     177         245 :     ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_l, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx );
     178             :     // Avg Energy Right
     179         245 :     ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_r, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_right_fx );
     180             : 
     181       14945 :     FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ )
     182             :     {
     183       14700 :         avg_pwr_left[freq_idx] = avg_pwr_left_fx[freq_idx];
     184       14700 :         avg_pwr_right[freq_idx] = avg_pwr_right_fx[freq_idx];
     185             :     }
     186         245 : }

Generated by: LCOV version 1.14