Flesh out the implementation a bit
This commit is contained in:
@@ -56,7 +56,9 @@ public:
|
||||
R3StretcherImpl(Parameters parameters) :
|
||||
m_parameters(parameters),
|
||||
m_guide(Guide::Parameters(m_parameters.sampleRate)),
|
||||
m_guideConfiguration(m_guide.getConfiguration())
|
||||
m_guideConfiguration(m_guide.getConfiguration()),
|
||||
m_channelAssembly(m_parameters.channels),
|
||||
m_troughPicker(m_guideConfiguration.classificationFftSize / 2 + 1)
|
||||
{
|
||||
BinSegmenter::Parameters segmenterParameters
|
||||
(m_guideConfiguration.classificationFftSize,
|
||||
@@ -64,7 +66,9 @@ public:
|
||||
BinClassifier::Parameters classifierParameters
|
||||
(m_guideConfiguration.classificationFftSize / 2 + 1,
|
||||
9, 1, 10, 2.0, 2.0, 1.0e-7);
|
||||
|
||||
int ringBufferSize = m_guideConfiguration.longestFftSize * 2;
|
||||
|
||||
for (int c = 0; c < m_parameters.channels; ++c) {
|
||||
m_channelData.push_back(std::make_shared<ChannelData>
|
||||
(segmenterParameters,
|
||||
@@ -72,11 +76,18 @@ public:
|
||||
ringBufferSize));
|
||||
for (auto band: m_guideConfiguration.fftBandLimits) {
|
||||
int fftSize = band.fftSize;
|
||||
m_ffts[fftSize] = std::make_shared<FFT>(fftSize);
|
||||
m_channelData[c]->scales[fftSize] =
|
||||
std::make_shared<ChannelScaleData>(fftSize);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto band: m_guideConfiguration.fftBandLimits) {
|
||||
int fftSize = band.fftSize;
|
||||
GuidedPhaseAdvance::Parameters guidedParameters
|
||||
(fftSize, m_parameters.sampleRate, m_parameters.channels,
|
||||
m_parameters.logger);
|
||||
m_scaleData[fftSize] = std::make_shared<ScaleData>(guidedParameters);
|
||||
}
|
||||
}
|
||||
|
||||
~R3StretcherImpl() { }
|
||||
@@ -89,29 +100,39 @@ public:
|
||||
double getTimeRatio() const;
|
||||
double getPitchScale() const;
|
||||
|
||||
size_t getSamplesRequired() const;
|
||||
void process(const float *const *input, size_t samples, bool final);
|
||||
int available() const;
|
||||
size_t retrieve(float *const *output, size_t samples) const;
|
||||
|
||||
size_t getLatency() const;
|
||||
size_t getChannelCount() const;
|
||||
|
||||
protected:
|
||||
struct ChannelScaleData {
|
||||
int fftSize;
|
||||
int bufSize; // size of every freq-domain array here: fftSize/2 + 1
|
||||
//!!! review later which of these we are actually using!
|
||||
FixedVector<float> timeDomainFrame;
|
||||
FixedVector<float> mag;
|
||||
FixedVector<float> phase;
|
||||
FixedVector<int> nearestPeaks;
|
||||
FixedVector<int> nearestTroughs;
|
||||
FixedVector<float> prevOutMag;
|
||||
FixedVector<double> outPhase; //!!! "advanced"?
|
||||
FixedVector<int> nextTroughs; //!!! not used in every scale
|
||||
FixedVector<float> prevMag; //!!! not used in every scale
|
||||
FixedVector<double> prevOutPhase;
|
||||
FixedVector<int> prevNearestPeaks;
|
||||
FixedVector<float> timeDomainFrame;
|
||||
Window<float> analysisWindow;
|
||||
Window<float> synthesisWindow;
|
||||
FixedVector<float> accumulator;
|
||||
|
||||
ChannelScaleData(int _fftSize) :
|
||||
fftSize(_fftSize), bufSize(fftSize/2 + 1),
|
||||
mag(bufSize, 0.f), phase(bufSize, 0.f),
|
||||
nearestPeaks(bufSize, 0), nearestTroughs(bufSize, 0),
|
||||
prevOutMag(bufSize, 0.f), prevOutPhase(bufSize, 0.f),
|
||||
prevNearestPeaks(bufSize, 0), timeDomainFrame(fftSize, 0.f),
|
||||
analysisWindow(HannWindow, fftSize),
|
||||
synthesisWindow(HannWindow, fftSize/2)
|
||||
fftSize(_fftSize),
|
||||
bufSize(fftSize/2 + 1),
|
||||
timeDomainFrame(fftSize, 0.f),
|
||||
mag(bufSize, 0.f),
|
||||
phase(bufSize, 0.f),
|
||||
outPhase(bufSize, 0.f),
|
||||
nextTroughs(bufSize, 0),
|
||||
prevMag(bufSize, 0.f),
|
||||
prevOutPhase(bufSize, 0.f),
|
||||
accumulator(fftSize, 0.f)
|
||||
{ }
|
||||
|
||||
private:
|
||||
@@ -126,8 +147,9 @@ protected:
|
||||
BinSegmenter::Segmentation prevSegmentation;
|
||||
BinSegmenter::Segmentation nextSegmentation;
|
||||
Guide::Guidance guidance;
|
||||
RingBuffer<float> inbuf;
|
||||
RingBuffer<float> outbuf;
|
||||
FixedVector<float> mixdown;
|
||||
std::unique_ptr<RingBuffer<float>> inbuf;
|
||||
std::unique_ptr<RingBuffer<float>> outbuf;
|
||||
ChannelData(BinSegmenter::Parameters segmenterParameters,
|
||||
BinClassifier::Parameters classifierParameters,
|
||||
int ringBufferSize) :
|
||||
@@ -135,19 +157,49 @@ protected:
|
||||
segmenter(new BinSegmenter(segmenterParameters,
|
||||
classifierParameters)),
|
||||
segmentation(), prevSegmentation(), nextSegmentation(),
|
||||
inbuf(ringBufferSize), outbuf(ringBufferSize) { }
|
||||
mixdown(ringBufferSize, 0.f), //!!! could be much shorter (bound is the max outhop)
|
||||
inbuf(new RingBuffer<float>(ringBufferSize)),
|
||||
outbuf(new RingBuffer<float>(ringBufferSize)) { }
|
||||
};
|
||||
|
||||
struct ChannelAssembly {
|
||||
// Vectors of bare pointers, used to package container data
|
||||
// from different channels into arguments for PhaseAdvance
|
||||
FixedVector<float *> mag;
|
||||
FixedVector<float *> phase;
|
||||
FixedVector<Guide::Guidance *> guidance;
|
||||
FixedVector<double *> outPhase;
|
||||
ChannelAssembly(int channels) :
|
||||
mag(channels, nullptr), phase(channels, nullptr),
|
||||
guidance(channels, nullptr), outPhase(channels, nullptr) { }
|
||||
};
|
||||
|
||||
struct ScaleData {
|
||||
FFT fft;
|
||||
Window<float> analysisWindow;
|
||||
Window<float> synthesisWindow;
|
||||
GuidedPhaseAdvance guided;
|
||||
ScaleData(GuidedPhaseAdvance::Parameters guidedParameters) :
|
||||
fft(guidedParameters.fftSize),
|
||||
analysisWindow(HannWindow, guidedParameters.fftSize),
|
||||
synthesisWindow(HannWindow, guidedParameters.fftSize/2),
|
||||
guided(guidedParameters) { }
|
||||
};
|
||||
|
||||
Parameters m_parameters;
|
||||
|
||||
double m_timeRatio;
|
||||
double m_pitchScale;
|
||||
|
||||
std::vector<std::shared_ptr<ChannelData>> m_channelData;
|
||||
std::map<int, std::shared_ptr<FFT>> m_ffts;
|
||||
std::map<int, std::shared_ptr<ScaleData>> m_scaleData;
|
||||
Guide m_guide;
|
||||
Guide::Configuration m_guideConfiguration;
|
||||
ChannelAssembly m_channelAssembly;
|
||||
Peak<float, std::less<float>> m_troughPicker;
|
||||
|
||||
void consume();
|
||||
|
||||
static void logCerr(const std::string &message) {
|
||||
std::cerr << "RubberBandStretcher: " << message << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user