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 <assert.h>
38 :
39 : #include <stdint.h>
40 : #include "options.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include <math.h>
45 : #include "cnst.h"
46 : #include "prot.h"
47 : #include "basop_util.h"
48 : #include "wmc_auto.h"
49 :
50 :
51 : /*-----------------------------------------------------------------*
52 : * Pitch prediction for frame erasure using linear fitting *
53 : *-----------------------------------------------------------------*/
54 :
55 40527 : void pitch_pred_linear_fit(
56 : const int16_t nbLostCmpt, /* i : bfi counter */
57 : const int16_t last_good, /* i : last classification type */
58 : float *old_pitch_buf, /* i : pitch lag buffer */
59 : float *old_fpitch, /* i : */
60 : float *T0_out, /* o : estimated close loop pitch */
61 : const int16_t pit_min, /* i : Minimum pitch lag */
62 : const int16_t pit_max, /* i : Maximum pitch lag */
63 : float *mem_pitch_gain, /* i : pitch gain [0] is the most recent subfr gain */
64 : const int16_t limitation,
65 : const int16_t plc_use_future_lag, /* i : */
66 : int16_t *extrapolationFailed, /* o : flag if extrap decides not to change the pitch*/
67 : const int16_t nb_subfr /* i : number of ACELP subframes */
68 : )
69 : {
70 40527 : float T0 = 0;
71 : float mdy, dy[5], ftmp;
72 40527 : int16_t lcor = 5;
73 : int16_t imax, i;
74 : float pg[8], ml[8]; /* local buffer for pitch gain and mem_lag*/
75 : int16_t no_subfr_pred;
76 : float mem_lag[2 * NB_SUBFR16k + 2];
77 :
78 :
79 40527 : if ( nb_subfr == 4 )
80 : {
81 151767 : for ( i = 0; i < 2 * NB_SUBFR + 2; i++ )
82 : {
83 137970 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR + 1 - i];
84 : }
85 : }
86 : else /* L_frame == L_FRAME16k */
87 : {
88 347490 : for ( i = 0; i < 2 * NB_SUBFR16k + 2; i++ )
89 : {
90 320760 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR16k + 1 - i];
91 : }
92 : }
93 :
94 40527 : if ( (int16_t) *old_fpitch > pit_max )
95 : {
96 0 : *extrapolationFailed = 1;
97 0 : *T0_out = pit_max;
98 0 : printf( "\n WARNING: *old_fpitch > pit_max : old_fpitch = %f, pit_max = %i \n\n", *old_fpitch, pit_max );
99 0 : return;
100 : }
101 :
102 40527 : if ( nbLostCmpt == 1 && last_good >= UNVOICED_TRANSITION && last_good < ONSET )
103 : {
104 16872 : if ( plc_use_future_lag )
105 : {
106 8055 : no_subfr_pred = 2;
107 : }
108 : else
109 : {
110 8817 : no_subfr_pred = 4;
111 : }
112 :
113 : /* copy to local buffers, depending on availability of info about future subframes */
114 16872 : mvr2r( mem_pitch_gain + no_subfr_pred - 2, pg, 8 );
115 16872 : mvr2r( mem_lag + no_subfr_pred - 2, ml, 8 );
116 :
117 16872 : mdy = 0.0f;
118 101232 : for ( i = ( lcor - 1 ); i >= 0; i-- )
119 : {
120 84360 : dy[i] = ( ml[i] - ml[i + 1] );
121 84360 : mdy += dy[i];
122 : }
123 :
124 : /*---------------------------------------------------*
125 : * remove maximum variation
126 : *---------------------------------------------------*/
127 16872 : ftmp = (float) fabs( dy[0] );
128 16872 : imax = 0;
129 84360 : for ( i = 1; i < lcor; i++ )
130 : {
131 67488 : if ( ftmp < (float) fabs( dy[i] ) )
132 : {
133 14535 : ftmp = (float) fabs( dy[i] );
134 14535 : imax = i;
135 : }
136 : }
137 16872 : if ( ( fabs( dy[imax] ) < 0.15f * *old_fpitch ) && ( ( limitation == 1 ) || ( fabs( dy[imax] ) < fabs( mdy ) ) ) )
138 8025 : {
139 : Word16 pg_fx[5];
140 : Word32 ml_fx[5];
141 : Word32 pit, a, b, pita, pitb;
142 : Word16 sum0;
143 8025 : Word16 const timeWeight[5] = { 20480 /*1.25f Q14*/, 18432 /*1.125f Q14*/, 16384 /*1.f Q14*/, 14336 /*0.875f Q14*/, 12288 /*.75f Q14*/ }; /*Q14*/
144 : Word16 a1, a2, a3, a4, a5, tmpa, tmpb, b1, b2, b3, b4, b5;
145 : Word16 a_e, b_e, sum0_q;
146 :
147 : /* convert gains and lags to fixed precision */
148 48150 : for ( i = 0; i < lcor; i++ )
149 : {
150 40125 : pg_fx[i] = (int16_t) ( pg[i] / pow( 2.f, -15 + 1 ) ); /* Q14 */
151 40125 : ml_fx[i] = (int32_t) ( ml[i] / pow( 2.f, -31 + 15 ) ); /* Q16 */
152 : }
153 :
154 : #define WMC_TOOL_SKIP
155 48150 : FOR( i = 0; i < lcor; i++ )
156 : {
157 40125 : pg_fx[i] = mult( mult( pg_fx[i], pg_fx[i] ), timeWeight[i] ); /*Q12 'til pg[lcor-1], Q14 'til pg[8]*/
158 40125 : move16();
159 : }
160 :
161 : /* Linear prediction (estimation) of pitch */
162 : /* sum0=(pg[1]+4*pg[2]+9*pg[3]+16*pg[4])*pg[0]+(pg[2]+4*pg[3]+9*pg[4])*pg[1]+(pg[3]+4*pg[4])*pg[2]+pg[4]*pg[3];*/
163 : {
164 : Word32 t1, t2, t3, t4, t5, t6, t7;
165 : Word16 e1, e2, e3, e4, e5, e6, e7;
166 : #ifdef BASOP_NOGLOB
167 : Flag Overflow;
168 : #endif
169 8025 : t1 = L_mult0( pg_fx[4], pg_fx[3] ); /*Q24*/ /* t1 = pg[4]*pg[3] */
170 8025 : e1 = 7;
171 8025 : t2 = L_add( L_deposit_l( pg_fx[3] ), L_shl( L_deposit_l( pg_fx[4] ), 2 ) ); /*Q12*/
172 8025 : e2 = norm_l( t2 );
173 8025 : t2 = L_shl( t2, e2 ); /*Q12,-e2*/
174 8025 : t2 = Mpy_32_16_1( t2, pg_fx[2] ); /*Q9,-e2*/ /* t2 = (pg[3]+4*pg[4])*pg[2] */
175 8025 : e2 = sub( 22, e2 );
176 8025 : t3 = L_add( L_deposit_l( pg_fx[2] ), L_add( L_shl( L_deposit_l( pg_fx[3] ), 2 ), L_add( L_shl( L_deposit_l( pg_fx[4] ), 3 ), L_deposit_l( pg_fx[4] ) ) ) ); /*Q12*/
177 8025 : e3 = norm_l( t3 );
178 8025 : t3 = L_shl( t3, e3 ); /*Q12,-e3*/
179 8025 : t3 = Mpy_32_16_1( t3, pg_fx[1] ); /*Q9,-e3*/ /* t3 = (pg[2]+4*pg[3]+9*pg[4])*pg[1] */
180 8025 : e3 = sub( 22, e3 );
181 8025 : t4 = L_add( pg_fx[1], L_add( L_shl( L_deposit_l( pg_fx[2] ), 2 ), L_add( L_add( L_shl( L_deposit_l( pg_fx[3] ), 3 ), L_deposit_l( pg_fx[3] ) ), L_shl( L_deposit_l( pg_fx[4] ), 4 ) ) ) ); /*Q12*/
182 8025 : e4 = norm_l( t4 );
183 8025 : t4 = L_shl( t4, e4 ); /*Q12,-e4*/
184 8025 : t4 = Mpy_32_16_1( t4, pg_fx[0] ); /*Q9,-e4*/ /* t4 = (pg[1]+4*pg[2]+9*pg[3]+16*pg[4])*pg[0] */
185 8025 : e4 = sub( 22, e4 );
186 8025 : t5 = BASOP_Util_Add_Mant32Exp( t1, e1, t2, e2, &e5 );
187 8025 : t6 = BASOP_Util_Add_Mant32Exp( t3, e3, t4, e4, &e6 );
188 8025 : t7 = BASOP_Util_Add_Mant32Exp( t5, e5, t6, e6, &e7 ); /*Q31,e7*/
189 8025 : sum0_q = norm_l( t7 );
190 : #ifdef BASOP_NOGLOB
191 8025 : sum0 = round_fx_o( L_shl( t7, sum0_q ), &Overflow ); /*Q15,e7-sum0_q*/
192 : #else
193 : sum0 = round_fx( L_shl( t7, sum0_q ) ); /*Q15,e7-sum0_q*/
194 : #endif
195 8025 : sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/
196 : }
197 :
198 8025 : pit = 0;
199 8025 : move16();
200 8025 : IF( sum0 != 0 )
201 : {
202 : /* Shift to the right, changing Q as long as no precision is lost */
203 11682 : WHILE( s_and( sum0, 1 ) == 0 )
204 : {
205 4758 : sum0 = shr( sum0, 1 );
206 4758 : sum0_q = sub( sum0_q, 1 );
207 : }
208 :
209 : /* float:
210 : a=-(
211 : ( 3*pg[1]+4*pg[2]+3*pg[3])*pg[0] */
212 : /*a1*/ /*
213 : *ml[0] +(
214 : ( 2*pg[2]+2*pg[3])*pg[1]-4*pg[1]*pg[0] */
215 : /*a2*/ /*
216 : )*ml[1] +(
217 : - 8*pg[2]*pg[0]-3*pg[2]*pg[1]+pg[3]*pg[2] */
218 : /*a3*/ /*
219 : )*ml[2] +(
220 : -12*pg[3]*pg[0]-6*pg[3]*pg[1]-2*pg[3]*pg[2] */
221 : /*a4*/ /*
222 : )*ml[3] +(
223 : -16*pg[4]*pg[0] -9*pg[4]*pg[1] -4*pg[4]*pg[2] -pg[4]*pg[3] */
224 : /*a5*/ /*
225 : )*ml[4] ) /sum0; MAC(19);MULT(9);DIV(1);*/
226 :
227 : /*magic numbers: Q11 if not DIRECTLY marked otherwise*/
228 6924 : a5 = mac_r( L_mac( L_mac( L_mult( mult_r( -32768, pg_fx[0] ) /*Q8*/, pg_fx[4] ) /*Q5+16*/, mult_r( -9 * 2048, pg_fx[1] ) /*Q8*/, pg_fx[4] /*Q12*/ ) /*Q5+16*/, mult_r( -4 * 2048, pg_fx[2] ) /*Q8*/, pg_fx[4] /*Q12*/ ) /*Q5+16*/, mult_r( pg_fx[4], -4096 /*Q12->Q9*/ ), mult_r( pg_fx[3], 16384 /*Q12->Q11*/ ) ) /*Q5*/;
229 6924 : a4 = mac_r( L_mac( L_mult( mult_r( -12 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[3] /*Q12*/ ) /*Q5+16*/, mult_r( -6 * 2048, pg_fx[1] ) /*Q8*/, pg_fx[3] /*Q12*/ ) /*Q5+16*/, mult_r( -2 * 2048, pg_fx[2] ) /*Q8*/, pg_fx[3] /*Q12*/ ) /*Q5*/;
230 6924 : a3 = mac_r( L_mac( L_mult( mult_r( -8 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[2] ), mult_r( -3 * 2048, pg_fx[1] ) /*Q8*/, pg_fx[2] ), mult_r( pg_fx[2], 4096 /*Q12->Q9*/ ), mult_r( pg_fx[3], 16384 /*12->Q11*/ ) ); /*Q5*/
231 6924 : a2 = mac_r( L_mac( L_mult( mult_r( 2 * 2048, pg_fx[1] ) /*Q8*/, pg_fx[2] ) /*Q5+16*/, mult_r( 2 * 2048, pg_fx[1] ) /*Q8*/, pg_fx[3] ) /*Q5+16*/, mult_r( -4 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[1] /*Q12*/ ) /*Q5*/;
232 6924 : a1 = mac_r( L_mac( L_mult( mult_r( 3 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[1] ) /*Q5+16*/, mult_r( 4 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[2] /*Q12*/ ) /*Q5+16*/, mult_r( 3 * 2048, pg_fx[0] ) /*Q8*/, pg_fx[3] /*Q12*/ ) /*Q5*/;
233 :
234 6924 : a = L_mac( L_mac( L_mac( L_mac( L_mult( a1, round_fx( L_shl( ml_fx[0], 4 ) ) ), /*Q4*/
235 6924 : round_fx( L_shl( ml_fx[1], 4 ) ) /*Q4*/, a2 ),
236 6924 : round_fx( L_shl( ml_fx[2], 4 ) ) /*Q4*/, a3 ),
237 6924 : round_fx( L_shl( ml_fx[3], 4 ) ) /*Q4*/, a4 ),
238 6924 : round_fx( L_shl( ml_fx[4], 4 ) ) /*Q4*/, a5 ); /*Q-6+16 = Q10*/
239 :
240 6924 : a_e = norm_l( a );
241 6924 : a = L_shl( a, a_e );
242 :
243 6924 : a1 = BASOP_Util_Divide3216_Scale( L_negate( a ), /* Numerator */ /*scalefactor 21*/
244 : sum0, /* Denominator*/ /*scalefactor 10*/
245 : &tmpa ); /* scalefactor for result */
246 :
247 : /* Float:
248 : b=(( pg[1]+2*pg[2]+3*pg[3]+4*pg[4])*pg[0] */
249 : /*b1*/ /*
250 : *ml[0] +
251 : (( pg[2]+2*pg[3]+3*pg[4])*pg[1]-pg[1]*pg[0]) */
252 : /*b2*/ /*
253 : *ml[1] +
254 : ( -2*pg[2]*pg[0]-pg[2]*pg[1]+(pg[3]+2*pg[4])*pg[2]) */
255 : /*b3*/ /*
256 : *ml[2] +
257 : ( -3*pg[3]*pg[0]-2*pg[3]*pg[1]-pg[3]*pg[2]+pg[4]*pg[3]) */
258 : /*b4*/ /*
259 : *ml[3] +
260 : ( -4*pg[4]*pg[0]-3*pg[4]*pg[1]-2*pg[4]*pg[2]-pg[4]*pg[3]) */
261 : /*b5*/ /*
262 : *ml[4] )/sum0; MAC(22);MULT(9);DIV(1);*/
263 :
264 : /*magic numbers in Q13 if not DIRECTLY marked otherwise*/
265 6924 : b1 = mac_r( L_mac( L_mac( L_mult( mult_r( pg_fx[1], pg_fx[0] ), 32768 / 4 ) /*Q7+16*/, mult_r( 2 * 8192, pg_fx[0] ) /*Q10*/, pg_fx[2] /*Q12*/ ) /*Q7+16*/, mult_r( 3 * 8192, pg_fx[0] ) /*Q10*/, pg_fx[3] /*Q12*/ ) /*Q7+16*/, /*mult_r(4*8192,pg_fx[0])*/ pg_fx[0] /*Q10*/, pg_fx[4] /*Q12*/ ) /*Q7*/;
266 6924 : b2 = mac_r( L_mac( L_mac( L_mult( mult_r( pg_fx[2], pg_fx[1] ), 32768 / 4 ) /*Q7+16*/, mult_r( 2 * 8192, pg_fx[1] ), pg_fx[3] ), mult_r( 3 * 8192, pg_fx[1] ), pg_fx[4] ) /*Q7+16*/, mult_r( pg_fx[1], -32768 / 2 /*Q12->Q12*/ ), mult_r( pg_fx[0], 32768 / 2 /*Q12->Q10*/ ) ) /*Q7*/;
267 6924 : b3 = mac_r( L_mac( L_mac( L_mult( mult_r( -2 * 8192, pg_fx[0] ), pg_fx[2] ) /*Q7+16*/, mult_r( pg_fx[2], -32768 / 2 ), mult_r( pg_fx[1], 32768 / 2 ) ), mult_r( pg_fx[3], 32768 / 2 ), mult_r( pg_fx[2], 32768 / 2 ) ) /*Q5+16*/, mult_r( 2 * 8192, pg_fx[2] ), pg_fx[4] ) /*Q7*/;
268 6924 : b4 = mac_r( L_mac( L_mac( L_mult( mult_r( -3 * 8192, pg_fx[0] ), pg_fx[3] ), mult_r( -2 * 8192, pg_fx[1] ), pg_fx[3] ), mult_r( -32768 / 2, pg_fx[3] ), mult_r( 32768 / 2, pg_fx[2] ) ), mult_r( 32768 / 2, pg_fx[4] ), mult_r( 32768 / 2, pg_fx[3] ) ); /*Q7*/
269 6924 : b5 = mac_r( L_mac( L_mac( L_mult( mult_r( -32768 /*(-4*8192)*/, pg_fx[0] ), pg_fx[4] ), mult_r( -3 * 8192, pg_fx[1] ), pg_fx[4] ), mult_r( -2 * 8192, pg_fx[2] ), pg_fx[4] ), mult_r( -32768 / 2, pg_fx[4] ), mult_r( 32768 / 2, pg_fx[3] ) ) /*Q7*/;
270 :
271 6924 : b = L_mac( L_mac( L_mac( L_mac( L_mult( b1, round_fx( L_shl( ml_fx[0], 4 ) ) ), /*Q4*/
272 6924 : round_fx( L_shl( ml_fx[1], 4 ) ) /*Q4*/, b2 ),
273 6924 : round_fx( L_shl( ml_fx[2], 4 ) ) /*Q4*/, b3 ),
274 6924 : round_fx( L_shl( ml_fx[3], 4 ) ) /*Q4*/, b4 ),
275 6924 : round_fx( L_shl( ml_fx[4], 4 ) ) /*Q4*/, b5 ); /*Q-4+16 = Q12*/
276 : /*predict pitch for 4th future subframe*/
277 :
278 6924 : b_e = norm_l( b );
279 6924 : b = L_shl( b, b_e );
280 :
281 6924 : b1 = BASOP_Util_Divide3216_Scale( b, /* Numerator */ /*scalefactor 19*/
282 : sum0, /* Denominator*/ /*scalefactor 10*/
283 : &tmpb ); /* scalefactor for result*/
284 :
285 : /*pit = a + b * ((float)no_subfr_pred + (float)nb_subfr);*/
286 6924 : pita = L_shl( L_deposit_l( a1 ), add( add( sum0_q, 16 - 10 + 1 ), sub( tmpa, a_e ) ) ) /*Q16*/;
287 6924 : pitb = L_shl_r( L_mult( b1 /*Q15*/, add( no_subfr_pred, nb_subfr ) /*Q0*/ ), add( add( sum0_q, 16 - 12 ), sub( tmpb, b_e ) ) );
288 6924 : pit = L_add( pita, pitb ); /*Q16*/
289 : #undef WMC_TOOL_SKIP
290 :
291 : /* convert pitch back to float precision */
292 6924 : T0 = (float) ( pit * pow( 2.f, -31 + 15 ) );
293 :
294 : /*limit pitch to allowed range*/
295 6924 : if ( T0 > pit_max )
296 : {
297 36 : T0 = (float) pit_max;
298 : }
299 :
300 6924 : if ( T0 < pit_min )
301 : {
302 21 : T0 = (float) pit_min;
303 : }
304 :
305 6924 : *extrapolationFailed = 0;
306 : }
307 : else
308 : {
309 1101 : T0 = 0;
310 1101 : *extrapolationFailed = 1;
311 : }
312 : }
313 : else
314 : {
315 8847 : T0 = 0;
316 8847 : *extrapolationFailed = 1;
317 : }
318 : }
319 : else
320 : {
321 23655 : T0 = *old_fpitch;
322 23655 : *extrapolationFailed = 1;
323 : }
324 :
325 40527 : *T0_out = T0;
326 :
327 40527 : return;
328 : }
329 :
330 :
331 3738 : void get_subframe_pitch(
332 : const int16_t nSubframes, /* i : number of subframes */
333 : float pitchStart, /* i : starting pitch lag (in subframe -1) */
334 : float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */
335 : float *pitchBuf /* o : interpolated pitch lag per subframe */
336 : )
337 : {
338 : int16_t i;
339 : float pitchDelta;
340 :
341 3738 : assert( ( nSubframes > 0 ) && ( pitchBuf != NULL ) && ( pitchStart >= 0 ) && ( pitchEnd > 0 ) );
342 :
343 3738 : pitchDelta = ( pitchEnd - pitchStart ) / nSubframes;
344 3738 : pitchBuf[0] = pitchStart + pitchDelta;
345 16644 : for ( i = 1; i < nSubframes; i++ )
346 : {
347 12906 : pitchBuf[i] = pitchBuf[i - 1] + pitchDelta;
348 : }
349 :
350 3738 : return;
351 : }
|