1 mars 1.1 /*
2 * MidiSyncThread.cpp
3 * SmallSteps
4 *
5 * Created by Martin Klang on 20/03/2008.
6 * Copyright 2008 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10 #include "MidiSyncThread.h"
11 #include <iostream>
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 MidiSyncThread::MidiSyncThread(MidiInputCallback* callback, int bpm)
16 : Thread(T("Internal MIDI Sync")),
17 callback(callback),
18 bpm(bpm),
19 ticksPerBeat(24),
20 latency(20),
21 name(T("Internal MIDI Sync"))
22 mars 1.1 {}
23
24 MidiSyncThread::~MidiSyncThread(){
25 if(isThreadRunning())
26 stopThread(100);
27 }
28
29 int MidiSyncThread::getBPM(){
30 return bpm;
31 }
32
33 void MidiSyncThread::setBPM(int newBpm){
34 bpm = newBpm;
35 }
36
37 const String MidiSyncThread::getName () const throw (){
38 return name;
39 }
40
41 void MidiSyncThread::setName (const String &newName) throw (){
42 name = newName;
43 mars 1.1 }
44
45 void MidiSyncThread::start (){
46 if(!isThreadRunning())
47 startThread();
48 }
49
50 void MidiSyncThread::stop (){
51 signalThreadShouldExit();
52 }
53
54 void MidiSyncThread::run(){
55 const MidiMessage msg = MidiMessage::midiClock();
56 int tick;
57 uint32 target, period;
58
59 while(!threadShouldExit()){
60 callback->handleIncomingMidiMessage(NULL, msg); // send first tick for this beat
61 tick = 1;
62 target = Time::getMillisecondCounter() + (60000 / bpm);
63 period = (60000 / bpm - latency) / ticksPerBeat;
64 mars 1.1 while(++tick < ticksPerBeat && !threadShouldExit()){
65 wait(period);
66 callback->handleIncomingMidiMessage(NULL, msg); // send mid beat ticks
67 }
68 target = target - Time::getMillisecondCounter();
69 if(target > latency && !threadShouldExit()) // adjust to beat target time
70 wait(target - latency);
|