Tristan Matthews | 0a329cc | 2013-07-17 13:20:14 -0400 | [diff] [blame] | 1 | |
| 2 | /****************************************************************** |
| 3 | |
| 4 | iLBC Speech Coder ANSI-C Source Code |
| 5 | |
| 6 | helpfun.c |
| 7 | |
| 8 | Copyright (C) The Internet Society (2004). |
| 9 | All Rights Reserved. |
| 10 | |
| 11 | ******************************************************************/ |
| 12 | |
| 13 | #include <math.h> |
| 14 | |
| 15 | #include "iLBC_define.h" |
| 16 | #include "constants.h" |
| 17 | |
| 18 | /*----------------------------------------------------------------* |
| 19 | * calculation of auto correlation |
| 20 | *---------------------------------------------------------------*/ |
| 21 | |
| 22 | void autocorr( |
| 23 | float *r, /* (o) autocorrelation vector */ |
| 24 | const float *x, /* (i) data vector */ |
| 25 | int N, /* (i) length of data vector */ |
| 26 | int order /* largest lag for calculated |
| 27 | autocorrelations */ |
| 28 | ){ |
| 29 | int lag, n; |
| 30 | float sum; |
| 31 | |
| 32 | for (lag = 0; lag <= order; lag++) { |
| 33 | sum = 0; |
| 34 | for (n = 0; n < N - lag; n++) { |
| 35 | sum += x[n] * x[n+lag]; |
| 36 | } |
| 37 | r[lag] = sum; |
| 38 | } |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | } |
| 45 | |
| 46 | /*----------------------------------------------------------------* |
| 47 | * window multiplication |
| 48 | *---------------------------------------------------------------*/ |
| 49 | |
| 50 | void window( |
| 51 | float *z, /* (o) the windowed data */ |
| 52 | const float *x, /* (i) the original data vector */ |
| 53 | const float *y, /* (i) the window */ |
| 54 | int N /* (i) length of all vectors */ |
| 55 | ){ |
| 56 | int i; |
| 57 | |
| 58 | for (i = 0; i < N; i++) { |
| 59 | z[i] = x[i] * y[i]; |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | /*----------------------------------------------------------------* |
| 64 | * levinson-durbin solution for lpc coefficients |
| 65 | *---------------------------------------------------------------*/ |
| 66 | |
| 67 | void levdurb( |
| 68 | float *a, /* (o) lpc coefficient vector starting |
| 69 | with 1.0 */ |
| 70 | float *k, /* (o) reflection coefficients */ |
| 71 | float *r, /* (i) autocorrelation vector */ |
| 72 | int order /* (i) order of lpc filter */ |
| 73 | ){ |
| 74 | float sum, alpha; |
| 75 | int m, m_h, i; |
| 76 | |
| 77 | a[0] = 1.0; |
| 78 | |
| 79 | if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ |
| 80 | for (i = 0; i < order; i++) { |
| 81 | k[i] = 0; |
| 82 | a[i+1] = 0; |
| 83 | } |
| 84 | } else { |
| 85 | a[1] = k[0] = -r[1]/r[0]; |
| 86 | alpha = r[0] + r[1] * k[0]; |
| 87 | for (m = 1; m < order; m++){ |
| 88 | sum = r[m + 1]; |
| 89 | for (i = 0; i < m; i++){ |
| 90 | sum += a[i+1] * r[m - i]; |
| 91 | } |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 | k[m] = -sum / alpha; |
| 98 | alpha += k[m] * sum; |
| 99 | m_h = (m + 1) >> 1; |
| 100 | for (i = 0; i < m_h; i++){ |
| 101 | sum = a[i+1] + k[m] * a[m - i]; |
| 102 | a[m - i] += k[m] * a[i+1]; |
| 103 | a[i+1] = sum; |
| 104 | } |
| 105 | a[m+1] = k[m]; |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /*----------------------------------------------------------------* |
| 111 | * interpolation between vectors |
| 112 | *---------------------------------------------------------------*/ |
| 113 | |
| 114 | void interpolate( |
| 115 | float *out, /* (o) the interpolated vector */ |
| 116 | float *in1, /* (i) the first vector for the |
| 117 | interpolation */ |
| 118 | float *in2, /* (i) the second vector for the |
| 119 | interpolation */ |
| 120 | float coef, /* (i) interpolation weights */ |
| 121 | int length /* (i) length of all vectors */ |
| 122 | ){ |
| 123 | int i; |
| 124 | float invcoef; |
| 125 | |
| 126 | invcoef = (float)1.0 - coef; |
| 127 | for (i = 0; i < length; i++) { |
| 128 | out[i] = coef * in1[i] + invcoef * in2[i]; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | /*----------------------------------------------------------------* |
| 133 | * lpc bandwidth expansion |
| 134 | *---------------------------------------------------------------*/ |
| 135 | |
| 136 | void bwexpand( |
| 137 | float *out, /* (o) the bandwidth expanded lpc |
| 138 | coefficients */ |
| 139 | float *in, /* (i) the lpc coefficients before bandwidth |
| 140 | expansion */ |
| 141 | float coef, /* (i) the bandwidth expansion factor */ |
| 142 | int length /* (i) the length of lpc coefficient vectors */ |
| 143 | ){ |
| 144 | int i; |
| 145 | |
| 146 | |
| 147 | |
| 148 | |
| 149 | |
| 150 | float chirp; |
| 151 | |
| 152 | chirp = coef; |
| 153 | |
| 154 | out[0] = in[0]; |
| 155 | for (i = 1; i < length; i++) { |
| 156 | out[i] = chirp * in[i]; |
| 157 | chirp *= coef; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /*----------------------------------------------------------------* |
| 162 | * vector quantization |
| 163 | *---------------------------------------------------------------*/ |
| 164 | |
| 165 | void vq( |
| 166 | float *Xq, /* (o) the quantized vector */ |
| 167 | int *index, /* (o) the quantization index */ |
| 168 | const float *CB,/* (i) the vector quantization codebook */ |
| 169 | float *X, /* (i) the vector to quantize */ |
| 170 | int n_cb, /* (i) the number of vectors in the codebook */ |
| 171 | int dim /* (i) the dimension of all vectors */ |
| 172 | ){ |
| 173 | int i, j; |
| 174 | int pos, minindex; |
| 175 | float dist, tmp, mindist; |
| 176 | |
| 177 | pos = 0; |
| 178 | mindist = FLOAT_MAX; |
| 179 | minindex = 0; |
| 180 | for (j = 0; j < n_cb; j++) { |
| 181 | dist = X[0] - CB[pos]; |
| 182 | dist *= dist; |
| 183 | for (i = 1; i < dim; i++) { |
| 184 | tmp = X[i] - CB[pos + i]; |
| 185 | dist += tmp*tmp; |
| 186 | } |
| 187 | |
| 188 | if (dist < mindist) { |
| 189 | mindist = dist; |
| 190 | minindex = j; |
| 191 | } |
| 192 | pos += dim; |
| 193 | } |
| 194 | for (i = 0; i < dim; i++) { |
| 195 | Xq[i] = CB[minindex*dim + i]; |
| 196 | } |
| 197 | *index = minindex; |
| 198 | |
| 199 | |
| 200 | |
| 201 | |
| 202 | |
| 203 | } |
| 204 | |
| 205 | /*----------------------------------------------------------------* |
| 206 | * split vector quantization |
| 207 | *---------------------------------------------------------------*/ |
| 208 | |
| 209 | void SplitVQ( |
| 210 | float *qX, /* (o) the quantized vector */ |
| 211 | int *index, /* (o) a vector of indexes for all vector |
| 212 | codebooks in the split */ |
| 213 | float *X, /* (i) the vector to quantize */ |
| 214 | const float *CB,/* (i) the quantizer codebook */ |
| 215 | int nsplit, /* the number of vector splits */ |
| 216 | const int *dim, /* the dimension of X and qX */ |
| 217 | const int *cbsize /* the number of vectors in the codebook */ |
| 218 | ){ |
| 219 | int cb_pos, X_pos, i; |
| 220 | |
| 221 | cb_pos = 0; |
| 222 | X_pos= 0; |
| 223 | for (i = 0; i < nsplit; i++) { |
| 224 | vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, |
| 225 | cbsize[i], dim[i]); |
| 226 | X_pos += dim[i]; |
| 227 | cb_pos += dim[i] * cbsize[i]; |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | /*----------------------------------------------------------------* |
| 232 | * scalar quantization |
| 233 | *---------------------------------------------------------------*/ |
| 234 | |
| 235 | void sort_sq( |
| 236 | float *xq, /* (o) the quantized value */ |
| 237 | int *index, /* (o) the quantization index */ |
| 238 | float x, /* (i) the value to quantize */ |
| 239 | const float *cb,/* (i) the quantization codebook */ |
| 240 | int cb_size /* (i) the size of the quantization codebook */ |
| 241 | ){ |
| 242 | int i; |
| 243 | |
| 244 | if (x <= cb[0]) { |
| 245 | *index = 0; |
| 246 | *xq = cb[0]; |
| 247 | } else { |
| 248 | i = 0; |
| 249 | while ((x > cb[i]) && i < cb_size - 1) { |
| 250 | i++; |
| 251 | |
| 252 | |
| 253 | |
| 254 | |
| 255 | |
| 256 | } |
| 257 | |
| 258 | if (x > ((cb[i] + cb[i - 1])/2)) { |
| 259 | *index = i; |
| 260 | *xq = cb[i]; |
| 261 | } else { |
| 262 | *index = i - 1; |
| 263 | *xq = cb[i - 1]; |
| 264 | } |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | /*----------------------------------------------------------------* |
| 269 | * check for stability of lsf coefficients |
| 270 | *---------------------------------------------------------------*/ |
| 271 | |
| 272 | int LSF_check( /* (o) 1 for stable lsf vectors and 0 for |
| 273 | nonstable ones */ |
| 274 | float *lsf, /* (i) a table of lsf vectors */ |
| 275 | int dim, /* (i) the dimension of each lsf vector */ |
| 276 | int NoAn /* (i) the number of lsf vectors in the |
| 277 | table */ |
| 278 | ){ |
| 279 | int k,n,m, Nit=2, change=0,pos; |
| 280 | float tmp; |
| 281 | static float eps=(float)0.039; /* 50 Hz */ |
| 282 | static float eps2=(float)0.0195; |
| 283 | static float maxlsf=(float)3.14; /* 4000 Hz */ |
| 284 | static float minlsf=(float)0.01; /* 0 Hz */ |
| 285 | |
| 286 | /* LSF separation check*/ |
| 287 | |
| 288 | for (n=0; n<Nit; n++) { /* Run through a couple of times */ |
| 289 | for (m=0; m<NoAn; m++) { /* Number of analyses per frame */ |
| 290 | for (k=0; k<(dim-1); k++) { |
| 291 | pos=m*dim+k; |
| 292 | |
| 293 | if ((lsf[pos+1]-lsf[pos])<eps) { |
| 294 | |
| 295 | if (lsf[pos+1]<lsf[pos]) { |
| 296 | tmp=lsf[pos+1]; |
| 297 | lsf[pos+1]= lsf[pos]+eps2; |
| 298 | lsf[pos]= lsf[pos+1]-eps2; |
| 299 | } else { |
| 300 | lsf[pos]-=eps2; |
| 301 | lsf[pos+1]+=eps2; |
| 302 | } |
| 303 | change=1; |
| 304 | |
| 305 | |
| 306 | |
| 307 | |
| 308 | |
| 309 | } |
| 310 | |
| 311 | if (lsf[pos]<minlsf) { |
| 312 | lsf[pos]=minlsf; |
| 313 | change=1; |
| 314 | } |
| 315 | |
| 316 | if (lsf[pos]>maxlsf) { |
| 317 | lsf[pos]=maxlsf; |
| 318 | change=1; |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | return change; |
| 325 | } |
| 326 | |