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 "wmc_auto.h"
46 :
47 :
48 : /*----------------------------------------------------------------------------
49 : * calc_rc0_h()
50 : *
51 : * computes 1st parcor from composed filter impulse response
52 : *---------------------------------------------------------------------------*/
53 :
54 3959070 : static void calc_rc0_h(
55 : const float *h, /* i : impulse response of composed filter */
56 : float *rc0 /* o : 1st parcor */
57 : )
58 : {
59 : float acf0, acf1;
60 : float temp, temp2;
61 : const float *ptrs;
62 : int16_t i;
63 :
64 : /* computation of the autocorrelation function acf */
65 3959070 : temp = 0.0f;
66 83140470 : for ( i = 0; i < LONG_H_ST; i++ )
67 : {
68 79181400 : temp += h[i] * h[i];
69 : }
70 3959070 : acf0 = temp;
71 :
72 3959070 : temp = 0.0f;
73 3959070 : ptrs = h;
74 79181400 : for ( i = 0; i < LONG_H_ST - 1; i++ )
75 : {
76 75222330 : temp2 = *ptrs++;
77 75222330 : temp += temp2 * ( *ptrs );
78 : }
79 3959070 : acf1 = temp;
80 :
81 : /* Initialisation of the calculation */
82 3959070 : if ( acf0 == 0.0f )
83 : {
84 0 : *rc0 = 0.0f;
85 0 : return;
86 : }
87 :
88 : /* Compute 1st parcor */
89 3959070 : if ( acf0 < (float) fabs( acf1 ) )
90 : {
91 0 : *rc0 = 0.0f;
92 0 : return;
93 : }
94 3959070 : *rc0 = -acf1 / acf0;
95 :
96 3959070 : return;
97 : }
98 :
99 :
100 : /*----------------------------------------------------------------------------
101 : * calc_st_filt()
102 : *
103 : * computes impulse response of A(gamma2) / A(gamma1)
104 : * controls gain : computation of energy impulse response as
105 : * SUMn (abs (h[n])) and computes parcor0
106 : *---------------------------------------------------------------------------- */
107 :
108 3959070 : void calc_st_filt(
109 : const float *apond2, /* i : coefficients of numerator */
110 : const float *apond1, /* i : coefficients of denominator */
111 : float *parcor0, /* o : 1st parcor calcul. on composed filter */
112 : float *sig_ltp_ptr, /* i/o: input of 1/A(gamma1) : scaled by 1/g0 */
113 : float *mem_zero, /* i/o: All zero memory */
114 : const int16_t L_subfr, /* i : the length of subframe */
115 : const int16_t extl /* i : extension layer info */
116 :
117 : )
118 : {
119 : float h[LONG_H_ST];
120 : float g0, temp;
121 : int16_t i;
122 :
123 : /* compute i.r. of composed filter apond2 / apond1 */
124 3959070 : if ( extl == SWB_TBE )
125 : {
126 1783092 : syn_filt( apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 );
127 : }
128 : else
129 : {
130 2175978 : syn_filt( apond1, M, apond2, h, LONG_H_ST, mem_zero, 0 );
131 : }
132 :
133 : /* compute 1st parcor */
134 3959070 : calc_rc0_h( h, parcor0 );
135 :
136 : /* compute g0 */
137 3959070 : g0 = 0.0f;
138 83140470 : for ( i = 0; i < LONG_H_ST; i++ )
139 : {
140 79181400 : g0 += (float) fabs( h[i] );
141 : }
142 :
143 : /* Scale signal input of 1/A(gamma1) */
144 3959070 : if ( g0 > 1.0f )
145 : {
146 2851863 : temp = 1.0f / g0;
147 :
148 213900567 : for ( i = 0; i < L_subfr; i++ )
149 : {
150 211048704 : sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
151 : }
152 : }
153 :
154 3959070 : return;
155 : }
156 :
157 :
158 : /*----------------------------------------------------------------------------
159 : * filt_mu()
160 : *
161 : * tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
162 : * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
163 : *---------------------------------------------------------------------------*/
164 :
165 3959070 : void filt_mu(
166 : const float *sig_in, /* i : signal (beginning at sample -1) */
167 : float *sig_out, /* o : output signal */
168 : const float parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */
169 : const int16_t L_subfr, /* i : the length of subframe */
170 : const int16_t extl /* i : extension layer info */
171 : )
172 : {
173 : int16_t n;
174 : float mu, ga, temp;
175 : const float *ptrs;
176 :
177 3959070 : if ( extl == SWB_TBE )
178 : {
179 1783092 : if ( parcor0 > 0.0f )
180 : {
181 1501912 : mu = parcor0 * GAMMA3_PLUS_WB;
182 : }
183 : else
184 : {
185 281180 : mu = parcor0 * GAMMA3_MINUS_WB;
186 : }
187 : }
188 : else
189 : {
190 2175978 : if ( parcor0 > 0.0f )
191 : {
192 166872 : mu = parcor0 * GAMMA3_PLUS;
193 : }
194 : else
195 : {
196 2009106 : mu = parcor0 * GAMMA3_MINUS;
197 : }
198 : }
199 :
200 3959070 : ga = (float) 1. / ( (float) 1. - (float) fabs( mu ) );
201 :
202 3959070 : ptrs = sig_in; /* points on sig_in(-1) */
203 :
204 285869022 : for ( n = 0; n < L_subfr; n++ )
205 : {
206 281909952 : temp = mu * ( *ptrs++ );
207 281909952 : temp += ( *ptrs );
208 281909952 : sig_out[n] = ga * temp;
209 : }
210 :
211 3959070 : return;
212 : }
213 :
214 :
215 : /*----------------------------------------------------------------------------
216 : * scale_st()
217 : *
218 : * control of the subframe gain
219 : * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
220 : *---------------------------------------------------------------------------*/
221 :
222 3963510 : void scale_st(
223 : const float *sig_in, /* i : postfilter input signal */
224 : float *sig_out, /* i/o: postfilter output signal */
225 : float *gain_prec, /* i/o: last value of gain for subframe */
226 : const int16_t L_subfr, /* i : the length of subframe */
227 : const int16_t extl /* i : extension layer info */
228 : )
229 : {
230 : int16_t i;
231 : float gain_in, gain_out;
232 : float g0, gain;
233 3963510 : float agc_fac1_para = 0.0f;
234 3963510 : float agc_fac_para = 0.0f;
235 :
236 3963510 : if ( extl == SWB_TBE )
237 : {
238 1783092 : agc_fac1_para = AGC_FAC1_WB;
239 1783092 : agc_fac_para = AGC_FAC_WB;
240 : }
241 : else
242 : {
243 2180418 : agc_fac1_para = AGC_FAC1;
244 2180418 : agc_fac_para = AGC_FAC;
245 : }
246 :
247 : /* compute input gain */
248 3963510 : gain_in = 0.0f;
249 286203702 : for ( i = 0; i < L_subfr; i++ )
250 : {
251 282240192 : gain_in += (float) fabs( sig_in[i] );
252 : }
253 :
254 3963510 : if ( gain_in == 0.0f )
255 : {
256 79899 : g0 = 0.0f;
257 : }
258 : else
259 : {
260 : /* Compute output gain */
261 3883611 : gain_out = 0.0f;
262 281010267 : for ( i = 0; i < L_subfr; i++ )
263 : {
264 277126656 : gain_out += (float) fabs( sig_out[i] );
265 : }
266 :
267 3883611 : if ( gain_out == 0.0f )
268 : {
269 0 : *gain_prec = 0.0f;
270 0 : return;
271 : }
272 :
273 3883611 : g0 = gain_in / gain_out;
274 3883611 : g0 *= agc_fac1_para;
275 : }
276 :
277 : /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
278 : /* sig_out(n) = gain(n) sig_out(n) */
279 3963510 : gain = *gain_prec;
280 286203702 : for ( i = 0; i < L_subfr; i++ )
281 : {
282 282240192 : gain *= agc_fac_para;
283 282240192 : gain += g0;
284 282240192 : sig_out[i] *= gain;
285 : }
286 :
287 3963510 : *gain_prec = gain;
288 :
289 3963510 : return;
290 : }
291 :
292 4440 : void blend_subfr2(
293 : float *sigIn1,
294 : float *sigIn2,
295 : float *sigOut )
296 : {
297 4440 : float fac1 = 1.f - ( 1.f / L_SUBFR );
298 4440 : float fac2 = 0.f + ( 1.f / L_SUBFR );
299 4440 : float step = 1.f / ( L_SUBFR / 2 );
300 : int16_t i;
301 :
302 146520 : for ( i = 0; i < L_SUBFR / 2; i++ )
303 : {
304 142080 : sigOut[i] = fac1 * sigIn1[i] + fac2 * sigIn2[i];
305 142080 : fac1 -= step;
306 142080 : fac2 += step;
307 : }
308 :
309 4440 : return;
310 : }
|