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 : }
|