FreeCalypso > hg > gsm-codec-lib
comparison libgsmefr/pitch_ol.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 | 509ba99f5136 |
comparison
equal
deleted
inserted
replaced
52:988fd7ff514f | 53:49dd1ac8e75b |
---|---|
1 /************************************************************************* | |
2 * | |
3 * FUNCTION: Pitch_ol | |
4 * | |
5 * PURPOSE: Compute the open loop pitch lag. | |
6 * | |
7 * DESCRIPTION: | |
8 * The open-loop pitch lag is determined based on the perceptually | |
9 * weighted speech signal. This is done in the following steps: | |
10 * - find three maxima of the correlation <sw[n],sw[n-T]> in the | |
11 * follwing three ranges of T : [18,35], [36,71], and [72, 143] | |
12 * - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at | |
13 * that maximum correlation. | |
14 * - select the delay of maximum normalized correlation (among the | |
15 * three candidates) while favoring the lower delay ranges. | |
16 * | |
17 *************************************************************************/ | |
18 | |
19 #include "typedef.h" | |
20 #include "basic_op.h" | |
21 #include "oper_32b.h" | |
22 #include "count.h" | |
23 #include "sig_proc.h" | |
24 | |
25 #define THRESHOLD 27853 | |
26 | |
27 /* local function */ | |
28 | |
29 static Word16 Lag_max ( /* output: lag found */ | |
30 Word16 scal_sig[], /* input : scaled signal */ | |
31 Word16 scal_fac, /* input : scaled signal factor */ | |
32 Word16 L_frame, /* input : length of frame to compute pitch */ | |
33 Word16 lag_max, /* input : maximum lag */ | |
34 Word16 lag_min, /* input : minimum lag */ | |
35 Word16 *cor_max); /* output: normalized correlation of selected lag */ | |
36 | |
37 Word16 Pitch_ol ( /* output: open loop pitch lag */ | |
38 Word16 signal[], /* input : signal used to compute the open loop pitch */ | |
39 /* signal[-pit_max] to signal[-1] should be known */ | |
40 Word16 pit_min, /* input : minimum pitch lag */ | |
41 Word16 pit_max, /* input : maximum pitch lag */ | |
42 Word16 L_frame /* input : length of frame to compute pitch */ | |
43 ) | |
44 { | |
45 Word16 i, j; | |
46 Word16 max1, max2, max3; | |
47 Word16 p_max1, p_max2, p_max3; | |
48 Word32 t0; | |
49 | |
50 /* Scaled signal */ | |
51 /* Can be allocated with memory allocation of(pit_max+L_frame) */ | |
52 | |
53 Word16 scaled_signal[512]; | |
54 Word16 *scal_sig, scal_fac; | |
55 | |
56 scal_sig = &scaled_signal[pit_max]; move16 (); | |
57 | |
58 t0 = 0L; move32 (); | |
59 for (i = -pit_max; i < L_frame; i++) | |
60 { | |
61 t0 = L_mac (t0, signal[i], signal[i]); | |
62 } | |
63 /*--------------------------------------------------------* | |
64 * Scaling of input signal. * | |
65 * * | |
66 * if Overflow -> scal_sig[i] = signal[i]>>2 * | |
67 * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 * | |
68 * else -> scal_sig[i] = signal[i] * | |
69 *--------------------------------------------------------*/ | |
70 | |
71 /*--------------------------------------------------------* | |
72 * Verification for risk of overflow. * | |
73 *--------------------------------------------------------*/ | |
74 | |
75 test (); test (); | |
76 if (L_sub (t0, MAX_32) == 0L) /* Test for overflow */ | |
77 { | |
78 for (i = -pit_max; i < L_frame; i++) | |
79 { | |
80 scal_sig[i] = shr (signal[i], 3); move16 (); | |
81 } | |
82 scal_fac = 3; move16 (); | |
83 } | |
84 else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) | |
85 /* if (t0 < 2^20) */ | |
86 { | |
87 for (i = -pit_max; i < L_frame; i++) | |
88 { | |
89 scal_sig[i] = shl (signal[i], 3); move16 (); | |
90 } | |
91 scal_fac = -3; move16 (); | |
92 } | |
93 else | |
94 { | |
95 for (i = -pit_max; i < L_frame; i++) | |
96 { | |
97 scal_sig[i] = signal[i]; move16 (); | |
98 } | |
99 scal_fac = 0; move16 (); | |
100 } | |
101 | |
102 /*--------------------------------------------------------------------* | |
103 * The pitch lag search is divided in three sections. * | |
104 * Each section cannot have a pitch multiple. * | |
105 * We find a maximum for each section. * | |
106 * We compare the maximum of each section by favoring small lags. * | |
107 * * | |
108 * First section: lag delay = pit_max downto 4*pit_min * | |
109 * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * | |
110 * Third section: lag delay = 2*pit_min-1 downto pit_min * | |
111 *-------------------------------------------------------------------*/ | |
112 | |
113 j = shl (pit_min, 2); | |
114 p_max1 = Lag_max (scal_sig, scal_fac, L_frame, pit_max, j, &max1); | |
115 | |
116 i = sub (j, 1); | |
117 j = shl (pit_min, 1); | |
118 p_max2 = Lag_max (scal_sig, scal_fac, L_frame, i, j, &max2); | |
119 | |
120 i = sub (j, 1); | |
121 p_max3 = Lag_max (scal_sig, scal_fac, L_frame, i, pit_min, &max3); | |
122 | |
123 /*--------------------------------------------------------------------* | |
124 * Compare the 3 sections maximum, and favor small lag. * | |
125 *-------------------------------------------------------------------*/ | |
126 | |
127 test (); | |
128 if (sub (mult (max1, THRESHOLD), max2) < 0) | |
129 { | |
130 max1 = max2; move16 (); | |
131 p_max1 = p_max2; move16 (); | |
132 } | |
133 test (); | |
134 if (sub (mult (max1, THRESHOLD), max3) < 0) | |
135 { | |
136 p_max1 = p_max3; move16 (); | |
137 } | |
138 return (p_max1); | |
139 } | |
140 | |
141 /************************************************************************* | |
142 * | |
143 * FUNCTION: Lag_max | |
144 * | |
145 * PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a | |
146 * given delay range. | |
147 * | |
148 * DESCRIPTION: | |
149 * The correlation is given by | |
150 * cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max | |
151 * The functions outputs the maximum correlation after normalization | |
152 * and the corresponding lag. | |
153 * | |
154 *************************************************************************/ | |
155 | |
156 static Word16 Lag_max ( /* output: lag found */ | |
157 Word16 scal_sig[], /* input : scaled signal. */ | |
158 Word16 scal_fac, /* input : scaled signal factor. */ | |
159 Word16 L_frame, /* input : length of frame to compute pitch */ | |
160 Word16 lag_max, /* input : maximum lag */ | |
161 Word16 lag_min, /* input : minimum lag */ | |
162 Word16 *cor_max) /* output: normalized correlation of selected lag */ | |
163 { | |
164 Word16 i, j; | |
165 Word16 *p, *p1; | |
166 Word32 max, t0; | |
167 Word16 max_h, max_l, ener_h, ener_l; | |
168 Word16 p_max; | |
169 | |
170 max = MIN_32; move32 (); | |
171 | |
172 for (i = lag_max; i >= lag_min; i--) | |
173 { | |
174 p = scal_sig; move16 (); | |
175 p1 = &scal_sig[-i]; move16 (); | |
176 t0 = 0; move32 (); | |
177 | |
178 for (j = 0; j < L_frame; j++, p++, p1++) | |
179 { | |
180 t0 = L_mac (t0, *p, *p1); | |
181 } | |
182 test (); | |
183 if (L_sub (t0, max) >= 0) | |
184 { | |
185 max = t0; move32 (); | |
186 p_max = i; move16 (); | |
187 } | |
188 } | |
189 | |
190 /* compute energy */ | |
191 | |
192 t0 = 0; move32 (); | |
193 p = &scal_sig[-p_max]; move16 (); | |
194 for (i = 0; i < L_frame; i++, p++) | |
195 { | |
196 t0 = L_mac (t0, *p, *p); | |
197 } | |
198 /* 1/sqrt(energy) */ | |
199 | |
200 t0 = Inv_sqrt (t0); | |
201 t0 = L_shl (t0, 1); | |
202 | |
203 /* max = max/sqrt(energy) */ | |
204 | |
205 L_Extract (max, &max_h, &max_l); | |
206 L_Extract (t0, &ener_h, &ener_l); | |
207 | |
208 t0 = Mpy_32 (max_h, max_l, ener_h, ener_l); | |
209 t0 = L_shr (t0, scal_fac); | |
210 | |
211 *cor_max = extract_h (L_shl (t0, 15)); move16 (); /* divide by 2 */ | |
212 | |
213 return (p_max); | |
214 } |