annotate src/init.c @ 246:bde5fa8692ff

Merge pull request #61 from seanlikeskites/master MSVC fixes
author Jamie Bullock <jamie@jamiebullock.com>
date Fri, 13 Jun 2014 17:29:26 +0100
parents ef80f7c52c6d
children d383a8c66b5d
rev   line source
jamie@141 1 /*
jamie@141 2 * Copyright (C) 2012 Jamie Bullock
jamie@140 3 *
jamie@141 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
jamie@141 5 * of this software and associated documentation files (the "Software"), to
jamie@141 6 * deal in the Software without restriction, including without limitation the
jamie@141 7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
jamie@141 8 * sell copies of the Software, and to permit persons to whom the Software is
jamie@141 9 * furnished to do so, subject to the following conditions:
jamie@1 10 *
jamie@141 11 * The above copyright notice and this permission notice shall be included in
jamie@141 12 * all copies or substantial portions of the Software.
jamie@1 13 *
jamie@141 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jamie@141 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jamie@141 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jamie@141 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jamie@141 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
jamie@141 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
jamie@141 20 * IN THE SOFTWARE.
jamie@1 21 *
jamie@1 22 */
jamie@1 23
jamie@107 24 /* init.c: defines initialisation and free functions. Also contains library constructor routine. */
jamie@1 25
jamie@98 26 #ifdef HAVE_CONFIG_H
jamie@150 27 #include <config.h>
jamie@98 28 #endif
jamie@98 29
jamie@1 30 #include <math.h>
jamie@26 31 #include <stdlib.h>
jamie@140 32 #include <stdio.h>
jamie@140 33
jamie@150 34 #include "fft.h"
jamie@1 35
jamie@159 36 #include "../xtract/libxtract.h"
jamie@107 37 #include "xtract_window_private.h"
jamie@102 38 #define DEFINE_GLOBALS
jamie@98 39 #include "xtract_globals_private.h"
jamie@98 40
jamie@98 41
jamie@150 42
jamie@150 43 #ifdef USE_OOURA
jamie@150 44 void xtract_init_ooura_data(xtract_ooura_data *ooura_data, unsigned int N)
jamie@150 45 {
andrea@211 46 ooura_data->ooura_ip = (int *)calloc(2 + sqrt((double)N), sizeof(int));
jamie@176 47 ooura_data->ooura_w = (double *)calloc(N * 5 / 4, sizeof(double));
jamie@150 48 ooura_data->initialised = true;
jamie@150 49 }
jamie@150 50
jamie@150 51 void xtract_free_ooura_data(xtract_ooura_data *ooura_data)
jamie@150 52 {
jamie@150 53 free(ooura_data->ooura_ip);
jamie@150 54 free(ooura_data->ooura_w);
jamie@150 55 ooura_data->ooura_ip = NULL;
jamie@150 56 ooura_data->ooura_w = NULL;
jamie@150 57 ooura_data->initialised = false;
jamie@150 58 }
jamie@150 59
jamie@150 60 int xtract_init_ooura_(int N, int feature_name)
jamie@150 61 {
jamie@150 62
jamie@150 63 int M = N >> 1;
jamie@150 64
jamie@150 65 if(feature_name == XTRACT_AUTOCORRELATION_FFT)
jamie@150 66 {
jamie@150 67 M = N; /* allow for zero padding */
jamie@150 68 }
jamie@150 69
jamie@150 70 switch(feature_name)
jamie@150 71 {
jamie@150 72 case XTRACT_SPECTRUM:
jamie@150 73 if(ooura_data_spectrum.initialised)
jamie@150 74 {
jamie@150 75 xtract_free_ooura_data(&ooura_data_spectrum);
jamie@150 76 }
jamie@150 77 xtract_init_ooura_data(&ooura_data_spectrum, M);
jamie@150 78 break;
jamie@150 79 case XTRACT_AUTOCORRELATION_FFT:
jamie@150 80 if(ooura_data_autocorrelation_fft.initialised)
jamie@150 81 {
jamie@150 82 xtract_free_ooura_data(&ooura_data_autocorrelation_fft);
jamie@150 83 }
jamie@150 84 xtract_init_ooura_data(&ooura_data_autocorrelation_fft, M);
jamie@150 85 break;
jamie@150 86 case XTRACT_DCT:
jamie@150 87 if(ooura_data_dct.initialised)
jamie@150 88 {
jamie@150 89 xtract_free_ooura_data(&ooura_data_dct);
jamie@150 90 }
jamie@150 91 xtract_init_ooura_data(&ooura_data_dct, M);
jamie@150 92 case XTRACT_MFCC:
jamie@150 93 if(ooura_data_mfcc.initialised)
jamie@150 94 {
jamie@150 95 xtract_free_ooura_data(&ooura_data_mfcc);
jamie@150 96 }
jamie@150 97 xtract_init_ooura_data(&ooura_data_mfcc, M);
jamie@150 98 break;
jamie@150 99 }
jamie@150 100
jamie@150 101 return XTRACT_SUCCESS;
jamie@150 102 }
jamie@150 103
jamie@150 104 void xtract_free_ooura_(void)
jamie@150 105 {
jamie@150 106 if(ooura_data_spectrum.initialised)
jamie@150 107 {
jamie@150 108 xtract_free_ooura_data(&ooura_data_spectrum);
jamie@150 109 }
jamie@150 110 if(ooura_data_autocorrelation_fft.initialised)
jamie@150 111 {
jamie@150 112 xtract_free_ooura_data(&ooura_data_autocorrelation_fft);
jamie@150 113 }
jamie@150 114 if(ooura_data_dct.initialised)
jamie@150 115 {
jamie@150 116 xtract_free_ooura_data(&ooura_data_dct);
jamie@150 117 }
jamie@150 118 if(ooura_data_mfcc.initialised)
jamie@150 119 {
jamie@150 120 xtract_free_ooura_data(&ooura_data_mfcc);
jamie@150 121 }
jamie@150 122 }
jamie@150 123
jamie@150 124 #else
jamie@150 125
jamie@150 126 void xtract_init_vdsp_data(xtract_vdsp_data *vdsp_data, unsigned int N)
jamie@150 127 {
jamie@150 128 vdsp_data->setup = vDSP_create_fftsetupD(log2f(N), FFT_RADIX2);
jamie@164 129 vdsp_data->fft.realp = (double *) malloc((N >> 1) * sizeof(double) + 1);
jamie@164 130 vdsp_data->fft.imagp = (double *) malloc((N >> 1) * sizeof(double) + 1);
jamie@150 131 vdsp_data->log2N = log2f(N);
jamie@150 132 vdsp_data->initialised = true;
jamie@150 133 }
jamie@150 134
jamie@150 135 void xtract_free_vdsp_data(xtract_vdsp_data *vdsp_data)
jamie@150 136 {
jamie@150 137 free(vdsp_data->fft.realp);
jamie@150 138 free(vdsp_data->fft.imagp);
jamie@150 139 vDSP_destroy_fftsetupD(vdsp_data->setup);
jamie@150 140 vdsp_data->fft.realp = NULL;
jamie@150 141 vdsp_data->fft.imagp = NULL;
jamie@150 142 vdsp_data->initialised = false;
jamie@150 143 }
jamie@150 144
jamie@150 145 int xtract_init_vdsp_(int N, int feature_name)
jamie@150 146 {
jamie@150 147 switch(feature_name)
jamie@150 148 {
jamie@150 149 case XTRACT_SPECTRUM:
jamie@150 150 if(vdsp_data_spectrum.initialised)
jamie@150 151 {
jamie@150 152 xtract_free_vdsp_data(&vdsp_data_spectrum);
jamie@150 153 }
jamie@164 154 xtract_init_vdsp_data(&vdsp_data_spectrum, N);
jamie@150 155 break;
jamie@150 156 case XTRACT_AUTOCORRELATION_FFT:
jamie@150 157 if(vdsp_data_autocorrelation_fft.initialised)
jamie@150 158 {
jamie@150 159 xtract_free_vdsp_data(&vdsp_data_autocorrelation_fft);
jamie@150 160 }
jamie@164 161 xtract_init_vdsp_data(&vdsp_data_autocorrelation_fft, N * 2); // allow for zero padding
jamie@150 162 break;
jamie@150 163 case XTRACT_DCT:
jamie@150 164 if(vdsp_data_dct.initialised)
jamie@150 165 {
jamie@150 166 xtract_free_vdsp_data(&vdsp_data_dct);
jamie@150 167 }
jamie@164 168 xtract_init_vdsp_data(&vdsp_data_dct, N);
jamie@150 169 case XTRACT_MFCC:
jamie@150 170 if(vdsp_data_mfcc.initialised)
jamie@150 171 {
jamie@150 172 xtract_free_vdsp_data(&vdsp_data_mfcc);
jamie@150 173 }
jamie@164 174 xtract_init_vdsp_data(&vdsp_data_mfcc, N);
jamie@150 175 break;
jamie@150 176 }
jamie@150 177
jamie@150 178 return XTRACT_SUCCESS;
jamie@150 179 }
jamie@150 180
jamie@150 181 void xtract_free_vdsp_(void)
jamie@150 182 {
jamie@150 183 if(vdsp_data_spectrum.initialised)
jamie@150 184 {
jamie@150 185 xtract_free_vdsp_data(&vdsp_data_spectrum);
jamie@150 186 }
jamie@150 187 if(vdsp_data_autocorrelation_fft.initialised)
jamie@150 188 {
jamie@150 189 xtract_free_vdsp_data(&vdsp_data_autocorrelation_fft);
jamie@150 190 }
jamie@150 191 if(vdsp_data_dct.initialised)
jamie@150 192 {
jamie@150 193 xtract_free_vdsp_data(&vdsp_data_dct);
jamie@150 194 }
jamie@150 195 if(vdsp_data_mfcc.initialised)
jamie@150 196 {
jamie@150 197 xtract_free_vdsp_data(&vdsp_data_mfcc);
jamie@150 198 }
jamie@150 199 }
jamie@150 200
jamie@150 201
jamie@150 202 #endif
jamie@150 203
jamie@150 204 int xtract_init_fft(int N, int feature_name)
jamie@150 205 {
jamie@150 206 if(!xtract_is_poweroftwo(N))
jamie@150 207 {
jamie@150 208 fprintf(stderr,
jamie@150 209 "libxtract: error: only power-of-two FFT sizes are supported by Ooura FFT.\n");
jamie@150 210 exit(EXIT_FAILURE);
jamie@150 211 }
jamie@150 212 #ifdef USE_OOURA
jamie@150 213 return xtract_init_ooura_(N, feature_name);
jamie@150 214 #else
jamie@150 215 return xtract_init_vdsp_(N, feature_name);
jamie@150 216 #endif
jamie@150 217 }
jamie@150 218
jamie@150 219 void xtract_free_fft(void)
jamie@150 220 {
jamie@150 221 #ifdef USE_OOURA
jamie@150 222 xtract_free_ooura_();
jamie@150 223 #else
jamie@150 224 xtract_free_vdsp_();
jamie@150 225 #endif
jamie@150 226 }
jamie@150 227
jamie@150 228
jamie@150 229 int xtract_init_bark(int N, double sr, int *band_limits)
jamie@150 230 {
jamie@150 231
jamie@150 232 double edges[] = {0, 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 20500, 27000}; /* Takes us up to sr = 54kHz (CCRMA: JOS)*/
jamie@150 233
jamie@150 234 int bands = XTRACT_BARK_BANDS;
jamie@150 235
jamie@150 236 while(bands--)
jamie@150 237 band_limits[bands] = edges[bands] / sr * N;
jamie@150 238 /*FIX shohuld use rounding, but couldn't get it to work */
jamie@150 239
jamie@150 240 return XTRACT_SUCCESS;
jamie@150 241 }
jamie@150 242
jamie@146 243 int xtract_init_mfcc(int N, double nyquist, int style, double freq_min, double freq_max, int freq_bands, double **fft_tables)
jamie@140 244 {
jamie@98 245
jamie@140 246 int n, i, k, *fft_peak, M, next_peak;
jamie@146 247 double norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
jamie@107 248 freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
jamie@1 249
jamie@1 250 mel_peak = height_norm = lin_peak = NULL;
jamie@1 251 fft_peak = NULL;
jamie@140 252 norm = 1;
jamie@1 253
jamie@204 254 if (freq_bands <= 1)
jamie@204 255 {
jamie@204 256 return XTRACT_ARGUMENT_ERROR;
jamie@204 257 }
jamie@204 258
jamie@1 259 mel_freq_max = 1127 * log(1 + freq_max / 700);
jamie@1 260 mel_freq_min = 1127 * log(1 + freq_min / 700);
jamie@1 261 freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
jamie@1 262
jamie@146 263 mel_peak = (double *)malloc((freq_bands + 2) * sizeof(double));
jamie@1 264 /* +2 for zeros at start and end */
jamie@202 265
jamie@202 266 if (mel_peak == NULL)
jamie@202 267 {
jamie@202 268 perror("error");
jamie@202 269 return XTRACT_MALLOC_FAILED;
jamie@202 270 }
jamie@202 271
jamie@146 272 lin_peak = (double *)malloc((freq_bands + 2) * sizeof(double));
jamie@202 273
jamie@202 274 if (lin_peak == NULL)
jamie@202 275 {
jamie@202 276 perror("error");
jamie@204 277 free(mel_peak);
jamie@202 278 return XTRACT_MALLOC_FAILED;
jamie@202 279 }
jamie@202 280
jamie@1 281 fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
jamie@202 282
jamie@202 283 if (fft_peak == NULL)
jamie@202 284 {
jamie@202 285 perror("error");
jamie@204 286 free(mel_peak);
jamie@204 287 free(lin_peak);
jamie@202 288 return XTRACT_MALLOC_FAILED;
jamie@202 289 }
jamie@202 290
jamie@146 291 height_norm = (double *)malloc(freq_bands * sizeof(double));
jamie@202 292
jamie@202 293 if (height_norm == NULL)
jamie@202 294 {
jamie@202 295 perror("error");
jamie@204 296 free(mel_peak);
jamie@204 297 free(lin_peak);
jamie@204 298 free(fft_peak);
jamie@107 299 return XTRACT_MALLOC_FAILED;
jamie@202 300 }
jamie@107 301
jamie@1 302 M = N >> 1;
jamie@1 303
jamie@1 304 mel_peak[0] = mel_freq_min;
danstowell@95 305 lin_peak[0] = freq_min; // === 700 * (exp(mel_peak[0] / 1127) - 1);
jamie@1 306 fft_peak[0] = lin_peak[0] / nyquist * M;
jamie@1 307
jamie@1 308
jamie@204 309 for (n = 1; n < (freq_bands + 2); ++n)
jamie@140 310 {
jamie@140 311 //roll out peak locations - mel, linear and linear on fft window scale
jamie@1 312 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
jamie@1 313 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
jamie@1 314 fft_peak[n] = lin_peak[n] / nyquist * M;
jamie@1 315 }
jamie@1 316
jamie@140 317 for (n = 0; n < freq_bands; n++)
jamie@140 318 {
danstowell@100 319 //roll out normalised gain of each peak
jamie@140 320 if (style == XTRACT_EQUAL_GAIN)
jamie@140 321 {
jamie@140 322 height = 1;
jamie@1 323 norm_fact = norm;
jamie@1 324 }
jamie@140 325 else
jamie@140 326 {
jamie@1 327 height = 2 / (lin_peak[n + 2] - lin_peak[n]);
jamie@1 328 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
jamie@1 329 }
jamie@1 330 height_norm[n] = height * norm_fact;
jamie@1 331 }
jamie@1 332
jamie@1 333 i = 0;
jamie@107 334
jamie@140 335 for(n = 0; n < freq_bands; n++)
jamie@140 336 {
jamie@107 337
jamie@107 338 // calculate the rise increment
danstowell@95 339 if(n==0)
danstowell@95 340 inc = height_norm[n] / fft_peak[n];
danstowell@95 341 else
jamie@1 342 inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
jamie@140 343 val = 0;
jamie@107 344
jamie@107 345 // zero the start of the array
jamie@107 346 for(k = 0; k < i; k++)
jamie@146 347 fft_tables[n][k] = 0.0;
jamie@107 348
jamie@107 349 // fill in the rise
jamie@140 350 for(; i <= fft_peak[n]; i++)
jamie@140 351 {
jamie@1 352 fft_tables[n][i] = val;
jamie@1 353 val += inc;
jamie@1 354 }
jamie@107 355
danstowell@95 356 // calculate the fall increment
jamie@1 357 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
jamie@107 358
jamie@1 359 val = 0;
jamie@107 360 next_peak = fft_peak[n + 1];
jamie@107 361
jamie@140 362 // reverse fill the 'fall'
jamie@140 363 for(i = next_peak; i > fft_peak[n]; i--)
jamie@140 364 {
jamie@1 365 fft_tables[n][i] = val;
jamie@1 366 val += inc;
jamie@1 367 }
jamie@39 368
jamie@107 369 // zero the rest of the array
jamie@107 370 for(k = next_peak + 1; k < N; k++)
jamie@146 371 fft_tables[n][k] = 0.0;
jamie@1 372 }
jamie@1 373
jamie@98 374
jamie@98 375 /* Initialise the fft_plan for the DCT */
jamie@140 376 /*
jamie@140 377 * Ooura doesn't support non power-of-two DCT
jamie@98 378 xtract_init_fft(freq_bands, XTRACT_MFCC);
jamie@140 379 */
jamie@98 380
jamie@1 381 free(mel_peak);
jamie@1 382 free(lin_peak);
jamie@1 383 free(height_norm);
jamie@1 384 free(fft_peak);
jamie@1 385
jamie@56 386 return XTRACT_SUCCESS;
jamie@1 387
jamie@1 388 }
jamie@1 389
jamie@161 390 int xtract_init_wavelet_f0_state(void)
jamie@161 391 {
jamie@161 392 dywapitch_inittracking(&wavelet_f0_state);
jamie@162 393 return XTRACT_SUCCESS;
jamie@161 394 }
jamie@161 395
jamie@146 396 double *xtract_init_window(const int N, const int type)
jamie@140 397 {
jamie@146 398 double *window;
jamie@107 399
andrea@211 400 window = (double*)malloc(N * sizeof(double));
jamie@107 401
jamie@140 402 switch (type)
jamie@140 403 {
jamie@140 404 case XTRACT_GAUSS:
jamie@140 405 gauss(window, N, 0.4);
jamie@140 406 break;
jamie@140 407 case XTRACT_HAMMING:
jamie@140 408 hamming(window, N);
jamie@140 409 break;
jamie@140 410 case XTRACT_HANN:
jamie@140 411 hann(window, N);
jamie@140 412 break;
jamie@140 413 case XTRACT_BARTLETT:
jamie@140 414 bartlett(window, N);
jamie@140 415 break;
jamie@140 416 case XTRACT_TRIANGULAR:
jamie@140 417 triangular(window, N);
jamie@140 418 break;
jamie@140 419 case XTRACT_BARTLETT_HANN:
jamie@140 420 bartlett_hann(window, N);
jamie@140 421 break;
jamie@140 422 case XTRACT_BLACKMAN:
jamie@140 423 blackman(window, N);
jamie@140 424 break;
jamie@140 425 case XTRACT_KAISER:
jamie@140 426 kaiser(window, N, 3 * PI);
jamie@140 427 break;
jamie@140 428 case XTRACT_BLACKMAN_HARRIS:
jamie@140 429 blackman_harris(window, N);
jamie@140 430 break;
jamie@140 431 default:
jamie@140 432 hann(window, N);
jamie@140 433 break;
jamie@107 434 }
jamie@107 435
jamie@107 436 return window;
jamie@107 437 }
jamie@107 438
jamie@146 439 void xtract_free_window(double *window)
jamie@140 440 {
jamie@107 441 free(window);
jamie@107 442 }
jamie@107 443
jamie@102 444 #ifdef __GNUC__
jamie@102 445 __attribute__((constructor)) void init()
jamie@102 446 #else
andrea@211 447 void _init()
jamie@102 448 #endif
jamie@102 449 {
jamie@150 450 #ifdef USE_OOURA
jamie@140 451 ooura_data_dct.initialised = false;
jamie@140 452 ooura_data_spectrum.initialised = false;
jamie@140 453 ooura_data_autocorrelation_fft.initialised = false;
jamie@140 454 ooura_data_mfcc.initialised = false;
jamie@173 455 printf("LibXtract compiled with ooura FFT\n");
jamie@150 456 #else
jamie@150 457 vdsp_data_dct.initialised = false;
jamie@150 458 vdsp_data_spectrum.initialised = false;
jamie@150 459 vdsp_data_autocorrelation_fft.initialised = false;
jamie@150 460 vdsp_data_mfcc.initialised = false;
jamie@173 461 printf("LibXtract compiled with Accelerate FFT\n");
jamie@150 462 #endif
jamie@102 463 }