Fix failure to calculate offline stretch correctly when a zero-chunk region is found; provide alternate projection calculation method for R3 without stop-the-world phase resets
This commit is contained in:
@@ -142,9 +142,15 @@ StretchCalculator::calculate(double ratio, size_t inputDuration,
|
|||||||
|
|
||||||
size_t nchunks = regionEndChunk - regionStartChunk;
|
size_t nchunks = regionEndChunk - regionStartChunk;
|
||||||
|
|
||||||
|
if (m_debugLevel > 1) {
|
||||||
|
std::cerr << "region from " << regionStartChunk << " to " << regionEndChunk << " (samples " << regionStart << " to " << regionEnd << ")" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (nchunks == 0) {
|
if (nchunks == 0) {
|
||||||
//!!!
|
if (m_debugLevel > 1) {
|
||||||
break;
|
std::cerr << "note: nchunks == 0" << std::endl;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double per = double(regionDuration) / double(nchunks);
|
double per = double(regionDuration) / double(nchunks);
|
||||||
@@ -335,7 +341,8 @@ StretchCalculator::calculateSingle(double timeRatio,
|
|||||||
float df,
|
float df,
|
||||||
size_t inIncrement,
|
size_t inIncrement,
|
||||||
size_t analysisWindowSize,
|
size_t analysisWindowSize,
|
||||||
size_t synthesisWindowSize)
|
size_t synthesisWindowSize,
|
||||||
|
bool alignFrameStarts)
|
||||||
{
|
{
|
||||||
double ratio = timeRatio / effectivePitchRatio;
|
double ratio = timeRatio / effectivePitchRatio;
|
||||||
|
|
||||||
@@ -414,10 +421,17 @@ StretchCalculator::calculateSingle(double timeRatio,
|
|||||||
std::cerr << "The next sample out is input sample " << m_inFrameCounter << std::endl;
|
std::cerr << "The next sample out is input sample " << m_inFrameCounter << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t intended = expectedOutFrame
|
int64_t intended, projected;
|
||||||
(m_inFrameCounter + analysisWindowSize/4, timeRatio);
|
if (alignFrameStarts) { // R3
|
||||||
int64_t projected = int64_t
|
intended = expectedOutFrame(m_inFrameCounter, timeRatio);
|
||||||
(round(m_outFrameCounter + (synthesisWindowSize/4 * effectivePitchRatio)));
|
projected = m_outFrameCounter;
|
||||||
|
} else { // R2
|
||||||
|
intended = expectedOutFrame
|
||||||
|
(m_inFrameCounter + analysisWindowSize/4, timeRatio);
|
||||||
|
projected =
|
||||||
|
int64_t(round(m_outFrameCounter +
|
||||||
|
(synthesisWindowSize/4 * effectivePitchRatio)));
|
||||||
|
}
|
||||||
|
|
||||||
int64_t divergence = projected - intended;
|
int64_t divergence = projected - intended;
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ public:
|
|||||||
float curveValue,
|
float curveValue,
|
||||||
size_t increment,
|
size_t increment,
|
||||||
size_t analysisWindowSize,
|
size_t analysisWindowSize,
|
||||||
size_t synthesisWindowSize);
|
size_t synthesisWindowSize,
|
||||||
|
bool alignFrameStarts);
|
||||||
|
|
||||||
void setUseHardPeaks(bool use) { m_useHardPeaks = use; }
|
void setUseHardPeaks(bool use) { m_useHardPeaks = use; }
|
||||||
|
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
|
|||||||
|
|
||||||
int incr = m_stretchCalculator->calculateSingle
|
int incr = m_stretchCalculator->calculateSingle
|
||||||
(m_timeRatio, effectivePitchRatio, df, m_increment,
|
(m_timeRatio, effectivePitchRatio, df, m_increment,
|
||||||
m_aWindowSize, m_sWindowSize);
|
m_aWindowSize, m_sWindowSize, false);
|
||||||
|
|
||||||
if (m_lastProcessPhaseResetDf.getWriteSpace() > 0) {
|
if (m_lastProcessPhaseResetDf.getWriteSpace() > 0) {
|
||||||
m_lastProcessPhaseResetDf.write(&df, 1);
|
m_lastProcessPhaseResetDf.write(&df, 1);
|
||||||
|
|||||||
@@ -128,12 +128,15 @@ R3StretcherImpl::R3StretcherImpl(Parameters parameters,
|
|||||||
// changes.
|
// changes.
|
||||||
|
|
||||||
if (!isRealTime()) {
|
if (!isRealTime()) {
|
||||||
|
m_parameters.logger("Offline mode: pre-padding");
|
||||||
int pad = m_guideConfiguration.longestFftSize / 2;
|
int pad = m_guideConfiguration.longestFftSize / 2;
|
||||||
for (int c = 0; c < m_parameters.channels; ++c) {
|
for (int c = 0; c < m_parameters.channels; ++c) {
|
||||||
m_channelData[c]->inbuf->zero(pad);
|
m_channelData[c]->inbuf->zero(pad);
|
||||||
}
|
}
|
||||||
// By the time we skip this later we will have resampled
|
// By the time we skip this later we will have resampled
|
||||||
m_startSkip = int(round(pad / m_pitchScale));
|
m_startSkip = int(round(pad / m_pitchScale));
|
||||||
|
} else {
|
||||||
|
m_parameters.logger("RT mode: no internal pre-pad");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,6 +455,7 @@ R3StretcherImpl::consume()
|
|||||||
int longest = m_guideConfiguration.longestFftSize;
|
int longest = m_guideConfiguration.longestFftSize;
|
||||||
int channels = m_parameters.channels;
|
int channels = m_parameters.channels;
|
||||||
|
|
||||||
|
//!!! todo: wire debug level & logger throughout
|
||||||
// m_calculator->setDebugLevel(3);
|
// m_calculator->setDebugLevel(3);
|
||||||
|
|
||||||
int inhop = m_inhop;
|
int inhop = m_inhop;
|
||||||
@@ -466,7 +470,8 @@ R3StretcherImpl::consume()
|
|||||||
1.f,
|
1.f,
|
||||||
inhop,
|
inhop,
|
||||||
longest,
|
longest,
|
||||||
longest);
|
longest,
|
||||||
|
true);
|
||||||
|
|
||||||
// Now inhop is the distance by which the input stream will be
|
// Now inhop is the distance by which the input stream will be
|
||||||
// advanced after our current frame has been read, and outhop is
|
// advanced after our current frame has been read, and outhop is
|
||||||
|
|||||||
Reference in New Issue
Block a user