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) :
m_parameters(parameters),
m_numeric(m_parameters.binCount, 0),
m_classFilter(3, 15)
m_classFilter(3, 18)
{
}

View File

@@ -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) {

View File

@@ -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)
{

View File

@@ -110,6 +110,7 @@ protected:
FixedVector<double> phase;
FixedVector<double> advancedPhase;
FixedVector<double> prevMag;
FixedVector<double> pendingKick;
FixedVector<double> 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 {