Mercurial > hg > libxtract
comparison src/vector.c @ 55:4ea1a8838b14
Finished the essentials of descriptors.c
author | Jamie Bullock <jamie@postlude.co.uk> |
---|---|
date | Sun, 21 Jan 2007 14:40:23 +0000 |
parents | 9762d7e3d129 |
children | 450712b21565 |
comparison
equal
deleted
inserted
replaced
54:9762d7e3d129 | 55:4ea1a8838b14 |
---|---|
30 | 30 |
31 #include <fftw3.h> | 31 #include <fftw3.h> |
32 | 32 |
33 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ | 33 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ |
34 | 34 |
35 float *input, *rfft, q, temp; | 35 float *input, *rfft, nyquist, temp; |
36 size_t bytes; | 36 size_t bytes; |
37 int n , NxN, M, vector; | 37 int n , NxN, M, vector; |
38 fftwf_plan plan; | 38 fftwf_plan plan; |
39 | 39 |
40 M = N >> 1; | 40 M = N >> 1; |
42 | 42 |
43 rfft = (float *)fftwf_malloc(N * sizeof(float)); | 43 rfft = (float *)fftwf_malloc(N * sizeof(float)); |
44 input = (float *)malloc(bytes = N * sizeof(float)); | 44 input = (float *)malloc(bytes = N * sizeof(float)); |
45 input = memcpy(input, data, bytes); | 45 input = memcpy(input, data, bytes); |
46 | 46 |
47 q = *(float *)argv; | 47 nyquist = *(float *)argv; |
48 vector = (int)*((float *)argv+1); | 48 vector = (int)*((float *)argv+1); |
49 | 49 |
50 CHECK_q; | 50 CHECK_nyquist; |
51 | 51 |
52 plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE); | 52 plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE); |
53 | 53 |
54 fftwf_execute(plan); | 54 fftwf_execute(plan); |
55 | 55 |
56 switch(vector){ | 56 switch(vector){ |
57 case MAGNITUDE_SPECTRUM: | 57 case MAGNITUDE_SPECTRUM: |
58 for(n = 0; n < M; n++){ | 58 for(n = 0; n < M; n++){ |
59 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; | 59 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; |
60 result[M + n] = n * q; | 60 result[M + n] = n * nyquist; |
61 } | 61 } |
62 break; | 62 break; |
63 case LOG_MAGNITUDE_SPECTRUM: | 63 case LOG_MAGNITUDE_SPECTRUM: |
64 for(n = 0; n < M; n++){ | 64 for(n = 0; n < M; n++){ |
65 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) | 65 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) |
66 temp = log(sqrt(temp) / N); | 66 temp = log(sqrt(temp) / N); |
67 else | 67 else |
68 temp = LOG_LIMIT_DB; | 68 temp = LOG_LIMIT_DB; |
69 /*Normalise*/ | 69 /*Normalise*/ |
70 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; | 70 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; |
71 result[M + n] = n * q; | 71 result[M + n] = n * nyquist; |
72 } | 72 } |
73 break; | 73 break; |
74 case POWER_SPECTRUM: | 74 case POWER_SPECTRUM: |
75 for(n = 0; n < M; n++){ | 75 for(n = 0; n < M; n++){ |
76 result[n] = (SQ(rfft[n]) + SQ(rfft[N - n])) / NxN; | 76 result[n] = (SQ(rfft[n]) + SQ(rfft[N - n])) / NxN; |
77 result[M + n] = n * q; | 77 result[M + n] = n * nyquist; |
78 } | 78 } |
79 break; | 79 break; |
80 case LOG_POWER_SPECTRUM: | 80 case LOG_POWER_SPECTRUM: |
81 for(n = 0; n < M; n++){ | 81 for(n = 0; n < M; n++){ |
82 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) | 82 if ((temp = SQ(rfft[n]) + SQ(rfft[N - n])) > LOG_LIMIT) |
83 temp = log(temp / NxN); | 83 temp = log(temp / NxN); |
84 else | 84 else |
85 temp = LOG_LIMIT_DB; | 85 temp = LOG_LIMIT_DB; |
86 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; | 86 result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET; |
87 result[M + n] = n * q; | 87 result[M + n] = n * nyquist; |
88 } | 88 } |
89 break; | 89 break; |
90 default: | 90 default: |
91 /* MAGNITUDE_SPECTRUM */ | 91 /* MAGNITUDE_SPECTRUM */ |
92 for(n = 0; n < M; n++){ | 92 for(n = 0; n < M; n++){ |
93 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; | 93 result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N; |
94 result[M + n] = n * q; | 94 result[M + n] = n * nyquist; |
95 } | 95 } |
96 break; | 96 break; |
97 } | 97 } |
98 | 98 |
99 /* result[0] = fabs(temp[0]) / N */ | 99 /* result[0] = fabs(temp[0]) / N */ |
100 result[M] = q * .5; | 100 result[M] = nyquist * .5; |
101 | 101 |
102 fftwf_destroy_plan(plan); | 102 fftwf_destroy_plan(plan); |
103 fftwf_free(rfft); | 103 fftwf_free(rfft); |
104 free(input); | 104 free(input); |
105 | 105 |
277 return SUCCESS; | 277 return SUCCESS; |
278 } | 278 } |
279 | 279 |
280 int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){ | 280 int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){ |
281 | 281 |
282 float thresh, max, y, y2, y3, p, q, *input = NULL; | 282 float threshold, max, y, y2, y3, p, nyquist, *input = NULL; |
283 size_t bytes; | 283 size_t bytes; |
284 int n = N, M, rv = SUCCESS; | 284 int n = N, M, rv = SUCCESS; |
285 | 285 |
286 thresh = max = y = y2 = y3 = p = q = 0.f; | 286 threshold = max = y = y2 = y3 = p = nyquist = 0.f; |
287 | 287 |
288 if(argv != NULL){ | 288 if(argv != NULL){ |
289 thresh = ((float *)argv)[0]; | 289 nyquist = ((float *)argv)[0]; |
290 q = ((float *)argv)[1]; | 290 threshold = ((float *)argv)[1]; |
291 } | 291 } |
292 else | 292 else |
293 rv = BAD_ARGV; | 293 rv = BAD_ARGV; |
294 | 294 |
295 if(thresh < 0 || thresh > 100){ | 295 if(threshold < 0 || threshold > 100){ |
296 thresh = 0; | 296 threshold = 0; |
297 rv = BAD_ARGV; | 297 rv = BAD_ARGV; |
298 } | 298 } |
299 | 299 |
300 CHECK_q; | 300 CHECK_nyquist; |
301 | 301 |
302 input = (float *)malloc(bytes = N * sizeof(float)); | 302 input = (float *)malloc(bytes = N * sizeof(float)); |
303 | 303 |
304 if(input != NULL) | 304 if(input != NULL) |
305 input = memcpy(input, data, bytes); | 305 input = memcpy(input, data, bytes); |
309 M = N >> 1; | 309 M = N >> 1; |
310 | 310 |
311 while(n--) | 311 while(n--) |
312 max = MAX(max, input[n]); | 312 max = MAX(max, input[n]); |
313 | 313 |
314 thresh *= .01 * max; | 314 threshold *= .01 * max; |
315 | 315 |
316 result[0] = 0; | 316 result[0] = 0; |
317 result[M] = 0; | 317 result[M] = 0; |
318 | 318 |
319 for(n = 1; n < M; n++){ | 319 for(n = 1; n < M; n++){ |
320 if(input[n] >= thresh){ | 320 if(input[n] >= threshold){ |
321 if(input[n] > input[n - 1] && input[n] > input[n + 1]){ | 321 if(input[n] > input[n - 1] && input[n] > input[n + 1]){ |
322 result[M + n] = q * (n + (p = .5 * (y = input[n-1] - | 322 result[M + n] = nyquist * (n + (p = .5 * (y = input[n-1] - |
323 (y3 = input[n+1])) / (input[n - 1] - 2 * | 323 (y3 = input[n+1])) / (input[n - 1] - 2 * |
324 (y2 = input[n]) + input[n + 1]))); | 324 (y2 = input[n]) + input[n + 1]))); |
325 result[n] = y2 - .25 * (y - y3) * p; | 325 result[n] = y2 - .25 * (y - y3) * p; |
326 } | 326 } |
327 else{ | 327 else{ |
342 int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){ | 342 int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){ |
343 | 343 |
344 int n = (N >> 1), M = n; | 344 int n = (N >> 1), M = n; |
345 | 345 |
346 const float *freqs, *amps; | 346 const float *freqs, *amps; |
347 float f0, thresh, ratio, nearest, distance; | 347 float f0, threshold, ratio, nearest, distance; |
348 | 348 |
349 amps = data; | 349 amps = data; |
350 freqs = data + n; | 350 freqs = data + n; |
351 f0 = *((float *)argv); | 351 f0 = *((float *)argv); |
352 thresh = *((float *)argv+1); | 352 threshold = *((float *)argv+1); |
353 | 353 |
354 ratio = nearest = distance = 0.f; | 354 ratio = nearest = distance = 0.f; |
355 | 355 |
356 while(n--){ | 356 while(n--){ |
357 if(freqs[n]){ | 357 if(freqs[n]){ |
358 ratio = freqs[n] / f0; | 358 ratio = freqs[n] / f0; |
359 nearest = round(ratio); | 359 nearest = round(ratio); |
360 distance = fabs(nearest - ratio); | 360 distance = fabs(nearest - ratio); |
361 if(distance > thresh) | 361 if(distance > threshold) |
362 result[n] = result[M + n] = 0.f; | 362 result[n] = result[M + n] = 0.f; |
363 else { | 363 else { |
364 result[n] = amps[n]; | 364 result[n] = amps[n]; |
365 result[M + n] = freqs[n]; | 365 result[M + n] = freqs[n]; |
366 } | 366 } |