Mercurial > hg > libxtract
comparison src/vector.c @ 56:450712b21565
Added namespacing to enumerations and defines. Made most macros private.
author | Jamie Bullock <jamie@postlude.co.uk> |
---|---|
date | Mon, 29 Jan 2007 11:30:11 +0000 |
parents | 4ea1a8838b14 |
children | 8fd7088c8ff6 |
comparison
equal
deleted
inserted
replaced
55:4ea1a8838b14 | 56:450712b21565 |
---|---|
20 | 20 |
21 | 21 |
22 /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */ | 22 /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */ |
23 | 23 |
24 #include "xtract/libxtract.h" | 24 #include "xtract/libxtract.h" |
25 #include "xtract_macros_private.h" | |
25 #include <math.h> | 26 #include <math.h> |
26 #include <string.h> | 27 #include <string.h> |
27 #include <stdlib.h> | 28 #include <stdlib.h> |
28 | 29 |
29 #ifdef XTRACT_FFT | 30 #ifdef XTRACT_FFT |
30 | 31 |
31 #include <fftw3.h> | 32 #include <fftw3.h> |
32 | 33 |
33 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ | 34 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ |
34 | 35 |
35 float *input, *rfft, nyquist, temp; | 36 float *input, *rfft, q, temp; |
36 size_t bytes; | 37 size_t bytes; |
37 int n , NxN, M, vector; | 38 int n , NxN, M, vector; |
38 fftwf_plan plan; | 39 fftwf_plan plan; |
39 | 40 |
40 M = N >> 1; | 41 M = N >> 1; |
41 NxN = SQ(N); | 42 NxN = XTRACT_SQ(N); |
42 | 43 |
43 rfft = (float *)fftwf_malloc(N * sizeof(float)); | 44 rfft = (float *)fftwf_malloc(N * sizeof(float)); |
44 input = (float *)malloc(bytes = N * sizeof(float)); | 45 input = (float *)malloc(bytes = N * sizeof(float)); |
45 input = memcpy(input, data, bytes); | 46 input = memcpy(input, data, bytes); |
46 | 47 |
47 nyquist = *(float *)argv; | 48 q = *(float *)argv; |
48 vector = (int)*((float *)argv+1); | 49 vector = (int)*((float *)argv+1); |
49 | 50 |
50 CHECK_nyquist; | 51 XTRACT_CHECK_q; |
51 | 52 |
52 plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE); | 53 plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE); |
53 | 54 |
54 fftwf_execute(plan); | 55 fftwf_execute(plan); |
55 | 56 |
56 switch(vector){ | 57 switch(vector){ |
57 case MAGNITUDE_SPECTRUM: | 58 case XTRACT_MAGNITUDE_SPECTRUM: |
58 for(n = 0; n < M; n++){ | 59 for(n = 0; n < M; n++){ |
59 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; | 60 result[n] = sqrt(XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / N; |
60 result[M + n] = n * nyquist; | 61 result[M + n] = n * q; |
61 } | 62 } |
62 break; | 63 break; |
63 case LOG_MAGNITUDE_SPECTRUM: | 64 case XTRACT_LOG_MAGNITUDE_SPECTRUM: |
64 for(n = 0; n < M; n++){ | 65 for(n = 0; n < M; n++){ |
65 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) | 66 if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) > XTRACT_LOG_LIMIT) |
66 temp = log(sqrt(temp) / N); | 67 temp = log(sqrt(temp) / N); |
67 else | 68 else |
68 temp = LOG_LIMIT_DB; | 69 temp = XTRACT_LOG_LIMIT_DB; |
69 /*Normalise*/ | 70 /*Normalise*/ |
70 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; | 71 result[n] = (temp + XTRACT_DB_SCALE_OFFSET) / XTRACT_DB_SCALE_OFFSET; |
71 result[M + n] = n * nyquist; | 72 result[M + n] = n * q; |
72 } | 73 } |
73 break; | 74 break; |
74 case POWER_SPECTRUM: | 75 case XTRACT_POWER_SPECTRUM: |
75 for(n = 0; n < M; n++){ | 76 for(n = 0; n < M; n++){ |
76 result[n] = (SQ(rfft[n]) + SQ(rfft[N - n])) / NxN; | 77 result[n] = (XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / NxN; |
77 result[M + n] = n * nyquist; | 78 result[M + n] = n * q; |
78 } | 79 } |
79 break; | 80 break; |
80 case LOG_POWER_SPECTRUM: | 81 case XTRACT_LOG_POWER_SPECTRUM: |
81 for(n = 0; n < M; n++){ | 82 for(n = 0; n < M; n++){ |
82 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) | 83 if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) > XTRACT_LOG_LIMIT) |
83 temp = log(temp / NxN); | 84 temp = log(temp / NxN); |
84 else | 85 else |
85 temp = LOG_LIMIT_DB; | 86 temp = XTRACT_LOG_LIMIT_DB; |
86 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; | 87 result[n] = (temp + XTRACT_DB_SCALE_OFFSET) / XTRACT_DB_SCALE_OFFSET; |
87 result[M + n] = n * nyquist; | 88 result[M + n] = n * q; |
88 } | 89 } |
89 break; | 90 break; |
90 default: | 91 default: |
91 /* MAGNITUDE_SPECTRUM */ | 92 /* MAGNITUDE_SPECTRUM */ |
92 for(n = 0; n < M; n++){ | 93 for(n = 0; n < M; n++){ |
93 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; | 94 result[n] = sqrt(XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / N; |
94 result[M + n] = n * nyquist; | 95 result[M + n] = n * q; |
95 } | 96 } |
96 break; | 97 break; |
97 } | 98 } |
98 | 99 |
99 /* result[0] = fabs(temp[0]) / N */ | 100 /* result[0] = fabs(temp[0]) / N */ |
100 result[M] = nyquist * .5; | 101 result[N] = q * M; |
101 | 102 |
102 fftwf_destroy_plan(plan); | 103 fftwf_destroy_plan(plan); |
103 fftwf_free(rfft); | 104 fftwf_free(rfft); |
104 free(input); | 105 free(input); |
105 | 106 |
106 return SUCCESS; | 107 return XTRACT_SUCCESS; |
107 } | 108 } |
108 | 109 |
109 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){ | 110 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){ |
110 | 111 |
111 float *temp, *input; | 112 float *temp, *input; |
126 | 127 |
127 fftwf_destroy_plan(plan); | 128 fftwf_destroy_plan(plan); |
128 fftwf_free(temp); | 129 fftwf_free(temp); |
129 free(input); | 130 free(input); |
130 | 131 |
131 return SUCCESS; | 132 return XTRACT_SUCCESS; |
132 } | 133 } |
133 | 134 |
134 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){ | 135 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){ |
135 | 136 |
136 xtract_mel_filter *f; | 137 xtract_mel_filter *f; |
145 | 146 |
146 for(filter = 0; filter < f->n_filters; filter++){ | 147 for(filter = 0; filter < f->n_filters; filter++){ |
147 for(n = 0; n < N; n++){ | 148 for(n = 0; n < N; n++){ |
148 result[filter] += input[n] * f->filters[filter][n]; | 149 result[filter] += input[n] * f->filters[filter][n]; |
149 } | 150 } |
150 if(result[filter] < LOG_LIMIT) result[filter] = LOG_LIMIT; | 151 if(result[filter] < XTRACT_LOG_LIMIT) result[filter] = XTRACT_LOG_LIMIT; |
151 result[filter] = log(result[filter]); | 152 result[filter] = log(result[filter]); |
152 } | 153 } |
153 | 154 |
154 for(n = filter + 1; n < N; n++) result[n] = 0; | 155 for(n = filter + 1; n < N; n++) result[n] = 0; |
155 | 156 |
156 xtract_dct(result, f->n_filters, NULL, result); | 157 xtract_dct(result, f->n_filters, NULL, result); |
157 | 158 |
158 free(input); | 159 free(input); |
159 | 160 |
160 return SUCCESS; | 161 return XTRACT_SUCCESS; |
161 } | 162 } |
162 | 163 |
163 int xtract_dct(const float *data, const int N, const void *argv, float *result){ | 164 int xtract_dct(const float *data, const int N, const void *argv, float *result){ |
164 | 165 |
165 fftwf_plan plan; | 166 fftwf_plan plan; |
174 | 175 |
175 fftwf_execute(plan); | 176 fftwf_execute(plan); |
176 fftwf_destroy_plan(plan); | 177 fftwf_destroy_plan(plan); |
177 free(input); | 178 free(input); |
178 | 179 |
179 return SUCCESS; | 180 return XTRACT_SUCCESS; |
180 } | 181 } |
181 | 182 |
182 #else | 183 #else |
183 | 184 |
184 int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result){ | 185 int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result){ |
221 corr += data[i] * data[i + n]; | 222 corr += data[i] * data[i + n]; |
222 } | 223 } |
223 result[n] = corr / N; | 224 result[n] = corr / N; |
224 } | 225 } |
225 | 226 |
226 return SUCCESS; | 227 return XTRACT_SUCCESS; |
227 } | 228 } |
228 | 229 |
229 int xtract_amdf(const float *data, const int N, const void *argv, float *result){ | 230 int xtract_amdf(const float *data, const int N, const void *argv, float *result){ |
230 | 231 |
231 int n = N, i; | 232 int n = N, i; |
240 md += temp; | 241 md += temp; |
241 } | 242 } |
242 result[n] = md / N; | 243 result[n] = md / N; |
243 } | 244 } |
244 | 245 |
245 return SUCCESS; | 246 return XTRACT_SUCCESS; |
246 } | 247 } |
247 | 248 |
248 int xtract_asdf(const float *data, const int N, const void *argv, float *result){ | 249 int xtract_asdf(const float *data, const int N, const void *argv, float *result){ |
249 | 250 |
250 int n = N, i; | 251 int n = N, i; |
253 | 254 |
254 while(n--){ | 255 while(n--){ |
255 sd = 0; | 256 sd = 0; |
256 for(i = 0; i < N - n; i++){ | 257 for(i = 0; i < N - n; i++){ |
257 /*sd = 1;*/ | 258 /*sd = 1;*/ |
258 sd += SQ(data[i] - data[i + n]); | 259 sd += XTRACT_SQ(data[i] - data[i + n]); |
259 } | 260 } |
260 result[n] = sd / N; | 261 result[n] = sd / N; |
261 } | 262 } |
262 | 263 |
263 return SUCCESS; | 264 return XTRACT_SUCCESS; |
264 } | 265 } |
265 | 266 |
266 int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result){ | 267 int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result){ |
267 | 268 |
268 int *limits, band, n; | 269 int *limits, band, n; |
269 | 270 |
270 limits = (int *)argv; | 271 limits = (int *)argv; |
271 | 272 |
272 for(band = 0; band < BARK_BANDS; band++){ | 273 for(band = 0; band < XTRACT_BARK_BANDS; band++){ |
273 for(n = limits[band]; n < limits[band + 1]; n++) | 274 for(n = limits[band]; n < limits[band + 1]; n++) |
274 result[band] += data[n]; | 275 result[band] += data[n]; |
275 } | 276 } |
276 | 277 |
277 return SUCCESS; | 278 return XTRACT_SUCCESS; |
278 } | 279 } |
279 | 280 |
280 int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){ | 281 int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){ |
281 | 282 |
282 float threshold, max, y, y2, y3, p, nyquist, *input = NULL; | 283 float threshold, max, y, y2, y3, p, q, *input = NULL; |
283 size_t bytes; | 284 size_t bytes; |
284 int n = N, M, rv = SUCCESS; | 285 int n = N, M, rv = XTRACT_SUCCESS; |
285 | 286 |
286 threshold = max = y = y2 = y3 = p = nyquist = 0.f; | 287 threshold = max = y = y2 = y3 = p = q = 0.f; |
287 | 288 |
288 if(argv != NULL){ | 289 if(argv != NULL){ |
289 nyquist = ((float *)argv)[0]; | 290 q = ((float *)argv)[0]; |
290 threshold = ((float *)argv)[1]; | 291 threshold = ((float *)argv)[1]; |
291 } | 292 } |
292 else | 293 else |
293 rv = BAD_ARGV; | 294 rv = XTRACT_BAD_ARGV; |
294 | 295 |
295 if(threshold < 0 || threshold > 100){ | 296 if(threshold < 0 || threshold > 100){ |
296 threshold = 0; | 297 threshold = 0; |
297 rv = BAD_ARGV; | 298 rv = XTRACT_BAD_ARGV; |
298 } | 299 } |
299 | 300 |
300 CHECK_nyquist; | 301 XTRACT_CHECK_q; |
301 | 302 |
302 input = (float *)malloc(bytes = N * sizeof(float)); | 303 input = (float *)malloc(bytes = N * sizeof(float)); |
303 | 304 |
304 if(input != NULL) | 305 if(input != NULL) |
305 input = memcpy(input, data, bytes); | 306 input = memcpy(input, data, bytes); |
306 else | 307 else |
307 return MALLOC_FAILED; | 308 return XTRACT_MALLOC_FAILED; |
308 | 309 |
309 M = N >> 1; | 310 M = N >> 1; |
310 | 311 |
311 while(n--) | 312 while(n--) |
312 max = MAX(max, input[n]); | 313 max = XTRACT_MAX(max, input[n]); |
313 | 314 |
314 threshold *= .01 * max; | 315 threshold *= .01 * max; |
315 | 316 |
316 result[0] = 0; | 317 result[0] = 0; |
317 result[M] = 0; | 318 result[M] = 0; |
318 | 319 |
319 for(n = 1; n < M; n++){ | 320 for(n = 1; n < M; n++){ |
320 if(input[n] >= threshold){ | 321 if(input[n] >= threshold){ |
321 if(input[n] > input[n - 1] && input[n] > input[n + 1]){ | 322 if(input[n] > input[n - 1] && input[n] > input[n + 1]){ |
322 result[M + n] = nyquist * (n + (p = .5 * (y = input[n-1] - | 323 result[M + n] = q * (n + (p = .5 * (y = input[n-1] - |
323 (y3 = input[n+1])) / (input[n - 1] - 2 * | 324 (y3 = input[n+1])) / (input[n - 1] - 2 * |
324 (y2 = input[n]) + input[n + 1]))); | 325 (y2 = input[n]) + input[n + 1]))); |
325 result[n] = y2 - .25 * (y - y3) * p; | 326 result[n] = y2 - .25 * (y - y3) * p; |
326 } | 327 } |
327 else{ | 328 else{ |
334 result[M + n] = 0; | 335 result[M + n] = 0; |
335 } | 336 } |
336 } | 337 } |
337 | 338 |
338 free(input); | 339 free(input); |
339 return (rv ? rv : SUCCESS); | 340 return (rv ? rv : XTRACT_SUCCESS); |
340 } | 341 } |
341 | 342 |
342 int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){ | 343 int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){ |
343 | 344 |
344 int n = (N >> 1), M = n; | 345 int n = (N >> 1), M = n; |
366 } | 367 } |
367 } | 368 } |
368 else | 369 else |
369 result[n] = result[M + n] = 0.f; | 370 result[n] = result[M + n] = 0.f; |
370 } | 371 } |
371 return SUCCESS; | 372 return XTRACT_SUCCESS; |
372 } | 373 } |
373 | 374 |