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 }