1 /*
2  ** Copyright 2003-2010, VisualOn, Inc.
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 /***********************************************************************
18 *      File: p_med_ol.c                                                *
19 *                                                                      *
20 *      Description: Compute the open loop pitch lag                    *
21 *               output: open loop pitch lag                        *
22 ************************************************************************/
23 
24 #include "typedef.h"
25 #include "basic_op.h"
26 #include "acelp.h"
27 #include "oper_32b.h"
28 #include "math_op.h"
29 #include "p_med_ol.tab"
30 
Pitch_med_ol(Word16 wsp[],Coder_State * st,Word16 L_frame)31 Word16 Pitch_med_ol(
32            Word16      wsp[],        /*   i: signal used to compute the open loop pitch*/
33                                      /*      wsp[-pit_max] to wsp[-1] should be known */
34            Coder_State *st,          /* i/o: codec global structure */
35            Word16      L_frame       /*   i: length of frame to compute pitch */
36         )
37 {
38     Word16 Tm;
39     Word16 hi, lo;
40     Word16 *ww, *we, *hp_wsp;
41     Word16 exp_R0, exp_R1, exp_R2;
42     Word32 i, j, max, R0, R1, R2;
43     Word16 *p1, *p2;
44     Word16 L_min = 17;                   /* minimum pitch lag: PIT_MIN / OPL_DECIM */
45     Word16 L_max = 115;                  /* maximum pitch lag: PIT_MAX / OPL_DECIM */
46     Word16 L_0 = st->old_T0_med;         /* old open-loop pitch */
47     Word16 *gain = &(st->ol_gain);       /* normalize correlation of hp_wsp for the lag */
48     Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/
49     Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */
50     Word16 wght_flg = st->ol_wght_flg;   /* is weighting function used */
51 
52     ww = &corrweight[198];
53     we = &corrweight[98 + L_max - L_0];
54 
55     max = MIN_32;
56     Tm = 0;
57     for (i = L_max; i > L_min; i--)
58     {
59         /* Compute the correlation */
60         R0 = 0;
61         p1 = wsp;
62         p2 = &wsp[-i];
63         for (j = 0; j < L_frame; j+=4)
64         {
65             R0 += vo_L_mult((*p1++), (*p2++));
66             R0 += vo_L_mult((*p1++), (*p2++));
67             R0 += vo_L_mult((*p1++), (*p2++));
68             R0 += vo_L_mult((*p1++), (*p2++));
69         }
70         /* Weighting of the correlation function.   */
71         hi = R0>>16;
72         lo = (R0 & 0xffff)>>1;
73 
74         R0 = Mpy_32_16(hi, lo, *ww);
75         ww--;
76 
77         if ((L_0 > 0) && (wght_flg > 0))
78         {
79             /* Weight the neighbourhood of the old lag. */
80             hi = R0>>16;
81             lo = (R0 & 0xffff)>>1;
82             R0 = Mpy_32_16(hi, lo, *we);
83             we--;
84         }
85         if(R0 >= max)
86         {
87             max = R0;
88             Tm = i;
89         }
90     }
91 
92     /* Hypass the wsp[] vector */
93     hp_wsp = old_hp_wsp + L_max;
94     Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
95 
96     /* Compute normalize correlation at delay Tm */
97     R0 = 0;
98     R1 = 0;
99     R2 = 0;
100     p1 = hp_wsp;
101     p2 = hp_wsp - Tm;
102     for (j = 0; j < L_frame; j+=4)
103     {
104         R2 += vo_mult32(*p1, *p1);
105         R1 += vo_mult32(*p2, *p2);
106         R0 += vo_mult32(*p1++, *p2++);
107         R2 += vo_mult32(*p1, *p1);
108         R1 += vo_mult32(*p2, *p2);
109         R0 += vo_mult32(*p1++, *p2++);
110         R2 += vo_mult32(*p1, *p1);
111         R1 += vo_mult32(*p2, *p2);
112         R0 += vo_mult32(*p1++, *p2++);
113         R2 += vo_mult32(*p1, *p1);
114         R1 += vo_mult32(*p2, *p2);
115         R0 += vo_mult32(*p1++, *p2++);
116     }
117     R0 = R0 <<1;
118     R1 = (R1 <<1) + 1L;
119     R2 = (R2 <<1) + 1L;
120     /* gain = R0/ sqrt(R1*R2) */
121 
122     exp_R0 = norm_l(R0);
123     R0 = (R0 << exp_R0);
124 
125     exp_R1 = norm_l(R1);
126     R1 = (R1 << exp_R1);
127 
128     exp_R2 = norm_l(R2);
129     R2 = (R2 << exp_R2);
130 
131 
132     R1 = vo_L_mult(voround(R1), voround(R2));
133 
134     i = norm_l(R1);
135     R1 = (R1 << i);
136 
137     exp_R1 += exp_R2;
138     exp_R1 += i;
139     exp_R1 = 62 - exp_R1;
140 
141     Isqrt_n(&R1, &exp_R1);
142 
143     R0 = vo_L_mult(voround(R0), voround(R1));
144     exp_R0 = 31 - exp_R0;
145     exp_R0 += exp_R1;
146 
147     *gain = vo_round(L_shl(R0, exp_R0));
148 
149     /* Shitf hp_wsp[] for next frame */
150 
151     for (i = 0; i < L_max; i++)
152     {
153         old_hp_wsp[i] = old_hp_wsp[i + L_frame];
154     }
155 
156     return (Tm);
157 }
158 
159 /************************************************************************
160 *  Function: median5                                                    *
161 *                                                                       *
162 *      Returns the median of the set {X[-2], X[-1],..., X[2]},          *
163 *      whose elements are 16-bit integers.                              *
164 *                                                                       *
165 *  Input:                                                               *
166 *      X[-2:2]   16-bit integers.                                       *
167 *                                                                       *
168 *  Return:                                                              *
169 *      The median of {X[-2], X[-1],..., X[2]}.                          *
170 ************************************************************************/
171 
median5(Word16 x[])172 Word16 median5(Word16 x[])
173 {
174     Word16 x1, x2, x3, x4, x5;
175     Word16 tmp;
176 
177     x1 = x[-2];
178     x2 = x[-1];
179     x3 = x[0];
180     x4 = x[1];
181     x5 = x[2];
182 
183     if (x2 < x1)
184     {
185         tmp = x1;
186         x1 = x2;
187         x2 = tmp;
188     }
189     if (x3 < x1)
190     {
191         tmp = x1;
192         x1 = x3;
193         x3 = tmp;
194     }
195     if (x4 < x1)
196     {
197         tmp = x1;
198         x1 = x4;
199         x4 = tmp;
200     }
201     if (x5 < x1)
202     {
203         x5 = x1;
204     }
205     if (x3 < x2)
206     {
207         tmp = x2;
208         x2 = x3;
209         x3 = tmp;
210     }
211     if (x4 < x2)
212     {
213         tmp = x2;
214         x2 = x4;
215         x4 = tmp;
216     }
217     if (x5 < x2)
218     {
219         x5 = x2;
220     }
221     if (x4 < x3)
222     {
223         x3 = x4;
224     }
225     if (x5 < x3)
226     {
227         x3 = x5;
228     }
229     return (x3);
230 }
231 
232 
Med_olag(Word16 prev_ol_lag,Word16 old_ol_lag[5])233 Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
234         Word16 prev_ol_lag,                /* input  : previous open-loop lag                     */
235         Word16 old_ol_lag[5]
236            )
237 {
238     Word32 i;
239 
240     /* Use median of 5 previous open-loop lags as old lag */
241 
242     for (i = 4; i > 0; i--)
243     {
244         old_ol_lag[i] = old_ol_lag[i - 1];
245     }
246 
247     old_ol_lag[0] = prev_ol_lag;
248 
249     i = median5(&old_ol_lag[2]);
250 
251     return i;
252 
253 }
254 
255 
256 
257