Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdint.h>
7 : #include <assert.h>
8 : #include "options.h"
9 : #include "cnst.h"
10 : #include "prot_fx.h"
11 : #include "basop_util.h"
12 :
13 : /*-------------------------------------------------------------------*
14 : * - num x 32768
15 : * ------------------- Q15
16 : * PIT_MAX x Fact
17 : *-------------------------------------------------------------------*/
18 :
19 : /*-----------------------------------------------------------------*
20 : * Pitch prediction for frame erasure using linear fitting *
21 : *-----------------------------------------------------------------*/
22 : /*port is up to date with trunk 38840*/
23 10646 : void pitch_pred_linear_fit(
24 : const Word16 /*short*/ bfi_cnt,
25 : /* i: bfi counter */ /*Q0 */
26 : const Word16 /*short*/ last_good,
27 : /* i: last classification type */ /*Q0 */
28 : Word32 /*Word32*/ *old_pitch_buf,
29 : /* i: pitch lag buffer */ /*Q16*/
30 : Word32 /*Word32*/ *old_fpitch,
31 : /* i: */ /*Q16*/
32 : Word32 /*Word32*/ *T0_out,
33 : /* o: estimated close loop pitch */ /*Q16*/
34 : Word16 /* int*/ pit_min,
35 : /* i: Minimum pitch lag */ /*Q0 */
36 : Word16 /* int*/ pit_max,
37 : /* i: Maximum pitch lag */ /*Q0 */
38 : Word16 /*Word16*/ *mem_pitch_gain,
39 : /* i: pitch gain [0] is the most recent subfr gain */ /*Q14*/
40 : Word16 /* int*/ limitation,
41 : Word16 /*short*/ plc_use_future_lag,
42 : /* i: */ /*Q0 */
43 : Word16 /*short*/ *extrapolationFailed,
44 : /* o: flag if extrap decides not to change the pitch */ /*Q0 */
45 : Word16 nb_subfr /* i: number of ACELP subframes*/
46 : )
47 : {
48 : Word32 pit, a, b, pita, pitb;
49 : Word16 sum0;
50 : Word32 T0;
51 : Word32 mdy, dy[5];
52 : Word16 lcor;
53 : Word16 imax, i;
54 : Word16 pg[8]; /* local buffer for pitch gain*/
55 : Word32 ml[8]; /* local buffer for mem_lag*/
56 10646 : Word16 const timeWeight[5] = { 20480 /*1.25f Q14*/, 18432 /*1.125f Q14*/, 16384 /*1.f Q14*/, 14336 /*0.875f Q14*/, 12288 /*.75f Q14*/ }; /*Q14*/
57 10646 : move16();
58 10646 : move16();
59 10646 : move16();
60 10646 : move16();
61 10646 : move16(); /*timeweight*/
62 : Word16 no_subfr_pred;
63 : Word16 a1, a2, a3, a4, a5, tmpa, tmpb, b1, b2, b3, b4, b5;
64 : Word16 a_e, b_e, sum0_q;
65 : Word32 mem_lag[2 * NB_SUBFR16k + 2];
66 :
67 :
68 : /* Inverse the order the pitch lag memory */
69 10646 : IF( EQ_16( nb_subfr, 4 ) )
70 : {
71 32879 : FOR( i = 0; i < 2 * NB_SUBFR + 2; i++ )
72 : {
73 29890 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR + 1 - i]; // Q16
74 29890 : move32();
75 : }
76 : }
77 : ELSE /* L_frame == L_FRAME16k */
78 : {
79 99541 : FOR( i = 0; i < 2 * NB_SUBFR16k + 2; i++ )
80 : {
81 91884 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR16k + 1 - i]; // Q16
82 91884 : move32();
83 : }
84 : }
85 :
86 10646 : IF( LT_16( pit_max, extract_h( *old_fpitch ) ) )
87 : {
88 0 : *extrapolationFailed = 1;
89 0 : move16();
90 0 : *T0_out = pit_max;
91 0 : move16();
92 0 : return;
93 : }
94 :
95 10646 : move16();
96 10646 : lcor = 5;
97 10646 : T0 = L_deposit_l( 0 );
98 :
99 10646 : test();
100 10646 : test();
101 10646 : IF( EQ_16( bfi_cnt, 1 ) && GE_16( last_good, UNVOICED_TRANSITION ) && LT_16( last_good, ONSET ) )
102 : {
103 4135 : move16();
104 4135 : no_subfr_pred = 4;
105 4135 : if ( plc_use_future_lag != 0 )
106 : {
107 2150 : move16();
108 2150 : no_subfr_pred = 2;
109 : }
110 :
111 : /* copy to local buffers, depending on availability of info about future subframes */
112 4135 : Copy( mem_pitch_gain + sub( no_subfr_pred, 2 ), pg, 8 );
113 4135 : Copy32( mem_lag + sub( no_subfr_pred, 2 ), ml, 8 );
114 :
115 4135 : mdy = L_deposit_l( 0 );
116 :
117 24810 : FOR( i = ( sub( lcor, 1 ) ); i >= 0; i-- )
118 : {
119 20675 : move32();
120 20675 : dy[i] = L_sub( ml[i], ml[i + 1] );
121 20675 : mdy = L_add( mdy, dy[i] );
122 : }
123 :
124 : /*---------------------------------------------------*
125 : * remove maximum variation
126 : *---------------------------------------------------*/
127 4135 : move16();
128 4135 : imax = 0;
129 4135 : pita = L_abs( dy[0] );
130 20675 : FOR( i = 1; i < lcor; i++ )
131 : {
132 :
133 16540 : IF( LT_32( pita, L_abs( dy[i] ) ) )
134 : {
135 3628 : pita = L_abs( dy[i] );
136 3628 : move16();
137 3628 : imax = i;
138 : }
139 : }
140 4135 : test();
141 4135 : test();
142 4135 : IF( LT_32( L_abs( dy[imax] ), Mpy_32_16_1( *old_fpitch, 4915 /*0.15f Q15*/ ) ) && ( ( EQ_16( limitation, 1 ) ) || ( LT_32( L_abs( dy[imax] ), L_abs( mdy ) ) ) ) )
143 : {
144 :
145 12066 : FOR( i = 0; i < lcor; i++ )
146 : {
147 10055 : pg[i] = mult( mult_sat( pg[i], pg[i] ), timeWeight[i] ); /*Q12 'til pg[lcor-1], Q14 'til pg[8]*/
148 10055 : move16(); // Overflow observed with 10dB cases
149 : }
150 :
151 : /* Linear prediction (estimation) of pitch */
152 : /*
153 : sum0=(pg[1]+4*pg[2]+9*pg[3]+16*pg[4])*pg[0]+
154 : (pg[2]+4*pg[3]+9*pg[4])*pg[1]+
155 : (pg[3]+4*pg[4])*pg[2]+
156 : pg[4]*pg[3];*/
157 : {
158 : Word32 t1, t2, t3, t4, t5, t6, t7;
159 : Word16 e1, e2, e3, e4, e5, e6, e7;
160 2011 : t1 = L_mult0( pg[4], pg[3] ); /*Q24*/ /* t1 = pg[4]*pg[3] */
161 2011 : e1 = 7;
162 2011 : move16();
163 2011 : t2 = L_add( L_deposit_l( pg[3] ), L_shl( L_deposit_l( pg[4] ), 2 ) ); /*Q12*/
164 2011 : e2 = norm_l( t2 );
165 2011 : t2 = L_shl( t2, e2 ); /*Q12,-e2*/
166 2011 : t2 = Mpy_32_16_1( t2, pg[2] ); /*Q9,-e2*/ /* t2 = (pg[3]+4*pg[4])*pg[2] */
167 2011 : e2 = sub( 22, e2 );
168 2011 : t3 = L_add( L_deposit_l( pg[2] ), L_add( L_shl( L_deposit_l( pg[3] ), 2 ), L_add( L_shl( L_deposit_l( pg[4] ), 3 ), L_deposit_l( pg[4] ) ) ) ); /*Q12*/
169 2011 : e3 = norm_l( t3 );
170 2011 : t3 = L_shl( t3, e3 ); /*Q12,-e3*/
171 2011 : t3 = Mpy_32_16_1( t3, pg[1] ); /*Q9,-e3*/ /* t3 = (pg[2]+4*pg[3]+9*pg[4])*pg[1] */
172 2011 : e3 = sub( 22, e3 );
173 2011 : t4 = L_add( pg[1], L_add( L_shl( L_deposit_l( pg[2] ), 2 ), L_add( L_add( L_shl( L_deposit_l( pg[3] ), 3 ), L_deposit_l( pg[3] ) ), L_shl( L_deposit_l( pg[4] ), 4 ) ) ) ); /*Q12*/
174 2011 : e4 = norm_l( t4 );
175 2011 : t4 = L_shl( t4, e4 ); /*Q12,-e4*/
176 2011 : t4 = Mpy_32_16_1( t4, pg[0] ); /*Q9,-e4*/ /* t4 = (pg[1]+4*pg[2]+9*pg[3]+16*pg[4])*pg[0] */
177 2011 : e4 = sub( 22, e4 );
178 2011 : t5 = BASOP_Util_Add_Mant32Exp( t1, e1, t2, e2, &e5 );
179 2011 : t6 = BASOP_Util_Add_Mant32Exp( t3, e3, t4, e4, &e6 );
180 2011 : t7 = BASOP_Util_Add_Mant32Exp( t5, e5, t6, e6, &e7 ); /*Q31,e7*/
181 2011 : sum0_q = norm_l( t7 );
182 2011 : sum0 = round_fx_sat( L_shl( t7, sum0_q ) ); /*Q15,e7-sum0_q*/
183 2011 : sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/
184 : }
185 :
186 2011 : pit = 0;
187 2011 : move16();
188 2011 : IF( sum0 != 0 )
189 : {
190 : /* Shift to the right, changing Q as long as no precision is lost */
191 2934 : WHILE( s_and( sum0, 1 ) == 0 )
192 : {
193 1175 : sum0 = shr( sum0, 1 );
194 1175 : sum0_q = sub( sum0_q, 1 );
195 : }
196 :
197 : /* float:
198 : a=-(
199 : ( 3*pg[1]+4*pg[2]+3*pg[3])*pg[0] */
200 : /*a1*/ /*
201 : *ml[0] +(
202 : ( 2*pg[2]+2*pg[3])*pg[1]-4*pg[1]*pg[0] */
203 : /*a2*/ /*
204 : )*ml[1] +(
205 : - 8*pg[2]*pg[0]-3*pg[2]*pg[1]+pg[3]*pg[2] */
206 : /*a3*/ /*
207 : )*ml[2] +(
208 : -12*pg[3]*pg[0]-6*pg[3]*pg[1]-2*pg[3]*pg[2] */
209 : /*a4*/ /*
210 : )*ml[3] +(
211 : -16*pg[4]*pg[0] -9*pg[4]*pg[1] -4*pg[4]*pg[2] -pg[4]*pg[3] */
212 : /*a5*/ /*
213 : )*ml[4] ) /sum0; MAC(19);MULT(9);DIV(1);
214 : */
215 :
216 : /*magic numbers: Q11 if not DIRECTLY marked otherwise*/
217 1759 : a5 = mac_r( L_mac( L_mac( L_mult( mult_r( -32768, pg[0] ) /*Q8*/, pg[4] ) /*Q5+16*/, mult_r( -9 * 2048, pg[1] ) /*Q8*/, pg[4] /*Q12*/ ) /*Q5+16*/, mult_r( -4 * 2048, pg[2] ) /*Q8*/, pg[4] /*Q12*/ ) /*Q5+16*/, mult_r( pg[4], -4096 /*Q12->Q9*/ ), mult_r( pg[3], 16384 /*Q12->Q11*/ ) ) /*Q5*/;
218 1759 : a4 = mac_r( L_mac( L_mult( mult_r( -12 * 2048, pg[0] ) /*Q8*/, pg[3] /*Q12*/ ) /*Q5+16*/, mult_r( -6 * 2048, pg[1] ) /*Q8*/, pg[3] /*Q12*/ ) /*Q5+16*/, mult_r( -2 * 2048, pg[2] ) /*Q8*/, pg[3] /*Q12*/ ) /*Q5*/;
219 1759 : a3 = mac_r( L_mac( L_mult( mult_r( -8 * 2048, pg[0] ) /*Q8*/, pg[2] ), mult_r( -3 * 2048, pg[1] ) /*Q8*/, pg[2] ), mult_r( pg[2], 4096 /*Q12->Q9*/ ), mult_r( pg[3], 16384 /*12->Q11*/ ) ); /*Q5*/
220 1759 : a2 = mac_r( L_mac( L_mult( mult_r( 2 * 2048, pg[1] ) /*Q8*/, pg[2] ) /*Q5+16*/, mult_r( 2 * 2048, pg[1] ) /*Q8*/, pg[3] ) /*Q5+16*/, mult_r( -4 * 2048, pg[0] ) /*Q8*/, pg[1] /*Q12*/ ) /*Q5*/;
221 1759 : a1 = mac_r( L_mac( L_mult( mult_r( 3 * 2048, pg[0] ) /*Q8*/, pg[1] ) /*Q5+16*/, mult_r( 4 * 2048, pg[0] ) /*Q8*/, pg[2] /*Q12*/ ) /*Q5+16*/, mult_r( 3 * 2048, pg[0] ) /*Q8*/, pg[3] /*Q12*/ ) /*Q5*/;
222 :
223 1759 : a = L_mac( L_mac( L_mac( L_mac( L_mult( a1, round_fx( L_shl( ml[0], 4 ) ) ) /*Q4*/
224 : ,
225 1759 : round_fx( L_shl( ml[1], 4 ) ) /*Q4*/, a2 ),
226 1759 : round_fx( L_shl( ml[2], 4 ) ) /*Q4*/, a3 ),
227 1759 : round_fx( L_shl( ml[3], 4 ) ) /*Q4*/, a4 ),
228 1759 : round_fx( L_shl( ml[4], 4 ) ) /*Q4*/, a5 ); /*Q-6+16 = Q10*/
229 :
230 1759 : a_e = norm_l( a );
231 1759 : a = L_shl( a, a_e );
232 :
233 1759 : a1 = BASOP_Util_Divide3216_Scale( L_negate( a ), /* Numerator */ /*scalefactor 21*/
234 : sum0, /* Denominator*/ /*scalefactor 10*/
235 : &tmpa ); /* scalefactor for result */
236 :
237 : /* Float:
238 : b=(( pg[1]+2*pg[2]+3*pg[3]+4*pg[4])*pg[0] */
239 : /*b1*/ /*
240 : *ml[0] +
241 : (( pg[2]+2*pg[3]+3*pg[4])*pg[1]-pg[1]*pg[0]) */
242 : /*b2*/ /*
243 : *ml[1] +
244 : ( -2*pg[2]*pg[0]-pg[2]*pg[1]+(pg[3]+2*pg[4])*pg[2]) */
245 : /*b3*/ /*
246 : *ml[2] +
247 : ( -3*pg[3]*pg[0]-2*pg[3]*pg[1]-pg[3]*pg[2]+pg[4]*pg[3]) */
248 : /*b4*/ /*
249 : *ml[3] +
250 : ( -4*pg[4]*pg[0]-3*pg[4]*pg[1]-2*pg[4]*pg[2]-pg[4]*pg[3]) */
251 : /*b5*/ /*
252 : *ml[4] )/sum0; MAC(22);MULT(9);DIV(1);*/
253 :
254 : /*magic numbers in Q13 if not DIRECTLY marked otherwise*/
255 1759 : b1 = mac_r( L_mac( L_mac( L_mult( mult_r( pg[1], pg[0] ), 32768 / 4 ) /*Q7+16*/, mult_r( 2 * 8192, pg[0] ) /*Q10*/, pg[2] /*Q12*/ ) /*Q7+16*/, mult_r( 3 * 8192, pg[0] ) /*Q10*/, pg[3] /*Q12*/ ) /*Q7+16*/, /*mult_r(4*8192,pg[0])*/ pg[0] /*Q10*/, pg[4] /*Q12*/ ) /*Q7*/;
256 1759 : b2 = mac_r( L_mac( L_mac( L_mult( mult_r( pg[2], pg[1] ), 32768 / 4 ) /*Q7+16*/, mult_r( 2 * 8192, pg[1] ), pg[3] ), mult_r( 3 * 8192, pg[1] ), pg[4] ) /*Q7+16*/, mult_r( pg[1], -32768 / 2 /*Q12->Q12*/ ), mult_r( pg[0], 32768 / 2 /*Q12->Q10*/ ) ) /*Q7*/;
257 1759 : b3 = mac_r( L_mac( L_mac( L_mult( mult_r( -2 * 8192, pg[0] ), pg[2] ) /*Q7+16*/, mult_r( pg[2], -32768 / 2 ), mult_r( pg[1], 32768 / 2 ) ), mult_r( pg[3], 32768 / 2 ), mult_r( pg[2], 32768 / 2 ) ) /*Q5+16*/, mult_r( 2 * 8192, pg[2] ), pg[4] ) /*Q7*/;
258 1759 : b4 = mac_r( L_mac( L_mac( L_mult( mult_r( -3 * 8192, pg[0] ), pg[3] ), mult_r( -2 * 8192, pg[1] ), pg[3] ), mult_r( -32768 / 2, pg[3] ), mult_r( 32768 / 2, pg[2] ) ), mult_r( 32768 / 2, pg[4] ), mult_r( 32768 / 2, pg[3] ) ); /*Q7*/
259 1759 : b5 = mac_r( L_mac( L_mac( L_mult( mult_r( -32768 /*(-4*8192)*/, pg[0] ), pg[4] ), mult_r( -3 * 8192, pg[1] ), pg[4] ), mult_r( -2 * 8192, pg[2] ), pg[4] ), mult_r( -32768 / 2, pg[4] ), mult_r( 32768 / 2, pg[3] ) ) /*Q7*/;
260 :
261 1759 : b = L_mac( L_mac( L_mac( L_mac( L_mult( b1, round_fx( L_shl( ml[0], 4 ) ) ) /*Q4*/
262 : ,
263 1759 : round_fx( L_shl( ml[1], 4 ) ) /*Q4*/, b2 ),
264 1759 : round_fx( L_shl( ml[2], 4 ) ) /*Q4*/, b3 ),
265 1759 : round_fx( L_shl( ml[3], 4 ) ) /*Q4*/, b4 ),
266 1759 : round_fx( L_shl( ml[4], 4 ) ) /*Q4*/, b5 ); /*Q-4+16 = Q12*/
267 : /*predict pitch for 4th future subframe*/
268 :
269 1759 : b_e = norm_l( b );
270 1759 : b = L_shl( b, b_e );
271 :
272 1759 : b1 = BASOP_Util_Divide3216_Scale( b, /* Numerator */ /*scalefactor 19*/
273 : sum0, /* Denominator*/ /*scalefactor 10*/
274 : &tmpb ); /* scalefactor for result*/
275 :
276 : /*pit = a + b * ((float)no_subfr_pred + (float)nb_subfr);*/
277 1759 : pita = L_shl( L_deposit_l( a1 ), add( add( sum0_q, 16 - 10 + 1 ), sub( tmpa, a_e ) ) ) /*Q16*/;
278 1759 : 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 ) ) );
279 1759 : pit = L_add( pita, pitb ); /*Q16*/
280 :
281 1759 : T0 = L_add( pit, 0 );
282 :
283 : /*limit pitch to allowed range*/
284 :
285 1759 : T0 = L_min( L_deposit_h( pit_max ), T0 );
286 1759 : T0 = L_max( L_deposit_h( pit_min ), T0 );
287 :
288 1759 : move16();
289 1759 : *extrapolationFailed = 0;
290 : }
291 : ELSE
292 : {
293 252 : T0 = L_deposit_l( 0 );
294 252 : *extrapolationFailed = 1;
295 252 : move16();
296 : }
297 : }
298 : ELSE
299 : {
300 :
301 2124 : T0 = L_deposit_l( 0 );
302 2124 : move16();
303 2124 : *extrapolationFailed = 1;
304 : }
305 : }
306 : ELSE
307 : {
308 6511 : T0 = L_add( *old_fpitch, 0 );
309 6511 : move16();
310 6511 : *extrapolationFailed = 1;
311 : }
312 10646 : move32();
313 10646 : *T0_out = T0;
314 :
315 10646 : return;
316 : }
317 :
318 : /* up to date with rev 8158*/
319 969 : void get_subframe_pitch(
320 : Word16 nSubframes,
321 : /* i: number of subframes */ /* Q0 */
322 : Word32 pitchStart,
323 : /* i: starting pitch lag (in subframe -1) */ /*15Q16*/
324 : Word32 pitchEnd,
325 : /* i: ending pitch lag (in subframe nSubframes-1) */ /*15Q16*/
326 : Word32 *pitchBuf /* o: interpolated pitch lag per subframe */ /*15Q16*/
327 : )
328 : {
329 : Word16 i, s;
330 : Word32 pitchDelta;
331 :
332 969 : assert( ( nSubframes > 0 ) && ( pitchBuf != NULL ) && ( pitchStart >= 0 ) && ( pitchEnd > 0 ) );
333 :
334 : /*pitchDelta = (pitchEnd - pitchStart)/nSubframes;*/
335 969 : pitchDelta = L_deposit_l( BASOP_Util_Divide3216_Scale( L_sub( pitchEnd, pitchStart ), nSubframes, &s ) ); /*Q15*/
336 969 : pitchDelta = L_shl( pitchDelta, add( s, 1 ) ); /*Q16*/
337 969 : pitchBuf[0] = L_add( pitchStart, pitchDelta );
338 969 : move32();
339 4317 : FOR( i = 1; i < nSubframes; i++ )
340 : {
341 3348 : pitchBuf[i] = L_add( pitchBuf[i - 1], pitchDelta );
342 3348 : move32();
343 : }
344 969 : }
|