p_med_ol.c revision 58996b6fa078bde4b8a68891962b43383848c190
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
31Word16 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
172Word16 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
233Word16 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