1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
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
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20 
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24 
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31 
32 
33 
34  Filename: /audio/gsm_amr/c/src/hp_max.c
35 
36      Date: 02/01/2002
37 
38 ------------------------------------------------------------------------------
39  REVISION HISTORY
40 
41  Description:  Replaced "int" and/or "char" with OSCL defined types.
42 
43  Description:
44 
45 ------------------------------------------------------------------------------
46 */
47 
48 /*----------------------------------------------------------------------------
49 ; INCLUDES
50 ----------------------------------------------------------------------------*/
51 #include    "hp_max.h"
52 #include    "basic_op.h"
53 #include    "cnst.h"
54 
55 /*----------------------------------------------------------------------------
56 ; MACROS
57 ; [Define module specific macros here]
58 ----------------------------------------------------------------------------*/
59 
60 /*----------------------------------------------------------------------------
61 ; DEFINES
62 ; [Include all pre-processor statements here. Include conditional
63 ; compile variables also.]
64 ----------------------------------------------------------------------------*/
65 
66 /*----------------------------------------------------------------------------
67 ; LOCAL FUNCTION DEFINITIONS
68 ; [List function prototypes here]
69 ----------------------------------------------------------------------------*/
70 
71 /*----------------------------------------------------------------------------
72 ; LOCAL VARIABLE DEFINITIONS
73 ; [Variable declaration - defined here and used outside this module]
74 ----------------------------------------------------------------------------*/
75 
76 /*
77 ------------------------------------------------------------------------------
78  FUNCTION NAME: hp_max
79 ------------------------------------------------------------------------------
80  INPUT AND OUTPUT DEFINITIONS
81 
82  Inputs:
83     corr[] = correlation vector (Word16)
84     scal_sig[] = scaled signal vector (Word16)
85     L_frame = length of frame to compute pitch (Word16
86     lag_max = maximum lag (Word16)
87     lag_min = minimum lag (Word16)
88     cor_hp_max = pointer to max high-pass filtered norm. correlation (Word16)
89     pOverflow = pointer to overflow (Flag)
90 
91  Outputs:
92     cor_hp_max contains max high-pass filtered norm. correlation (Word16)
93     pOverflow -> 1 if the maximum correlation computation resulted in overflow
94 
95  Returns:
96     0 (Word16)
97 
98  Global Variables Used:
99     None
100 
101  Local Variables Needed:
102     None
103 
104 ------------------------------------------------------------------------------
105  FUNCTION DESCRIPTION
106 
107  This function finds the maximum high-pass filtered correlation of scal_sig[]
108  in a given delay range.
109 
110  The correlation is given by
111     corr[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
112  The functions outputs the maximum high-pass filtered correlation after
113  normalization.
114 
115 ------------------------------------------------------------------------------
116  REQUIREMENTS
117 
118  None
119 
120 ------------------------------------------------------------------------------
121  REFERENCES
122 
123  [1] hp_max.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
124 
125 ------------------------------------------------------------------------------
126  PSEUDO-CODE
127 
128 Word16 hp_max (
129     Word32 corr[],      // i   : correlation vector
130     Word16 scal_sig[],  // i   : scaled signal
131     Word16 L_frame,     // i   : length of frame to compute pitch
132     Word16 lag_max,     // i   : maximum lag
133     Word16 lag_min,     // i   : minimum lag
134     Word16 *cor_hp_max) // o   : max high-pass filtered norm. correlation
135 {
136     Word16 i;
137     Word16 *p, *p1;
138     Word32 max, t0, t1;
139     Word16 max16, t016, cor_max;
140     Word16 shift, shift1, shift2;
141 
142     max = MIN_32;
143     t0 = 0L;
144 * The reference ETSI code uses a global flag for Overflow inside the math functions
145 * saturate(). In the actual implementation a pointer to Overflow flag is passed in
146 * as a parameter to the function
147 
148     for (i = lag_max-1; i > lag_min; i--)
149     {
150        // high-pass filtering
151        t0 = L_sub (L_sub(L_shl(corr[-i], 1), corr[-i-1]), corr[-i+1]);
152        t0 = L_abs (t0);
153 
154        if (L_sub (t0, max) >= 0)
155        {
156           max = t0;
157        }
158     }
159 
160     // compute energy
161     p = scal_sig;
162     p1 = &scal_sig[0];
163     t0 = 0L;
164     for (i = 0; i < L_frame; i++, p++, p1++)
165     {
166        t0 = L_mac (t0, *p, *p1);
167     }
168 
169     p = scal_sig;
170     p1 = &scal_sig[-1];
171     t1 = 0L;
172     for (i = 0; i < L_frame; i++, p++, p1++)
173     {
174        t1 = L_mac (t1, *p, *p1);
175     }
176 
177     // high-pass filtering
178     t0 = L_sub(L_shl(t0, 1), L_shl(t1, 1));
179     t0 = L_abs (t0);
180 
181     // max/t0
182     shift1 = sub(norm_l(max), 1);
183     max16  = extract_h(L_shl(max, shift1));
184     shift2 = norm_l(t0);
185     t016 =  extract_h(L_shl(t0, shift2));
186 
187     if (t016 != 0)
188     {
189        cor_max = div_s(max16, t016);
190     }
191     else
192     {
193        cor_max = 0;
194     }
195 
196     shift = sub(shift1, shift2);
197 
198     if (shift >= 0)
199     {
200        *cor_hp_max = shr(cor_max, shift); // Q15
201     }
202     else
203     {
204        *cor_hp_max = shl(cor_max, negate(shift)); // Q15
205     }
206 
207     return 0;
208 }
209 
210 
211 ------------------------------------------------------------------------------
212  RESOURCES USED [optional]
213 
214  When the code is written for a specific target processor the
215  the resources used should be documented below.
216 
217  HEAP MEMORY USED: x bytes
218 
219  STACK MEMORY USED: x bytes
220 
221  CLOCK CYCLES: (cycle count equation for this function) + (variable
222                 used to represent cycle count for each subroutine
223                 called)
224      where: (cycle count variable) = cycle count for [subroutine
225                                      name]
226 
227 ------------------------------------------------------------------------------
228  CAUTION [optional]
229  [State any special notes, constraints or cautions for users of this function]
230 
231 ------------------------------------------------------------------------------
232 */
233 
234 /*----------------------------------------------------------------------------
235 ; FUNCTION CODE
236 ----------------------------------------------------------------------------*/
hp_max(Word32 corr[],Word16 scal_sig[],Word16 L_frame,Word16 lag_max,Word16 lag_min,Word16 * cor_hp_max,Flag * pOverflow)237 Word16 hp_max(
238     Word32 corr[],      /* i   : correlation vector.                      */
239     Word16 scal_sig[],  /* i   : scaled signal.                           */
240     Word16 L_frame,     /* i   : length of frame to compute pitch         */
241     Word16 lag_max,     /* i   : maximum lag                              */
242     Word16 lag_min,     /* i   : minimum lag                              */
243     Word16 *cor_hp_max, /* o   : max high-pass filtered norm. correlation */
244     Flag   *pOverflow   /* i/o : overflow Flag                            */
245 )
246 {
247     Word16 i;
248     Word16 *p, *p1;
249     Word32 max, t0, t1;
250     Word16 max16, t016, cor_max;
251     Word16 shift, shift1, shift2;
252     Word32 L_temp;
253 
254     max = MIN_32;
255     t0 = 0L;
256 
257     for (i = lag_max - 1; i > lag_min; i--)
258     {
259         /* high-pass filtering */
260         t0 = L_shl(corr[-i], 1, pOverflow);
261         L_temp = L_sub(t0, corr[-i-1], pOverflow);
262         t0 = L_sub(L_temp, corr[-i+1], pOverflow);
263         t0 = L_abs(t0);
264 
265         if (t0 >= max)
266         {
267             max = t0;
268         }
269     }
270 
271     /* compute energy */
272     p = scal_sig;
273     p1 = &scal_sig[0];
274     t0 = 0L;
275     for (i = 0; i < L_frame; i++, p++, p1++)
276     {
277         t0 = L_mac(t0, *p, *p1, pOverflow);
278     }
279 
280     p = scal_sig;
281     p1 = &scal_sig[-1];
282     t1 = 0L;
283     for (i = 0; i < L_frame; i++, p++, p1++)
284     {
285         t1 = L_mac(t1, *p, *p1, pOverflow);
286     }
287 
288     /* high-pass filtering */
289     L_temp = L_shl(t0, 1, pOverflow);
290     t1 = L_shl(t1, 1, pOverflow);
291     t0 = L_sub(L_temp, t1, pOverflow);
292     t0 = L_abs(t0);
293 
294     /* max/t0 */
295     /*  shift1 = sub(norm_l(max), 1);
296         max16  = extract_h(L_shl(max, shift1));
297         shift2 = norm_l(t0);
298         t016 =  extract_h(L_shl(t0, shift2));   */
299 
300     t016 = norm_l(max);
301     shift1 = sub(t016, 1, pOverflow);
302 
303     L_temp = L_shl(max, shift1, pOverflow);
304     max16  = (Word16)(L_temp >> 16);
305 
306     shift2 = norm_l(t0);
307     L_temp = L_shl(t0, shift2, pOverflow);
308     t016 = (Word16)(L_temp >> 16);
309 
310     if (t016 != 0)
311     {
312         cor_max = div_s(max16, t016);
313     }
314     else
315     {
316         cor_max = 0;
317     }
318 
319     shift = sub(shift1, shift2, pOverflow);
320 
321     if (shift >= 0)
322     {
323         *cor_hp_max = shr(cor_max, shift, pOverflow); /* Q15 */
324     }
325     else
326     {
327         *cor_hp_max = shl(cor_max, negate(shift), pOverflow); /* Q15 */
328     }
329 
330     return 0;
331 }
332 
333