Little speedup

This commit is contained in:
Flamefire committed 2014-03-28 12:40:04 +01:00
1 parent ae9f8bb30a
commit b1bca37bf8
2 files changed
+19 -20

No files matched your search

+5 -5
View File
@@ -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<unsigned>(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<Peak> 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<float>(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
+14 -15
View File
@@ -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 <size_t SIZE> class RingBuffer {
template <unsigned SIZE> class RingBuffer {
public:
constexpr static size_t capacity = SIZE;
constexpr static unsigned capacity = SIZE;
RingBuffer(): m_read(), m_write() {} ///< Initialize empty buffer
template <typename InIt> void insert(InIt begin, InIt end) {
unsigned r = static_cast<unsigned>(m_read); // The read position
unsigned w = static_cast<unsigned>(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 <typename OutIt> bool read(OutIt begin, OutIt end) {
unsigned r = static_cast<unsigned>(m_read);
if (modulo(static_cast<unsigned>(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<unsigned>(m_read + n)); } ///< Move reading pointer forward.
unsigned size() const { return modulo(static_cast<unsigned>(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<Tone> 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 <typename InIt> 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;