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 Pathname: ./audio/gsm-amr/c/src/cor_h_x.c 35 36 Date: 09/07/2000 37 38 ------------------------------------------------------------------------------ 39 REVISION HISTORY 40 41 Description: Created a separate file for cor_h_x function. 42 43 Description: Synchronized file with UMTS versin 3.2.0. Updated coding 44 template. 45 46 Description: Made the following changes per comments from Phase 2/3 review: 47 1. Modified FOR loop in the code to count down. 48 2. Fixed typecasting issue with TI C compiler. 49 50 Description: Added call to round() and L_shl() functions in the last FOR 51 loop to make code bit-exact. Updated copyright year. 52 53 Description: Modified to pass pOverflow in via a pointer, rather than 54 invoking it as a global variable. 55 56 Description: Made the following changes 57 1. Unrolled the correlation loop and add mechanism control 58 to compute odd or even number of computations. 59 2. Use pointer to avoid continuos addresses calculation 60 2. Eliminated math operations that check for saturation. 61 62 Description: Changed round function name to pv_round to avoid conflict with 63 round function in C standard library. 64 65 Description: 66 67 ------------------------------------------------------------------------------ 68 */ 69 70 /*---------------------------------------------------------------------------- 71 ; INCLUDES 72 ----------------------------------------------------------------------------*/ 73 #include "typedef.h" 74 #include "cnst.h" 75 #include "cor_h_x.h" 76 #include "basic_op.h" 77 78 /*---------------------------------------------------------------------------- 79 ; MACROS 80 ; Define module specific macros here 81 ----------------------------------------------------------------------------*/ 82 83 84 /*---------------------------------------------------------------------------- 85 ; DEFINES 86 ; Include all pre-processor statements here. Include conditional 87 ; compile variables also. 88 ----------------------------------------------------------------------------*/ 89 90 /*---------------------------------------------------------------------------- 91 ; LOCAL FUNCTION DEFINITIONS 92 ; Function Prototype declaration 93 ----------------------------------------------------------------------------*/ 94 95 /*---------------------------------------------------------------------------- 96 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 97 ; Variable declaration - defined here and used outside this module 98 ----------------------------------------------------------------------------*/ 99 100 /*---------------------------------------------------------------------------- 101 ; EXTERNAL FUNCTION REFERENCES 102 ; Declare functions defined elsewhere and referenced in this module 103 ----------------------------------------------------------------------------*/ 104 105 /*---------------------------------------------------------------------------- 106 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 107 ; Declare variables used in this module but defined elsewhere 108 ----------------------------------------------------------------------------*/ 109 110 /* 111 ------------------------------------------------------------------------------ 112 FUNCTION NAME: cor_h_x 113 ------------------------------------------------------------------------------ 114 INPUT AND OUTPUT DEFINITIONS 115 116 Inputs: 117 h = vector containing the impulse response of the weighted synthesis 118 filter; vector contents are of type Word16; vector length is 119 2 * L_SUBFR 120 x = target signal vector; vector contents are of type Word16; vector 121 length is L_SUBFR 122 dn = vector containing the correlation between the target and the 123 impulse response; vector contents are of type Word16; vector 124 length is L_CODE 125 sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all 126 other modes 127 128 Outputs: 129 dn contents are the newly calculated correlation values 130 131 pOverflow = pointer of type Flag * to overflow indicator. 132 133 Returns: 134 None 135 136 Global Variables Used: 137 None 138 139 Local Variables Needed: 140 None 141 142 ------------------------------------------------------------------------------ 143 FUNCTION DESCRIPTION 144 145 This function computes the correlation between the target signal (x) and the 146 impulse response (h). 147 148 The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n], 149 where: n=0,...,L-1 150 151 d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to 152 each position track does not saturate. 153 154 ------------------------------------------------------------------------------ 155 REQUIREMENTS 156 157 None 158 159 ------------------------------------------------------------------------------ 160 REFERENCES 161 162 cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 163 164 ------------------------------------------------------------------------------ 165 PSEUDO-CODE 166 167 void cor_h_x ( 168 Word16 h[], // (i): impulse response of weighted synthesis filter 169 Word16 x[], // (i): target 170 Word16 dn[], // (o): correlation between target and h[] 171 Word16 sf // (i): scaling factor: 2 for 12.2, 1 for others 172 ) 173 { 174 cor_h_x2(h, x, dn, sf, NB_TRACK, STEP); 175 } 176 177 178 void cor_h_x2 ( 179 Word16 h[], // (i): impulse response of weighted synthesis filter 180 Word16 x[], // (i): target 181 Word16 dn[], // (o): correlation between target and h[] 182 Word16 sf, // (i): scaling factor: 2 for 12.2, 1 for others 183 Word16 nb_track,// (i): the number of ACB tracks 184 Word16 step // (i): step size from one pulse position to the next 185 in one track 186 ) 187 { 188 Word16 i, j, k; 189 Word32 s, y32[L_CODE], max, tot; 190 191 // first keep the result on 32 bits and find absolute maximum 192 193 tot = 5; 194 195 for (k = 0; k < nb_track; k++) 196 { 197 max = 0; 198 for (i = k; i < L_CODE; i += step) 199 { 200 s = 0; 201 for (j = i; j < L_CODE; j++) 202 s = L_mac (s, x[j], h[j - i]); 203 204 y32[i] = s; 205 206 s = L_abs (s); 207 if (L_sub (s, max) > (Word32) 0L) 208 max = s; 209 } 210 tot = L_add (tot, L_shr (max, 1)); 211 } 212 213 j = sub (norm_l (tot), sf); 214 215 for (i = 0; i < L_CODE; i++) 216 { 217 dn[i] = pv_round (L_shl (y32[i], j)); 218 } 219 } 220 221 ------------------------------------------------------------------------------ 222 RESOURCES USED [optional] 223 224 When the code is written for a specific target processor the 225 the resources used should be documented below. 226 227 HEAP MEMORY USED: x bytes 228 229 STACK MEMORY USED: x bytes 230 231 CLOCK CYCLES: (cycle count equation for this function) + (variable 232 used to represent cycle count for each subroutine 233 called) 234 where: (cycle count variable) = cycle count for [subroutine 235 name] 236 237 ------------------------------------------------------------------------------ 238 CAUTION [optional] 239 [State any special notes, constraints or cautions for users of this function] 240 241 ------------------------------------------------------------------------------ 242 */ 243 244 void cor_h_x( 245 Word16 h[], /* (i): impulse response of weighted synthesis filter */ 246 Word16 x[], /* (i): target */ 247 Word16 dn[], /* (o): correlation between target and h[] */ 248 Word16 sf, /* (i): scaling factor: 2 for 12.2, 1 for others */ 249 Flag *pOverflow /* (o): pointer to overflow flag */ 250 ) 251 { 252 register Word16 i; 253 register Word16 j; 254 register Word16 k; 255 256 Word32 s; 257 Word32 y32[L_CODE]; 258 Word32 max; 259 Word32 tot; 260 261 Word16 *p_x; 262 Word16 *p_ptr; 263 Word32 *p_y32; 264 265 266 tot = 5; 267 for (k = 0; k < NB_TRACK; k++) /* NB_TRACK = 5 */ 268 { 269 max = 0; 270 for (i = k; i < L_CODE; i += STEP) /* L_CODE = 40; STEP = 5 */ 271 { 272 s = 0; 273 p_x = &x[i]; 274 p_ptr = h; 275 276 for (j = (L_CODE - i - 1) >> 1; j != 0; j--) 277 { 278 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; 279 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; 280 } 281 282 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; 283 284 if (!((L_CODE - i) & 1)) /* if even number of iterations */ 285 { 286 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; 287 } 288 289 y32[i] = s; 290 291 if (s < 0) 292 { 293 s = -s; 294 } 295 296 if (s > max) 297 { 298 max = s; 299 } 300 } 301 302 tot += (max >> 1); 303 } 304 305 306 j = norm_l(tot) - sf; 307 308 p_ptr = dn; 309 p_y32 = y32;; 310 311 for (i = L_CODE >> 1; i != 0; i--) 312 { 313 s = L_shl(*(p_y32++), j, pOverflow); 314 *(p_ptr++) = (s + 0x00008000) >> 16; 315 s = L_shl(*(p_y32++), j, pOverflow); 316 *(p_ptr++) = (s + 0x00008000) >> 16; 317 } 318 319 return; 320 } 321