Add convertToPolar to capture some of the awkward decisions in analyseChannel
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user