Donald Meyers / Mbed OS evan

metronome.hpp

Committer:
djmeyers
Date:
2017-03-18
Revision:
0:06ee5f8a484a

File content as of revision 0:06ee5f8a484a:

#pragma once

#include "mbed.h"

class metronome
{
public:
    enum { beat_samples = 3 };

public:
    metronome()
    : m_timing(false), m_beat_count(0) {}
    ~metronome() {}

public:
	// Call when entering "learn" mode
    void start_timing() {
    	m_timing = true;
    	m_beat_count = 0;
    	m_timer.reset();
    	m_timer.start();	
    }
    
	// Call when leaving "learn" mode
    void stop_timing() {
    	m_timing = false;
    	m_timer.stop();	
    }

	// Should only record the current time when timing
	// Insert the time at the next free position of m_beats
    void tap() {
		m_timer.stop();
		if( m_beat_count <  beat_samples ) {
			m_beats[m_beat_count] = m_timer.read_ms();
			m_beat_count++;	
		} else {
			for(int i = 0; i < beat_samples - 1; i++) {
				m_beats[i] = m_beats[i + 1];	
			}
			m_beats[beat_samples - 1] = m_timer.read_ms();
		}
    	m_timer.reset();
		m_timer.start();
    	   	
    }

    bool is_timing() const { return m_timing; }
    
    float get_delay() const {
    	if (m_beat_count < beat_samples - 1) {
    		return 0;
    	} else {
    		float sum = 0.0f;
    		for(int i = 0; i < beat_samples; i++) {
    			sum += m_beats[i];
    		}
	   		return (float) (sum / beat_samples);
    	}
    }
    
    size_t get_bpm() const {
    	return (size_t) 60000 / get_delay();
    }

private:
    bool m_timing;
    Timer m_timer;

	// Insert new samples at the end of the array, removing the oldest
    size_t m_beats[beat_samples];
    size_t m_beat_count;
};