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