From d1386b0a0c48e64aed4fb2a278c1cfc362e56e7a Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Thu, 4 Aug 2022 10:02:09 +0100 Subject: [PATCH] Provide a separate window source buffer to simplify single/multi window logic --- src/finer/R3Stretcher.cpp | 33 +++++++++++++-------------------- src/finer/R3Stretcher.h | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp index bc24b44..2ee86ca 100644 --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -44,6 +44,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, m_parameters.options & RubberBandStretcher::OptionWindowShort), m_log), m_guideConfiguration(m_guide.getConfiguration()), + m_windowSourceBuffer(getWindowSourceBufferLength()), m_channelAssembly(m_parameters.channels), m_inhop(1), m_prevInhop(1), @@ -74,14 +75,6 @@ R3Stretcher::R3Stretcher(Parameters parameters, if (isSingleWindowed()) { 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; if (maxClassifierFrequency > m_parameters.sampleRate/2) { @@ -98,14 +91,14 @@ R3Stretcher::R3Stretcher(Parameters parameters, BinClassifier::Parameters classifierParameters (classificationBins, 9, 1, 10, 2.0, 2.0); - int inRingBufferSize = m_timeDomainFrameLength * 2; - int outRingBufferSize = m_timeDomainFrameLength * 16; + int inRingBufferSize = getWindowSourceBufferLength() * 2; + int outRingBufferSize = getWindowSourceBufferLength() * 16; for (int c = 0; c < m_parameters.channels; ++c) { m_channelData.push_back(std::make_shared (segmenterParameters, classifierParameters, - m_timeDomainFrameLength, + m_guideConfiguration.longestFftSize, inRingBufferSize, outRingBufferSize)); for (int b = 0; b < m_guideConfiguration.fftBandLimitCount; ++b) { @@ -113,7 +106,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, int fftSize = band.fftSize; m_channelData[c]->scales[fftSize] = std::make_shared - (fftSize, m_timeDomainFrameLength); + (fftSize, m_guideConfiguration.longestFftSize); } } @@ -283,7 +276,7 @@ R3Stretcher::createResampler() } resamplerParameters.initialSampleRate = m_parameters.sampleRate; - resamplerParameters.maxBufferSize = m_timeDomainFrameLength; + resamplerParameters.maxBufferSize = m_guideConfiguration.longestFftSize; if (isRealTime()) { // If we knew the caller would never change ratio, we could @@ -457,7 +450,7 @@ R3Stretcher::getPreferredStartPad() const if (!isRealTime()) { return 0; } else { - return m_timeDomainFrameLength / 2; + return m_windowSourceBuffer.size() / 2; } } @@ -468,7 +461,7 @@ R3Stretcher::getStartDelay() const return 0; } else { 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; int rs = m_channelData[0]->inbuf->getReadSpace(); - if (rs < m_timeDomainFrameLength) { - return m_timeDomainFrameLength - rs; + if (rs < m_windowSourceBuffer.size()) { + return m_windowSourceBuffer.size() - rs; } else { return 0; } @@ -553,7 +546,7 @@ void R3Stretcher::setMaxProcessSize(size_t n) { size_t oldSize = m_channelData[0]->inbuf->getSize(); - size_t newSize = m_timeDomainFrameLength + n; + size_t newSize = m_windowSourceBuffer.size() + n; if (newSize > oldSize) { 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 // than introduce more latency, and we don't want gaps // when the ratio changes. - int pad = m_timeDomainFrameLength / 2; + int pad = m_windowSourceBuffer.size() / 2; m_log.log(1, "offline mode: prefilling with", pad); for (int c = 0; c < m_parameters.channels; ++c) { m_channelData[c]->inbuf->zero(pad); @@ -744,7 +737,7 @@ R3Stretcher::consume() // the map iterators int readSpace = cd0->inbuf->getReadSpace(); - if (readSpace < m_timeDomainFrameLength) { + if (readSpace < m_windowSourceBuffer.size()) { if (m_mode == ProcessMode::Finished) { if (readSpace == 0) { int fill = cd0->scales.at(longest)->accumulatorFill; diff --git a/src/finer/R3Stretcher.h b/src/finer/R3Stretcher.h index c97887a..1da9bea 100644 --- a/src/finer/R3Stretcher.h +++ b/src/finer/R3Stretcher.h @@ -132,7 +132,7 @@ protected: FixedVector accumulator; int accumulatorFill; - ChannelScaleData(int _fftSize, int _timeDomainLength) : + ChannelScaleData(int _fftSize, int _longestFftSize) : fftSize(_fftSize), bufSize(fftSize/2 + 1), timeDomain(fftSize, 0.f), @@ -143,7 +143,7 @@ protected: advancedPhase(bufSize, 0.f), prevMag(bufSize, 0.f), pendingKick(bufSize, 0.f), - accumulator(_timeDomainLength, 0.f), + accumulator(_longestFftSize, 0.f), accumulatorFill(0) { } @@ -202,7 +202,7 @@ protected: std::unique_ptr formant; ChannelData(BinSegmenter::Parameters segmenterParameters, BinClassifier::Parameters classifierParameters, - int timeDomainLength, + int longestFftSize, int inRingBufferSize, int outRingBufferSize) : scales(), @@ -215,7 +215,7 @@ protected: BinClassifier::Classification::Residual), segmenter(new BinSegmenter(segmenterParameters)), segmentation(), prevSegmentation(), nextSegmentation(), - mixdown(timeDomainLength, 0.f), + mixdown(longestFftSize, 0.f), resampled(outRingBufferSize, 0.f), inbuf(new RingBuffer(inRingBufferSize)), outbuf(new RingBuffer(outRingBufferSize)), @@ -297,7 +297,7 @@ protected: std::map> m_scaleData; Guide m_guide; Guide::Configuration m_guideConfiguration; - int m_timeDomainFrameLength; + FixedVector m_windowSourceBuffer; ChannelAssembly m_channelAssembly; std::unique_ptr m_calculator; std::unique_ptr m_resampler; @@ -376,6 +376,15 @@ protected: return m_parameters.options & RubberBandStretcher::OptionWindowShort; } + + int getWindowSourceBufferLength() const { + if (m_guideConfiguration.longestFftSize > + m_guideConfiguration.classificationFftSize) { + return m_guideConfiguration.longestFftSize; + } else { + return (m_guideConfiguration.classificationFftSize * 3) / 2; + } + } }; }