* 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 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<int> getExactTimePoints() const; //!!! meaningless in RT mode
virtual size_t getChannelCount() const;

View File

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

View File

@@ -85,7 +85,8 @@ StretchCalculator::calculate(double ratio, size_t inputDuration,
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();
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
//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) {

View File

@@ -53,13 +53,15 @@ public:
void setDebugLevel(int level) { m_debugLevel = level; }
std::vector<float> smoothDF(const std::vector<float> &df);
protected:
struct Peak {
size_t frame;
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<int> distributeRegion(const std::vector<float> &regionCurve,
@@ -82,6 +84,8 @@ protected:
bool m_wasTransient;
int m_debugLevel;
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
RubberBandStretcher::Impl::calculateStretch()
{

View File

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

View File

@@ -63,6 +63,7 @@ public:
FeatureSet createFeatures(size_t inputIncrement,
std::vector<int> &outputIncrements,
std::vector<float> &lockDf,
std::vector<int> &exactPoints,
std::vector<float> &smoothedDF,
size_t baseCount,
bool includeFinal);
@@ -409,10 +410,12 @@ RubberBandVampPlugin::Impl::getRemainingFeaturesOffline()
size_t inputIncrement = m_stretcher->getInputIncrement();
std::vector<int> outputIncrements = m_stretcher->getOutputIncrements();
std::vector<float> lockDf = m_stretcher->getLockCurve();
std::vector<int> peaks = m_stretcher->getExactTimePoints();
std::vector<float> 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<int> outputIncrements = m_stretcher->getOutputIncrements();
std::vector<float> lockDf = m_stretcher->getLockCurve();
std::vector<float> smoothedDf; // not meaningful in RT mode
FeatureSet features = createFeatures(inputIncrement, outputIncrements,
lockDf, smoothedDf, m_counter, false);
std::vector<int> 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<int> &outputIncrements,
std::vector<float> &lockDf,
std::vector<int> &exactPoints,
std::vector<float> &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,9 +542,13 @@ 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);
}
}