Enable PROCESS_SAMPLE_TYPE for R3 as well, switching from double to process_t throughout
This commit is contained in:
@@ -62,18 +62,18 @@ public:
|
||||
|
||||
BinClassifier(Parameters parameters) :
|
||||
m_parameters(parameters),
|
||||
m_hFilters(new MovingMedianStack<double>(m_parameters.binCount,
|
||||
m_parameters.horizontalFilterLength)),
|
||||
m_vFilter(new MovingMedian<double>(m_parameters.verticalFilterLength)),
|
||||
m_hFilters(new MovingMedianStack<process_t>(m_parameters.binCount,
|
||||
m_parameters.horizontalFilterLength)),
|
||||
m_vFilter(new MovingMedian<process_t>(m_parameters.verticalFilterLength)),
|
||||
m_vfQueue(parameters.horizontalFilterLag)
|
||||
{
|
||||
int n = m_parameters.binCount;
|
||||
|
||||
m_hf = allocate_and_zero<double>(n);
|
||||
m_vf = allocate_and_zero<double>(n);
|
||||
m_hf = allocate_and_zero<process_t>(n);
|
||||
m_vf = allocate_and_zero<process_t>(n);
|
||||
|
||||
for (int i = 0; i < m_parameters.horizontalFilterLag; ++i) {
|
||||
double *entry = allocate_and_zero<double>(n);
|
||||
process_t *entry = allocate_and_zero<process_t>(n);
|
||||
m_vfQueue.write(&entry, 1);
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
~BinClassifier()
|
||||
{
|
||||
while (m_vfQueue.getReadSpace() > 0) {
|
||||
double *entry = m_vfQueue.readOne();
|
||||
process_t *entry = m_vfQueue.readOne();
|
||||
deallocate(entry);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
m_hFilters->reset();
|
||||
}
|
||||
|
||||
void classify(const double *const mag, // input, of at least binCount bins
|
||||
void classify(const process_t *const mag, // input, of at least binCount bins
|
||||
Classification *classification) // output, of binCount bins
|
||||
{
|
||||
const int n = m_parameters.binCount;
|
||||
@@ -105,22 +105,22 @@ public:
|
||||
}
|
||||
|
||||
v_copy(m_vf, mag, n);
|
||||
MovingMedian<double>::filter(*m_vFilter, m_vf, n);
|
||||
MovingMedian<process_t>::filter(*m_vFilter, m_vf, n);
|
||||
|
||||
if (m_parameters.horizontalFilterLag > 0) {
|
||||
double *lagged = m_vfQueue.readOne();
|
||||
process_t *lagged = m_vfQueue.readOne();
|
||||
m_vfQueue.write(&m_vf, 1);
|
||||
m_vf = lagged;
|
||||
}
|
||||
|
||||
double eps = 1.0e-7;
|
||||
process_t eps = 1.0e-7;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Classification c;
|
||||
if (double(m_hf[i]) / (double(m_vf[i]) + eps) >
|
||||
if (process_t(m_hf[i]) / (process_t(m_vf[i]) + eps) >
|
||||
m_parameters.harmonicThreshold) {
|
||||
c = Classification::Harmonic;
|
||||
} else if (double(m_vf[i]) / (double(m_hf[i]) + eps) >
|
||||
} else if (process_t(m_vf[i]) / (process_t(m_hf[i]) + eps) >
|
||||
m_parameters.percussiveThreshold) {
|
||||
c = Classification::Percussive;
|
||||
} else {
|
||||
@@ -132,13 +132,13 @@ public:
|
||||
|
||||
protected:
|
||||
Parameters m_parameters;
|
||||
std::unique_ptr<MovingMedianStack<double>> m_hFilters;
|
||||
std::unique_ptr<MovingMedian<double>> m_vFilter;
|
||||
std::unique_ptr<MovingMedianStack<process_t>> m_hFilters;
|
||||
std::unique_ptr<MovingMedian<process_t>> m_vFilter;
|
||||
// We manage the queued frames through pointer swapping, hence
|
||||
// bare pointers here
|
||||
double *m_hf;
|
||||
double *m_vf;
|
||||
RingBuffer<double *> m_vfQueue;
|
||||
process_t *m_hf;
|
||||
process_t *m_vf;
|
||||
RingBuffer<process_t *> m_vfQueue;
|
||||
|
||||
BinClassifier(const BinClassifier &) =delete;
|
||||
BinClassifier &operator=(const BinClassifier &) =delete;
|
||||
|
||||
@@ -147,13 +147,13 @@ public:
|
||||
|
||||
void updateGuidance(double ratio,
|
||||
int outhop,
|
||||
const double *const magnitudes,
|
||||
const double *const prevMagnitudes,
|
||||
const double *const nextMagnitudes,
|
||||
const process_t *const magnitudes,
|
||||
const process_t *const prevMagnitudes,
|
||||
const process_t *const nextMagnitudes,
|
||||
const BinSegmenter::Segmentation &segmentation,
|
||||
const BinSegmenter::Segmentation &prevSegmentation,
|
||||
const BinSegmenter::Segmentation &nextSegmentation,
|
||||
double meanMagnitude,
|
||||
process_t meanMagnitude,
|
||||
int unityCount,
|
||||
bool realtime,
|
||||
bool tighterChannelLock,
|
||||
@@ -388,7 +388,7 @@ protected:
|
||||
void updateForUnity(Guidance &guidance,
|
||||
bool hadPhaseReset,
|
||||
uint32_t /* unityCount */,
|
||||
const double *const /* magnitudes */,
|
||||
const process_t *const /* magnitudes */,
|
||||
const BinSegmenter::Segmentation &segmentation,
|
||||
bool realtime) const {
|
||||
|
||||
@@ -449,11 +449,11 @@ protected:
|
||||
// }
|
||||
}
|
||||
|
||||
bool checkPotentialKick(const double *const magnitudes,
|
||||
const double *const prevMagnitudes) const {
|
||||
bool checkPotentialKick(const process_t *const magnitudes,
|
||||
const process_t *const prevMagnitudes) const {
|
||||
int b = binForFrequency(200.0, m_configuration.classificationFftSize,
|
||||
m_parameters.sampleRate);
|
||||
double here = 0.0, there = 0.0;
|
||||
process_t here = 0.0, there = 0.0;
|
||||
for (int i = 1; i <= b; ++i) {
|
||||
here += magnitudes[i];
|
||||
}
|
||||
@@ -463,7 +463,7 @@ protected:
|
||||
return (here > 10.e-3 && here > there * 1.4);
|
||||
}
|
||||
|
||||
double descendToValley(double f, const double *const magnitudes) const {
|
||||
double descendToValley(double f, const process_t *const magnitudes) const {
|
||||
if (f == 0.0 || f == m_parameters.sampleRate/2.0) {
|
||||
// These are special cases
|
||||
return f;
|
||||
|
||||
@@ -56,9 +56,9 @@ public:
|
||||
m_currentPeaks = allocate_and_zero_channels<int>(ch, m_binCount);
|
||||
m_prevPeaks = allocate_and_zero_channels<int>(ch, m_binCount);
|
||||
m_greatestChannel = allocate_and_zero<int>(m_binCount);
|
||||
m_prevInPhase = allocate_and_zero_channels<double>(ch, m_binCount);
|
||||
m_prevOutPhase = allocate_and_zero_channels<double>(ch, m_binCount);
|
||||
m_unlocked = allocate_and_zero_channels<double>(ch, m_binCount);
|
||||
m_prevInPhase = allocate_and_zero_channels<process_t>(ch, m_binCount);
|
||||
m_prevOutPhase = allocate_and_zero_channels<process_t>(ch, m_binCount);
|
||||
m_unlocked = allocate_and_zero_channels<process_t>(ch, m_binCount);
|
||||
|
||||
for (int c = 0; c < ch; ++c) {
|
||||
for (int i = 0; i < m_binCount; ++i) {
|
||||
@@ -84,10 +84,10 @@ public:
|
||||
v_zero_channels(m_prevOutPhase, ch, m_binCount);
|
||||
}
|
||||
|
||||
void advance(double *const *outPhase,
|
||||
const double *const *mag,
|
||||
const double *const *phase,
|
||||
const double *const *prevMag,
|
||||
void advance(process_t *const *outPhase,
|
||||
const process_t *const *mag,
|
||||
const process_t *const *phase,
|
||||
const process_t *const *prevMag,
|
||||
const Guide::Configuration &configuration,
|
||||
const Guide::Guidance *const *guidance,
|
||||
int inhop,
|
||||
@@ -163,14 +163,14 @@ public:
|
||||
v_zero(m_greatestChannel, bs);
|
||||
}
|
||||
|
||||
double omegaFactor = 2.0 * M_PI * double(inhop) /
|
||||
double(m_parameters.fftSize);
|
||||
process_t omegaFactor = 2.0 * M_PI * process_t(inhop) /
|
||||
process_t(m_parameters.fftSize);
|
||||
for (int c = 0; c < channels; ++c) {
|
||||
for (int i = lowest; i <= highest; ++i) {
|
||||
double omega = omegaFactor * double(i);
|
||||
double expected = m_prevInPhase[c][i] + omega;
|
||||
double error = princarg(phase[c][i] - expected);
|
||||
double advance = ratio * (omega + error);
|
||||
process_t omega = omegaFactor * process_t(i);
|
||||
process_t expected = m_prevInPhase[c][i] + omega;
|
||||
process_t error = princarg(phase[c][i] - expected);
|
||||
process_t advance = ratio * (omega + error);
|
||||
m_unlocked[c][i] = m_prevOutPhase[c][i] + advance;
|
||||
}
|
||||
}
|
||||
@@ -179,12 +179,12 @@ public:
|
||||
const Guide::Guidance *g = guidance[c];
|
||||
int phaseLockBand = 0;
|
||||
for (int i = lowest; i <= highest; ++i) {
|
||||
double f = frequencyForBin
|
||||
process_t f = frequencyForBin
|
||||
(i, m_parameters.fftSize, m_parameters.sampleRate);
|
||||
while (f > g->phaseLockBands[phaseLockBand].f1) {
|
||||
++phaseLockBand;
|
||||
}
|
||||
double ph = 0.0;
|
||||
process_t ph = 0.0;
|
||||
if (inRange(f, g->phaseReset) || inRange(f, g->kick)) {
|
||||
ph = phase[c][i];
|
||||
} else if (inhop == outhop) {
|
||||
@@ -206,14 +206,14 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
double peakAdvance =
|
||||
process_t peakAdvance =
|
||||
m_unlocked[peakCh][peak] - m_prevOutPhase[peakCh][peak];
|
||||
double peakNew =
|
||||
process_t peakNew =
|
||||
m_prevOutPhase[peakCh][prevPeak] + peakAdvance;
|
||||
double diff =
|
||||
double(phase[c][i]) - double(phase[peakCh][peak]);
|
||||
double beta =
|
||||
double(g->phaseLockBands[phaseLockBand].beta);
|
||||
process_t diff =
|
||||
process_t(phase[c][i]) - process_t(phase[peakCh][peak]);
|
||||
process_t beta =
|
||||
process_t(g->phaseLockBands[phaseLockBand].beta);
|
||||
ph = peakNew + beta * diff;
|
||||
}
|
||||
outPhase[c][i] = princarg(ph);
|
||||
@@ -238,16 +238,16 @@ protected:
|
||||
Parameters m_parameters;
|
||||
Log m_log;
|
||||
int m_binCount;
|
||||
Peak<double> m_peakPicker;
|
||||
Peak<process_t> m_peakPicker;
|
||||
int **m_currentPeaks;
|
||||
int **m_prevPeaks;
|
||||
int *m_greatestChannel;
|
||||
double **m_prevInPhase;
|
||||
double **m_prevOutPhase;
|
||||
double **m_unlocked;
|
||||
process_t **m_prevInPhase;
|
||||
process_t **m_prevOutPhase;
|
||||
process_t **m_unlocked;
|
||||
bool m_reported;
|
||||
|
||||
bool inRange(double f, const Guide::Range &r) {
|
||||
bool inRange(process_t f, const Guide::Range &r) {
|
||||
return r.present && f >= r.f0 && f < r.f1;
|
||||
}
|
||||
|
||||
|
||||
@@ -796,7 +796,7 @@ R3Stretcher::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
|
||||
int classify = m_guideConfiguration.classificationFftSize;
|
||||
|
||||
auto &cd = m_channelData.at(c);
|
||||
double *buf = cd->scales.at(longest)->timeDomain.data();
|
||||
process_t *buf = cd->scales.at(longest)->timeDomain.data();
|
||||
|
||||
int readSpace = cd->inbuf->getReadSpace();
|
||||
if (readSpace < longest) {
|
||||
@@ -1074,20 +1074,20 @@ R3Stretcher::adjustFormant(int c)
|
||||
auto &scale = it.second;
|
||||
|
||||
int highBin = int(floor(fftSize * 10000.0 / m_parameters.sampleRate));
|
||||
double targetFactor = double(cd->formant->fftSize) / double(fftSize);
|
||||
double formantScale = m_formantScale;
|
||||
process_t targetFactor = process_t(cd->formant->fftSize) / process_t(fftSize);
|
||||
process_t formantScale = m_formantScale;
|
||||
if (formantScale == 0.0) formantScale = 1.0 / m_pitchScale;
|
||||
double sourceFactor = targetFactor / formantScale;
|
||||
double maxRatio = 60.0;
|
||||
double minRatio = 1.0 / maxRatio;
|
||||
process_t sourceFactor = targetFactor / formantScale;
|
||||
process_t maxRatio = 60.0;
|
||||
process_t minRatio = 1.0 / maxRatio;
|
||||
|
||||
for (const auto &b : m_guideConfiguration.fftBandLimits) {
|
||||
if (b.fftSize != fftSize) continue;
|
||||
for (int i = b.b0min; i < b.b1max && i < highBin; ++i) {
|
||||
double source = cd->formant->envelopeAt(i * sourceFactor);
|
||||
double target = cd->formant->envelopeAt(i * targetFactor);
|
||||
process_t source = cd->formant->envelopeAt(i * sourceFactor);
|
||||
process_t target = cd->formant->envelopeAt(i * targetFactor);
|
||||
if (target > 0.0) {
|
||||
double ratio = source / target;
|
||||
process_t ratio = source / target;
|
||||
if (ratio < minRatio) ratio = minRatio;
|
||||
if (ratio > maxRatio) ratio = maxRatio;
|
||||
scale->mag[i] *= ratio;
|
||||
@@ -1109,7 +1109,7 @@ R3Stretcher::adjustPreKick(int c)
|
||||
int to = binForFrequency(cd->guidance.preKick.f1,
|
||||
fftSize, m_parameters.sampleRate);
|
||||
for (int i = from; i <= to; ++i) {
|
||||
double diff = scale->mag[i] - scale->prevMag[i];
|
||||
process_t diff = scale->mag[i] - scale->prevMag[i];
|
||||
if (diff > 0.0) {
|
||||
scale->pendingKick[i] = diff;
|
||||
scale->mag[i] -= diff;
|
||||
@@ -1145,7 +1145,7 @@ R3Stretcher::synthesiseChannel(int c, int outhop)
|
||||
scale->mag.data(),
|
||||
scale->bufSize);
|
||||
|
||||
double winscale = double(outhop) / scaleData->windowScaleFactor;
|
||||
process_t winscale = process_t(outhop) / scaleData->windowScaleFactor;
|
||||
|
||||
// The frequency filter is applied naively in the frequency
|
||||
// domain. Aliasing is reduced by the shorter resynthesis
|
||||
@@ -1204,7 +1204,7 @@ R3Stretcher::synthesiseChannel(int c, int outhop)
|
||||
for (auto &it : cd->scales) {
|
||||
auto &scale = it.second;
|
||||
|
||||
double *accptr = scale->accumulator.data();
|
||||
process_t *accptr = scale->accumulator.data();
|
||||
for (int i = 0; i < outhop; ++i) {
|
||||
mixptr[i] += float(accptr[i]);
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ public:
|
||||
|
||||
protected:
|
||||
struct ClassificationReadaheadData {
|
||||
FixedVector<double> timeDomain;
|
||||
FixedVector<double> mag;
|
||||
FixedVector<double> phase;
|
||||
FixedVector<process_t> timeDomain;
|
||||
FixedVector<process_t> mag;
|
||||
FixedVector<process_t> phase;
|
||||
ClassificationReadaheadData(int _fftSize) :
|
||||
timeDomain(_fftSize, 0.f),
|
||||
mag(_fftSize/2 + 1, 0.f),
|
||||
@@ -120,15 +120,15 @@ protected:
|
||||
struct ChannelScaleData {
|
||||
int fftSize;
|
||||
int bufSize; // size of every freq-domain array here: fftSize/2 + 1
|
||||
FixedVector<double> timeDomain;
|
||||
FixedVector<double> real;
|
||||
FixedVector<double> imag;
|
||||
FixedVector<double> mag;
|
||||
FixedVector<double> phase;
|
||||
FixedVector<double> advancedPhase;
|
||||
FixedVector<double> prevMag;
|
||||
FixedVector<double> pendingKick;
|
||||
FixedVector<double> accumulator;
|
||||
FixedVector<process_t> timeDomain;
|
||||
FixedVector<process_t> real;
|
||||
FixedVector<process_t> imag;
|
||||
FixedVector<process_t> mag;
|
||||
FixedVector<process_t> phase;
|
||||
FixedVector<process_t> advancedPhase;
|
||||
FixedVector<process_t> prevMag;
|
||||
FixedVector<process_t> pendingKick;
|
||||
FixedVector<process_t> accumulator;
|
||||
|
||||
ChannelScaleData(int _fftSize, int _longestFftSize) :
|
||||
fftSize(_fftSize),
|
||||
@@ -156,9 +156,9 @@ protected:
|
||||
|
||||
struct FormantData {
|
||||
int fftSize;
|
||||
FixedVector<double> cepstra;
|
||||
FixedVector<double> envelope;
|
||||
FixedVector<double> spare;
|
||||
FixedVector<process_t> cepstra;
|
||||
FixedVector<process_t> envelope;
|
||||
FixedVector<process_t> spare;
|
||||
|
||||
FormantData(int _fftSize) :
|
||||
fftSize(_fftSize),
|
||||
@@ -166,14 +166,14 @@ protected:
|
||||
envelope(_fftSize/2 + 1, 0.0),
|
||||
spare(_fftSize/2 + 1, 0.0) { }
|
||||
|
||||
double envelopeAt(double bin) const {
|
||||
process_t envelopeAt(process_t bin) const {
|
||||
int b0 = int(floor(bin)), b1 = int(ceil(bin));
|
||||
if (b0 < 0 || b0 > fftSize/2) {
|
||||
return 0.0;
|
||||
} else if (b1 == b0 || b1 > fftSize/2) {
|
||||
return envelope.at(b0);
|
||||
} else {
|
||||
double diff = bin - double(b0);
|
||||
process_t diff = bin - process_t(b0);
|
||||
return envelope.at(b0) * (1.0 - diff) + envelope.at(b1) * diff;
|
||||
}
|
||||
}
|
||||
@@ -233,11 +233,11 @@ protected:
|
||||
struct ChannelAssembly {
|
||||
// Vectors of bare pointers, used to package container data
|
||||
// from different channels into arguments for PhaseAdvance
|
||||
FixedVector<double *> mag;
|
||||
FixedVector<double *> phase;
|
||||
FixedVector<double *> prevMag;
|
||||
FixedVector<process_t *> mag;
|
||||
FixedVector<process_t *> phase;
|
||||
FixedVector<process_t *> prevMag;
|
||||
FixedVector<Guide::Guidance *> guidance;
|
||||
FixedVector<double *> outPhase;
|
||||
FixedVector<process_t *> outPhase;
|
||||
FixedVector<float *> mixdown;
|
||||
FixedVector<float *> resampled;
|
||||
ChannelAssembly(int channels) :
|
||||
@@ -250,9 +250,9 @@ protected:
|
||||
struct ScaleData {
|
||||
int fftSize;
|
||||
FFT fft;
|
||||
Window<double> analysisWindow;
|
||||
Window<double> synthesisWindow;
|
||||
double windowScaleFactor;
|
||||
Window<process_t> analysisWindow;
|
||||
Window<process_t> synthesisWindow;
|
||||
process_t windowScaleFactor;
|
||||
GuidedPhaseAdvance guided;
|
||||
ScaleData(GuidedPhaseAdvance::Parameters guidedParameters,
|
||||
Log log) :
|
||||
@@ -331,8 +331,8 @@ protected:
|
||||
int polarBinCount;
|
||||
};
|
||||
|
||||
void convertToPolar(double *mag, double *phase,
|
||||
const double *real, const double *imag,
|
||||
void convertToPolar(process_t *mag, process_t *phase,
|
||||
const process_t *real, const process_t *imag,
|
||||
const ToPolarSpec &s) const {
|
||||
v_cartesian_to_polar(mag + s.polarFromBin,
|
||||
phase + s.polarFromBin,
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "../finer/BinClassifier.h"
|
||||
#include "../finer/BinSegmenter.h"
|
||||
|
||||
#include "../common/sysutils.h"
|
||||
|
||||
using namespace RubberBand;
|
||||
using namespace std;
|
||||
namespace tt = boost::test_tools;
|
||||
@@ -59,7 +61,7 @@ BOOST_AUTO_TEST_SUITE(TestBinClassifier)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(classify_bins)
|
||||
{
|
||||
vector<vector<double>> magColumns {
|
||||
vector<vector<process_t>> magColumns {
|
||||
{ 0, 8, 1, 1, 0, 1 },
|
||||
{ 0, 8, 0, 0, 0, 0 },
|
||||
{ 8, 8, 8, 8, 8, 0 },
|
||||
|
||||
Reference in New Issue
Block a user