diff --git a/src/finer/Guide.h b/src/finer/Guide.h index 1f90d69..2e07c4e 100644 --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -147,37 +147,37 @@ public: const BinSegmenter::Segmentation &segmentation, const BinSegmenter::Segmentation &prevSegmentation, const BinSegmenter::Segmentation &nextSegmentation, - bool specialCaseUnity, + double meanMagnitude, + int unityCount, Guidance &guidance) const { + bool hadPhaseReset = guidance.phaseReset.present; + + guidance.phaseReset.present = false; guidance.kick.present = false; guidance.preKick.present = false; guidance.highUnlocked.present = false; - guidance.phaseReset.present = false; + guidance.channelLock.present = false; double nyquist = m_parameters.sampleRate / 2.0; - guidance.fftBands[0].fftSize = roundUp(int(ceil(nyquist/8.0))); guidance.fftBands[1].fftSize = roundUp(int(ceil(nyquist/16.0))); guidance.fftBands[2].fftSize = roundUp(int(ceil(nyquist/32.0))); - if (specialCaseUnity && (fabs(ratio - 1.0) < 1.0e-6)) { - guidance.fftBands[0].f0 = 0.0; - guidance.fftBands[0].f1 = 0.0; - guidance.fftBands[1].f0 = 0.0; - guidance.fftBands[1].f1 = m_minHigher; - guidance.fftBands[2].f0 = m_minHigher; - guidance.fftBands[2].f1 = nyquist; - for (int i = 0; i < int(sizeof(guidance.phaseLockBands) / - sizeof(guidance.phaseLockBands[0])); ++i) { - guidance.phaseLockBands[i].p = 0; - guidance.phaseLockBands[i].beta = 1.0; - guidance.phaseLockBands[i].f0 = nyquist; - guidance.phaseLockBands[i].f1 = nyquist; - } - guidance.phaseLockBands[0].f0 = 0.0; - guidance.phaseLockBands[0].f1 = nyquist; - guidance.channelLock.present = false; + // This is a vital stop case for PhaseAdvance + guidance.phaseLockBands[3].f1 = nyquist; + + if (meanMagnitude < 1.0e-6) { + updateForSilence(guidance); + return; + } + + if (unityCount > 0) { + updateForUnity(guidance, + hadPhaseReset, + unityCount, + magnitudes, + segmentation); return; } @@ -351,7 +351,69 @@ protected: value = 1 << bits; return value; } - + + void updateForSilence(Guidance &guidance) const { +// std::cout << "phase reset on silence" << std::endl; + double nyquist = m_parameters.sampleRate / 2.0; + guidance.fftBands[0].f0 = 0.0; + guidance.fftBands[0].f1 = 0.0; + guidance.fftBands[1].f0 = 0.0; + guidance.fftBands[1].f1 = nyquist; + guidance.fftBands[2].f0 = nyquist; + guidance.fftBands[2].f1 = nyquist; + guidance.phaseReset.present = true; + guidance.phaseReset.f0 = 0.0; + guidance.phaseReset.f1 = nyquist; + } + + void updateForUnity(Guidance &guidance, + bool hadPhaseReset, + uint32_t unityCount, + const double *const magnitudes, + const BinSegmenter::Segmentation &segmentation) const { + +// std::cout << "unity" << std::endl; + + double nyquist = m_parameters.sampleRate / 2.0; + + guidance.fftBands[0].f0 = 0.0; + guidance.fftBands[0].f1 = m_minLower; + guidance.fftBands[1].f0 = m_minLower; + guidance.fftBands[1].f1 = m_minHigher; + guidance.fftBands[2].f0 = m_minHigher; + guidance.fftBands[2].f1 = nyquist; + + guidance.phaseReset.present = true; + + if (!hadPhaseReset) { + guidance.phaseReset.f0 = 16000.0; + guidance.phaseReset.f1 = nyquist; +// std::cout << "f0 = " << guidance.phaseReset.f0 << std::endl; + return; + } else { + guidance.phaseReset.f0 *= 0.9; + guidance.phaseReset.f1 *= 1.1; + } + + if (guidance.phaseReset.f0 < segmentation.residualAbove) { + guidance.phaseReset.f0 = std::min(guidance.phaseReset.f0, + segmentation.percussiveAbove); + } + + if (guidance.phaseReset.f1 > 16000.0) { + guidance.phaseReset.f1 = nyquist; + } + + if (guidance.phaseReset.f0 < 100.0) { + guidance.phaseReset.f0 = 0.0; + } + +// if (guidance.phaseReset.f0 > 0.0) { +// std::cout << unityCount << ": f0 = " << guidance.phaseReset.f0 +// << ", f1 = " << guidance.phaseReset.f1 << std::endl; +// } + } + bool checkPotentialKick(const double *const magnitudes, const double *const prevMagnitudes) const { int b = binForFrequency(200.0, m_configuration.classificationFftSize, diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index 0808699..5fc6f99 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -186,19 +186,20 @@ public: ++phaseLockBand; } double ph = 0.0; - if (inhop == outhop) { - ph = m_unlocked[c][i]; - } else if (inRange(f, g->phaseReset) || inRange(f, g->kick)) { + if (inRange(f, g->phaseReset) || inRange(f, g->kick)) { ph = phase[c][i]; + } else if (inhop == outhop) { + ph = m_unlocked[c][i]; } else if (inRange (f, g->highUnlocked)) { ph = m_unlocked[c][i]; } else { int peak = m_currentPeaks[c][i]; int prevPeak = m_prevPeaks[c][peak]; int peakCh = c; - if (inRange (f, g->channelLock)) { + if (inRange(f, g->channelLock)) { int other = m_greatestChannel[i]; - if (other != c) { + if (other != c && + inRange(f, guidance[other]->channelLock)) { int otherPeak = m_currentPeaks[other][i]; int otherPrevPeak = m_prevPeaks[other][otherPeak]; if (otherPrevPeak == prevPeak) { @@ -216,7 +217,7 @@ public: double(g->phaseLockBands[phaseLockBand].beta); ph = peakNew + beta * diff; } - outPhase[c][i] = ph; + outPhase[c][i] = princarg(ph); } } diff --git a/src/finer/R3StretcherImpl.cpp b/src/finer/R3StretcherImpl.cpp index e471372..f97c727 100644 --- a/src/finer/R3StretcherImpl.cpp +++ b/src/finer/R3StretcherImpl.cpp @@ -40,7 +40,9 @@ R3StretcherImpl::R3StretcherImpl(Parameters parameters, m_guideConfiguration(m_guide.getConfiguration()), m_channelAssembly(m_parameters.channels), m_inhop(1), + m_prevInhop(1), m_prevOuthop(1), + m_unityCount(0), m_startSkip(0), m_studyInputDuration(0), m_totalTargetDuration(0), @@ -826,9 +828,16 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) std::cout << std::endl; } */ - bool specialCaseUnity = true; + + double ratio = getEffectiveRatio(); + + if (fabs(ratio - 1.0) < 1.0e-6) { + ++m_unityCount; + } else { + m_unityCount = 0; + } - m_guide.updateGuidance(getEffectiveRatio(), + m_guide.updateGuidance(ratio, prevOuthop, classifyScale->mag.data(), classifyScale->prevMag.data(), @@ -836,7 +845,8 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) cd->segmentation, cd->prevSegmentation, cd->nextSegmentation, - specialCaseUnity, + v_mean(classifyScale->mag.data() + 1, classify/2), + m_unityCount, cd->guidance); /* if (c == 0) { diff --git a/src/finer/R3StretcherImpl.h b/src/finer/R3StretcherImpl.h index 198e03a..aa08d27 100644 --- a/src/finer/R3StretcherImpl.h +++ b/src/finer/R3StretcherImpl.h @@ -281,6 +281,7 @@ protected: std::atomic m_inhop; int m_prevInhop; int m_prevOuthop; + uint32_t m_unityCount; int m_startSkip; size_t m_studyInputDuration;