Add convertToPolar to capture some of the awkward decisions in analyseChannel

This commit is contained in:
Chris Cannam
2022-06-17 16:32:14 +01:00
parent 08f7fce5f2
commit 6128ba6d36
2 changed files with 72 additions and 49 deletions

View File

@@ -700,26 +700,17 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
for (const auto &b : m_guideConfiguration.fftBandLimits) {
if (b.fftSize == classify) {
if (b.b0min > 0) {
v_cartesian_to_magnitudes(readahead.mag.data(),
classifyScale->real.data(),
classifyScale->imag.data(),
b.b0min);
}
v_cartesian_to_polar(readahead.mag.data() + b.b0min,
readahead.phase.data() + b.b0min,
classifyScale->real.data() + b.b0min,
classifyScale->imag.data() + b.b0min,
b.b1max - b.b0min);
if (b.b1max < classify/2 + 1) {
v_cartesian_to_magnitudes
(readahead.mag.data() + b.b1max,
classifyScale->real.data() + b.b1max,
classifyScale->imag.data() + b.b1max,
classify/2 + 1 - b.b1max);
}
ToPolarSpec spec;
spec.magFromBin = 0;
spec.magBinCount = classify/2 + 1;
spec.polarFromBin = b.b0min;
spec.polarBinCount = b.b1max - b.b0min + 1;
convertToPolar(readahead.mag.data(),
readahead.phase.data(),
classifyScale->real.data(),
classifyScale->imag.data(),
spec);
v_scale(classifyScale->mag.data(),
1.0 / double(classify),
@@ -749,38 +740,39 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
scale->real.data(),
scale->imag.data());
// For the classify scale we always want the full range, as
// all the magnitudes (though not phases) are potentially
// relevant to classification and formant analysis. But this
// case here only happens if we don't haveValidReadahead - the
// normal case is above and just copies from the previous
// readahead.
if (fftSize == classify) {
//!!! and because not all the phases are relevant, there
//!!! is room for an optimisation here, though this is
//!!! used only when ratio changes
v_cartesian_to_polar(scale->mag.data(),
scale->phase.data(),
scale->real.data(),
scale->imag.data(),
fftSize/2 + 1);
v_scale(scale->mag.data(),
1.0 / double(fftSize),
scale->mag.size());
continue;
}
//!!! should this be a map?
for (const auto &b : m_guideConfiguration.fftBandLimits) {
if (b.fftSize == fftSize) {
v_cartesian_to_polar(scale->mag.data() + b.b0min,
scale->phase.data() + b.b0min,
scale->real.data() + b.b0min,
scale->imag.data() + b.b0min,
b.b1max - b.b0min);
v_scale(scale->mag.data() + b.b0min,
ToPolarSpec spec;
// For the classify scale we always want the full
// range, as all the magnitudes (though not phases)
// are potentially relevant to classification and
// formant analysis. But this case here only happens
// if we don't haveValidReadahead - the normal case is
// above and just copies from the previous readahead.
if (fftSize == classify) {
spec.magFromBin = 0;
spec.magBinCount = classify/2 + 1;
spec.polarFromBin = b.b0min;
spec.polarBinCount = b.b1max - b.b0min + 1;
} else {
spec.magFromBin = b.b0min;
spec.magBinCount = b.b1max - b.b0min + 1;
spec.polarFromBin = spec.magFromBin;
spec.polarBinCount = spec.magBinCount;
}
convertToPolar(scale->mag.data(),
scale->phase.data(),
scale->real.data(),
scale->imag.data(),
spec);
v_scale(scale->mag.data() + spec.magFromBin,
1.0 / double(fftSize),
b.b1max - b.b0min);
spec.magBinCount);
break;
}
}

View File

@@ -35,6 +35,7 @@
#include "../common/FixedVector.h"
#include "../common/Allocators.h"
#include "../common/Window.h"
#include "../common/VectorOpsComplex.h"
#include "../../rubberband/RubberBandStretcher.h"
@@ -307,6 +308,36 @@ protected:
void adjustPreKick(int channel);
void synthesiseChannel(int channel, int outhop);
struct ToPolarSpec {
int magFromBin;
int magBinCount;
int polarFromBin;
int polarBinCount;
};
void convertToPolar(double *mag, double *phase,
const double *real, const double *imag,
const ToPolarSpec &s) const {
v_cartesian_to_polar(mag + s.polarFromBin,
phase + s.polarFromBin,
real + s.polarFromBin,
imag + s.polarFromBin,
s.polarBinCount);
if (s.magFromBin < s.polarFromBin) {
v_cartesian_to_magnitudes(mag + s.magFromBin,
real + s.magFromBin,
imag + s.magFromBin,
s.polarFromBin - s.magFromBin);
}
if (s.magFromBin + s.magBinCount > s.polarFromBin + s.polarBinCount) {
v_cartesian_to_magnitudes(mag + s.polarFromBin + s.polarBinCount,
real + s.polarFromBin + s.polarBinCount,
imag + s.polarFromBin + s.polarBinCount,
s.magFromBin + s.magBinCount -
s.polarFromBin - s.polarBinCount);
}
}
double getEffectiveRatio() const {
return m_timeRatio * m_pitchScale;
}