Experimental preKick to slightly reduce frame just before kick and boost kick accordingly

This commit is contained in:
Chris Cannam
2022-06-13 09:40:26 +01:00
parent 321a89e372
commit 05fb611544
4 changed files with 77 additions and 13 deletions

View File

@@ -55,7 +55,7 @@ public:
BinSegmenter(Parameters parameters) : BinSegmenter(Parameters parameters) :
m_parameters(parameters), m_parameters(parameters),
m_numeric(m_parameters.binCount, 0), m_numeric(m_parameters.binCount, 0),
m_classFilter(3, 15) m_classFilter(3, 18)
{ {
} }

View File

@@ -68,7 +68,7 @@ public:
FftBand fftBands[3]; FftBand fftBands[3];
PhaseLockBand phaseLockBands[5]; PhaseLockBand phaseLockBands[5];
Range kick; Range kick;
Range lowPercussive; Range preKick;
Range highPercussive; Range highPercussive;
Range phaseReset; Range phaseReset;
Range channelLock; Range channelLock;
@@ -140,6 +140,7 @@ public:
void updateGuidance(double ratio, void updateGuidance(double ratio,
const double *const magnitudes, const double *const magnitudes,
const double *const prevMagnitudes, const double *const prevMagnitudes,
const double *const nextMagnitudes,
const BinSegmenter::Segmentation &segmentation, const BinSegmenter::Segmentation &segmentation,
const BinSegmenter::Segmentation &prevSegmentation, const BinSegmenter::Segmentation &prevSegmentation,
const BinSegmenter::Segmentation &nextSegmentation, const BinSegmenter::Segmentation &nextSegmentation,
@@ -147,7 +148,7 @@ public:
Guidance &guidance) const { Guidance &guidance) const {
guidance.kick.present = false; guidance.kick.present = false;
guidance.lowPercussive.present = false; guidance.preKick.present = false;
guidance.highPercussive.present = false; guidance.highPercussive.present = false;
guidance.phaseReset.present = false; guidance.phaseReset.present = false;
@@ -180,16 +181,33 @@ public:
guidance.channelLock.f0 = 0.0; guidance.channelLock.f0 = 0.0;
guidance.channelLock.f1 = 600.0; guidance.channelLock.f1 = 600.0;
if (segmentation.percussiveBelow > 40.0) { bool kick =
guidance.lowPercussive.present = true; (segmentation.percussiveBelow > 40.0) &&
guidance.lowPercussive.f0 = 0.0; (prevSegmentation.percussiveBelow < 40.0) &&
guidance.lowPercussive.f1 = segmentation.percussiveBelow; checkPotentialKick(magnitudes, prevMagnitudes);
}
bool potentialKick = checkPotentialKick(magnitudes, prevMagnitudes);
if (potentialKick && prevSegmentation.percussiveBelow < 40.0) { bool futureKick = !kick &&
guidance.kick = guidance.lowPercussive; (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) { if (segmentation.residualAbove > segmentation.percussiveAbove) {

View File

@@ -436,6 +436,10 @@ R3StretcherImpl::consume()
m_prevOuthop); m_prevOuthop);
} }
for (int c = 0; c < channels; ++c) {
adjustPreKick(c);
}
// Resynthesis // Resynthesis
for (int c = 0; c < channels; ++c) { 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; std::cout << std::endl;
} }
*/ */
double instantaneousRatio = double(prevOuthop) / double(prevInhop); double instantaneousRatio = double(prevOuthop) / double(prevInhop);
bool specialCaseUnity = true; bool specialCaseUnity = true;
m_guide.updateGuidance(instantaneousRatio, m_guide.updateGuidance(instantaneousRatio,
classifyScale->mag.data(), classifyScale->mag.data(),
classifyScale->prevMag.data(), classifyScale->prevMag.data(),
cd->readahead.mag.data(),
cd->segmentation, cd->segmentation,
cd->prevSegmentation, cd->prevSegmentation,
cd->nextSegmentation, cd->nextSegmentation,
specialCaseUnity, specialCaseUnity,
cd->guidance); 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 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 void
R3StretcherImpl::synthesiseChannel(int c, int outhop) R3StretcherImpl::synthesiseChannel(int c, int outhop)
{ {

View File

@@ -110,6 +110,7 @@ protected:
FixedVector<double> phase; FixedVector<double> phase;
FixedVector<double> advancedPhase; FixedVector<double> advancedPhase;
FixedVector<double> prevMag; FixedVector<double> prevMag;
FixedVector<double> pendingKick;
FixedVector<double> accumulator; FixedVector<double> accumulator;
ChannelScaleData(int _fftSize, int _longestFftSize) : ChannelScaleData(int _fftSize, int _longestFftSize) :
@@ -122,6 +123,7 @@ protected:
phase(bufSize, 0.f), phase(bufSize, 0.f),
advancedPhase(bufSize, 0.f), advancedPhase(bufSize, 0.f),
prevMag(bufSize, 0.f), prevMag(bufSize, 0.f),
pendingKick(bufSize, 0.f),
accumulator(_longestFftSize, 0.f) accumulator(_longestFftSize, 0.f)
{ } { }
@@ -282,6 +284,7 @@ protected:
void analyseChannel(int channel, int inhop, int prevInhop, int prevOuthop); void analyseChannel(int channel, int inhop, int prevInhop, int prevOuthop);
void analyseFormant(int channel); void analyseFormant(int channel);
void adjustFormant(int channel); void adjustFormant(int channel);
void adjustPreKick(int channel);
void synthesiseChannel(int channel, int outhop); void synthesiseChannel(int channel, int outhop);
double getEffectiveRatio() const { double getEffectiveRatio() const {