# HG changeset patch # User Chris Cannam # Date 1151338331 0 # Node ID 12340cb6e6cb3a0b5dd7fc0858bc2bb02010ae33 # Parent 4772fc75ac7c65befad4fdf17040fc3e9686064f * Add FFT data server class to provide a file cache mapping for each required set of FFT parameters and source model. Make use of it in feature extraction plugin transform, though not in other places yet. * Add zero-pad option to spectrogram layer and remove window shape option from the property box. To be revised. diff -r 4772fc75ac7c -r 12340cb6e6cb layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Mon Jun 26 16:08:57 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Mon Jun 26 16:12:11 2006 +0000 @@ -36,31 +36,6 @@ //#define DEBUG_SPECTROGRAM_REPAINT 1 -static double mod(double x, double y) -{ - double a = floor(x / y); - double b = x - (y * a); - return b; -} - -static float modf(float x, float y) -{ - float a = floorf(x / y); - float b = x - (y * a); - return b; -} - -static double princarg(double ang) -{ - return mod(ang + M_PI, -2 * M_PI) + M_PI; -} - -static float princargf(float ang) -{ - return modf(ang + M_PI, -2 * M_PI) + M_PI; -} - - SpectrogramLayer::SpectrogramLayer(Configuration config) : Layer(), m_model(0), @@ -68,6 +43,7 @@ m_windowSize(1024), m_windowType(HanningWindow), m_windowHopLevel(2), + m_zeroPadLevel(0), m_fftSize(1024), m_gain(1.0), m_threshold(0.0), @@ -91,13 +67,13 @@ if (config == MelodicRange) { setWindowSize(8192); setWindowHopLevel(4); - setWindowType(ParzenWindow); +// setWindowType(ParzenWindow); setMaxFrequency(1000); setColourScale(LinearColourScale); } else if (config == MelodicPeaks) { setWindowSize(4096); setWindowHopLevel(5); - setWindowType(BlackmanWindow); +// setWindowType(BlackmanWindow); setMaxFrequency(2000); setMinFrequency(40); setFrequencyScale(LogFrequencyScale); @@ -154,7 +130,7 @@ PropertyList list; list.push_back("Colour"); list.push_back("Colour Scale"); - list.push_back("Window Type"); +// list.push_back("Window Type"); list.push_back("Window Size"); list.push_back("Window Increment"); list.push_back("Normalize Columns"); @@ -165,6 +141,7 @@ list.push_back("Min Frequency"); list.push_back("Max Frequency"); list.push_back("Frequency Scale"); + list.push_back("Zero Padding"); return list; } @@ -184,6 +161,7 @@ if (name == "Min Frequency") return tr("Min Frequency"); if (name == "Max Frequency") return tr("Max Frequency"); if (name == "Frequency Scale") return tr("Frequency Scale"); + if (name == "Zero Padding") return tr("Smoothing"); return ""; } @@ -194,6 +172,7 @@ if (name == "Colour Rotation") return RangeProperty; if (name == "Normalize Columns") return ToggleProperty; if (name == "Threshold") return RangeProperty; + if (name == "Zero Padding") return ToggleProperty; return ValueProperty; } @@ -202,7 +181,8 @@ { if (name == "Window Size" || name == "Window Type" || - name == "Window Increment") return tr("Window"); + name == "Window Increment" || + name == "Zero Padding") return tr("Window"); if (name == "Colour" || name == "Gain" || name == "Threshold" || @@ -289,6 +269,13 @@ deft = m_windowHopLevel; + } else if (name == "Zero Padding") { + + *min = 0; + *max = 1; + + deft = m_zeroPadLevel > 0 ? 1 : 0; + } else if (name == "Min Frequency") { *min = 0; @@ -399,6 +386,10 @@ case 5: return tr("1/16"); } } + if (name == "Zero Padding") { + if (value == 0) return tr("None"); + return QString("%1x").arg(value + 1); + } if (name == "Min Frequency") { switch (value) { default: @@ -474,6 +465,8 @@ setWindowSize(32 << value); } else if (name == "Window Increment") { setWindowHopLevel(value); + } else if (name == "Zero Padding") { + setZeroPadLevel(value > 0.1 ? 3 : 0); } else if (name == "Min Frequency") { switch (value) { default: @@ -585,7 +578,7 @@ invalidatePixmapCaches(); m_windowSize = ws; - m_fftSize = ws; + m_fftSize = ws * (m_zeroPadLevel + 1); m_mutex.unlock(); @@ -625,6 +618,31 @@ } void +SpectrogramLayer::setZeroPadLevel(size_t v) +{ + if (m_zeroPadLevel == v) return; + + m_mutex.lock(); + m_cacheInvalid = true; + invalidatePixmapCaches(); + + m_zeroPadLevel = v; + m_fftSize = m_windowSize * (v + 1); + + m_mutex.unlock(); + + emit layerParametersChanged(); + + fillCache(); +} + +size_t +SpectrogramLayer::getZeroPadLevel() const +{ + return m_zeroPadLevel; +} + +void SpectrogramLayer::setWindowType(WindowType w) { if (m_windowType == w) return; @@ -1150,7 +1168,8 @@ } size_t got = m_model->getValues(m_channel, startFrame + pfx, - endFrame, input + pfx); + endFrame, input + off + pfx); + while (got + pfx < windowSize) { input[off + got + pfx] = 0.0; ++got; @@ -1165,12 +1184,12 @@ } } - windower.cut(input); - - for (size_t i = 0; i < windowSize/2; ++i) { - fftsample temp = input[off + i]; - input[off + i] = input[off + i + windowSize/2]; - input[off + i + windowSize/2] = temp; + windower.cut(input + off); + + for (size_t i = 0; i < fftSize/2; ++i) { + fftsample temp = input[i]; + input[i] = input[i + fftSize/2]; + input[i + fftSize/2] = temp; } fftwf_execute(plan); @@ -1181,7 +1200,7 @@ fftsample mag = sqrtf(output[i][0] * output[i][0] + output[i][1] * output[i][1]); - mag /= fftSize / 2; + mag /= windowSize / 2; if (mag > factor) factor = mag; @@ -1341,13 +1360,13 @@ if (!m_layer.m_writeCache) { m_layer.m_writeCache = new FFTFileCache (QString("%1").arg(getObjectExportId(&m_layer)), - MatrixFile::ReadWrite); + MatrixFile::ReadWrite, true); } m_layer.m_writeCache->resize(width, height); if (m_layer.m_cache) delete m_layer.m_cache; m_layer.m_cache = new FFTFileCache (QString("%1").arg(getObjectExportId(&m_layer)), - MatrixFile::ReadOnly); + MatrixFile::ReadOnly, true); m_layer.setColourmap(); //!!! m_layer.m_writeCache->reset(); diff -r 4772fc75ac7c -r 12340cb6e6cb layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Mon Jun 26 16:08:57 2006 +0000 +++ b/layer/SpectrogramLayer.h Mon Jun 26 16:12:11 2006 +0000 @@ -93,12 +93,15 @@ void setWindowSize(size_t); size_t getWindowSize() const; - void setWindowHopLevel(size_t percent); + void setWindowHopLevel(size_t level); size_t getWindowHopLevel() const; void setWindowType(WindowType type); WindowType getWindowType() const; + void setZeroPadLevel(size_t level); + size_t getZeroPadLevel() const; + /** * Set the gain multiplier for sample values in this view prior to * FFT calculation. @@ -215,6 +218,7 @@ size_t m_windowSize; WindowType m_windowType; size_t m_windowHopLevel; + size_t m_zeroPadLevel; size_t m_fftSize; float m_gain; float m_threshold;