From b1bca37bf883017ce4b802e0bf271412f47b84f5 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 28 Mar 2014 12:40:04 +0100 Subject: [PATCH] Little speedup --- PitchTracker/pitch.cc | 10 +++++----- PitchTracker/pitch.hh | 29 ++++++++++++++--------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc index 85169769..076dbc70 100644 --- a/PitchTracker/pitch.cc +++ b/PitchTracker/pitch.cc @@ -30,7 +30,7 @@ bool Tone::operator==(double f) const { return std::abs(freq / f - 1.0) < 0.05; } -Analyzer::Analyzer(double rate, std::string id, std::size_t step): +Analyzer::Analyzer(double rate, std::string id, unsigned step): m_step(step), m_resampleFactor(1.0), m_resamplePos(), @@ -110,7 +110,7 @@ bool Analyzer::calcFFT() { float pcm[FFT_N]; // Read FFT_N samples, move forward by m_step samples if (!m_buf.read(pcm, pcm + FFT_N)) return false; - m_buf.pop(static_cast(m_step)); + m_buf.pop(m_step); // Peak level calculation of the most recent m_step samples (the rest is overlap) for (float const* ptr = pcm + FFT_N - m_step; ptr != pcm + FFT_N; ++ptr) { float s = *ptr; @@ -133,11 +133,11 @@ void Analyzer::calcTones() { const size_t kMax = std::min(FFT_N / 2, size_t(FFT_MAXFREQ / freqPerBin)); std::vector peaks(kMax + 1); // One extra to simplify loops for (size_t k = 1; k <= kMax; ++k) { - double magnitude = std::abs(m_fft[k]); - double phase = std::arg(m_fft[k]); + float magnitude = std::abs(m_fft[k]); + float phase = std::arg(m_fft[k]); // process phase difference double delta = phase - m_fftLastPhase[k]; - m_fftLastPhase[k] = static_cast(phase); + m_fftLastPhase[k] = phase; delta -= k * phaseStep; // subtract expected phase difference delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval delta /= phaseStep; // calculate diff from bin center frequency diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh index ec759d1f..fc431733 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/pitch.hh @@ -34,35 +34,34 @@ static const unsigned FFT_P = 10; static const std::size_t FFT_N = 1 << FFT_P; /// Lock-free ring buffer. Discards oldest data on overflow (not strictly thread-safe). -template class RingBuffer { +template class RingBuffer { public: - constexpr static size_t capacity = SIZE; + constexpr static unsigned capacity = SIZE; RingBuffer(): m_read(), m_write() {} ///< Initialize empty buffer template void insert(InIt begin, InIt end) { - unsigned r = static_cast(m_read); // The read position - unsigned w = static_cast(m_write); // The write position - bool overflow = false; + unsigned r = m_read; // The read position + unsigned w = m_write; // The write position + bool overflow = (end - begin >= SIZE - size()); while (begin != end) { m_buf[w] = *begin++; // Copy sample w = modulo(w + 1); // Update cursor - if (w == r) overflow = true; } m_write = w; if (overflow) m_read = modulo(w + 1); // Reset read pointer on overflow } /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer. template bool read(OutIt begin, OutIt end) { - unsigned r = static_cast(m_read); - if (modulo(static_cast(m_write) - r) <= end - begin) return false; // Not enough audio available + unsigned r = m_read; + if (size() <= end - begin) return false; // Not enough audio available while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator return true; } - void pop(unsigned n) { m_read = modulo(static_cast(m_read + n)); } ///< Move reading pointer forward. - unsigned size() const { return modulo(static_cast(m_write - m_read)); } + void pop(unsigned n) { m_read = modulo(m_read + n); } ///< Move reading pointer forward. + unsigned size() const { return modulo(m_write - m_read); } private: - static unsigned modulo(unsigned idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) + static unsigned modulo(int idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) float m_buf[SIZE]; - volatile size_t m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. + volatile unsigned m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. }; /// analyzer class @@ -75,7 +74,7 @@ public: /// list of tones typedef std::list tones_t; /// constructor - Analyzer(double rate, std::string id, std::size_t step = 200); + Analyzer(double rate, std::string id, unsigned step = 200); /** Add input data to buffer. This is thread-safe (against other functions). **/ template void input(InIt begin, InIt end) { m_buf.insert(begin, end); @@ -113,8 +112,8 @@ public: std::string const& getId() const { return m_id; } private: - const std::size_t m_step; - RingBuffer<2 * FFT_N> m_buf; // Twice the FFT size should give enough room for sliding window and for engine delays + const unsigned m_step; + RingBuffer<4 * FFT_N> m_buf; // Twice the FFT size should give enough room for sliding window and for engine delays RingBuffer<4096> m_passthrough; double m_resampleFactor; double m_resamplePos;