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 10344 : 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 10344 : 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 10344 : move16();
58 10344 : move16();
59 10344 : move16();
60 10344 : move16();
61 10344 : 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 10344 : IF( EQ_16( nb_subfr, 4 ) )
70 : {
71 31801 : FOR( i = 0; i < 2 * NB_SUBFR + 2; i++ )
72 : {
73 28910 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR + 1 - i]; // Q16
74 28910 : move32();
75 : }
76 : }
77 : ELSE /* L_frame == L_FRAME16k */
78 : {
79 96889 : FOR( i = 0; i < 2 * NB_SUBFR16k + 2; i++ )
80 : {
81 89436 : mem_lag[i] = old_pitch_buf[2 * NB_SUBFR16k + 1 - i]; // Q16
82 89436 : move32();
83 : }
84 : }
85 :
86 10344 : 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 10344 : move16();
96 10344 : lcor = 5;
97 10344 : T0 = L_deposit_l( 0 );
98 :
99 10344 : test();
100 10344 : test();
101 10344 : IF( EQ_16( bfi_cnt, 1 ) && GE_16( last_good, UNVOICED_TRANSITION ) && LT_16( last_good, ONSET ) )
102 : {
103 3956 : move16();
104 3956 : no_subfr_pred = 4;
105 3956 : if ( plc_use_future_lag != 0 )
106 : {
107 2007 : move16();
108 2007 : no_subfr_pred = 2;
109 : }
110 :
111 : /* copy to local buffers, depending on availability of info about future subframes */
112 3956 : Copy( mem_pitch_gain + sub( no_subfr_pred, 2 ), pg, 8 );
113 3956 : Copy32( mem_lag + sub( no_subfr_pred, 2 ), ml, 8 );
114 :
115 3956 : mdy = L_deposit_l( 0 );
116 :
117 23736 : FOR( i = ( sub( lcor, 1 ) ); i >= 0; i-- )
118 : {
119 19780 : move32();
120 19780 : dy[i] = L_sub( ml[i], ml[i + 1] );
121 19780 : mdy = L_add( mdy, dy[i] );
122 : }
123 :
124 : /*---------------------------------------------------*
125 : * remove maximum variation
126 : *---------------------------------------------------*/
127 3956 : move16();
128 3956 : imax = 0;
129 3956 : pita = L_abs( dy[0] );
130 19780 : FOR( i = 1; i < lcor; i++ )
131 : {
132 :
133 15824 : IF( LT_32( pita, L_abs( dy[i] ) ) )
134 : {
135 3431 : pita = L_abs( dy[i] );
136 3431 : move16();
137 3431 : imax = i;
138 : }
139 : }
140 3956 : test();
141 3956 : test();
142 3956 : 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 11550 : FOR( i = 0; i < lcor; i++ )
146 : {
147 9625 : pg[i] = mult( mult_sat( pg[i], pg[i] ), timeWeight[i] ); /*Q12 'til pg[lcor-1], Q14 'til pg[8]*/
148 9625 : 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 : Flag Overflow;
161 1925 : t1 = L_mult0( pg[4], pg[3] ); /*Q24*/ /* t1 = pg[4]*pg[3] */
162 1925 : e1 = 7;
163 1925 : move16();
164 1925 : t2 = L_add( L_deposit_l( pg[3] ), L_shl( L_deposit_l( pg[4] ), 2 ) ); /*Q12*/
165 1925 : e2 = norm_l( t2 );
166 1925 : t2 = L_shl( t2, e2 ); /*Q12,-e2*/
167 1925 : t2 = Mpy_32_16_1( t2, pg[2] ); /*Q9,-e2*/ /* t2 = (pg[3]+4*pg[4])*pg[2] */
168 1925 : e2 = sub( 22, e2 );
169 1925 : 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*/
170 1925 : e3 = norm_l( t3 );
171 1925 : t3 = L_shl( t3, e3 ); /*Q12,-e3*/
172 1925 : t3 = Mpy_32_16_1( t3, pg[1] ); /*Q9,-e3*/ /* t3 = (pg[2]+4*pg[3]+9*pg[4])*pg[1] */
173 1925 : e3 = sub( 22, e3 );
174 1925 : 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*/
175 1925 : e4 = norm_l( t4 );
176 1925 : t4 = L_shl( t4, e4 ); /*Q12,-e4*/
177 1925 : t4 = Mpy_32_16_1( t4, pg[0] ); /*Q9,-e4*/ /* t4 = (pg[1]+4*pg[2]+9*pg[3]+16*pg[4])*pg[0] */
178 1925 : e4 = sub( 22, e4 );
179 1925 : t5 = BASOP_Util_Add_Mant32Exp( t1, e1, t2, e2, &e5 );
180 1925 : t6 = BASOP_Util_Add_Mant32Exp( t3, e3, t4, e4, &e6 );
181 1925 : t7 = BASOP_Util_Add_Mant32Exp( t5, e5, t6, e6, &e7 ); /*Q31,e7*/
182 1925 : sum0_q = norm_l( t7 );
183 1925 : sum0 = round_fx_o( L_shl( t7, sum0_q ), &Overflow ); /*Q15,e7-sum0_q*/
184 1925 : sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/
185 : }
186 :
187 1925 : pit = 0;
188 1925 : move16();
189 1925 : IF( sum0 != 0 )
190 : {
191 : /* Shift to the right, changing Q as long as no precision is lost */
192 2756 : WHILE( s_and( sum0, 1 ) == 0 )
193 : {
194 1076 : sum0 = shr( sum0, 1 );
195 1076 : sum0_q = sub( sum0_q, 1 );
196 : }
197 :
198 : /* float:
199 : a=-(
200 : ( 3*pg[1]+4*pg[2]+3*pg[3])*pg[0] */
201 : /*a1*/ /*
202 : *ml[0] +(
203 : ( 2*pg[2]+2*pg[3])*pg[1]-4*pg[1]*pg[0] */
204 : /*a2*/ /*
205 : )*ml[1] +(
206 : - 8*pg[2]*pg[0]-3*pg[2]*pg[1]+pg[3]*pg[2] */
207 : /*a3*/ /*
208 : )*ml[2] +(
209 : -12*pg[3]*pg[0]-6*pg[3]*pg[1]-2*pg[3]*pg[2] */
210 : /*a4*/ /*
211 : )*ml[3] +(
212 : -16*pg[4]*pg[0] -9*pg[4]*pg[1] -4*pg[4]*pg[2] -pg[4]*pg[3] */
213 : /*a5*/ /*
214 : )*ml[4] ) /sum0; MAC(19);MULT(9);DIV(1);
215 : */
216 :
217 : /*magic numbers: Q11 if not DIRECTLY marked otherwise*/
218 1680 : 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*/;
219 1680 : 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*/;
220 1680 : 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*/
221 1680 : 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*/;
222 1680 : 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*/;
223 :
224 1680 : a = L_mac( L_mac( L_mac( L_mac( L_mult( a1, round_fx( L_shl( ml[0], 4 ) ) ) /*Q4*/
225 : ,
226 1680 : round_fx( L_shl( ml[1], 4 ) ) /*Q4*/, a2 ),
227 1680 : round_fx( L_shl( ml[2], 4 ) ) /*Q4*/, a3 ),
228 1680 : round_fx( L_shl( ml[3], 4 ) ) /*Q4*/, a4 ),
229 1680 : round_fx( L_shl( ml[4], 4 ) ) /*Q4*/, a5 ); /*Q-6+16 = Q10*/
230 :
231 1680 : a_e = norm_l( a );
232 1680 : a = L_shl( a, a_e );
233 :
234 1680 : a1 = BASOP_Util_Divide3216_Scale( L_negate( a ), /* Numerator */ /*scalefactor 21*/
235 : sum0, /* Denominator*/ /*scalefactor 10*/
236 : &tmpa ); /* scalefactor for result */
237 :
238 : /* Float:
239 : b=(( pg[1]+2*pg[2]+3*pg[3]+4*pg[4])*pg[0] */
240 : /*b1*/ /*
241 : *ml[0] +
242 : (( pg[2]+2*pg[3]+3*pg[4])*pg[1]-pg[1]*pg[0]) */
243 : /*b2*/ /*
244 : *ml[1] +
245 : ( -2*pg[2]*pg[0]-pg[2]*pg[1]+(pg[3]+2*pg[4])*pg[2]) */
246 : /*b3*/ /*
247 : *ml[2] +
248 : ( -3*pg[3]*pg[0]-2*pg[3]*pg[1]-pg[3]*pg[2]+pg[4]*pg[3]) */
249 : /*b4*/ /*
250 : *ml[3] +
251 : ( -4*pg[4]*pg[0]-3*pg[4]*pg[1]-2*pg[4]*pg[2]-pg[4]*pg[3]) */
252 : /*b5*/ /*
253 : *ml[4] )/sum0; MAC(22);MULT(9);DIV(1);*/
254 :
255 : /*magic numbers in Q13 if not DIRECTLY marked otherwise*/
256 1680 : 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*/;
257 1680 : 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*/;
258 1680 : 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*/;
259 1680 : 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*/
260 1680 : 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*/;
261 :
262 1680 : b = L_mac( L_mac( L_mac( L_mac( L_mult( b1, round_fx( L_shl( ml[0], 4 ) ) ) /*Q4*/
263 : ,
264 1680 : round_fx( L_shl( ml[1], 4 ) ) /*Q4*/, b2 ),
265 1680 : round_fx( L_shl( ml[2], 4 ) ) /*Q4*/, b3 ),
266 1680 : round_fx( L_shl( ml[3], 4 ) ) /*Q4*/, b4 ),
267 1680 : round_fx( L_shl( ml[4], 4 ) ) /*Q4*/, b5 ); /*Q-4+16 = Q12*/
268 : /*predict pitch for 4th future subframe*/
269 :
270 1680 : b_e = norm_l( b );
271 1680 : b = L_shl( b, b_e );
272 :
273 1680 : b1 = BASOP_Util_Divide3216_Scale( b, /* Numerator */ /*scalefactor 19*/
274 : sum0, /* Denominator*/ /*scalefactor 10*/
275 : &tmpb ); /* scalefactor for result*/
276 :
277 : /*pit = a + b * ((float)no_subfr_pred + (float)nb_subfr);*/
278 1680 : pita = L_shl( L_deposit_l( a1 ), add( add( sum0_q, 16 - 10 + 1 ), sub( tmpa, a_e ) ) ) /*Q16*/;
279 1680 : 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 ) ) );
280 1680 : pit = L_add( pita, pitb ); /*Q16*/
281 :
282 1680 : T0 = L_add( pit, 0 );
283 :
284 : /*limit pitch to allowed range*/
285 :
286 1680 : T0 = L_min( L_deposit_h( pit_max ), T0 );
287 1680 : T0 = L_max( L_deposit_h( pit_min ), T0 );
288 :
289 1680 : move16();
290 1680 : *extrapolationFailed = 0;
291 : }
292 : ELSE
293 : {
294 245 : T0 = L_deposit_l( 0 );
295 245 : *extrapolationFailed = 1;
296 245 : move16();
297 : }
298 : }
299 : ELSE
300 : {
301 :
302 2031 : T0 = L_deposit_l( 0 );
303 2031 : move16();
304 2031 : *extrapolationFailed = 1;
305 : }
306 : }
307 : ELSE
308 : {
309 6388 : T0 = L_add( *old_fpitch, 0 );
310 6388 : move16();
311 6388 : *extrapolationFailed = 1;
312 : }
313 10344 : move32();
314 10344 : *T0_out = T0;
315 :
316 10344 : return;
317 : }
318 :
319 : /* up to date with rev 8158*/
320 912 : void get_subframe_pitch(
321 : Word16 nSubframes,
322 : /* i: number of subframes */ /* Q0 */
323 : Word32 pitchStart,
324 : /* i: starting pitch lag (in subframe -1) */ /*15Q16*/
325 : Word32 pitchEnd,
326 : /* i: ending pitch lag (in subframe nSubframes-1) */ /*15Q16*/
327 : Word32 *pitchBuf /* o: interpolated pitch lag per subframe */ /*15Q16*/
328 : )
329 : {
330 : Word16 i, s;
331 : Word32 pitchDelta;
332 :
333 912 : assert( ( nSubframes > 0 ) && ( pitchBuf != NULL ) && ( pitchStart >= 0 ) && ( pitchEnd > 0 ) );
334 :
335 : /*pitchDelta = (pitchEnd - pitchStart)/nSubframes;*/
336 912 : pitchDelta = L_deposit_l( BASOP_Util_Divide3216_Scale( L_sub( pitchEnd, pitchStart ), nSubframes, &s ) ); /*Q15*/
337 912 : pitchDelta = L_shl( pitchDelta, add( s, 1 ) ); /*Q16*/
338 912 : pitchBuf[0] = L_add( pitchStart, pitchDelta );
339 912 : move32();
340 4054 : FOR( i = 1; i < nSubframes; i++ )
341 : {
342 3142 : pitchBuf[i] = L_add( pitchBuf[i - 1], pitchDelta );
343 3142 : move32();
344 : }
345 912 : }
|