FreeCalypso > hg > efr-experiments
comparison src/pitch_f6.c @ 0:56410792419a
src: original EFR source from ETSI
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 03 Apr 2024 05:31:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:56410792419a |
---|---|
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 } |