/* * MidiSyncThread.cpp * SmallSteps * * Created by Martin Klang on 20/03/2008. * Copyright 2008 __MyCompanyName__. All rights reserved. * */ #include "MidiSyncThread.h" #include #include #include MidiSyncThread::MidiSyncThread(MidiInputCallback* callback, int bpm) : Thread(T("Internal MIDI Sync")), callback(callback), bpm(bpm), ticksPerBeat(24), latency(20), name(T("Internal MIDI Sync")) {} MidiSyncThread::~MidiSyncThread(){ if(isThreadRunning()) stopThread(100); } int MidiSyncThread::getBPM(){ return bpm; } void MidiSyncThread::setBPM(int newBpm){ bpm = newBpm; } const String MidiSyncThread::getName () const throw (){ return name; } void MidiSyncThread::setName (const String &newName) throw (){ name = newName; } void MidiSyncThread::start (){ if(!isThreadRunning()) startThread(); } void MidiSyncThread::stop (){ signalThreadShouldExit(); } void MidiSyncThread::run(){ const MidiMessage msg = MidiMessage::midiClock(); int tick; juce::uint32 target, period; while(!threadShouldExit()){ callback->handleIncomingMidiMessage(NULL, msg); // send first tick for this beat tick = 1; target = Time::getMillisecondCounter() + (60000 / bpm); period = (60000 / bpm - latency) / ticksPerBeat; while(++tick < ticksPerBeat && !threadShouldExit()){ wait(period); callback->handleIncomingMidiMessage(NULL, msg); // send mid beat ticks } target = target - Time::getMillisecondCounter(); if(target > latency && !threadShouldExit()) // adjust to beat target time wait(target - latency); if(!threadShouldExit()) callback->handleIncomingMidiMessage(NULL, msg); // send last tick } } MidiSyncThread* MidiSyncThread::openDevice(int bpm, MidiInputCallback* callback){ MidiSyncThread* device = new MidiSyncThread(callback, bpm); device->start(); return device; }