* Better reporting of soft peaks (time sync points)

This commit is contained in:
Chris Cannam
2007-11-07 22:34:30 +00:00
parent d2f4833a0a
commit 5863e9070b
7 changed files with 61 additions and 14 deletions

View File

@@ -89,6 +89,7 @@ public:
virtual size_t getInputIncrement() const; virtual size_t getInputIncrement() const;
virtual std::vector<int> getOutputIncrements() const; //!!! document particular meaning in RT mode virtual std::vector<int> getOutputIncrements() const; //!!! document particular meaning in RT mode
virtual std::vector<float> getLockCurve() const; //!!! document particular meaning in RT mode virtual std::vector<float> getLockCurve() const; //!!! document particular meaning in RT mode
virtual std::vector<int> getExactTimePoints() const; //!!! meaningless in RT mode
virtual size_t getChannelCount() const; virtual size_t getChannelCount() const;

View File

@@ -155,6 +155,12 @@ RubberBandStretcher::getLockCurve() const
return m_d->getLockCurve(); return m_d->getLockCurve();
} }
std::vector<int>
RubberBandStretcher::getExactTimePoints() const
{
return m_d->getExactTimePoints();
}
size_t size_t
RubberBandStretcher::getChannelCount() const RubberBandStretcher::getChannelCount() const
{ {

View File

@@ -85,7 +85,8 @@ StretchCalculator::calculate(double ratio, size_t inputDuration,
assert(lockDf.size() == stretchDf.size()); assert(lockDf.size() == stretchDf.size());
std::vector<Peak> peaks = findPeaks(lockDf); m_lastPeaks = findPeaks(lockDf);
std::vector<Peak> &peaks = m_lastPeaks;
size_t totalCount = lockDf.size(); size_t totalCount = lockDf.size();
std::vector<int> increments; std::vector<int> increments;
@@ -434,12 +435,14 @@ StretchCalculator::findPeaks(const std::vector<float> &rawDf)
//locate the lock). For hard peaks we need to lock in //locate the lock). For hard peaks we need to lock in
//time to preserve the shape of the transient (unless some //time to preserve the shape of the transient (unless some
//option is set to soft mode), for soft peaks we just want //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 //to avoid poor timing positioning so we build up to the
//exact peak moment. //lock at the exact peak moment.
// size_t peak = i + maxindex - mediansize; // size_t peak = i + maxindex - mediansize;
size_t peak = i + maxindex - middle; 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 (peak > 0) --peak; //!!! that's a fudge
if (softPeakCandidates.empty() || lastSoftPeak != peak) { if (softPeakCandidates.empty() || lastSoftPeak != peak) {

View File

@@ -53,13 +53,15 @@ public:
void setDebugLevel(int level) { m_debugLevel = level; } void setDebugLevel(int level) { m_debugLevel = level; }
std::vector<float> smoothDF(const std::vector<float> &df);
protected:
struct Peak { struct Peak {
size_t frame; size_t frame;
bool hard; bool hard;
}; };
std::vector<Peak> getLastCalculatedPeaks() const { return m_lastPeaks; }
std::vector<float> smoothDF(const std::vector<float> &df);
protected:
std::vector<Peak> findPeaks(const std::vector<float> &audioCurve); std::vector<Peak> findPeaks(const std::vector<float> &audioCurve);
std::vector<int> distributeRegion(const std::vector<float> &regionCurve, std::vector<int> distributeRegion(const std::vector<float> &regionCurve,
@@ -82,6 +84,8 @@ protected:
bool m_wasTransient; bool m_wasTransient;
int m_debugLevel; int m_debugLevel;
bool m_useHardPeaks; bool m_useHardPeaks;
std::vector<Peak> m_lastPeaks;
}; };
} }

View File

@@ -769,6 +769,20 @@ RubberBandStretcher::Impl::getLockCurve() const
} }
} }
vector<int>
RubberBandStretcher::Impl::getExactTimePoints() const
{
std::vector<int> points;
if (!m_realtime) {
std::vector<StretchCalculator::Peak> peaks =
m_stretchCalculator->getLastCalculatedPeaks();
for (size_t i = 0; i < peaks.size(); ++i) {
points.push_back(peaks[i].frame);
}
}
return points;
}
void void
RubberBandStretcher::Impl::calculateStretch() RubberBandStretcher::Impl::calculateStretch()
{ {

View File

@@ -71,6 +71,7 @@ public:
std::vector<int> getOutputIncrements() const; std::vector<int> getOutputIncrements() const;
std::vector<float> getLockCurve() const; std::vector<float> getLockCurve() const;
std::vector<int> getExactTimePoints() const;
size_t getChannelCount() const { size_t getChannelCount() const {
return m_channels; return m_channels;

View File

@@ -63,6 +63,7 @@ public:
FeatureSet createFeatures(size_t inputIncrement, FeatureSet createFeatures(size_t inputIncrement,
std::vector<int> &outputIncrements, std::vector<int> &outputIncrements,
std::vector<float> &lockDf, std::vector<float> &lockDf,
std::vector<int> &exactPoints,
std::vector<float> &smoothedDF, std::vector<float> &smoothedDF,
size_t baseCount, size_t baseCount,
bool includeFinal); bool includeFinal);
@@ -409,10 +410,12 @@ RubberBandVampPlugin::Impl::getRemainingFeaturesOffline()
size_t inputIncrement = m_stretcher->getInputIncrement(); size_t inputIncrement = m_stretcher->getInputIncrement();
std::vector<int> outputIncrements = m_stretcher->getOutputIncrements(); std::vector<int> outputIncrements = m_stretcher->getOutputIncrements();
std::vector<float> lockDf = m_stretcher->getLockCurve(); std::vector<float> lockDf = m_stretcher->getLockCurve();
std::vector<int> peaks = m_stretcher->getExactTimePoints();
std::vector<float> smoothedDf = sc.smoothDF(lockDf); std::vector<float> smoothedDf = sc.smoothDF(lockDf);
FeatureSet features = createFeatures FeatureSet features = createFeatures
(inputIncrement, outputIncrements, lockDf, smoothedDf, 0, true); (inputIncrement, outputIncrements, lockDf, peaks, smoothedDf,
0, true);
return features; return features;
} }
@@ -438,8 +441,10 @@ RubberBandVampPlugin::Impl::processRealTime(const float *const *inputBuffers,
std::vector<int> outputIncrements = m_stretcher->getOutputIncrements(); std::vector<int> outputIncrements = m_stretcher->getOutputIncrements();
std::vector<float> lockDf = m_stretcher->getLockCurve(); std::vector<float> lockDf = m_stretcher->getLockCurve();
std::vector<float> smoothedDf; // not meaningful in RT mode std::vector<float> smoothedDf; // not meaningful in RT mode
FeatureSet features = createFeatures(inputIncrement, outputIncrements, std::vector<int> dummyPoints;
lockDf, smoothedDf, m_counter, false); FeatureSet features = createFeatures
(inputIncrement, outputIncrements, lockDf, dummyPoints, smoothedDf,
m_counter, false);
m_counter += outputIncrements.size(); m_counter += outputIncrements.size();
return features; return features;
@@ -455,6 +460,7 @@ RubberBandVampPlugin::FeatureSet
RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement, RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement,
std::vector<int> &outputIncrements, std::vector<int> &outputIncrements,
std::vector<float> &lockDf, std::vector<float> &lockDf,
std::vector<int> &exactPoints,
std::vector<float> &smoothedDf, std::vector<float> &smoothedDf,
size_t baseCount, size_t baseCount,
bool includeFinal) bool includeFinal)
@@ -469,16 +475,24 @@ RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement,
int rate = m_sampleRate; int rate = m_sampleRate;
size_t epi = 0;
for (size_t i = 0; i < outputIncrements.size(); ++i) { for (size_t i = 0; i < outputIncrements.size(); ++i) {
size_t frame = (baseCount + i) * inputIncrement; size_t frame = (baseCount + i) * inputIncrement;
int oi = outputIncrements[i]; int oi = outputIncrements[i];
bool lock = false; bool hardLock = false;
bool softLock = false;
if (oi < 0) { if (oi < 0) {
oi = -oi; oi = -oi;
lock = true; hardLock = true;
}
if (epi < exactPoints.size() && int(i) == exactPoints[epi]) {
softLock = true;
++epi;
} }
double linear = (frame * overallRatio); double linear = (frame * overallRatio);
@@ -528,11 +542,15 @@ RubberBandVampPlugin::Impl::createFeatures(size_t inputIncrement,
features[m_smoothedLockDfOutput].push_back(feature); features[m_smoothedLockDfOutput].push_back(feature);
} }
if (lock) { if (hardLock) {
feature.values.clear(); feature.values.clear();
feature.label = buf; feature.label = "Phase Reset";
features[m_lockPointsOutput].push_back(feature); features[m_lockPointsOutput].push_back(feature);
} } else if (softLock) {
feature.values.clear();
feature.label = "Time Sync";
features[m_lockPointsOutput].push_back(feature);
}
} }
if (includeFinal) { if (includeFinal) {