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