26 MidiOutput::MidiOutput (
const String& deviceName,
const String& deviceIdentifier)
27 : Thread (
"midi out"), deviceInfo (deviceName, deviceIdentifier)
31 void MidiOutput::sendBlockOfMessagesNow (
const MidiBuffer& buffer)
38 sendMessageNow (message);
41 void MidiOutput::sendBlockOfMessages (
const MidiBuffer& buffer,
42 double millisecondCounterToStartAt,
43 double samplesPerSecondForBuffer)
46 jassert (isThreadRunning());
49 jassert (millisecondCounterToStartAt > 0);
51 auto timeScaleFactor = 1000.0 / samplesPerSecondForBuffer;
58 auto eventTime = millisecondCounterToStartAt + timeScaleFactor * time;
59 auto* m =
new PendingMessage (data, len, eventTime);
63 if (firstMessage ==
nullptr || firstMessage->message.getTimeStamp() > eventTime)
65 m->next = firstMessage;
70 auto* mm = firstMessage;
72 while (mm->next !=
nullptr && mm->next->message.getTimeStamp() <= eventTime)
83 void MidiOutput::clearAllPendingMessages()
87 while (firstMessage !=
nullptr)
89 auto* m = firstMessage;
90 firstMessage = firstMessage->next;
95 void MidiOutput::startBackgroundThread()
100 void MidiOutput::stopBackgroundThread()
105 void MidiOutput::run()
107 while (! threadShouldExit())
109 auto now = Time::getMillisecondCounter();
110 uint32 eventTime = 0;
111 uint32 timeToWait = 500;
113 PendingMessage* message;
117 message = firstMessage;
119 if (message !=
nullptr)
121 eventTime = (uint32) roundToInt (message->message.getTimeStamp());
123 if (eventTime > now + 20)
125 timeToWait = eventTime - (now + 20);
130 firstMessage = message->next;
135 if (message !=
nullptr)
137 std::unique_ptr<PendingMessage> messageDeleter (message);
141 Time::waitForMillisecondCounter (eventTime);
143 if (threadShouldExit())
147 if (eventTime > now - 200)
148 sendMessageNow (message->message);
152 jassert (timeToWait < 1000 * 30);
153 wait ((
int) timeToWait);
157 clearAllPendingMessages();
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept