1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   FFTwrapper.c  -  A wrapper for Fast Fourier Transforms
5   Copyright (C) 2002-2005 Nasca Octavian Paul
6   Author: Nasca Octavian Paul
7 
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License
10   as published by the Free Software Foundation; either version 2
11   of the License, or (at your option) any later version.
12 */
13 
14 #include <cmath>
15 #include <cassert>
16 #include <cstring>
17 #include <pthread.h>
18 #include "FFTwrapper.h"
19 
20 namespace zyn {
21 
22 static pthread_mutex_t *mutex = NULL;
23 
24 FFTwrapper::FFTwrapper(int fftsize_)
25 {
26     //first one will spawn the mutex (yeah this may be a race itself)
27     if(!mutex) {
28         mutex = new pthread_mutex_t;
29         pthread_mutex_init(mutex, NULL);
30     }
31 
32 
33     fftsize  = fftsize_;
34     time     = new fftwf_real[fftsize];
35     fft      = new fftwf_complex[fftsize + 1];
36     pthread_mutex_lock(mutex);
37     planfftw = fftwf_plan_dft_r2c_1d(fftsize,
38                                     time,
39                                     fft,
40                                     FFTW_ESTIMATE);
41     planfftw_inv = fftwf_plan_dft_c2r_1d(fftsize,
42                                         fft,
43                                         time,
44                                         FFTW_ESTIMATE);
45     pthread_mutex_unlock(mutex);
46 }
47 
48 FFTwrapper::~FFTwrapper()
49 {
50     pthread_mutex_lock(mutex);
51     fftwf_destroy_plan(planfftw);
52     fftwf_destroy_plan(planfftw_inv);
53     pthread_mutex_unlock(mutex);
54 
55     delete [] time;
56     delete [] fft;
57 }
58 
59 void FFTwrapper::smps2freqs(const float *smps, fft_t *freqs)
60 {
61     //Load data
62     memcpy((void *)time, (const void *)smps, fftsize * sizeof(float));
63 
64     //DFT
65     fftwf_execute(planfftw);
66 
67     //Grab data
68     memcpy((void *)freqs, (const void *)fft, fftsize * sizeof(float));
69 }
70 
71 void FFTwrapper::freqs2smps(const fft_t *freqs, float *smps)
72 {
73     //Load data
74     memcpy((void *)fft, (const void *)freqs, fftsize * sizeof(float));
75 
76     //clear unused freq channel
77     fft[fftsize / 2][0] = 0.0f;
78     fft[fftsize / 2][1] = 0.0f;
79 
80     //IDFT
81     fftwf_execute(planfftw_inv);
82 
83     //Grab data
84     memcpy((void*)smps, (const void*)time, fftsize * sizeof(float));
85 }
86 
87 void FFT_cleanup()
88 {
89     fftwf_cleanup();
90     pthread_mutex_destroy(mutex);
91     delete mutex;
92     mutex = NULL;
93 }
94 
95 }
96