#include "BeatSequencePlayer.h" namespace midi { BeatSequencePlayer::BeatSequencePlayer() : BeatSequencePlayer(0) { } BeatSequencePlayer::BeatSequencePlayer(Output* out) : BeatSequencePlayer(out, 0) { } BeatSequencePlayer::BeatSequencePlayer(Output* out, const BeatSequence* seq) : looping(false), nextBeat(0), clock(&beat, (void*)this), sequence(seq), output(out) { } bool BeatSequencePlayer::getLooping() { looping_mutex.lock(); bool l = looping; looping_mutex.unlock(); return l; } void BeatSequencePlayer::setLooping(bool l) { looping_mutex.lock(); looping = l; looping_mutex.unlock(); } BeatSequencePlayer::BeatIndex BeatSequencePlayer::getNextBeat() { nextBeat_mutex.lock(); BeatIndex n = nextBeat; nextBeat_mutex.unlock(); return n; } BeatSequencePlayer::Bpm BeatSequencePlayer::getBpm() { return clock.getBpm(); } void BeatSequencePlayer::setBpm(Bpm bpm) { clock.setBpm(bpm); } void BeatSequencePlayer::setNextBeat(BeatIndex n) { nextBeat_mutex.lock(); nextBeat = n; nextBeat_mutex.unlock(); } void BeatSequencePlayer::play() { setLooping(false); start(); } void BeatSequencePlayer::loop() { setLooping(true); start(); } void BeatSequencePlayer::start() { clock.start(); } void BeatSequencePlayer::stop() { clock.stop(); } bool BeatSequencePlayer::isPlaying() { return clock.isRunning(); } void BeatSequencePlayer::beforeBeat(BeatIndex beat) { } void BeatSequencePlayer::afterBeat(BeatIndex beat) { } void BeatSequencePlayer::beat(void* data) { BeatSequencePlayer& player = *(BeatSequencePlayer*)data; if(player.sequence) { BeatIndex beat = player.getNextBeat(); if(beat >= player.sequence->size()) { if(player.getLooping() && player.sequence->size() > 0) { beat = 0; } else { player.clock.stop(); } } if(beat < player.sequence->size()) { player.beforeBeat(beat); const BeatSequence& seq = *player.sequence; const MessageList& messages = seq[beat]; player.output->sendMessages(messages); if(beat + 1 == player.sequence->size()) { if(player.getLooping()) { player.setNextBeat(0); } else { player.clock.stop(); } } else { player.setNextBeat(beat + 1); } player.afterBeat(beat); } } else { if(!player.getLooping()) { player.clock.stop(); } } } } // namespace