Attempt to "fade in" phase resets on return to unity, so as to return to an approximate pass-through without too audible a click
This commit is contained in:
@@ -147,37 +147,37 @@ public:
|
|||||||
const BinSegmenter::Segmentation &segmentation,
|
const BinSegmenter::Segmentation &segmentation,
|
||||||
const BinSegmenter::Segmentation &prevSegmentation,
|
const BinSegmenter::Segmentation &prevSegmentation,
|
||||||
const BinSegmenter::Segmentation &nextSegmentation,
|
const BinSegmenter::Segmentation &nextSegmentation,
|
||||||
bool specialCaseUnity,
|
double meanMagnitude,
|
||||||
|
int unityCount,
|
||||||
Guidance &guidance) const {
|
Guidance &guidance) const {
|
||||||
|
|
||||||
|
bool hadPhaseReset = guidance.phaseReset.present;
|
||||||
|
|
||||||
|
guidance.phaseReset.present = false;
|
||||||
guidance.kick.present = false;
|
guidance.kick.present = false;
|
||||||
guidance.preKick.present = false;
|
guidance.preKick.present = false;
|
||||||
guidance.highUnlocked.present = false;
|
guidance.highUnlocked.present = false;
|
||||||
guidance.phaseReset.present = false;
|
guidance.channelLock.present = false;
|
||||||
|
|
||||||
double nyquist = m_parameters.sampleRate / 2.0;
|
double nyquist = m_parameters.sampleRate / 2.0;
|
||||||
|
|
||||||
guidance.fftBands[0].fftSize = roundUp(int(ceil(nyquist/8.0)));
|
guidance.fftBands[0].fftSize = roundUp(int(ceil(nyquist/8.0)));
|
||||||
guidance.fftBands[1].fftSize = roundUp(int(ceil(nyquist/16.0)));
|
guidance.fftBands[1].fftSize = roundUp(int(ceil(nyquist/16.0)));
|
||||||
guidance.fftBands[2].fftSize = roundUp(int(ceil(nyquist/32.0)));
|
guidance.fftBands[2].fftSize = roundUp(int(ceil(nyquist/32.0)));
|
||||||
|
|
||||||
if (specialCaseUnity && (fabs(ratio - 1.0) < 1.0e-6)) {
|
// This is a vital stop case for PhaseAdvance
|
||||||
guidance.fftBands[0].f0 = 0.0;
|
guidance.phaseLockBands[3].f1 = nyquist;
|
||||||
guidance.fftBands[0].f1 = 0.0;
|
|
||||||
guidance.fftBands[1].f0 = 0.0;
|
if (meanMagnitude < 1.0e-6) {
|
||||||
guidance.fftBands[1].f1 = m_minHigher;
|
updateForSilence(guidance);
|
||||||
guidance.fftBands[2].f0 = m_minHigher;
|
return;
|
||||||
guidance.fftBands[2].f1 = nyquist;
|
}
|
||||||
for (int i = 0; i < int(sizeof(guidance.phaseLockBands) /
|
|
||||||
sizeof(guidance.phaseLockBands[0])); ++i) {
|
if (unityCount > 0) {
|
||||||
guidance.phaseLockBands[i].p = 0;
|
updateForUnity(guidance,
|
||||||
guidance.phaseLockBands[i].beta = 1.0;
|
hadPhaseReset,
|
||||||
guidance.phaseLockBands[i].f0 = nyquist;
|
unityCount,
|
||||||
guidance.phaseLockBands[i].f1 = nyquist;
|
magnitudes,
|
||||||
}
|
segmentation);
|
||||||
guidance.phaseLockBands[0].f0 = 0.0;
|
|
||||||
guidance.phaseLockBands[0].f1 = nyquist;
|
|
||||||
guidance.channelLock.present = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +352,68 @@ protected:
|
|||||||
return value;
|
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,
|
bool checkPotentialKick(const double *const magnitudes,
|
||||||
const double *const prevMagnitudes) const {
|
const double *const prevMagnitudes) const {
|
||||||
int b = binForFrequency(200.0, m_configuration.classificationFftSize,
|
int b = binForFrequency(200.0, m_configuration.classificationFftSize,
|
||||||
|
|||||||
@@ -186,19 +186,20 @@ public:
|
|||||||
++phaseLockBand;
|
++phaseLockBand;
|
||||||
}
|
}
|
||||||
double ph = 0.0;
|
double ph = 0.0;
|
||||||
if (inhop == outhop) {
|
if (inRange(f, g->phaseReset) || inRange(f, g->kick)) {
|
||||||
ph = m_unlocked[c][i];
|
|
||||||
} else if (inRange(f, g->phaseReset) || inRange(f, g->kick)) {
|
|
||||||
ph = phase[c][i];
|
ph = phase[c][i];
|
||||||
|
} else if (inhop == outhop) {
|
||||||
|
ph = m_unlocked[c][i];
|
||||||
} else if (inRange (f, g->highUnlocked)) {
|
} else if (inRange (f, g->highUnlocked)) {
|
||||||
ph = m_unlocked[c][i];
|
ph = m_unlocked[c][i];
|
||||||
} else {
|
} else {
|
||||||
int peak = m_currentPeaks[c][i];
|
int peak = m_currentPeaks[c][i];
|
||||||
int prevPeak = m_prevPeaks[c][peak];
|
int prevPeak = m_prevPeaks[c][peak];
|
||||||
int peakCh = c;
|
int peakCh = c;
|
||||||
if (inRange (f, g->channelLock)) {
|
if (inRange(f, g->channelLock)) {
|
||||||
int other = m_greatestChannel[i];
|
int other = m_greatestChannel[i];
|
||||||
if (other != c) {
|
if (other != c &&
|
||||||
|
inRange(f, guidance[other]->channelLock)) {
|
||||||
int otherPeak = m_currentPeaks[other][i];
|
int otherPeak = m_currentPeaks[other][i];
|
||||||
int otherPrevPeak = m_prevPeaks[other][otherPeak];
|
int otherPrevPeak = m_prevPeaks[other][otherPeak];
|
||||||
if (otherPrevPeak == prevPeak) {
|
if (otherPrevPeak == prevPeak) {
|
||||||
@@ -216,7 +217,7 @@ public:
|
|||||||
double(g->phaseLockBands[phaseLockBand].beta);
|
double(g->phaseLockBands[phaseLockBand].beta);
|
||||||
ph = peakNew + beta * diff;
|
ph = peakNew + beta * diff;
|
||||||
}
|
}
|
||||||
outPhase[c][i] = ph;
|
outPhase[c][i] = princarg(ph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ R3StretcherImpl::R3StretcherImpl(Parameters parameters,
|
|||||||
m_guideConfiguration(m_guide.getConfiguration()),
|
m_guideConfiguration(m_guide.getConfiguration()),
|
||||||
m_channelAssembly(m_parameters.channels),
|
m_channelAssembly(m_parameters.channels),
|
||||||
m_inhop(1),
|
m_inhop(1),
|
||||||
|
m_prevInhop(1),
|
||||||
m_prevOuthop(1),
|
m_prevOuthop(1),
|
||||||
|
m_unityCount(0),
|
||||||
m_startSkip(0),
|
m_startSkip(0),
|
||||||
m_studyInputDuration(0),
|
m_studyInputDuration(0),
|
||||||
m_totalTargetDuration(0),
|
m_totalTargetDuration(0),
|
||||||
@@ -826,9 +828,16 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
bool specialCaseUnity = true;
|
|
||||||
|
|
||||||
m_guide.updateGuidance(getEffectiveRatio(),
|
double ratio = getEffectiveRatio();
|
||||||
|
|
||||||
|
if (fabs(ratio - 1.0) < 1.0e-6) {
|
||||||
|
++m_unityCount;
|
||||||
|
} else {
|
||||||
|
m_unityCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_guide.updateGuidance(ratio,
|
||||||
prevOuthop,
|
prevOuthop,
|
||||||
classifyScale->mag.data(),
|
classifyScale->mag.data(),
|
||||||
classifyScale->prevMag.data(),
|
classifyScale->prevMag.data(),
|
||||||
@@ -836,7 +845,8 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
|
|||||||
cd->segmentation,
|
cd->segmentation,
|
||||||
cd->prevSegmentation,
|
cd->prevSegmentation,
|
||||||
cd->nextSegmentation,
|
cd->nextSegmentation,
|
||||||
specialCaseUnity,
|
v_mean(classifyScale->mag.data() + 1, classify/2),
|
||||||
|
m_unityCount,
|
||||||
cd->guidance);
|
cd->guidance);
|
||||||
/*
|
/*
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ protected:
|
|||||||
std::atomic<int> m_inhop;
|
std::atomic<int> m_inhop;
|
||||||
int m_prevInhop;
|
int m_prevInhop;
|
||||||
int m_prevOuthop;
|
int m_prevOuthop;
|
||||||
|
uint32_t m_unityCount;
|
||||||
int m_startSkip;
|
int m_startSkip;
|
||||||
|
|
||||||
size_t m_studyInputDuration;
|
size_t m_studyInputDuration;
|
||||||
|
|||||||
Reference in New Issue
Block a user