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 ----------------------------------------------------------------------------*/ 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