Fix calculation of recovery value now that divergence is recalculated afresh on each update
This commit is contained in:
@@ -24,4 +24,5 @@ Release/
|
|||||||
Debug/
|
Debug/
|
||||||
build
|
build
|
||||||
build_*
|
build_*
|
||||||
|
build-*
|
||||||
UpgradeLog*
|
UpgradeLog*
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ StretchCalculator::StretchCalculator(size_t sampleRate,
|
|||||||
m_sampleRate(sampleRate),
|
m_sampleRate(sampleRate),
|
||||||
m_increment(inputIncrement),
|
m_increment(inputIncrement),
|
||||||
m_prevDf(0),
|
m_prevDf(0),
|
||||||
m_divergence(0),
|
|
||||||
m_recovery(0),
|
|
||||||
m_prevRatio(1.0),
|
m_prevRatio(1.0),
|
||||||
m_prevTimeRatio(1.0),
|
m_prevTimeRatio(1.0),
|
||||||
m_transientAmnesty(0),
|
m_transientAmnesty(0),
|
||||||
@@ -417,10 +415,11 @@ StretchCalculator::calculateSingle(double timeRatio,
|
|||||||
(m_inFrameCounter + analysisWindowSize/4, timeRatio);
|
(m_inFrameCounter + analysisWindowSize/4, timeRatio);
|
||||||
int64_t projected = int64_t
|
int64_t projected = int64_t
|
||||||
(round(m_outFrameCounter + (synthesisWindowSize/4 * effectivePitchRatio)));
|
(round(m_outFrameCounter + (synthesisWindowSize/4 * effectivePitchRatio)));
|
||||||
m_divergence = projected - intended;
|
|
||||||
|
int64_t divergence = projected - intended;
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
std::cerr << "for current frame + quarter frame: intended " << intended << ", projected " << projected << ", divergence " << m_divergence << std::endl;
|
std::cerr << "for current frame + quarter frame: intended " << intended << ", projected " << projected << ", divergence " << divergence << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In principle, the threshold depends on chunk size: larger chunk
|
// In principle, the threshold depends on chunk size: larger chunk
|
||||||
@@ -462,37 +461,36 @@ StretchCalculator::calculateSingle(double timeRatio,
|
|||||||
m_transientAmnesty =
|
m_transientAmnesty =
|
||||||
lrint(ceil(double(m_sampleRate) / (20 * double(increment))));
|
lrint(ceil(double(m_sampleRate) / (20 * double(increment))));
|
||||||
|
|
||||||
m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment);
|
|
||||||
|
|
||||||
outIncrement = increment;
|
outIncrement = increment;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (ratioChanged) {
|
double recovery = 0.0;
|
||||||
m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment);
|
if (divergence > 1000 || divergence < -1000) {
|
||||||
|
recovery = divergence / ((m_sampleRate / 10.0) / increment);
|
||||||
|
} else if (divergence > 100 || divergence < -100) {
|
||||||
|
recovery = divergence / ((m_sampleRate / 25.0) / increment);
|
||||||
|
} else {
|
||||||
|
recovery = divergence / 4.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int incr = lrint(outIncrement - m_recovery);
|
int incr = lrint(outIncrement - recovery);
|
||||||
if (m_debugLevel > 2 || (m_debugLevel > 1 && m_divergence != 0)) {
|
if (m_debugLevel > 2 || (m_debugLevel > 1 && divergence != 0)) {
|
||||||
std::cerr << "divergence = " << m_divergence << ", recovery = " << m_recovery << ", incr = " << incr << ", ";
|
std::cerr << "divergence = " << divergence << ", recovery = " << recovery << ", incr = " << incr << ", ";
|
||||||
}
|
|
||||||
if (incr < lrint((increment * ratio) / 2)) {
|
|
||||||
incr = lrint((increment * ratio) / 2);
|
|
||||||
} else if (incr > lrint(increment * ratio * 2)) {
|
|
||||||
incr = lrint(increment * ratio * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double divdiff = (increment * ratio) - incr;
|
int minIncr = lrint(increment * ratio * 0.5);
|
||||||
|
int maxIncr = lrint(increment * ratio * 2);
|
||||||
|
|
||||||
if (m_debugLevel > 2 || (m_debugLevel > 1 && m_divergence != 0)) {
|
if (incr < minIncr) {
|
||||||
std::cerr << "possibly clamped to " << incr << ", divdiff = " << divdiff << std::endl;
|
incr = minIncr;
|
||||||
|
} else if (incr > maxIncr) {
|
||||||
|
incr = maxIncr;
|
||||||
}
|
}
|
||||||
|
|
||||||
double prevDivergence = m_divergence;
|
if (m_debugLevel > 2 || (m_debugLevel > 1 && divergence != 0)) {
|
||||||
m_divergence -= divdiff;
|
std::cerr << "clamped into [" << minIncr << ", " << maxIncr
|
||||||
if ((prevDivergence < 0 && m_divergence > 0) ||
|
<< "] becomes " << incr << std::endl;
|
||||||
(prevDivergence > 0 && m_divergence < 0)) {
|
|
||||||
m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (incr < 0) {
|
if (incr < 0) {
|
||||||
@@ -524,9 +522,11 @@ void
|
|||||||
StretchCalculator::reset()
|
StretchCalculator::reset()
|
||||||
{
|
{
|
||||||
m_prevDf = 0;
|
m_prevDf = 0;
|
||||||
m_divergence = 0;
|
|
||||||
m_recovery = 0;
|
|
||||||
m_prevRatio = 1.0;
|
m_prevRatio = 1.0;
|
||||||
|
m_prevTimeRatio = 1.0;
|
||||||
|
m_inFrameCounter = 0;
|
||||||
|
m_frameCheckpoint = std::pair<int64_t, int64_t>(0, 0);
|
||||||
|
m_outFrameCounter = 0.0;
|
||||||
m_transientAmnesty = 0;
|
m_transientAmnesty = 0;
|
||||||
m_keyFrameMap.clear();
|
m_keyFrameMap.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,6 @@ protected:
|
|||||||
size_t m_sampleRate;
|
size_t m_sampleRate;
|
||||||
size_t m_increment;
|
size_t m_increment;
|
||||||
float m_prevDf;
|
float m_prevDf;
|
||||||
double m_divergence;
|
|
||||||
double m_recovery;
|
|
||||||
double m_prevRatio;
|
double m_prevRatio;
|
||||||
double m_prevTimeRatio;
|
double m_prevTimeRatio;
|
||||||
int m_transientAmnesty; // only in RT mode; handled differently offline
|
int m_transientAmnesty; // only in RT mode; handled differently offline
|
||||||
|
|||||||
@@ -685,7 +685,7 @@ RubberBandStretcher::Impl::configure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
params.maxBufferSize = 4096 * 16;
|
params.maxBufferSize = 4096 * 16;
|
||||||
params.debugLevel = m_debugLevel;
|
params.debugLevel = (m_debugLevel > 0 ? m_debugLevel-1 : 0);
|
||||||
|
|
||||||
m_channelData[c]->resampler = new Resampler(params, 1);
|
m_channelData[c]->resampler = new Resampler(params, 1);
|
||||||
|
|
||||||
@@ -837,7 +837,7 @@ RubberBandStretcher::Impl::reconfigure()
|
|||||||
params.dynamism = Resampler::RatioOftenChanging;
|
params.dynamism = Resampler::RatioOftenChanging;
|
||||||
params.ratioChange = Resampler::SmoothRatioChange;
|
params.ratioChange = Resampler::SmoothRatioChange;
|
||||||
params.maxBufferSize = m_sWindowSize;
|
params.maxBufferSize = m_sWindowSize;
|
||||||
params.debugLevel = m_debugLevel;
|
params.debugLevel = (m_debugLevel > 0 ? m_debugLevel-1 : 0);
|
||||||
|
|
||||||
m_channelData[c]->resampler = new Resampler(params, 1);
|
m_channelData[c]->resampler = new Resampler(params, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -189,6 +189,8 @@ RubberBandStretcher::Impl::consumeChannel(size_t c,
|
|||||||
|
|
||||||
if (resampling) {
|
if (resampling) {
|
||||||
|
|
||||||
|
Profiler profiler2("RubberBandStretcher::Impl::resample");
|
||||||
|
|
||||||
toWrite = int(ceil(samples / m_pitchScale));
|
toWrite = int(ceil(samples / m_pitchScale));
|
||||||
if (writable < toWrite) {
|
if (writable < toWrite) {
|
||||||
samples = int(floor(writable * m_pitchScale));
|
samples = int(floor(writable * m_pitchScale));
|
||||||
@@ -1077,6 +1079,8 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
|||||||
(m_pitchScale != 1.0 || m_options & OptionPitchHighConsistency) &&
|
(m_pitchScale != 1.0 || m_options & OptionPitchHighConsistency) &&
|
||||||
cd.resampler) {
|
cd.resampler) {
|
||||||
|
|
||||||
|
Profiler profiler2("RubberBandStretcher::Impl::resample");
|
||||||
|
|
||||||
size_t reqSize = int(ceil(si / m_pitchScale));
|
size_t reqSize = int(ceil(si / m_pitchScale));
|
||||||
if (reqSize > cd.resamplebufSize) {
|
if (reqSize > cd.resamplebufSize) {
|
||||||
// This shouldn't normally happen -- the buffer is
|
// This shouldn't normally happen -- the buffer is
|
||||||
|
|||||||
Reference in New Issue
Block a user