annotate src/init.c @ 144:7fbca00c2c05

removed floatArray and intArray from Java SWIG bindings
author Jamie Bullock <jamie@jamiebullock.com>
date Tue, 08 Jan 2013 14:32:45 +0000
parents e4f704649c50
children baaa9d8b4d10
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@98 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@140 34 #include "fftsg.h"
jamie@1 35
jamie@98 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@140 42 int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq_max, int freq_bands, float **fft_tables)
jamie@140 43 {
jamie@98 44
jamie@140 45 int n, i, k, *fft_peak, M, next_peak;
jamie@140 46 float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
jamie@107 47 freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
jamie@1 48
jamie@1 49 mel_peak = height_norm = lin_peak = NULL;
jamie@1 50 fft_peak = NULL;
jamie@140 51 norm = 1;
jamie@1 52
jamie@1 53 mel_freq_max = 1127 * log(1 + freq_max / 700);
jamie@1 54 mel_freq_min = 1127 * log(1 + freq_min / 700);
jamie@1 55 freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
jamie@1 56
jamie@140 57 mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 58 /* +2 for zeros at start and end */
jamie@1 59 lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 60 fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
jamie@1 61 height_norm = (float *)malloc(freq_bands * sizeof(float));
jamie@1 62
jamie@140 63 if(mel_peak == NULL || height_norm == NULL ||
jamie@107 64 lin_peak == NULL || fft_peak == NULL)
jamie@107 65 return XTRACT_MALLOC_FAILED;
jamie@107 66
jamie@1 67 M = N >> 1;
jamie@1 68
jamie@1 69 mel_peak[0] = mel_freq_min;
danstowell@95 70 lin_peak[0] = freq_min; // === 700 * (exp(mel_peak[0] / 1127) - 1);
jamie@1 71 fft_peak[0] = lin_peak[0] / nyquist * M;
jamie@1 72
jamie@1 73
jamie@140 74 for (n = 1; n < freq_bands + 2; n++)
jamie@140 75 {
jamie@140 76 //roll out peak locations - mel, linear and linear on fft window scale
jamie@1 77 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
jamie@1 78 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
jamie@1 79 fft_peak[n] = lin_peak[n] / nyquist * M;
jamie@1 80 }
jamie@1 81
jamie@140 82 for (n = 0; n < freq_bands; n++)
jamie@140 83 {
danstowell@100 84 //roll out normalised gain of each peak
jamie@140 85 if (style == XTRACT_EQUAL_GAIN)
jamie@140 86 {
jamie@140 87 height = 1;
jamie@1 88 norm_fact = norm;
jamie@1 89 }
jamie@140 90 else
jamie@140 91 {
jamie@1 92 height = 2 / (lin_peak[n + 2] - lin_peak[n]);
jamie@1 93 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
jamie@1 94 }
jamie@1 95 height_norm[n] = height * norm_fact;
jamie@1 96 }
jamie@1 97
jamie@1 98 i = 0;
jamie@107 99
jamie@140 100 for(n = 0; n < freq_bands; n++)
jamie@140 101 {
jamie@107 102
jamie@107 103 // calculate the rise increment
danstowell@95 104 if(n==0)
danstowell@95 105 inc = height_norm[n] / fft_peak[n];
danstowell@95 106 else
jamie@1 107 inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
jamie@140 108 val = 0;
jamie@107 109
jamie@107 110 // zero the start of the array
jamie@107 111 for(k = 0; k < i; k++)
jamie@107 112 fft_tables[n][k] = 0.f;
jamie@107 113
jamie@107 114 // fill in the rise
jamie@140 115 for(; i <= fft_peak[n]; i++)
jamie@140 116 {
jamie@1 117 fft_tables[n][i] = val;
jamie@1 118 val += inc;
jamie@1 119 }
jamie@107 120
danstowell@95 121 // calculate the fall increment
jamie@1 122 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
jamie@107 123
jamie@1 124 val = 0;
jamie@107 125 next_peak = fft_peak[n + 1];
jamie@107 126
jamie@140 127 // reverse fill the 'fall'
jamie@140 128 for(i = next_peak; i > fft_peak[n]; i--)
jamie@140 129 {
jamie@1 130 fft_tables[n][i] = val;
jamie@1 131 val += inc;
jamie@1 132 }
jamie@39 133
jamie@107 134 // zero the rest of the array
jamie@107 135 for(k = next_peak + 1; k < N; k++)
jamie@107 136 fft_tables[n][k] = 0.f;
jamie@1 137 }
jamie@1 138
jamie@98 139
jamie@98 140 /* Initialise the fft_plan for the DCT */
jamie@140 141 /*
jamie@140 142 * Ooura doesn't support non power-of-two DCT
jamie@98 143 xtract_init_fft(freq_bands, XTRACT_MFCC);
jamie@140 144 */
jamie@98 145
jamie@1 146 free(mel_peak);
jamie@1 147 free(lin_peak);
jamie@1 148 free(height_norm);
jamie@1 149 free(fft_peak);
jamie@1 150
jamie@56 151 return XTRACT_SUCCESS;
jamie@1 152
jamie@1 153 }
jamie@1 154
jamie@140 155 void xtract_init_ooura(xtract_ooura_data *ooura_data, unsigned int N)
jamie@140 156 {
jamie@140 157 ooura_data->ooura_ip = (int *)calloc((2 + sqrt(N)), sizeof(int));
jamie@140 158 ooura_data->ooura_w = (double *)calloc((N - 1), sizeof(double));
jamie@140 159 ooura_data->initialised = true;
jamie@140 160 }
jamie@98 161
jamie@140 162 void xtract_free_ooura(xtract_ooura_data *ooura_data)
jamie@140 163 {
jamie@140 164 free(ooura_data->ooura_ip);
jamie@140 165 free(ooura_data->ooura_w);
jamie@140 166 ooura_data->ooura_ip = NULL;
jamie@140 167 ooura_data->ooura_w = NULL;
jamie@140 168 ooura_data->initialised = false;
jamie@140 169 }
jamie@107 170
jamie@140 171 int xtract_init_fft(int N, int feature_name)
jamie@140 172 {
jamie@107 173
jamie@140 174 int M = N >> 1;
jamie@98 175
jamie@140 176 if(!xtract_is_poweroftwo(N))
jamie@140 177 {
jamie@140 178 fprintf(stderr,
jamie@140 179 "libxtract: error: only power-of-two FFT sizes are supported.\n");
jamie@140 180 exit(EXIT_FAILURE);
jamie@140 181 }
jamie@98 182
jamie@98 183 if(feature_name == XTRACT_AUTOCORRELATION_FFT)
jamie@140 184 {
jamie@140 185 M = N; /* allow for zero padding */
jamie@98 186 }
jamie@98 187
jamie@140 188 switch(feature_name)
jamie@140 189 {
jamie@140 190 case XTRACT_SPECTRUM:
jamie@140 191 if(ooura_data_spectrum.initialised)
jamie@140 192 {
jamie@140 193 xtract_free_ooura(&ooura_data_spectrum);
jamie@140 194 }
jamie@140 195 xtract_init_ooura(&ooura_data_spectrum, M);
jamie@140 196 break;
jamie@140 197 case XTRACT_AUTOCORRELATION_FFT:
jamie@140 198 if(ooura_data_autocorrelation_fft.initialised)
jamie@140 199 {
jamie@140 200 xtract_free_ooura(&ooura_data_autocorrelation_fft);
jamie@140 201 }
jamie@140 202 xtract_init_ooura(&ooura_data_autocorrelation_fft, M);
jamie@140 203 break;
jamie@140 204 case XTRACT_DCT:
jamie@140 205 if(ooura_data_dct.initialised)
jamie@140 206 {
jamie@140 207 xtract_free_ooura(&ooura_data_dct);
jamie@140 208 }
jamie@140 209 xtract_init_ooura(&ooura_data_dct, M);
jamie@140 210 case XTRACT_MFCC:
jamie@140 211 if(ooura_data_mfcc.initialised)
jamie@140 212 {
jamie@140 213 xtract_free_ooura(&ooura_data_mfcc);
jamie@140 214 }
jamie@140 215 xtract_init_ooura(&ooura_data_mfcc, M);
jamie@140 216 break;
jamie@140 217 }
jamie@98 218
jamie@98 219 return XTRACT_SUCCESS;
jamie@98 220 }
jamie@98 221
jamie@140 222 void xtract_free_fft(void)
jamie@140 223 {
jamie@140 224 if(ooura_data_spectrum.initialised)
jamie@140 225 {
jamie@140 226 xtract_free_ooura(&ooura_data_spectrum);
jamie@140 227 }
jamie@140 228 if(ooura_data_autocorrelation_fft.initialised)
jamie@140 229 {
jamie@140 230 xtract_free_ooura(&ooura_data_autocorrelation_fft);
jamie@140 231 }
jamie@140 232 if(ooura_data_dct.initialised)
jamie@140 233 {
jamie@140 234 xtract_free_ooura(&ooura_data_dct);
jamie@140 235 }
jamie@140 236 if(ooura_data_mfcc.initialised)
jamie@140 237 {
jamie@140 238 xtract_free_ooura(&ooura_data_mfcc);
jamie@140 239 }
jamie@110 240 }
jamie@110 241
jamie@140 242 int xtract_init_bark(int N, float sr, int *band_limits)
jamie@140 243 {
jamie@1 244
jamie@38 245 float 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@1 246
jamie@59 247 int bands = XTRACT_BARK_BANDS;
jamie@107 248
jamie@1 249 while(bands--)
jamie@59 250 band_limits[bands] = edges[bands] / sr * N;
jamie@107 251 /*FIX shohuld use rounding, but couldn't get it to work */
jamie@38 252
jamie@56 253 return XTRACT_SUCCESS;
jamie@1 254 }
jamie@98 255
jamie@140 256 float *xtract_init_window(const int N, const int type)
jamie@140 257 {
jamie@107 258 float *window;
jamie@107 259
jamie@107 260 window = malloc(N * sizeof(float));
jamie@107 261
jamie@140 262 switch (type)
jamie@140 263 {
jamie@140 264 case XTRACT_GAUSS:
jamie@140 265 gauss(window, N, 0.4);
jamie@140 266 break;
jamie@140 267 case XTRACT_HAMMING:
jamie@140 268 hamming(window, N);
jamie@140 269 break;
jamie@140 270 case XTRACT_HANN:
jamie@140 271 hann(window, N);
jamie@140 272 break;
jamie@140 273 case XTRACT_BARTLETT:
jamie@140 274 bartlett(window, N);
jamie@140 275 break;
jamie@140 276 case XTRACT_TRIANGULAR:
jamie@140 277 triangular(window, N);
jamie@140 278 break;
jamie@140 279 case XTRACT_BARTLETT_HANN:
jamie@140 280 bartlett_hann(window, N);
jamie@140 281 break;
jamie@140 282 case XTRACT_BLACKMAN:
jamie@140 283 blackman(window, N);
jamie@140 284 break;
jamie@140 285 case XTRACT_KAISER:
jamie@140 286 kaiser(window, N, 3 * PI);
jamie@140 287 break;
jamie@140 288 case XTRACT_BLACKMAN_HARRIS:
jamie@140 289 blackman_harris(window, N);
jamie@140 290 break;
jamie@140 291 default:
jamie@140 292 hann(window, N);
jamie@140 293 break;
jamie@107 294 }
jamie@107 295
jamie@107 296 return window;
jamie@107 297 }
jamie@107 298
jamie@140 299 void xtract_free_window(float *window)
jamie@140 300 {
jamie@107 301 free(window);
jamie@107 302 }
jamie@107 303
jamie@102 304 #ifdef __GNUC__
jamie@102 305 __attribute__((constructor)) void init()
jamie@102 306 #else
jamie@140 307 void _init()ยท
jamie@102 308 #endif
jamie@102 309 {
jamie@140 310 ooura_data_dct.initialised = false;
jamie@140 311 ooura_data_spectrum.initialised = false;
jamie@140 312 ooura_data_autocorrelation_fft.initialised = false;
jamie@140 313 ooura_data_mfcc.initialised = false;
jamie@102 314 }