From e018458736dc5729d3ee0ff13f49c41a7ab0286c Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Thu, 14 Jul 2022 13:44:22 +0100 Subject: [PATCH] Make this fully single-windowed rather than just short-windowed --- main/main.cpp | 6 +++- src/finer/Guide.h | 24 +++++++++------- src/finer/PhaseAdvance.h | 6 ++-- src/finer/R3Stretcher.cpp | 59 ++++++++++++++++++++------------------- src/finer/R3Stretcher.h | 6 ++-- 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 4f004ae..fcb5920 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -418,7 +418,11 @@ int main(int argc, char **argv) if (!quiet) { if (finer) { - cerr << "Using R3 (finer) engine" << endl; + if (shortwin) { + cerr << "Using intermediate R3 (finer) single-windowed engine" << endl; + } else { + cerr << "Using R3 (finer) engine" << endl; + } } else { cerr << "Using R2 (faster) engine" << endl; cerr << "Using crispness level: " << crispness << " ("; diff --git a/src/finer/Guide.h b/src/finer/Guide.h index 07c75a0..14d41bf 100644 --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -105,10 +105,10 @@ public: struct Parameters { double sampleRate; - bool shortWindowMode; - Parameters(double _sampleRate, bool _shortWindow) : + bool singleWindowMode; + Parameters(double _sampleRate, bool _singleWindow) : sampleRate(_sampleRate), - shortWindowMode(_shortWindow) { } + singleWindowMode(_singleWindow) { } }; Guide(Parameters parameters, Log log) : @@ -123,13 +123,16 @@ public: { double rate = m_parameters.sampleRate; - m_log.log(1, "Guide: rate and short-window mode", - rate, m_parameters.shortWindowMode); + m_log.log(1, "Guide: rate and single-window mode", + rate, m_parameters.singleWindowMode); - if (m_parameters.shortWindowMode) { - m_minLower = 0.0; + if (m_parameters.singleWindowMode) { m_defaultLower = 0.0; - m_maxLower = 0.0; + m_defaultHigher = parameters.sampleRate / 2.0; + m_minLower = m_defaultLower; + m_maxLower = m_defaultLower; + m_minHigher = m_defaultHigher; + m_maxHigher = m_defaultHigher; } int bandFftSize = roundUp(int(ceil(rate/16.0))); @@ -312,9 +315,10 @@ public: guidance.phaseLockBands[3].f0 = higher; guidance.phaseLockBands[3].f1 = nyquist; - if (m_parameters.shortWindowMode) { + if (m_parameters.singleWindowMode) { guidance.phaseLockBands[1].p = 1; guidance.phaseLockBands[2].p = 2; + guidance.phaseLockBands[3].p = 5; } if (outhop > 256) { @@ -436,7 +440,7 @@ protected: guidance.fftBands[2].f0 = m_minHigher; guidance.fftBands[2].f1 = nyquist; - if (m_parameters.shortWindowMode) { + if (m_parameters.singleWindowMode) { guidance.fftBands[0].f1 = 0.0; guidance.fftBands[1].f0 = 0.0; guidance.fftBands[1].f1 = nyquist; diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index 4474c9e..6015a22 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -43,11 +43,11 @@ public: int fftSize; double sampleRate; int channels; - bool shortWindowMode; + bool singleWindowMode; Parameters(int _fftSize, double _sampleRate, int _channels, - bool _shortWindow) : + bool _singleWindow) : fftSize(_fftSize), sampleRate(_sampleRate), channels(_channels), - shortWindowMode(_shortWindow) { } + singleWindowMode(_singleWindow) { } }; GuidedPhaseAdvance(Parameters parameters, Log log) : diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp index c65fb1a..49bde17 100644 --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -71,7 +71,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, m_log.log(1, "R3Stretcher::R3Stretcher: offline mode"); } - if (isShortWindowed()) { + if (isSingleWindowed()) { m_log.log(1, "R3Stretcher::R3Stretcher: intermediate shorter-window mode requested"); } @@ -112,7 +112,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, int fftSize = band.fftSize; GuidedPhaseAdvance::Parameters guidedParameters (fftSize, m_parameters.sampleRate, m_parameters.channels, - isShortWindowed()); + isSingleWindowed()); m_scaleData[fftSize] = std::make_shared (guidedParameters, m_log); } @@ -146,9 +146,8 @@ R3Stretcher::R3Stretcher(Parameters parameters, WindowType R3Stretcher::ScaleData::analysisWindowShape() { - if (shortWindowMode) { - if (fftSize >= 2048) return HannWindow; - else return NiemitaloForwardWindow; + if (singleWindowMode) { + return HannWindow; } else { if (fftSize > 2048) return HannWindow; else return NiemitaloForwardWindow; @@ -164,9 +163,8 @@ R3Stretcher::ScaleData::analysisWindowLength() WindowType R3Stretcher::ScaleData::synthesisWindowShape() { - if (shortWindowMode) { - if (fftSize >= 2048) return HannWindow; - else return NiemitaloReverseWindow; + if (singleWindowMode) { + return HannWindow; } else { if (fftSize > 2048) return HannWindow; else return NiemitaloReverseWindow; @@ -176,7 +174,7 @@ R3Stretcher::ScaleData::synthesisWindowShape() int R3Stretcher::ScaleData::synthesisWindowLength() { - if (shortWindowMode) { + if (singleWindowMode) { return fftSize; } else { if (fftSize > 2048) return fftSize/2; @@ -320,12 +318,12 @@ R3Stretcher::calculateHop() if (proposedOuthop > 512.0) proposedOuthop = 512.0; if (proposedOuthop < 128.0) proposedOuthop = 128.0; - if (isShortWindowed()) { - // perhaps ironically, the short window mode actually uses a - // longer synthesis window for the 2048-bin FFT and, since - // reduced CPU consumption is the motivation, it can generally - // survive longer hops - proposedOuthop *= 1.5; + if (isSingleWindowed()) { + // the single (shorter) window mode actually uses a longer + // synthesis window for the 2048-bin FFT and drops the + // 1024-bin one, so it can survive longer hops, which is good + // because reduced CPU consumption is the whole motivation + proposedOuthop *= 2.0; } m_log.log(1, "calculateHop: ratio and proposed outhop", ratio, proposedOuthop); @@ -764,8 +762,8 @@ R3Stretcher::consume() for (auto &it : m_channelData[0]->scales) { int fftSize = it.first; - if (isShortWindowed() && - fftSize == m_guideConfiguration.longestFftSize) { + if (isSingleWindowed() && + fftSize != m_guideConfiguration.classificationFftSize) { continue; } for (int c = 0; c < channels; ++c) { @@ -905,12 +903,14 @@ R3Stretcher::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) // the longest. (In practice this means we are probably only // populating one scale) - for (auto &it: cd->scales) { - int fftSize = it.first; - if (fftSize == classify || fftSize == longest) continue; - int offset = (longest - fftSize) / 2; - m_scaleData.at(fftSize)->analysisWindow.cut - (buf + offset, it.second->timeDomain.data()); + if (!isSingleWindowed()) { + for (auto &it: cd->scales) { + int fftSize = it.first; + if (fftSize == classify || fftSize == longest) continue; + int offset = (longest - fftSize) / 2; + m_scaleData.at(fftSize)->analysisWindow.cut + (buf + offset, it.second->timeDomain.data()); + } } // The classification scale has a one-hop readahead, so populate @@ -938,7 +938,7 @@ R3Stretcher::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) } // Finally window the longest scale - if (!isShortWindowed()) { + if (!isSingleWindowed()) { m_scaleData.at(longest)->analysisWindow.cut(buf); } @@ -998,7 +998,7 @@ R3Stretcher::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) if (fftSize == classify && haveValidReadahead) { continue; } - if (isShortWindowed() && fftSize == longest) { + if (isSingleWindowed() && fftSize != classify) { continue; } @@ -1172,8 +1172,8 @@ R3Stretcher::adjustFormant(int c) for (auto &it : cd->scales) { int fftSize = it.first; - if (isShortWindowed() && - fftSize == m_guideConfiguration.longestFftSize) { + if (isSingleWindowed() && + fftSize != m_guideConfiguration.classificationFftSize) { continue; } @@ -1206,7 +1206,7 @@ R3Stretcher::adjustFormant(int c) void R3Stretcher::adjustPreKick(int c) { - if (isShortWindowed()) return; + if (isSingleWindowed()) return; Profiler profiler("R3Stretcher::adjustPreKick"); @@ -1250,7 +1250,8 @@ R3Stretcher::synthesiseChannel(int c, int outhop, bool draining) for (const auto &band : cd->guidance.fftBands) { int fftSize = band.fftSize; - if (isShortWindowed() && fftSize == longest) { + if (isSingleWindowed() && + fftSize != m_guideConfiguration.classificationFftSize) { continue; } diff --git a/src/finer/R3Stretcher.h b/src/finer/R3Stretcher.h index b781eb9..1ca6367 100644 --- a/src/finer/R3Stretcher.h +++ b/src/finer/R3Stretcher.h @@ -253,7 +253,7 @@ protected: struct ScaleData { int fftSize; - bool shortWindowMode; + bool singleWindowMode; FFT fft; Window analysisWindow; Window synthesisWindow; @@ -263,7 +263,7 @@ protected: ScaleData(GuidedPhaseAdvance::Parameters guidedParameters, Log log) : fftSize(guidedParameters.fftSize), - shortWindowMode(guidedParameters.shortWindowMode), + singleWindowMode(guidedParameters.singleWindowMode), fft(fftSize), analysisWindow(analysisWindowShape(), analysisWindowLength()), @@ -371,7 +371,7 @@ protected: RubberBandStretcher::OptionProcessRealTime; } - bool isShortWindowed() const { + bool isSingleWindowed() const { return m_parameters.options & RubberBandStretcher::OptionWindowShort; }