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