X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ffft.cc;h=a4e34bf2aafedbb56116c372772ef017c2320506;hb=20ea90a186748f34061fec323faa74f084c7937c;hp=eda1a96e3f6c601b6cad76fdd5d80cc15d2db969;hpb=1bca6b5c74064b9e8a6f70b45fb1c04a95534d30;p=ardour.git diff --git a/gtk2_ardour/fft.cc b/gtk2_ardour/fft.cc index eda1a96e3f..a4e34bf2aa 100644 --- a/gtk2_ardour/fft.cc +++ b/gtk2_ardour/fft.cc @@ -23,10 +23,13 @@ #include #include +using namespace GTKArdour; + FFT::FFT(uint32_t windowSize) : _window_size(windowSize), _data_size(_window_size/2), - _iterations(0) + _iterations(0), + _hann_window(0) { _fftInput = (float *) fftwf_malloc(sizeof(float) * _window_size); @@ -45,17 +48,24 @@ FFT::reset() { memset(_power_at_bin, 0, sizeof(float) * _data_size); memset(_phase_at_bin, 0, sizeof(float) * _data_size); - + _iterations = 0; } void -FFT::analyze(ARDOUR::Sample *input) +FFT::analyze(ARDOUR::Sample *input, WindowingType windowing_type) { _iterations++; memcpy(_fftInput, input, sizeof(float) * _window_size); + if (windowing_type == HANN) { + float *window = get_hann_window(); + for (uint32_t i = 0; i < _window_size; i++) { + _fftInput[i] *= window[i]; + } + } + fftwf_execute(_plan); _power_at_bin[0] += _fftOutput[0] * _fftOutput[0]; @@ -66,11 +76,11 @@ FFT::analyze(ARDOUR::Sample *input) #define Re (_fftOutput[i]) #define Im (_fftOutput[_window_size-i]) - for (uint32_t i=1; i < _data_size - 1; i++) { + for (uint32_t i=1; i < _data_size - 1; i++) { power = (Re * Re) + (Im * Im); phase = atanf(Im / Re); - + if (Re < 0.0 && Im > 0.0) { phase += M_PI; } else if (Re < 0.0 && Im < 0.0) { @@ -88,7 +98,7 @@ void FFT::calculate() { if (_iterations > 1) { - for (uint32_t i=0; i < _data_size - 1; i++) { + for (uint32_t i=0; i < _data_size - 1; i++) { _power_at_bin[i] /= (float)_iterations; _phase_at_bin[i] /= (float)_iterations; } @@ -96,9 +106,37 @@ FFT::calculate() } } +float * +FFT::get_hann_window() +{ + if (_hann_window) + return _hann_window; + + + _hann_window = (float *) malloc(sizeof(float) * _window_size); + + double sum = 0.0; + + for (uint32_t i=0; i < _window_size; i++) { + _hann_window[i]=0.81f * ( 0.5f - (0.5f * (float) cos(2.0f * M_PI * (float)i / (float)(_window_size)))); + sum += _hann_window[i]; + } + + double isum = 1.0 / sum; + + for (uint32_t i=0; i < _window_size; i++) { + _hann_window[i] *= isum; + } + + return _hann_window; +} + FFT::~FFT() { + if (_hann_window) { + free(_hann_window); + } fftwf_destroy_plan(_plan); free(_power_at_bin); free(_phase_at_bin);