Provide a separate window source buffer to simplify single/multi window logic
This commit is contained in:
@@ -44,6 +44,7 @@ R3Stretcher::R3Stretcher(Parameters parameters,
|
|||||||
m_parameters.options & RubberBandStretcher::OptionWindowShort),
|
m_parameters.options & RubberBandStretcher::OptionWindowShort),
|
||||||
m_log),
|
m_log),
|
||||||
m_guideConfiguration(m_guide.getConfiguration()),
|
m_guideConfiguration(m_guide.getConfiguration()),
|
||||||
|
m_windowSourceBuffer(getWindowSourceBufferLength()),
|
||||||
m_channelAssembly(m_parameters.channels),
|
m_channelAssembly(m_parameters.channels),
|
||||||
m_inhop(1),
|
m_inhop(1),
|
||||||
m_prevInhop(1),
|
m_prevInhop(1),
|
||||||
@@ -75,14 +76,6 @@ R3Stretcher::R3Stretcher(Parameters parameters,
|
|||||||
m_log.log(1, "R3Stretcher::R3Stretcher: intermediate shorter-window mode requested");
|
m_log.log(1, "R3Stretcher::R3Stretcher: intermediate shorter-window mode requested");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_guideConfiguration.longestFftSize >
|
|
||||||
m_guideConfiguration.classificationFftSize) {
|
|
||||||
m_timeDomainFrameLength = m_guideConfiguration.longestFftSize;
|
|
||||||
} else {
|
|
||||||
m_timeDomainFrameLength =
|
|
||||||
(m_guideConfiguration.classificationFftSize * 3) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
double maxClassifierFrequency = 16000.0;
|
double maxClassifierFrequency = 16000.0;
|
||||||
if (maxClassifierFrequency > m_parameters.sampleRate/2) {
|
if (maxClassifierFrequency > m_parameters.sampleRate/2) {
|
||||||
maxClassifierFrequency = m_parameters.sampleRate/2;
|
maxClassifierFrequency = m_parameters.sampleRate/2;
|
||||||
@@ -98,14 +91,14 @@ R3Stretcher::R3Stretcher(Parameters parameters,
|
|||||||
BinClassifier::Parameters classifierParameters
|
BinClassifier::Parameters classifierParameters
|
||||||
(classificationBins, 9, 1, 10, 2.0, 2.0);
|
(classificationBins, 9, 1, 10, 2.0, 2.0);
|
||||||
|
|
||||||
int inRingBufferSize = m_timeDomainFrameLength * 2;
|
int inRingBufferSize = getWindowSourceBufferLength() * 2;
|
||||||
int outRingBufferSize = m_timeDomainFrameLength * 16;
|
int outRingBufferSize = getWindowSourceBufferLength() * 16;
|
||||||
|
|
||||||
for (int c = 0; c < m_parameters.channels; ++c) {
|
for (int c = 0; c < m_parameters.channels; ++c) {
|
||||||
m_channelData.push_back(std::make_shared<ChannelData>
|
m_channelData.push_back(std::make_shared<ChannelData>
|
||||||
(segmenterParameters,
|
(segmenterParameters,
|
||||||
classifierParameters,
|
classifierParameters,
|
||||||
m_timeDomainFrameLength,
|
m_guideConfiguration.longestFftSize,
|
||||||
inRingBufferSize,
|
inRingBufferSize,
|
||||||
outRingBufferSize));
|
outRingBufferSize));
|
||||||
for (int b = 0; b < m_guideConfiguration.fftBandLimitCount; ++b) {
|
for (int b = 0; b < m_guideConfiguration.fftBandLimitCount; ++b) {
|
||||||
@@ -113,7 +106,7 @@ R3Stretcher::R3Stretcher(Parameters parameters,
|
|||||||
int fftSize = band.fftSize;
|
int fftSize = band.fftSize;
|
||||||
m_channelData[c]->scales[fftSize] =
|
m_channelData[c]->scales[fftSize] =
|
||||||
std::make_shared<ChannelScaleData>
|
std::make_shared<ChannelScaleData>
|
||||||
(fftSize, m_timeDomainFrameLength);
|
(fftSize, m_guideConfiguration.longestFftSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +276,7 @@ R3Stretcher::createResampler()
|
|||||||
}
|
}
|
||||||
|
|
||||||
resamplerParameters.initialSampleRate = m_parameters.sampleRate;
|
resamplerParameters.initialSampleRate = m_parameters.sampleRate;
|
||||||
resamplerParameters.maxBufferSize = m_timeDomainFrameLength;
|
resamplerParameters.maxBufferSize = m_guideConfiguration.longestFftSize;
|
||||||
|
|
||||||
if (isRealTime()) {
|
if (isRealTime()) {
|
||||||
// If we knew the caller would never change ratio, we could
|
// If we knew the caller would never change ratio, we could
|
||||||
@@ -457,7 +450,7 @@ R3Stretcher::getPreferredStartPad() const
|
|||||||
if (!isRealTime()) {
|
if (!isRealTime()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return m_timeDomainFrameLength / 2;
|
return m_windowSourceBuffer.size() / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,7 +461,7 @@ R3Stretcher::getStartDelay() const
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
double factor = 0.5 / m_pitchScale;
|
double factor = 0.5 / m_pitchScale;
|
||||||
return size_t(ceil(m_timeDomainFrameLength * factor));
|
return size_t(ceil(m_windowSourceBuffer.size() * factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,8 +535,8 @@ R3Stretcher::getSamplesRequired() const
|
|||||||
{
|
{
|
||||||
if (available() != 0) return 0;
|
if (available() != 0) return 0;
|
||||||
int rs = m_channelData[0]->inbuf->getReadSpace();
|
int rs = m_channelData[0]->inbuf->getReadSpace();
|
||||||
if (rs < m_timeDomainFrameLength) {
|
if (rs < m_windowSourceBuffer.size()) {
|
||||||
return m_timeDomainFrameLength - rs;
|
return m_windowSourceBuffer.size() - rs;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -553,7 +546,7 @@ void
|
|||||||
R3Stretcher::setMaxProcessSize(size_t n)
|
R3Stretcher::setMaxProcessSize(size_t n)
|
||||||
{
|
{
|
||||||
size_t oldSize = m_channelData[0]->inbuf->getSize();
|
size_t oldSize = m_channelData[0]->inbuf->getSize();
|
||||||
size_t newSize = m_timeDomainFrameLength + n;
|
size_t newSize = m_windowSourceBuffer.size() + n;
|
||||||
|
|
||||||
if (newSize > oldSize) {
|
if (newSize > oldSize) {
|
||||||
m_log.log(1, "setMaxProcessSize: resizing from and to", oldSize, newSize);
|
m_log.log(1, "setMaxProcessSize: resizing from and to", oldSize, newSize);
|
||||||
@@ -612,7 +605,7 @@ R3Stretcher::process(const float *const *input, size_t samples, bool final)
|
|||||||
// don't do this -- it's better to start with a swoosh
|
// don't do this -- it's better to start with a swoosh
|
||||||
// than introduce more latency, and we don't want gaps
|
// than introduce more latency, and we don't want gaps
|
||||||
// when the ratio changes.
|
// when the ratio changes.
|
||||||
int pad = m_timeDomainFrameLength / 2;
|
int pad = m_windowSourceBuffer.size() / 2;
|
||||||
m_log.log(1, "offline mode: prefilling with", pad);
|
m_log.log(1, "offline mode: prefilling with", pad);
|
||||||
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);
|
||||||
@@ -744,7 +737,7 @@ R3Stretcher::consume()
|
|||||||
// the map iterators
|
// the map iterators
|
||||||
|
|
||||||
int readSpace = cd0->inbuf->getReadSpace();
|
int readSpace = cd0->inbuf->getReadSpace();
|
||||||
if (readSpace < m_timeDomainFrameLength) {
|
if (readSpace < m_windowSourceBuffer.size()) {
|
||||||
if (m_mode == ProcessMode::Finished) {
|
if (m_mode == ProcessMode::Finished) {
|
||||||
if (readSpace == 0) {
|
if (readSpace == 0) {
|
||||||
int fill = cd0->scales.at(longest)->accumulatorFill;
|
int fill = cd0->scales.at(longest)->accumulatorFill;
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ protected:
|
|||||||
FixedVector<process_t> accumulator;
|
FixedVector<process_t> accumulator;
|
||||||
int accumulatorFill;
|
int accumulatorFill;
|
||||||
|
|
||||||
ChannelScaleData(int _fftSize, int _timeDomainLength) :
|
ChannelScaleData(int _fftSize, int _longestFftSize) :
|
||||||
fftSize(_fftSize),
|
fftSize(_fftSize),
|
||||||
bufSize(fftSize/2 + 1),
|
bufSize(fftSize/2 + 1),
|
||||||
timeDomain(fftSize, 0.f),
|
timeDomain(fftSize, 0.f),
|
||||||
@@ -143,7 +143,7 @@ protected:
|
|||||||
advancedPhase(bufSize, 0.f),
|
advancedPhase(bufSize, 0.f),
|
||||||
prevMag(bufSize, 0.f),
|
prevMag(bufSize, 0.f),
|
||||||
pendingKick(bufSize, 0.f),
|
pendingKick(bufSize, 0.f),
|
||||||
accumulator(_timeDomainLength, 0.f),
|
accumulator(_longestFftSize, 0.f),
|
||||||
accumulatorFill(0)
|
accumulatorFill(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ protected:
|
|||||||
std::unique_ptr<FormantData> formant;
|
std::unique_ptr<FormantData> formant;
|
||||||
ChannelData(BinSegmenter::Parameters segmenterParameters,
|
ChannelData(BinSegmenter::Parameters segmenterParameters,
|
||||||
BinClassifier::Parameters classifierParameters,
|
BinClassifier::Parameters classifierParameters,
|
||||||
int timeDomainLength,
|
int longestFftSize,
|
||||||
int inRingBufferSize,
|
int inRingBufferSize,
|
||||||
int outRingBufferSize) :
|
int outRingBufferSize) :
|
||||||
scales(),
|
scales(),
|
||||||
@@ -215,7 +215,7 @@ protected:
|
|||||||
BinClassifier::Classification::Residual),
|
BinClassifier::Classification::Residual),
|
||||||
segmenter(new BinSegmenter(segmenterParameters)),
|
segmenter(new BinSegmenter(segmenterParameters)),
|
||||||
segmentation(), prevSegmentation(), nextSegmentation(),
|
segmentation(), prevSegmentation(), nextSegmentation(),
|
||||||
mixdown(timeDomainLength, 0.f),
|
mixdown(longestFftSize, 0.f),
|
||||||
resampled(outRingBufferSize, 0.f),
|
resampled(outRingBufferSize, 0.f),
|
||||||
inbuf(new RingBuffer<float>(inRingBufferSize)),
|
inbuf(new RingBuffer<float>(inRingBufferSize)),
|
||||||
outbuf(new RingBuffer<float>(outRingBufferSize)),
|
outbuf(new RingBuffer<float>(outRingBufferSize)),
|
||||||
@@ -297,7 +297,7 @@ protected:
|
|||||||
std::map<int, std::shared_ptr<ScaleData>> m_scaleData;
|
std::map<int, std::shared_ptr<ScaleData>> m_scaleData;
|
||||||
Guide m_guide;
|
Guide m_guide;
|
||||||
Guide::Configuration m_guideConfiguration;
|
Guide::Configuration m_guideConfiguration;
|
||||||
int m_timeDomainFrameLength;
|
FixedVector<process_t> m_windowSourceBuffer;
|
||||||
ChannelAssembly m_channelAssembly;
|
ChannelAssembly m_channelAssembly;
|
||||||
std::unique_ptr<StretchCalculator> m_calculator;
|
std::unique_ptr<StretchCalculator> m_calculator;
|
||||||
std::unique_ptr<Resampler> m_resampler;
|
std::unique_ptr<Resampler> m_resampler;
|
||||||
@@ -376,6 +376,15 @@ protected:
|
|||||||
return m_parameters.options &
|
return m_parameters.options &
|
||||||
RubberBandStretcher::OptionWindowShort;
|
RubberBandStretcher::OptionWindowShort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getWindowSourceBufferLength() const {
|
||||||
|
if (m_guideConfiguration.longestFftSize >
|
||||||
|
m_guideConfiguration.classificationFftSize) {
|
||||||
|
return m_guideConfiguration.longestFftSize;
|
||||||
|
} else {
|
||||||
|
return (m_guideConfiguration.classificationFftSize * 3) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user