Mercurial > hg > svcore
changeset 1837:1b688ab5f1b3
Unify various vectors to our base floatvec_t type; store columns in fft model cache at their desired height so we can return a reference (speeding up the peak-frequency spectrogram in particular)
author | Chris Cannam |
---|---|
date | Thu, 09 Apr 2020 11:22:55 +0100 |
parents | 804dd0c06f0e |
children | 403e961ec6ab |
files | base/ColumnOp.cpp base/ColumnOp.h base/Extents.h base/test/TestColumnOp.h data/model/Dense3DModelPeakCache.h data/model/FFTModel.cpp data/model/FFTModel.h transform/FeatureExtractionModelTransformer.cpp |
diffstat | 8 files changed, 51 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/base/ColumnOp.cpp Mon Apr 06 13:55:44 2020 +0100 +++ b/base/ColumnOp.cpp Thu Apr 09 11:22:55 2020 +0100 @@ -32,7 +32,7 @@ ColumnOp::Column ColumnOp::peakPick(const Column &in) { - vector<float> out(in.size(), 0.f); + Column out(in.size(), 0.f); for (int i = 0; in_range_for(in, i); ++i) { if (isPeak(in, i)) { @@ -119,7 +119,7 @@ int minbin, bool interpolate) { - vector<float> out(h, 0.f); + Column out(h, 0.f); int bins = int(in.size()); if (interpolate) {
--- a/base/ColumnOp.h Mon Apr 06 13:55:44 2020 +0100 +++ b/base/ColumnOp.h Thu Apr 09 11:22:55 2020 +0100 @@ -53,7 +53,7 @@ /** * Column type. */ - typedef std::vector<float> Column; + typedef floatvec_t Column; /** * Scale the given column using the given gain multiplier.
--- a/base/Extents.h Mon Apr 06 13:55:44 2020 +0100 +++ b/base/Extents.h Thu Apr 09 11:22:55 2020 +0100 @@ -59,7 +59,8 @@ } return changed; } - bool sample(const std::vector<T> &ff) { + template <typename Alloc> + bool sample(const std::vector<T, Alloc> &ff) { bool changed = false; for (auto f: ff) { if (sample(f)) {
--- a/base/test/TestColumnOp.h Mon Apr 06 13:55:44 2020 +0100 +++ b/base/test/TestColumnOp.h Thu Apr 09 11:22:55 2020 +0100 @@ -36,8 +36,8 @@ typedef vector<double> BinMapping; #ifdef REPORT - template <typename T> - void report(vector<T> v) { + template <typename T, typename Alloc> + void report(vector<T, Alloc> v) { cerr << "Vector is: [ "; for (int i = 0; i < int(v.size()); ++i) { if (i > 0) cerr << ", "; @@ -46,8 +46,8 @@ cerr << " ]\n"; } #else - template <typename T> - void report(vector<T> ) { } + template <typename T, typename Alloc> + void report(vector<T, Alloc> ) { } #endif private slots:
--- a/data/model/Dense3DModelPeakCache.h Mon Apr 06 13:55:44 2020 +0100 +++ b/data/model/Dense3DModelPeakCache.h Thu Apr 09 11:22:55 2020 +0100 @@ -136,7 +136,7 @@ ModelId m_source; int m_columnsPerPeak; - mutable std::vector<std::vector<float>> m_cache; + mutable std::vector<Column> m_cache; mutable std::vector<bool> m_coverage; // bool for space efficiency // (vector of bool is a bitmap) mutable bool m_finalColumnIncomplete;
--- a/data/model/FFTModel.cpp Mon Apr 06 13:55:44 2020 +0100 +++ b/data/model/FFTModel.cpp Thu Apr 09 11:22:55 2020 +0100 @@ -51,9 +51,7 @@ m_cacheWriteIndex(0), m_cacheSize(3) { - while (m_cached.size() < m_cacheSize) { - m_cached.push_back({ -1, cvec(m_fftSize / 2 + 1) }); - } + clearCaches(); if (m_windowSize > m_fftSize) { SVCERR << "ERROR: FFTModel::FFTModel: window size (" << m_windowSize @@ -80,6 +78,17 @@ { } +void +FFTModel::clearCaches() +{ + m_cached.clear(); + while (m_cached.size() < m_cacheSize) { + m_cached.push_back({ -1, complexvec_t(m_fftSize / 2 + 1) }); + } + m_cacheWriteIndex = 0; + m_savedData.range = { 0, 0 }; +} + bool FFTModel::isOK() const { @@ -110,6 +119,7 @@ FFTModel::setMaximumFrequency(double freq) { m_maximumFrequency = freq; + clearCaches(); } int @@ -246,7 +256,7 @@ return true; } -FFTModel::fvec +floatvec_t FFTModel::getSourceSamples(int column) const { // m_fftSize may be greater than m_windowSize, but not the reverse @@ -262,7 +272,7 @@ return data; } else { vector<float> pad(off, 0.f); - fvec padded; + floatvec_t padded; padded.reserve(m_fftSize); padded.insert(padded.end(), pad.begin(), pad.end()); padded.insert(padded.end(), data.begin(), data.end()); @@ -271,7 +281,7 @@ } } -FFTModel::fvec +floatvec_t FFTModel::getSourceData(pair<sv_frame_t, sv_frame_t> range) const { // cerr << "getSourceData(" << range.first << "," << range.second @@ -293,14 +303,14 @@ sv_frame_t discard = range.first - m_savedData.range.first; - fvec data; + floatvec_t data; data.reserve(range.second - range.first); data.insert(data.end(), m_savedData.data.begin() + discard, m_savedData.data.end()); - fvec rest = getSourceDataUncached + floatvec_t rest = getSourceDataUncached ({ m_savedData.range.second, range.second }); data.insert(data.end(), rest.begin(), rest.end()); @@ -318,7 +328,7 @@ } } -FFTModel::fvec +floatvec_t FFTModel::getSourceDataUncached(pair<sv_frame_t, sv_frame_t> range) const { Profiler profiler("FFTModel::getSourceDataUncached"); @@ -366,12 +376,9 @@ return data; } -FFTModel::cvec +const complexvec_t & FFTModel::getFFTColumn(int n) const { - int h = getHeight(); - bool truncate = (h < m_fftSize / 2 + 1); - // The small cache (i.e. the m_cached deque) is for cases where // values are looked up individually, and for e.g. peak-frequency // spectrograms where values from two consecutive columns are @@ -381,11 +388,7 @@ for (const auto &incache : m_cached) { if (incache.n == n) { inSmallCache.hit(); - if (!truncate) { - return incache.col; - } else { - return cvec(incache.col.begin(), incache.col.begin() + h); - } + return incache.col; } } inSmallCache.miss(); @@ -396,20 +399,23 @@ m_windower.cut(samples.data() + (m_fftSize - m_windowSize) / 2); breakfastquay::v_fftshift(samples.data(), m_fftSize); - cvec &col = m_cached[m_cacheWriteIndex].col; + complexvec_t &col = m_cached[m_cacheWriteIndex].col; + + // expand to large enough for fft destination, if truncated previously + col.resize(m_fftSize / 2 + 1); m_fft.forwardInterleaved(samples.data(), reinterpret_cast<float *>(col.data())); + // keep only the number of elements we need - so that we can + // return a const ref without having to resize on a cache hit + col.resize(getHeight()); + m_cached[m_cacheWriteIndex].n = n; m_cacheWriteIndex = (m_cacheWriteIndex + 1) % m_cacheSize; - if (!truncate) { - return col; - } else { - return cvec(col.begin(), col.begin() + h); - } + return col; } bool
--- a/data/model/FFTModel.h Mon Apr 06 13:55:44 2020 +0100 +++ b/data/model/FFTModel.h Thu Apr 09 11:22:55 2020 +0100 @@ -193,28 +193,26 @@ return { startFrame, endFrame }; } - typedef std::vector<float, breakfastquay::StlAllocator<float>> fvec; - typedef std::vector<std::complex<float>, - breakfastquay::StlAllocator<std::complex<float>>> cvec; - - cvec getFFTColumn(int column) const; - fvec getSourceSamples(int column) const; - fvec getSourceData(std::pair<sv_frame_t, sv_frame_t>) const; - fvec getSourceDataUncached(std::pair<sv_frame_t, sv_frame_t>) const; + const complexvec_t &getFFTColumn(int column) const; + floatvec_t getSourceSamples(int column) const; + floatvec_t getSourceData(std::pair<sv_frame_t, sv_frame_t>) const; + floatvec_t getSourceDataUncached(std::pair<sv_frame_t, sv_frame_t>) const; struct SavedSourceData { std::pair<sv_frame_t, sv_frame_t> range; - fvec data; + floatvec_t data; }; mutable SavedSourceData m_savedData; struct SavedColumn { int n; - cvec col; + complexvec_t col; }; mutable std::vector<SavedColumn> m_cached; mutable size_t m_cacheWriteIndex; size_t m_cacheSize; + + void clearCaches(); }; #endif
--- a/transform/FeatureExtractionModelTransformer.cpp Mon Apr 06 13:55:44 2020 +0100 +++ b/transform/FeatureExtractionModelTransformer.cpp Thu Apr 09 11:22:55 2020 +0100 @@ -1156,7 +1156,9 @@ <BasicCompressedDenseThreeDimensionalModel>(outputId); if (!model) return; - DenseThreeDimensionalModel::Column values = feature.values; + DenseThreeDimensionalModel::Column values; + values.insert(values.begin(), + feature.values.begin(), feature.values.end()); if (!feature.hasTimestamp && m_fixedRateFeatureNos[n] >= 0) { model->setColumn(m_fixedRateFeatureNos[n], values);