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 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "prot.h"
45 : #include "rom_com.h"
46 : #include "wmc_auto.h"
47 :
48 : /*---------------------------------------------------------------------*
49 : * Local function prototypes
50 : *---------------------------------------------------------------------*/
51 :
52 : static void hp400_12k8( float signal[], const int16_t lg, float mem[] );
53 : static void filt_6k_8k( float signal[], const int16_t lg, float mem[] );
54 :
55 :
56 : /*---------------------------------------------------------------------*
57 : * hf_cod_init()
58 : *
59 : *
60 : *---------------------------------------------------------------------*/
61 :
62 3 : void hf_cod_init(
63 : float *mem_hp400_enc, /* o : memory of hp 400 Hz filter */
64 : float *mem_hf1_enc, /* o : HF band-pass filter memory */
65 : float *mem_syn_hf_enc, /* o : HF synthesis memory */
66 : float *mem_hf2_enc, /* o : HF band-pass filter memory */
67 : float *gain_alpha /* o : smoothing gain for transitions between active and inactive frames */
68 : )
69 : {
70 3 : set_f( mem_hp400_enc, 0, 4 );
71 3 : set_f( mem_hf1_enc, 0, L_FIR - 1 );
72 3 : set_f( mem_syn_hf_enc, 0, M );
73 3 : set_f( mem_hf2_enc, 0, L_FIR - 1 );
74 3 : *gain_alpha = 1.0;
75 :
76 3 : return;
77 : }
78 :
79 :
80 : /*---------------------------------------------------------------------*
81 : * hf_cod()
82 : *
83 : *
84 : *---------------------------------------------------------------------*/
85 :
86 0 : void hf_cod(
87 : const int32_t core_brate, /* i : core bitrate */
88 : const float *speech16k, /* i : original speech at 16 kHz */
89 : const float Aq[], /* i : quantized Aq */
90 : const float exc[], /* i : excitation at 12.8 kHz */
91 : float synth[], /* i : 12.8kHz synthesis signal */
92 : int16_t *seed2_enc, /* i/o: random seed for HF noise gen */
93 : float *mem_hp400_enc, /* i/o: memory of hp 400 Hz filter */
94 : float *mem_syn_hf_enc, /* i/o: HF synthesis memory */
95 : float *mem_hf1_enc, /* i/o: HF band-pass filter memory */
96 : float *mem_hf2_enc, /* i/o: HF band-pass filter memory */
97 : const int16_t *dtxHangoverCount,
98 : float *gain_alpha, /* i/o: smoothing gain for transitions between active and inactive frames */
99 : int16_t *hf_gain /* o : HF gain to be transmitted to decoder */
100 : )
101 : {
102 : int16_t i;
103 : float ener_hf, ener_exc, ener_input, fac, HF_syn[L_SUBFR16k], tmp, ener, scale;
104 : float Ap[M16k + 1];
105 : float HF_SP[L_SUBFR16k];
106 : float HF_est_gain;
107 : float HF_calc_gain;
108 : float HF_corr_gain;
109 : int16_t HF_gain_ind;
110 : float dist_min, dist;
111 : float HF[L_SUBFR16k]; /* HF excitation */
112 :
113 : /* Original speech signal as reference for high band gain quantisation */
114 0 : for ( i = 0; i < L_SUBFR16k; i++ )
115 : {
116 0 : HF_SP[i] = speech16k[i];
117 : }
118 :
119 : /*-----------------------------------------------------------------*
120 : * generate white noise vector
121 : *-----------------------------------------------------------------*/
122 :
123 0 : for ( i = 0; i < L_SUBFR16k; i++ )
124 : {
125 0 : HF[i] = (float) own_random( seed2_enc );
126 : }
127 :
128 : /*-----------------------------------------------------------------*
129 : * calculate energy scaling factor so that white noise would have the
130 : * same energy as exc12k8
131 : *-----------------------------------------------------------------*/
132 :
133 0 : ener_exc = 0.01f;
134 0 : for ( i = 0; i < L_SUBFR; i++ )
135 : {
136 0 : ener_exc += exc[i] * exc[i];
137 : }
138 :
139 0 : ener_hf = 0.01f;
140 0 : for ( i = 0; i < L_SUBFR16k; i++ )
141 : {
142 0 : ener_hf += HF[i] * HF[i];
143 : }
144 :
145 0 : scale = (float) ( sqrt( ener_exc / ener_hf ) );
146 :
147 0 : for ( i = 0; i < L_SUBFR16k; i++ )
148 : {
149 0 : HF[i] *= scale;
150 : }
151 :
152 : /*-----------------------------------------------------------------*
153 : * calculate energy scaling factor to respect tilt of synth12k8
154 : * (tilt: 1=voiced, -1=unvoiced)
155 : *-----------------------------------------------------------------*/
156 :
157 0 : hp400_12k8( synth, L_SUBFR, mem_hp400_enc );
158 :
159 0 : ener = 0.001f;
160 0 : tmp = 0.001f;
161 0 : for ( i = 1; i < L_SUBFR; i++ )
162 : {
163 0 : ener += synth[i] * synth[i]; /* ener = r[0] */
164 0 : tmp += synth[i] * synth[i - 1]; /* tmp = r[1] */
165 : }
166 0 : fac = tmp / ener;
167 :
168 0 : HF_est_gain = (float) ( 1.0f - fac );
169 0 : if ( core_brate == SID_1k75 || core_brate == FRAME_NO_DATA )
170 : {
171 : /* emphasize HF noise in CNG */
172 0 : HF_est_gain *= 1.25f; /* full alignment with G.722 and AMR-WB */
173 : }
174 :
175 0 : if ( HF_est_gain < 0.1f )
176 : {
177 0 : HF_est_gain = 0.1f;
178 : }
179 :
180 0 : if ( HF_est_gain > 1.0f ) /* this condition is not in G.722.2, but in AMR-WB!*/
181 : {
182 0 : HF_est_gain = 1.0f;
183 : }
184 :
185 : /*-----------------------------------------------------------------*
186 : * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
187 : *-----------------------------------------------------------------*/
188 :
189 0 : weight_a( Aq, Ap, 0.6f, M );
190 0 : syn_filt( Ap, M, HF, HF_syn, L_SUBFR16k, mem_syn_hf_enc, 1 );
191 :
192 : /*-----------------------------------------------------------------*
193 : * high pass filtering (0.9375ms of delay = 15 samples@16k)
194 : *-----------------------------------------------------------------*/
195 :
196 0 : filt_6k_8k( HF_syn, L_SUBFR16k, mem_hf1_enc );
197 :
198 : /* filtering of the original signal */
199 0 : filt_6k_8k( HF_SP, L_SUBFR16k, mem_hf2_enc );
200 :
201 : /* check the gain difference */
202 0 : ener_input = 0.01f;
203 0 : ener_hf = 0.01f;
204 0 : for ( i = 0; i < L_SUBFR16k; i++ )
205 : {
206 0 : ener_input += HF_SP[i] * HF_SP[i];
207 0 : ener_hf += HF_syn[i] * HF_syn[i];
208 : }
209 :
210 0 : HF_calc_gain = (float) sqrt( ener_input / ener_hf );
211 :
212 : /* set energy of HF synthesis to energy of original HF:
213 : cross-fade between HF levels in active and inactive frame in hangover period */
214 :
215 0 : *gain_alpha *= (float) ( 10 - ( *dtxHangoverCount ) ) / 7.0f;
216 0 : if ( ( 10 - ( *dtxHangoverCount ) ) > 6 )
217 : {
218 0 : *gain_alpha = 1.0f;
219 : }
220 :
221 0 : HF_corr_gain = ( *gain_alpha ) * HF_calc_gain + ( 1.0f - ( *gain_alpha ) ) * HF_est_gain;
222 0 : HF_corr_gain /= 2.0f; /* to stay in aligned with AMR-WB legacy decoder where decoded gain is multiplied by 2 */
223 :
224 : /* Quantize the correction gain */
225 0 : dist_min = 100000.0f;
226 0 : HF_gain_ind = 0;
227 0 : for ( i = 0; i < 16; i++ )
228 : {
229 0 : dist = ( HF_corr_gain - HP_gain[i] ) * ( HF_corr_gain - HP_gain[i] );
230 0 : if ( dist_min > dist )
231 : {
232 0 : dist_min = dist;
233 0 : HF_gain_ind = i;
234 : }
235 : }
236 :
237 0 : *hf_gain = HF_gain_ind;
238 :
239 0 : return;
240 : }
241 :
242 : /*-----------------------------------------------------------------------*
243 : * Function hp400_12k8() *
244 : * *
245 : * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz. *
246 : * Optimized for fixed-point to get the following frequency response : *
247 : * *
248 : * frequency : 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz *
249 : * dB loss : -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB *
250 : * *
251 : * Algorithm : *
252 : * *
253 : * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
254 : * + a[1]*y[i-1] + a[2]*y[i-2]; *
255 : * *
256 : * short b[3] = {3660, -7320, 3660}; in Q12 *
257 : * short a[3] = {4096, 7320, -3540}; in Q12 *
258 : * *
259 : * float --> b[3] = {0.893554687, -1.787109375, 0.893554687}; *
260 : * a[3] = {1.000000000, 1.787109375, -0.864257812}; *
261 : *-----------------------------------------------------------------------*/
262 :
263 0 : static void hp400_12k8(
264 : float signal[], /* i/o: signal */
265 : const int16_t lg, /* i : length of signal */
266 : float mem[] /* i/o: filter memory [4] */
267 : )
268 : {
269 : int16_t i;
270 : float x0, x1, x2;
271 : float yy0, yy1, y2;
272 :
273 0 : yy1 = mem[0];
274 0 : y2 = mem[1];
275 0 : x0 = mem[2];
276 0 : x1 = mem[3];
277 0 : for ( i = 0; i < lg; i++ )
278 : {
279 0 : x2 = x1;
280 0 : x1 = x0;
281 0 : x0 = signal[i];
282 0 : yy0 = yy1 * a_hp400[1] + y2 * a_hp400[2] + x0 * b_hp400[0] + x1 * b_hp400[1] + x2 * b_hp400[2];
283 :
284 0 : signal[i] = yy0;
285 0 : y2 = yy1;
286 0 : yy1 = yy0;
287 : }
288 :
289 0 : mem[0] = yy1;
290 0 : mem[1] = y2;
291 0 : mem[2] = x0;
292 0 : mem[3] = x1;
293 :
294 0 : return;
295 : }
296 :
297 : /*-------------------------------------------------------------------*
298 : * filt_6k_7k:
299 : *
300 : * 15th order band pass 6kHz to 7kHz FIR filter.
301 : *
302 : * frequency :4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz
303 : * dB loss : -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB
304 : * (gain=4.0)
305 : *-------------------------------------------------------------------*/
306 :
307 0 : static void filt_6k_8k(
308 : float signal[], /* i/o: signal */
309 : const int16_t lg, /* i : signal length */
310 : float mem[] /* i/o: filter memory */
311 : )
312 : {
313 : int16_t i, j;
314 : float s, x[L_FRAME48k / NB_SUBFR + ( L_FIR - 1 )];
315 :
316 0 : for ( i = 0; i < ( L_FIR - 1 ); i++ )
317 : {
318 0 : x[i] = mem[i];
319 : }
320 :
321 0 : for ( i = 0; i < lg; i++ )
322 : {
323 0 : x[i + ( L_FIR - 1 )] = signal[i];
324 : }
325 :
326 0 : for ( i = 0; i < lg; i++ )
327 : {
328 0 : s = 0.0;
329 0 : for ( j = 0; j < L_FIR; j++ )
330 : {
331 0 : s += x[i + j] * fir_6k_8k[j];
332 : }
333 :
334 0 : signal[i] = (float) ( s * 1.0f );
335 : }
336 :
337 0 : for ( i = 0; i < ( L_FIR - 1 ); i++ )
338 : {
339 0 : mem[i] = x[i + lg];
340 : }
341 :
342 0 : return;
343 : }
|