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 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include <math.h>
40 : #include "prot.h"
41 : #include "rom_enc.h"
42 : #include "wmc_auto.h"
43 :
44 :
45 : /*-------------------------------------------------------------------*
46 : * SNR_calc()
47 : *
48 : *
49 : *-------------------------------------------------------------------*/
50 :
51 3100 : void SNR_calc(
52 : const float frame_sb_energy[], /* i : energy of sub-band divided non-uniformly */
53 : const float sb_bg_energy[], /* i : sub-band background energy */
54 : const float t_bg_energy, /* i : time background energy of several frames */
55 : float *snr, /* o : frequency domain SNR */
56 : float *tsnr, /* o : time domain SNR */
57 : const float frame_energy, /* i : current frame energy */
58 : const int16_t bwidth /* i : audio band width */
59 : )
60 : {
61 : int16_t i;
62 : float snr_tmp, tmp;
63 : int16_t SNR_sb_num;
64 3100 : SNR_sb_num = ENERGY_BAND_NUM[bwidth - CLDFBVAD_NB_ID];
65 :
66 3100 : snr_tmp = 0;
67 40300 : for ( i = 0; i < SNR_sb_num; i++ )
68 : {
69 37200 : tmp = ( frame_sb_energy[i] + 0.0001f ) / ( sb_bg_energy[i] + 0.0001f );
70 37200 : tmp = (float) log10( tmp );
71 37200 : if ( tmp > -0.1 )
72 : {
73 29880 : if ( bwidth == CLDFBVAD_SWB_ID )
74 : {
75 29880 : tmp = tmp * 3.2f;
76 : }
77 0 : else if ( bwidth == CLDFBVAD_WB_ID )
78 : {
79 0 : tmp = tmp * 3.31f;
80 : }
81 : else
82 : {
83 0 : tmp = tmp * 3.0f;
84 : }
85 29880 : snr_tmp += tmp;
86 : }
87 : }
88 3100 : if ( snr_tmp < 0 )
89 : {
90 18 : snr_tmp = 0;
91 : }
92 3100 : *snr = snr_tmp / SNR_sb_num;
93 3100 : tmp = ( frame_energy + 0.0001f ) / ( t_bg_energy + 0.0001f );
94 3100 : tmp = (float) log10( tmp );
95 3100 : *tsnr = tmp * 3.0f;
96 3100 : if ( bwidth == CLDFBVAD_SWB_ID )
97 : {
98 3100 : tmp = ( frame_energy ) / ( t_bg_energy + FLT_MIN );
99 3100 : tmp = (float) log10( tmp + FLT_MIN );
100 3100 : *tsnr = tmp * 2.8f;
101 : }
102 :
103 3100 : return;
104 : }
105 :
106 :
107 : /*-------------------------------------------------------------------*
108 : * calc_snr_flux()
109 : *
110 : *
111 : *-------------------------------------------------------------------*/
112 :
113 3100 : void calc_snr_flux(
114 : float tsnr, /* i : time-domain SNR */
115 : float pre_snr[], /* i/o: time-domain SNR storage */
116 : float *snr_flux /* o : average tsnr */
117 : )
118 : {
119 : int16_t i;
120 3100 : float snr_sum = 0.0f;
121 :
122 3100 : if ( tsnr < 2.6f && tsnr > 0 )
123 : {
124 107 : pre_snr[0] = tsnr;
125 : }
126 2993 : else if ( tsnr <= 0 )
127 : {
128 110 : pre_snr[0] = 0;
129 : }
130 : else
131 : {
132 2883 : pre_snr[0] = 2.6f;
133 : }
134 :
135 3100 : snr_sum = 0;
136 102300 : for ( i = 0; i < PRE_SNR_NUM; i++ )
137 : {
138 99200 : snr_sum += pre_snr[i];
139 : }
140 3100 : *snr_flux = snr_sum / PRE_SNR_NUM;
141 99200 : for ( i = PRE_SNR_NUM - 1; i > 0; i-- )
142 : {
143 96100 : pre_snr[i] = pre_snr[i - 1];
144 : }
145 :
146 3100 : return;
147 : }
148 :
149 :
150 : /*-------------------------------------------------------------------*
151 : * calc_lt_snr()
152 : *
153 : *
154 : *-------------------------------------------------------------------*/
155 :
156 3100 : void calc_lt_snr(
157 : float *lt_snr_org, /* o : original long time SNR */
158 : float *lt_snr, /* o : long time SNR calculated by fg_energy and bg_energy */
159 : const float fg_energy, /* i : foreground energy sum */
160 : const int16_t fg_energy_count, /* i : number of the foreground energy frame */
161 : const float bg_energy, /* i : background energy sum */
162 : const int16_t bg_energy_count, /* i : number of the background energy frame */
163 : const int16_t bw_index, /* i : band width index */
164 : const float lt_noise_sp_center0 /* i : long time noise spectral center by 0 */
165 : )
166 : {
167 : float tmp_lt_noise_sp_center;
168 : float rtn_lt_snr;
169 :
170 3100 : const float offset = -0.00156247615814208984375f;
171 :
172 3100 : tmp_lt_noise_sp_center = lt_noise_sp_center0 - 1.4f;
173 3100 : if ( tmp_lt_noise_sp_center > 0.8 )
174 : {
175 0 : tmp_lt_noise_sp_center = 0.8f;
176 : }
177 3100 : if ( tmp_lt_noise_sp_center < 0 )
178 : {
179 54 : tmp_lt_noise_sp_center = 0.0f;
180 : }
181 3100 : rtn_lt_snr = (float) log10( ( fg_energy * bg_energy_count + FLT_MIN ) / ( bg_energy * fg_energy_count + FLT_MIN ) );
182 3100 : *lt_snr_org = rtn_lt_snr;
183 :
184 3100 : if ( bg_energy_count < 56 || fg_energy_count < 56 )
185 : {
186 3100 : rtn_lt_snr = 2.1f;
187 : }
188 :
189 3100 : if ( bw_index == CLDFBVAD_NB_ID )
190 : {
191 0 : rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.5f;
192 : }
193 3100 : else if ( bw_index == CLDFBVAD_WB_ID )
194 : {
195 0 : rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.50f;
196 : }
197 : else
198 : {
199 3100 : rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.46f;
200 : }
201 3100 : rtn_lt_snr = rtn_lt_snr + ( rtn_lt_snr * 0.4f + offset ) * tmp_lt_noise_sp_center * 0.4f;
202 3100 : if ( rtn_lt_snr < 0 )
203 : {
204 0 : rtn_lt_snr = 0.0f;
205 : }
206 :
207 3100 : if ( rtn_lt_snr > 2.0 )
208 : {
209 0 : rtn_lt_snr = 2.0f;
210 : }
211 :
212 3100 : *lt_snr = rtn_lt_snr;
213 :
214 3100 : return;
215 : }
216 :
217 :
218 : /*-------------------------------------------------------------------*
219 : * calc_lf_snr()
220 : *
221 : *
222 : *-------------------------------------------------------------------*/
223 :
224 3100 : void calc_lf_snr(
225 : float *lf_snr_smooth, /* o : smoothed lf_snr */
226 : float *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/
227 : const float l_speech_snr, /* i : sum of active frames snr */
228 : const int16_t l_speech_snr_count, /* i : number of the active frame */
229 : const float l_silence_snr, /* i : sum of the nonactive frames snr */
230 : const int16_t l_silence_snr_count, /* i : number of the nonactive frame */
231 : const int16_t fg_energy_count, /* i : number of the foreground energy frame */
232 : const int16_t bg_energy_count, /* i : number of the background energy frame */
233 : const int16_t bw_index /* i : band width index */
234 : )
235 : {
236 : float l_snr;
237 :
238 3100 : l_snr = l_speech_snr / l_speech_snr_count - l_silence_snr / l_silence_snr_count;
239 3100 : *lf_snr_smooth = *lf_snr_smooth * 0.9f + 0.1f * l_snr;
240 :
241 3100 : if ( bg_energy_count < 56 || fg_energy_count < 56 )
242 : {
243 3100 : l_snr = 4.8f;
244 : }
245 :
246 3100 : l_snr = ( l_snr - 3.0f ) * 0.12f;
247 :
248 3100 : if ( l_snr < 0 )
249 : {
250 0 : l_snr = 0;
251 : }
252 :
253 3100 : if ( l_snr > MAX_LF_SNR_TAB[bw_index] )
254 : {
255 0 : l_snr = MAX_LF_SNR_TAB[bw_index];
256 : }
257 :
258 3100 : *lf_snr = l_snr;
259 :
260 3100 : return;
261 : }
|