X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ffft_result.cc;h=37c045b7b052a1b38bd299263060de4a575d0f5c;hb=71a4796dc3dbf8a7fe1df5c5d7acea388b40eae0;hp=f5acef92ed64b6a8ac905d72109549e7bbb0fddf;hpb=22c20ab6f215c0ab24702a479aa6821c25a7d058;p=ardour.git diff --git a/gtk2_ardour/fft_result.cc b/gtk2_ardour/fft_result.cc index f5acef92ed..37c045b7b0 100644 --- a/gtk2_ardour/fft_result.cc +++ b/gtk2_ardour/fft_result.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -31,14 +32,22 @@ using namespace std; FFTResult::FFTResult(FFTGraph *graph, Gdk::Color color, string trackname) { _graph = graph; - + _windowSize = _graph->windowSize(); _dataSize = _windowSize / 2; _averages = 0; - _data = (float *) malloc(sizeof(float) * _dataSize); - memset(_data,0,sizeof(float) * _dataSize); + _data_avg = (float *) malloc(sizeof(float) * _dataSize); + memset(_data_avg,0,sizeof(float) * _dataSize); + + _data_min = (float *) malloc(sizeof(float) * _dataSize); + _data_max = (float *) malloc(sizeof(float) * _dataSize); + + for (int i = 0; i < _dataSize; i++) { + _data_min[i] = FLT_MAX; + _data_max[i] = FLT_MIN; + } _color = color; _trackname = trackname; @@ -47,7 +56,34 @@ FFTResult::FFTResult(FFTGraph *graph, Gdk::Color color, string trackname) void FFTResult::analyzeWindow(float *window) { - _graph->analyze(window, _data); + float *_hanning = _graph->_hanning; + float *_in = _graph->_in; + float *_out = _graph->_out; + + int i; + // Copy the data and apply the hanning window + for (i = 0; i < _windowSize; i++) { + _in[i] = window[ i ] * _hanning[ i ]; + } + + fftwf_execute(_graph->_plan); + + float b = _out[0] * _out[0]; + + _data_avg[0] += b; + if (b < _data_min[0]) _data_min[0] = b; + if (b > _data_max[0]) _data_max[0] = b; + + for (i=1; i < _dataSize - 1; i++) { // TODO: check with Jesse whether this is really correct + b = (_out[i] * _out[i]); + + _data_avg[i] += b; // + (_out[_windowSize-i] * _out[_windowSize-i]);, TODO: thanks to Stefan Kost + + if (_data_min[i] > b) _data_min[i] = b; + if (_data_max[i] < b ) _data_max[i] = b; + } + + _averages++; } @@ -59,21 +95,27 @@ FFTResult::finalize() _maximum = 0.0; return; } - + // Average & scale for (int i = 0; i < _dataSize; i++) { - _data[i] /= _averages; - _data[i] = 10.0f * log10f(_data[i]); + _data_avg[i] /= _averages; + _data_avg[i] = 10.0f * log10f(_data_avg[i]); + + _data_min[i] = 10.0f * log10f(_data_min[i]); + if (_data_min[i] < -10000.0f) { + _data_min[i] = -10000.0f; + } + _data_max[i] = 10.0f * log10f(_data_max[i]); } // find min & max - _minimum = _maximum = _data[0]; - + _minimum = _maximum = _data_avg[0]; + for (int i = 1; i < _dataSize; i++) { - if (_data[i] < _minimum && !isinf(_data[i])) { - _minimum = _data[i]; - } else if (_data[i] > _maximum && !isinf(_data[i])) { - _maximum = _data[i]; + if (_data_avg[i] < _minimum && !isinf(_data_avg[i])) { + _minimum = _data_avg[i]; + } else if (_data_avg[i] > _maximum && !isinf(_data_avg[i])) { + _maximum = _data_avg[i]; } } @@ -82,16 +124,36 @@ FFTResult::finalize() FFTResult::~FFTResult() { - free(_data); + free(_data_avg); + free(_data_min); + free(_data_max); +} + + +float +FFTResult::avgAt(int x) +{ + if (x < 0 || x>= _dataSize) + return 0.0f; + + return _data_avg[x]; } +float +FFTResult::minAt(int x) +{ + if (x < 0 || x>= _dataSize) + return 0.0f; + + return _data_min[x]; +} float -FFTResult::sampleAt(int x) +FFTResult::maxAt(int x) { if (x < 0 || x>= _dataSize) return 0.0f; - return _data[x]; + return _data_max[x]; }