From 5863e9070bee48ffd477ee52dcd279b861ab5246 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 7 Nov 2007 22:34:30 +0000 Subject: [PATCH] * Better reporting of soft peaks (time sync points) --- rubberband/RubberBandStretcher.h | 1 + src/RubberBandStretcher.cpp | 6 ++++++ src/StretchCalculator.cpp | 9 +++++--- src/StretchCalculator.h | 10 ++++++--- src/StretcherImpl.cpp | 14 +++++++++++++ src/StretcherImpl.h | 1 + src/vamp/RubberBandVampPlugin.cpp | 34 +++++++++++++++++++++++-------- 7 files changed, 61 insertions(+), 14 deletions(-) diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h index 4221bdc..c595c40 100644 --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -89,6 +89,7 @@ public: virtual size_t getInputIncrement() const; virtual std::vector getOutputIncrements() const; //!!! document particular meaning in RT mode virtual std::vector getLockCurve() const; //!!! document particular meaning in RT mode + virtual std::vector getExactTimePoints() const; //!!! meaningless in RT mode virtual size_t getChannelCount() const; diff --git a/src/RubberBandStretcher.cpp b/src/RubberBandStretcher.cpp index 7d67f90..e78d897 100644 --- a/src/RubberBandStretcher.cpp +++ b/src/RubberBandStretcher.cpp @@ -155,6 +155,12 @@ RubberBandStretcher::getLockCurve() const return m_d->getLockCurve(); } +std::vector +RubberBandStretcher::getExactTimePoints() const +{ + return m_d->getExactTimePoints(); +} + size_t RubberBandStretcher::getChannelCount() const { diff --git a/src/StretchCalculator.cpp b/src/StretchCalculator.cpp index e970d5a..ec15fb4 100644 --- a/src/StretchCalculator.cpp +++ b/src/StretchCalculator.cpp @@ -85,7 +85,8 @@ StretchCalculator::calculate(double ratio, size_t inputDuration, assert(lockDf.size() == stretchDf.size()); - std::vector peaks = findPeaks(lockDf); + m_lastPeaks = findPeaks(lockDf); + std::vector &peaks = m_lastPeaks; size_t totalCount = lockDf.size(); std::vector increments; @@ -434,12 +435,14 @@ StretchCalculator::findPeaks(const std::vector &rawDf) //locate the lock). For hard peaks we need to lock in //time to preserve the shape of the transient (unless some //option is set to soft mode), for soft peaks we just want - //to avoid phase drift so we build up to the lock at the - //exact peak moment. + //to avoid poor timing positioning so we build up to the + //lock at the exact peak moment. // size_t peak = i + maxindex - mediansize; size_t peak = i + maxindex - middle; + std::cerr << "i = " << i << ", maxindex = " << maxindex << ", middle = " << middle << ", so peak at " << peak << std::endl; + // if (peak > 0) --peak; //!!! that's a fudge if (softPeakCandidates.empty() || lastSoftPeak != peak) { diff --git a/src/StretchCalculator.h b/src/StretchCalculator.h index 293293f..1af4711 100644 --- a/src/StretchCalculator.h +++ b/src/StretchCalculator.h @@ -53,13 +53,15 @@ public: void setDebugLevel(int level) { m_debugLevel = level; } - std::vector smoothDF(const std::vector &df); - -protected: struct Peak { size_t frame; bool hard; }; + std::vector getLastCalculatedPeaks() const { return m_lastPeaks; } + + std::vector smoothDF(const std::vector &df); + +protected: std::vector findPeaks(const std::vector &audioCurve); std::vector distributeRegion(const std::vector ®ionCurve, @@ -82,6 +84,8 @@ protected: bool m_wasTransient; int m_debugLevel; bool m_useHardPeaks; + + std::vector m_lastPeaks; }; } diff --git a/src/StretcherImpl.cpp b/src/StretcherImpl.cpp index c386231..8fef6ad 100644 --- a/src/StretcherImpl.cpp +++ b/src/StretcherImpl.cpp @@ -769,6 +769,20 @@ RubberBandStretcher::Impl::getLockCurve() const } } +vector +RubberBandStretcher::Impl::getExactTimePoints() const +{ + std::vector points; + if (!m_realtime) { + std::vector peaks = + m_stretchCalculator->getLastCalculatedPeaks(); + for (size_t i = 0; i < peaks.size(); ++i) { + points.push_back(peaks[i].frame); + } + } + return points; +} + void RubberBandStretcher::Impl::calculateStretch() { diff --git a/src/StretcherImpl.h b/src/StretcherImpl.h index 64f7b3a..6fea166 100644 --- a/src/StretcherImpl.h +++ b/src/StretcherImpl.h @@ -71,6 +71,7 @@ public: std::vector getOutputIncrements() const; std::vector getLockCurve() const; + std::vector getExactTimePoints() const; size_t getChannelCount() const { return m_channels; diff --git a/src/vamp/RubberBandVampPlugin.cpp b/src/vamp/RubberBandVampPlugin.cpp index a735971..f30da89 100644 --- a/src/vamp/RubberBandVampPlugin.cpp +++ b/src/vamp/RubberBandVampPlugin.cpp @@ -63,6 +63,7 @@ public: FeatureSet createFeatures(size_t inputIncrement, std::vector &outputIncrements, std::vector &lockDf, + std::vector &exactPoints, std::vector &smoothedDF, size_t baseCount, bool includeFinal); @@ -409,10 +410,12 @@ RubberBandVampPlugin::Impl::getRemainingFeaturesOffline() size_t inputIncrement = m_stretcher->getInputIncrement(); std::vector outputIncrements = m_stretcher->getOutputIncrements(); std::vector lockDf = m_stretcher->getLockCurve(); + std::vector peaks = m_stretcher->getExactTimePoints(); std::vector smoothedDf = sc.smoothDF(lockDf); FeatureSet features = createFeatures - (inputIncrement, outputIncrements, lockDf, smoothedDf, 0, true); + (inputIncrement, outputIncrements, lockDf, peaks, smoothedDf, + 0, true); return features; } @@ -438,8 +441,10 @@ RubberBandVampPlugin::Impl::processRealTime(const float *const *inputBuffers, std::vector outputIncrements = m_stretcher->getOutputIncrements(); std::vector lockDf = m_stretcher->getLockCurve(); std::vector smoothedDf; // not meaningful in RT mode - FeatureSet features = createFeatures(inputIncrement, outputIncrements, - lockDf, smoothedDf, m_counter, false); + std::vector dummyPoints; + FeatureSet features = createFeatures + (inputIncrement, outputIncrements, lockDf, dummyPoints, smoothedDf, + m_counter, false); m_counter += outputIncrements.size(); return features; @@ -455,6 +460,7 @@ RubberBandVampPlugin::FeatureSet RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement, std::vector &outputIncrements, std::vector &lockDf, + std::vector &exactPoints, std::vector &smoothedDf, size_t baseCount, bool includeFinal) @@ -469,16 +475,24 @@ RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement, int rate = m_sampleRate; + size_t epi = 0; + for (size_t i = 0; i < outputIncrements.size(); ++i) { size_t frame = (baseCount + i) * inputIncrement; int oi = outputIncrements[i]; - bool lock = false; + bool hardLock = false; + bool softLock = false; if (oi < 0) { oi = -oi; - lock = true; + hardLock = true; + } + + if (epi < exactPoints.size() && int(i) == exactPoints[epi]) { + softLock = true; + ++epi; } double linear = (frame * overallRatio); @@ -528,11 +542,15 @@ RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement, features[m_smoothedLockDfOutput].push_back(feature); } - if (lock) { + if (hardLock) { feature.values.clear(); - feature.label = buf; + feature.label = "Phase Reset"; features[m_lockPointsOutput].push_back(feature); - } + } else if (softLock) { + feature.values.clear(); + feature.label = "Time Sync"; + features[m_lockPointsOutput].push_back(feature); + } } if (includeFinal) {