diff --git a/src/finer/BinSegmenter.h b/src/finer/BinSegmenter.h index 5b2c7d3..1e00521 100644 --- a/src/finer/BinSegmenter.h +++ b/src/finer/BinSegmenter.h @@ -55,7 +55,7 @@ public: BinSegmenter(Parameters parameters) : m_parameters(parameters), m_numeric(m_parameters.binCount, 0), - m_classFilter(3, 15) + m_classFilter(3, 18) { } diff --git a/src/finer/Guide.h b/src/finer/Guide.h index 0614231..2204065 100644 --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -68,7 +68,7 @@ public: FftBand fftBands[3]; PhaseLockBand phaseLockBands[5]; Range kick; - Range lowPercussive; + Range preKick; Range highPercussive; Range phaseReset; Range channelLock; @@ -140,6 +140,7 @@ public: void updateGuidance(double ratio, const double *const magnitudes, const double *const prevMagnitudes, + const double *const nextMagnitudes, const BinSegmenter::Segmentation &segmentation, const BinSegmenter::Segmentation &prevSegmentation, const BinSegmenter::Segmentation &nextSegmentation, @@ -147,7 +148,7 @@ public: Guidance &guidance) const { guidance.kick.present = false; - guidance.lowPercussive.present = false; + guidance.preKick.present = false; guidance.highPercussive.present = false; guidance.phaseReset.present = false; @@ -180,16 +181,33 @@ public: guidance.channelLock.f0 = 0.0; guidance.channelLock.f1 = 600.0; - if (segmentation.percussiveBelow > 40.0) { - guidance.lowPercussive.present = true; - guidance.lowPercussive.f0 = 0.0; - guidance.lowPercussive.f1 = segmentation.percussiveBelow; - } - - bool potentialKick = checkPotentialKick(magnitudes, prevMagnitudes); + bool kick = + (segmentation.percussiveBelow > 40.0) && + (prevSegmentation.percussiveBelow < 40.0) && + checkPotentialKick(magnitudes, prevMagnitudes); - if (potentialKick && prevSegmentation.percussiveBelow < 40.0) { - guidance.kick = guidance.lowPercussive; + bool futureKick = !kick && + (nextSegmentation.percussiveBelow > 40.0) && + (segmentation.percussiveBelow < 40.0) && + checkPotentialKick(nextMagnitudes, magnitudes); +/* + std::cout << "d:" + << prevSegmentation.percussiveBelow << "," + << segmentation.percussiveBelow << "," + << nextSegmentation.percussiveBelow << "," + << checkPotentialKick(magnitudes, prevMagnitudes) << "," + << checkPotentialKick(nextMagnitudes, magnitudes) << "," + << (kick ? "K" : "N") << "," + << (futureKick ? "F" : "N") << std::endl; +*/ + if (kick) { + guidance.kick.present = true; + guidance.kick.f0 = 0.0; + guidance.kick.f1 = segmentation.percussiveBelow; + } else if (futureKick) { + guidance.preKick.present = true; + guidance.preKick.f0 = 0.0; + guidance.preKick.f1 = nextSegmentation.percussiveBelow; } if (segmentation.residualAbove > segmentation.percussiveAbove) { diff --git a/src/finer/R3StretcherImpl.cpp b/src/finer/R3StretcherImpl.cpp index 815ade3..cd73c76 100644 --- a/src/finer/R3StretcherImpl.cpp +++ b/src/finer/R3StretcherImpl.cpp @@ -436,6 +436,10 @@ R3StretcherImpl::consume() m_prevOuthop); } + for (int c = 0; c < channels; ++c) { + adjustPreKick(c); + } + // Resynthesis for (int c = 0; c < channels; ++c) { @@ -701,18 +705,30 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop) } std::cout << std::endl; } -*/ +*/ double instantaneousRatio = double(prevOuthop) / double(prevInhop); bool specialCaseUnity = true; m_guide.updateGuidance(instantaneousRatio, classifyScale->mag.data(), classifyScale->prevMag.data(), + cd->readahead.mag.data(), cd->segmentation, cd->prevSegmentation, cd->nextSegmentation, specialCaseUnity, cd->guidance); +/* + if (c == 0) { + if (cd->guidance.kick.present) { + std::cout << "k:2" << std::endl; + } else if (cd->guidance.preKick.present) { + std::cout << "k:1" << std::endl; + } else { + std::cout << "k:0" << std::endl; + } + } +*/ } void @@ -781,6 +797,33 @@ R3StretcherImpl::adjustFormant(int c) } } +void +R3StretcherImpl::adjustPreKick(int c) +{ + auto &cd = m_channelData.at(c); + auto fftSize = cd->guidance.fftBands[0].fftSize; + if (cd->guidance.preKick.present) { + auto &scale = cd->scales.at(fftSize); + int from = binForFrequency(cd->guidance.preKick.f0, fftSize); + int to = binForFrequency(cd->guidance.preKick.f1, fftSize); + for (int i = from; i <= to; ++i) { + double diff = scale->mag[i] - scale->prevMag[i]; + if (diff > 0.0) { + scale->pendingKick[i] = diff; + scale->mag[i] -= diff; + } + } + } else if (cd->guidance.kick.present) { + auto &scale = cd->scales.at(fftSize); + int from = binForFrequency(cd->guidance.preKick.f0, fftSize); + int to = binForFrequency(cd->guidance.preKick.f1, fftSize); + for (int i = from; i <= to; ++i) { + scale->mag[i] += scale->pendingKick[i]; + scale->pendingKick[i] = 0.0; + } + } +} + void R3StretcherImpl::synthesiseChannel(int c, int outhop) { diff --git a/src/finer/R3StretcherImpl.h b/src/finer/R3StretcherImpl.h index c022d3c..ad97207 100644 --- a/src/finer/R3StretcherImpl.h +++ b/src/finer/R3StretcherImpl.h @@ -110,6 +110,7 @@ protected: FixedVector phase; FixedVector advancedPhase; FixedVector prevMag; + FixedVector pendingKick; FixedVector accumulator; ChannelScaleData(int _fftSize, int _longestFftSize) : @@ -122,6 +123,7 @@ protected: phase(bufSize, 0.f), advancedPhase(bufSize, 0.f), prevMag(bufSize, 0.f), + pendingKick(bufSize, 0.f), accumulator(_longestFftSize, 0.f) { } @@ -282,6 +284,7 @@ protected: void analyseChannel(int channel, int inhop, int prevInhop, int prevOuthop); void analyseFormant(int channel); void adjustFormant(int channel); + void adjustPreKick(int channel); void synthesiseChannel(int channel, int outhop); double getEffectiveRatio() const {