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 27303105 : 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 27303105 : temp = 0.0f;
66 573365205 : for ( i = 0; i < LONG_H_ST; i++ )
67 : {
68 546062100 : temp += h[i] * h[i];
69 : }
70 27303105 : acf0 = temp;
71 :
72 27303105 : temp = 0.0f;
73 27303105 : ptrs = h;
74 546062100 : for ( i = 0; i < LONG_H_ST - 1; i++ )
75 : {
76 518758995 : temp2 = *ptrs++;
77 518758995 : temp += temp2 * ( *ptrs );
78 : }
79 27303105 : acf1 = temp;
80 :
81 : /* Initialisation of the calculation */
82 27303105 : if ( acf0 == 0.0f )
83 : {
84 0 : *rc0 = 0.0f;
85 0 : return;
86 : }
87 :
88 : /* Compute 1st parcor */
89 27303105 : if ( acf0 < (float) fabs( acf1 ) )
90 : {
91 0 : *rc0 = 0.0f;
92 0 : return;
93 : }
94 27303105 : *rc0 = -acf1 / acf0;
95 :
96 27303105 : 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 27303105 : 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 27303105 : if ( extl == SWB_TBE )
125 : {
126 11969464 : syn_filt( apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 );
127 : }
128 : else
129 : {
130 15333641 : syn_filt( apond1, M, apond2, h, LONG_H_ST, mem_zero, 0 );
131 : }
132 :
133 : /* compute 1st parcor */
134 27303105 : calc_rc0_h( h, parcor0 );
135 :
136 : /* compute g0 */
137 27303105 : g0 = 0.0f;
138 573365205 : for ( i = 0; i < LONG_H_ST; i++ )
139 : {
140 546062100 : g0 += (float) fabs( h[i] );
141 : }
142 :
143 : /* Scale signal input of 1/A(gamma1) */
144 27303105 : if ( g0 > 1.0f )
145 : {
146 19097149 : temp = 1.0f / g0;
147 :
148 1432826109 : for ( i = 0; i < L_subfr; i++ )
149 : {
150 1413728960 : sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
151 : }
152 : }
153 :
154 27303105 : 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 27303105 : 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 27303105 : if ( extl == SWB_TBE )
178 : {
179 11969464 : if ( parcor0 > 0.0f )
180 : {
181 9647632 : mu = parcor0 * GAMMA3_PLUS_WB;
182 : }
183 : else
184 : {
185 2321832 : mu = parcor0 * GAMMA3_MINUS_WB;
186 : }
187 : }
188 : else
189 : {
190 15333641 : if ( parcor0 > 0.0f )
191 : {
192 882703 : mu = parcor0 * GAMMA3_PLUS;
193 : }
194 : else
195 : {
196 14450938 : mu = parcor0 * GAMMA3_MINUS;
197 : }
198 : }
199 :
200 27303105 : ga = (float) 1. / ( (float) 1. - (float) fabs( mu ) );
201 :
202 27303105 : ptrs = sig_in; /* points on sig_in(-1) */
203 :
204 1966213249 : for ( n = 0; n < L_subfr; n++ )
205 : {
206 1938910144 : temp = mu * ( *ptrs++ );
207 1938910144 : temp += ( *ptrs );
208 1938910144 : sig_out[n] = ga * temp;
209 : }
210 :
211 27303105 : 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 27318016 : 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 27318016 : float agc_fac1_para = 0.0f;
234 27318016 : float agc_fac_para = 0.0f;
235 :
236 27318016 : if ( extl == SWB_TBE )
237 : {
238 11969464 : agc_fac1_para = AGC_FAC1_WB;
239 11969464 : agc_fac_para = AGC_FAC_WB;
240 : }
241 : else
242 : {
243 15348552 : agc_fac1_para = AGC_FAC1;
244 15348552 : agc_fac_para = AGC_FAC;
245 : }
246 :
247 : /* compute input gain */
248 27318016 : gain_in = 0.0f;
249 1967432960 : for ( i = 0; i < L_subfr; i++ )
250 : {
251 1940114944 : gain_in += (float) fabs( sig_in[i] );
252 : }
253 :
254 27318016 : if ( gain_in == 0.0f )
255 : {
256 1256948 : g0 = 0.0f;
257 : }
258 : else
259 : {
260 : /* Compute output gain */
261 26061068 : gain_out = 0.0f;
262 1885721228 : for ( i = 0; i < L_subfr; i++ )
263 : {
264 1859660160 : gain_out += (float) fabs( sig_out[i] );
265 : }
266 :
267 26061068 : if ( gain_out == 0.0f )
268 : {
269 0 : *gain_prec = 0.0f;
270 0 : return;
271 : }
272 :
273 26061068 : g0 = gain_in / gain_out;
274 26061068 : 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 27318016 : gain = *gain_prec;
280 1967432960 : for ( i = 0; i < L_subfr; i++ )
281 : {
282 1940114944 : gain *= agc_fac_para;
283 1940114944 : gain += g0;
284 1940114944 : sig_out[i] *= gain;
285 : }
286 :
287 27318016 : *gain_prec = gain;
288 :
289 27318016 : return;
290 : }
291 :
292 14911 : void blend_subfr2(
293 : float *sigIn1,
294 : float *sigIn2,
295 : float *sigOut )
296 : {
297 14911 : float fac1 = 1.f - ( 1.f / L_SUBFR );
298 14911 : float fac2 = 0.f + ( 1.f / L_SUBFR );
299 14911 : float step = 1.f / ( L_SUBFR / 2 );
300 : int16_t i;
301 :
302 492063 : for ( i = 0; i < L_SUBFR / 2; i++ )
303 : {
304 477152 : sigOut[i] = fac1 * sigIn1[i] + fac2 * sigIn2[i];
305 477152 : fac1 -= step;
306 477152 : fac2 += step;
307 : }
308 :
309 14911 : return;
310 : }
|