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 }