diff --git a/src/common/RingBuffer.h b/src/common/RingBuffer.h index fb80788..a905a33 100644 --- a/src/common/RingBuffer.h +++ b/src/common/RingBuffer.h @@ -138,8 +138,13 @@ public: * necessary to empty the buffer. If fewer than n are available, * the remainder will be zeroed out. Returns the number of * samples actually read. + * + * This is a template function, taking an argument S for the target + * sample type, which is permitted to differ from T if the two + * types are compatible for arithmetic operations. */ - int peek(T *const R__ destination, int n) const; + template + int peek(S *const R__ destination, int n) const; /** * Read one sample from the buffer, if available, without @@ -384,8 +389,9 @@ RingBuffer::readOne() } template +template int -RingBuffer::peek(T *const R__ destination, int n) const +RingBuffer::peek(S *const R__ destination, int n) const { int w = m_writer; int r = m_reader; @@ -394,7 +400,6 @@ RingBuffer::peek(T *const R__ destination, int n) const if (n > available) { std::cerr << "WARNING: RingBuffer::peek: " << n << " requested, only " << available << " available" << std::endl; - memset(destination + available, 0, (n - available) * sizeof(T)); n = available; } if (n == 0) return n; @@ -403,10 +408,10 @@ RingBuffer::peek(T *const R__ destination, int n) const const T *const R__ bufbase = m_buffer + r; if (here >= n) { - v_copy(destination, bufbase, n); + v_convert(destination, bufbase, n); } else { - v_copy(destination, bufbase, here); - v_copy(destination + here, m_buffer, n - here); + v_convert(destination, bufbase, here); + v_convert(destination + here, m_buffer, n - here); } return n; diff --git a/src/finer/BinClassifier.h b/src/finer/BinClassifier.h index cf2655c..73febee 100644 --- a/src/finer/BinClassifier.h +++ b/src/finer/BinClassifier.h @@ -50,11 +50,11 @@ public: int verticalFilterLength; double harmonicThreshold; double percussiveThreshold; - float silenceThreshold; + double silenceThreshold; Parameters(int _binCount, int _horizontalFilterLength, int _horizontalFilterLag, int _verticalFilterLength, double _harmonicThreshold, double _percussiveThreshold, - float _silenceThreshold) : + double _silenceThreshold) : binCount(_binCount), horizontalFilterLength(_horizontalFilterLength), horizontalFilterLag(_horizontalFilterLag), @@ -66,21 +66,21 @@ public: BinClassifier(Parameters parameters) : m_parameters(parameters), - m_vFilter(new MovingMedian(m_parameters.verticalFilterLength)), + m_vFilter(new MovingMedian(m_parameters.verticalFilterLength)), m_vfQueue(parameters.horizontalFilterLag) { int n = m_parameters.binCount; for (int i = 0; i < n; ++i) { - m_hFilters.push_back(std::make_shared> + m_hFilters.push_back(std::make_shared> (m_parameters.horizontalFilterLength)); } - m_hf = allocate_and_zero(n); - m_vf = allocate_and_zero(n); + m_hf = allocate_and_zero(n); + m_vf = allocate_and_zero(n); for (int i = 0; i < m_parameters.horizontalFilterLag; ++i) { - float *entry = allocate_and_zero(n); + double *entry = allocate_and_zero(n); m_vfQueue.write(&entry, 1); } } @@ -88,7 +88,7 @@ public: ~BinClassifier() { while (m_vfQueue.getReadSpace() > 0) { - float *entry = m_vfQueue.readOne(); + double *entry = m_vfQueue.readOne(); deallocate(entry); } @@ -96,7 +96,7 @@ public: deallocate(m_vf); } - void classify(const float *const mag, Classification *classification) { + void classify(const double *const mag, Classification *classification) { const int n = m_parameters.binCount; for (int i = 0; i < n; ++i) { @@ -105,10 +105,10 @@ public: } v_copy(m_vf, mag, n); - MovingMedian::filter(*m_vFilter, m_vf); + MovingMedian::filter(*m_vFilter, m_vf); if (m_parameters.horizontalFilterLag > 0) { - float *lagged = m_vfQueue.readOne(); + double *lagged = m_vfQueue.readOne(); m_vfQueue.write(&m_vf, 1); m_vf = lagged; } @@ -134,13 +134,13 @@ public: protected: Parameters m_parameters; - std::vector>> m_hFilters; - std::unique_ptr> m_vFilter; + std::vector>> m_hFilters; + std::unique_ptr> m_vFilter; // We manage the queued frames through pointer swapping, hence // bare pointers here - float *m_hf; - float *m_vf; - RingBuffer m_vfQueue; + double *m_hf; + double *m_vf; + RingBuffer m_vfQueue; BinClassifier(const BinClassifier &) =delete; BinClassifier &operator=(const BinClassifier &) =delete; diff --git a/src/finer/BinSegmenter.h b/src/finer/BinSegmenter.h index e64ed39..f6636aa 100644 --- a/src/finer/BinSegmenter.h +++ b/src/finer/BinSegmenter.h @@ -62,7 +62,7 @@ public: { } - Segmentation segment(const float *const mag) { + Segmentation segment(const double *const mag) { int n = m_classifierParameters.binCount; m_classifier.classify(mag, m_classification.data()); for (int i = 0; i < n; ++i) { diff --git a/src/finer/Guide.h b/src/finer/Guide.h index 40313bc..de6f10e 100644 --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -35,9 +35,9 @@ class Guide public: struct FftBand { int fftSize; - float f0; - float f1; - FftBand(int _s, float _f0, float _f1) : + double f0; + double f1; + FftBand(int _s, double _f0, double _f1) : fftSize(_s), f0(_f0), f1(_f1) { } FftBand() : fftSize(0), f0(0.f), f1(0.f) { } @@ -45,10 +45,10 @@ public: struct PhaseLockBand { int p; - float beta; - float f0; - float f1; - PhaseLockBand(int _p, float _beta, float _f0, float _f1) : + double beta; + double f0; + double f1; + PhaseLockBand(int _p, double _beta, double _f0, double _f1) : p(_p), beta(_beta), f0(_f0), f1(_f1) { } PhaseLockBand() : p(0), beta(1.0), f0(0.f), f1(0.f) { } @@ -56,9 +56,9 @@ public: struct Range { bool present; - float f0; - float f1; - Range(bool _present, float _f0, float _f1) : + double f0; + double f1; + Range(bool _present, double _f0, double _f1) : present(_present), f0(_f0), f1(_f1) { } Range() : present(false), f0(0.f), f1(0.f) { } @@ -76,9 +76,9 @@ public: struct BandLimits { int fftSize; - float f0min; - float f1max; - BandLimits(int _fftSize, float _f0min, float _f1max) : + double f0min; + double f1max; + BandLimits(int _fftSize, double _f0min, double _f1max) : fftSize(_fftSize), f0min(_f0min), f1max(_f1max) { } BandLimits() : fftSize(0), f0min(0.f), f1max(0.f) { } @@ -132,9 +132,9 @@ public: } void calculate(double ratio, - const float *const magnitudes, + const double *const magnitudes, const int *const troughs, - const float *const prevMagnitudes, + const double *const prevMagnitudes, const BinSegmenter::Segmentation &segmentation, const BinSegmenter::Segmentation &prevSegmentation, const BinSegmenter::Segmentation &nextSegmentation, @@ -272,17 +272,17 @@ protected: return value; } - bool checkPotentialKick(const float *const magnitudes, - const float *const prevMagnitudes) const { + bool checkPotentialKick(const double *const magnitudes, + const double *const prevMagnitudes) const { int b = binForFrequency(200.0); - float here = 0.0, there = 0.0; + double here = 0.0, there = 0.0; for (int i = 1; i <= b; ++i) { here += magnitudes[i]; } for (int i = 1; i <= b; ++i) { there += prevMagnitudes[i]; } - return (here > 10.e-3f && here > there * 1.4f); + return (here > 10.e-3 && here > there * 1.4); } double snapToTrough(double f, const int *const troughs) const { diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index ef2ac40..147e089 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -55,8 +55,9 @@ public: m_currentPeaks = allocate_and_zero_channels(ch, m_blockSize); m_prevPeaks = allocate_and_zero_channels(ch, m_blockSize); m_greatestChannel = allocate_and_zero(m_blockSize); - m_prevInMag = allocate_and_zero_channels(ch, m_blockSize); - m_prevInPhase = allocate_and_zero_channels(ch, m_blockSize); + //!!! there is also a prevMag in R3StretcherImpl which could be passed in to here instead + m_prevInMag = allocate_and_zero_channels(ch, m_blockSize); + m_prevInPhase = allocate_and_zero_channels(ch, m_blockSize); m_prevOutPhase = allocate_and_zero_channels(ch, m_blockSize); m_unlocked = allocate_and_zero_channels(ch, m_blockSize); } @@ -73,8 +74,8 @@ public: } void advance(double *const *outPhase, - const float *const *mag, - const float *const *phase, + const double *const *mag, + const double *const *phase, const Guide::Configuration &configuration, const Guide::Guidance *const *guidance, int inhop, @@ -245,12 +246,12 @@ public: protected: Parameters m_parameters; int m_blockSize; - Peak m_peakPicker; + Peak m_peakPicker; int **m_currentPeaks; int **m_prevPeaks; int *m_greatestChannel; - float **m_prevInMag; - float **m_prevInPhase; + double **m_prevInMag; + double **m_prevInPhase; double **m_prevOutPhase; double **m_unlocked; bool m_reported; diff --git a/src/finer/R3StretcherImpl.cpp b/src/finer/R3StretcherImpl.cpp index a6f0fdc..c5397bf 100644 --- a/src/finer/R3StretcherImpl.cpp +++ b/src/finer/R3StretcherImpl.cpp @@ -240,7 +240,7 @@ R3StretcherImpl::consume() (scale->timeDomainFrame.data(), scale->mag.data(), scale->phase.data()); - v_scale(scale->mag.data(), 1.f / float(fftSize), + v_scale(scale->mag.data(), 1.0 / double(fftSize), scale->mag.size()); } @@ -291,10 +291,6 @@ R3StretcherImpl::consume() // copy to prevMag before filtering v_copy(scale->prevMag.data(), scale->mag.data(), bufSize); v_copy(scale->prevOutPhase.data(), scale->outPhase.data(), bufSize); - //!!! seems wasteful - for (int i = 0; i < bufSize; ++i) { - scale->phase[i] = princarg(scale->outPhase[i]); - } } for (const auto &band : cd->guidance.fftBands) { @@ -302,18 +298,18 @@ R3StretcherImpl::consume() auto scale = cd->scales.at(fftSize); auto scaleData = m_scaleData.at(fftSize); - //!!! messy and v slow, but leave it until we've + //!!! messy and slow, but leave it until we've //!!! discovered whether we need a window accumulator //!!! (we probably do) int analysisWindowSize = scaleData->analysisWindow.getSize(); int synthesisWindowSize = scaleData->synthesisWindow.getSize(); int offset = (analysisWindowSize - synthesisWindowSize) / 2; - float winscale = 0.f; + double winscale = 0.0; for (int i = 0; i < synthesisWindowSize; ++i) { winscale += scaleData->analysisWindow.getValue(i + offset) * scaleData->synthesisWindow.getValue(i); } - winscale = float(outhop) / winscale; + winscale = double(outhop) / winscale; double factor = m_parameters.sampleRate / double(fftSize); for (int i = 0; i < fftSize/2 + 1; ++i) { @@ -333,7 +329,7 @@ R3StretcherImpl::consume() auto scaleData = m_scaleData.at(fftSize); scaleData->fft.inversePolar(scale->mag.data(), - scale->phase.data(), + scale->outPhase.data(), scale->timeDomainFrame.data()); int synthesisWindowSize = scaleData->synthesisWindow.getSize(); diff --git a/src/finer/R3StretcherImpl.h b/src/finer/R3StretcherImpl.h index 7e31432..d0bd650 100644 --- a/src/finer/R3StretcherImpl.h +++ b/src/finer/R3StretcherImpl.h @@ -127,14 +127,14 @@ protected: int fftSize; int bufSize; // size of every freq-domain array here: fftSize/2 + 1 //!!! review later which of these we are actually using! - FixedVector timeDomainFrame; - FixedVector mag; - FixedVector phase; + FixedVector timeDomainFrame; + FixedVector mag; + FixedVector phase; FixedVector outPhase; //!!! "advanced"? FixedVector nextTroughs; //!!! not used in every scale - FixedVector prevMag; //!!! not used in every scale + FixedVector prevMag; //!!! not used in every scale FixedVector prevOutPhase; - FixedVector accumulator; + FixedVector accumulator; ChannelScaleData(int _fftSize, int _longestFftSize) : fftSize(_fftSize), @@ -161,7 +161,7 @@ protected: BinSegmenter::Segmentation prevSegmentation; BinSegmenter::Segmentation nextSegmentation; Guide::Guidance guidance; - FixedVector mixdown; + FixedVector mixdown; std::unique_ptr> inbuf; std::unique_ptr> outbuf; ChannelData(BinSegmenter::Parameters segmenterParameters, @@ -179,8 +179,8 @@ protected: struct ChannelAssembly { // Vectors of bare pointers, used to package container data // from different channels into arguments for PhaseAdvance - FixedVector mag; - FixedVector phase; + FixedVector mag; + FixedVector phase; FixedVector guidance; FixedVector outPhase; ChannelAssembly(int channels) : @@ -190,8 +190,8 @@ protected: struct ScaleData { FFT fft; - Window analysisWindow; - Window synthesisWindow; + Window analysisWindow; + Window synthesisWindow; GuidedPhaseAdvance guided; ScaleData(GuidedPhaseAdvance::Parameters guidedParameters) : fft(guidedParameters.fftSize), @@ -210,7 +210,7 @@ protected: Guide m_guide; Guide::Configuration m_guideConfiguration; ChannelAssembly m_channelAssembly; - Peak> m_troughPicker; + Peak> m_troughPicker; std::unique_ptr m_calculator; int m_inhop; bool m_draining;