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) {
|
for (const auto &b : m_guideConfiguration.fftBandLimits) {
|
||||||
if (b.fftSize == classify) {
|
if (b.fftSize == classify) {
|
||||||
if (b.b0min > 0) {
|
|
||||||
v_cartesian_to_magnitudes(readahead.mag.data(),
|
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->real.data(),
|
||||||
classifyScale->imag.data(),
|
classifyScale->imag.data(),
|
||||||
b.b0min);
|
spec);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
v_scale(classifyScale->mag.data(),
|
v_scale(classifyScale->mag.data(),
|
||||||
1.0 / double(classify),
|
1.0 / double(classify),
|
||||||
@@ -749,38 +740,39 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
|
|||||||
scale->real.data(),
|
scale->real.data(),
|
||||||
scale->imag.data());
|
scale->imag.data());
|
||||||
|
|
||||||
// For the classify scale we always want the full range, as
|
for (const auto &b : m_guideConfiguration.fftBandLimits) {
|
||||||
// all the magnitudes (though not phases) are potentially
|
if (b.fftSize == fftSize) {
|
||||||
// relevant to classification and formant analysis. But this
|
|
||||||
// case here only happens if we don't haveValidReadahead - the
|
ToPolarSpec spec;
|
||||||
// normal case is above and just copies from the previous
|
|
||||||
// readahead.
|
// 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) {
|
if (fftSize == classify) {
|
||||||
//!!! and because not all the phases are relevant, there
|
spec.magFromBin = 0;
|
||||||
//!!! is room for an optimisation here, though this is
|
spec.magBinCount = classify/2 + 1;
|
||||||
//!!! used only when ratio changes
|
spec.polarFromBin = b.b0min;
|
||||||
v_cartesian_to_polar(scale->mag.data(),
|
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->phase.data(),
|
||||||
scale->real.data(),
|
scale->real.data(),
|
||||||
scale->imag.data(),
|
scale->imag.data(),
|
||||||
fftSize/2 + 1);
|
spec);
|
||||||
v_scale(scale->mag.data(),
|
|
||||||
1.0 / double(fftSize),
|
|
||||||
scale->mag.size());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//!!! should this be a map?
|
v_scale(scale->mag.data() + spec.magFromBin,
|
||||||
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,
|
|
||||||
1.0 / double(fftSize),
|
1.0 / double(fftSize),
|
||||||
b.b1max - b.b0min);
|
spec.magBinCount);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "../common/FixedVector.h"
|
#include "../common/FixedVector.h"
|
||||||
#include "../common/Allocators.h"
|
#include "../common/Allocators.h"
|
||||||
#include "../common/Window.h"
|
#include "../common/Window.h"
|
||||||
|
#include "../common/VectorOpsComplex.h"
|
||||||
|
|
||||||
#include "../../rubberband/RubberBandStretcher.h"
|
#include "../../rubberband/RubberBandStretcher.h"
|
||||||
|
|
||||||
@@ -307,6 +308,36 @@ protected:
|
|||||||
void adjustPreKick(int channel);
|
void adjustPreKick(int channel);
|
||||||
void synthesiseChannel(int channel, int outhop);
|
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 {
|
double getEffectiveRatio() const {
|
||||||
return m_timeRatio * m_pitchScale;
|
return m_timeRatio * m_pitchScale;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user