comparison libgsmefr/pitch_f6.c @ 53:49dd1ac8e75b

libgsmefr: import most *.c files from ETSI source
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 25 Nov 2022 16:18:21 +0000
parents
children e0e53bfe1a8a
comparison
equal deleted inserted replaced
52:988fd7ff514f 53:49dd1ac8e75b
1 /*************************************************************************
2 *
3 * FUNCTION: Pitch_fr6()
4 *
5 * PURPOSE: Find the pitch period with 1/6 subsample resolution (closed loop).
6 *
7 * DESCRIPTION:
8 * - find the normalized correlation between the target and filtered
9 * past excitation in the search range.
10 * - select the delay with maximum normalized correlation.
11 * - interpolate the normalized correlation at fractions -3/6 to 3/6
12 * with step 1/6 around the chosen delay.
13 * - The fraction which gives the maximum interpolated value is chosen.
14 *
15 *************************************************************************/
16
17 #include "typedef.h"
18 #include "basic_op.h"
19 #include "oper_32b.h"
20 #include "count.h"
21 #include "sig_proc.h"
22 #include "codec.h"
23
24 /* L_inter = Length for fractional interpolation = nb.coeff/2 */
25
26 #define L_inter 4
27
28 /* Local functions */
29
30 void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
31 Word16 t_min, Word16 t_max, Word16 corr_norm[]);
32
33 Word16 Pitch_fr6 ( /* (o) : pitch period. */
34 Word16 exc[], /* (i) : excitation buffer */
35 Word16 xn[], /* (i) : target vector */
36 Word16 h[], /* (i) : impulse response of synthesis and
37 weighting filters */
38 Word16 L_subfr, /* (i) : Length of subframe */
39 Word16 t0_min, /* (i) : minimum value in the searched range. */
40 Word16 t0_max, /* (i) : maximum value in the searched range. */
41 Word16 i_subfr, /* (i) : indicator for first subframe. */
42 Word16 *pit_frac /* (o) : chosen fraction. */
43 )
44 {
45 Word16 i;
46 Word16 t_min, t_max;
47 Word16 max, lag, frac;
48 Word16 *corr;
49 Word16 corr_int;
50 Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_inter */
51
52 /* Find interval to compute normalized correlation */
53
54 t_min = sub (t0_min, L_inter);
55 t_max = add (t0_max, L_inter);
56
57 corr = &corr_v[-t_min]; move16 ();
58
59 /* Compute normalized correlation between target and filtered excitation */
60
61 Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
62
63 /* Find integer pitch */
64
65 max = corr[t0_min]; move16 ();
66 lag = t0_min; move16 ();
67
68 for (i = t0_min + 1; i <= t0_max; i++)
69 {
70 test ();
71 if (sub (corr[i], max) >= 0)
72 {
73 max = corr[i]; move16 ();
74 lag = i; move16 ();
75 }
76 }
77
78 /* If first subframe and lag > 94 do not search fractional pitch */
79
80 test (); test ();
81 if ((i_subfr == 0) && (sub (lag, 94) > 0))
82 {
83 *pit_frac = 0; move16 ();
84 return (lag);
85 }
86 /* Test the fractions around T0 and choose the one which maximizes */
87 /* the interpolated normalized correlation. */
88
89 max = Interpol_6 (&corr[lag], -3);
90 frac = -3; move16 ();
91
92 for (i = -2; i <= 3; i++)
93 {
94 corr_int = Interpol_6 (&corr[lag], i); move16 ();
95 test ();
96 if (sub (corr_int, max) > 0)
97 {
98 max = corr_int; move16 ();
99 frac = i; move16 ();
100 }
101 }
102
103 /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
104
105 test ();
106 if (sub (frac, -3) == 0)
107 {
108 frac = 3; move16 ();
109 lag = sub (lag, 1);
110 }
111 *pit_frac = frac; move16 ();
112
113 return (lag);
114 }
115
116 /*************************************************************************
117 *
118 * FUNCTION: Norm_Corr()
119 *
120 * PURPOSE: Find the normalized correlation between the target vector
121 * and the filtered past excitation.
122 *
123 * DESCRIPTION:
124 * The normalized correlation is given by the correlation between the
125 * target and filtered past excitation divided by the square root of
126 * the energy of filtered excitation.
127 * corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[])
128 * where x[] is the target vector and y_k[] is the filtered past
129 * excitation at delay k.
130 *
131 *************************************************************************/
132
133 void
134 Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
135 Word16 t_min, Word16 t_max, Word16 corr_norm[])
136 {
137 Word16 i, j, k;
138 Word16 corr_h, corr_l, norm_h, norm_l;
139 Word32 s;
140
141 /* Usally dynamic allocation of (L_subfr) */
142 Word16 excf[80];
143 Word16 scaling, h_fac, *s_excf, scaled_excf[80];
144
145 k = -t_min; move16 ();
146
147 /* compute the filtered excitation for the first delay t_min */
148
149 Convolve (&exc[k], h, excf, L_subfr);
150
151 /* scale "excf[]" to avoid overflow */
152
153 for (j = 0; j < L_subfr; j++)
154 {
155 scaled_excf[j] = shr (excf[j], 2); move16 ();
156 }
157
158 /* Compute 1/sqrt(energy of excf[]) */
159
160 s = 0; move32 ();
161 for (j = 0; j < L_subfr; j++)
162 {
163 s = L_mac (s, excf[j], excf[j]);
164 }
165 test ();
166 if (L_sub (s, 67108864L) <= 0) /* if (s <= 2^26) */
167 {
168 s_excf = excf; move16 ();
169 h_fac = 15 - 12; move16 ();
170 scaling = 0; move16 ();
171 }
172 else
173 {
174 /* "excf[]" is divided by 2 */
175 s_excf = scaled_excf; move16 ();
176 h_fac = 15 - 12 - 2; move16 ();
177 scaling = 2; move16 ();
178 }
179
180 /* loop for every possible period */
181
182 for (i = t_min; i <= t_max; i++)
183 {
184 /* Compute 1/sqrt(energy of excf[]) */
185
186 s = 0; move32 ();
187 for (j = 0; j < L_subfr; j++)
188 {
189 s = L_mac (s, s_excf[j], s_excf[j]);
190 }
191
192 s = Inv_sqrt (s); move16 ();
193 L_Extract (s, &norm_h, &norm_l);
194
195 /* Compute correlation between xn[] and excf[] */
196
197 s = 0; move32 ();
198 for (j = 0; j < L_subfr; j++)
199 {
200 s = L_mac (s, xn[j], s_excf[j]);
201 }
202 L_Extract (s, &corr_h, &corr_l);
203
204 /* Normalize correlation = correlation * (1/sqrt(energy)) */
205
206 s = Mpy_32 (corr_h, corr_l, norm_h, norm_l);
207
208 corr_norm[i] = extract_h (L_shl (s, 16));
209 move16 ();
210
211 /* modify the filtered excitation excf[] for the next iteration */
212
213 test ();
214 if (sub (i, t_max) != 0)
215 {
216 k--;
217 for (j = L_subfr - 1; j > 0; j--)
218 {
219 s = L_mult (exc[k], h[j]);
220 s = L_shl (s, h_fac);
221 s_excf[j] = add (extract_h (s), s_excf[j - 1]); move16 ();
222 }
223 s_excf[0] = shr (exc[k], scaling); move16 ();
224 }
225 }
226 return;
227 }