26 MidiOutput::MidiOutput (
const String& deviceName,
const String& deviceIdentifier)
27 : Thread (
"midi out"), deviceInfo (deviceName, deviceIdentifier)
38 sendMessageNow (message);
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)
87 while (firstMessage !=
nullptr)
89 auto* m = firstMessage;
90 firstMessage = firstMessage->next;
105 void MidiOutput::run()
107 while (! threadShouldExit())
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);
143 if (threadShouldExit())
147 if (eventTime > now - 200)
148 sendMessageNow (message->message);
152 jassert (timeToWait < 1000 * 30);
153 wait ((
int) timeToWait);
157 clearAllPendingMessages();
static void waitForMillisecondCounter(uint32 targetTime) noexcept
Waits until the getMillisecondCounter() reaches a given value.
Encapsulates a MIDI message.
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
Retrieves a copy of the next event from the buffer.
void sendBlockOfMessages(const MidiBuffer &buffer, double millisecondCounterToStartAt, double samplesPerSecondForBuffer)
This lets you supply a block of messages that will be sent out at some point in the future...
void stopBackgroundThread()
Stops the background thread, and clears any pending midi events.
void startBackgroundThread()
Starts up a background thread so that the device can send blocks of data.
void clearAllPendingMessages()
Gets rid of any midi messages that had been added by sendBlockOfMessages().
Holds a sequence of time-stamped midi events.
Array< uint8 > data
The raw data holding this buffer.
Used to iterate through the events in a MidiBuffer.
Automatically locks and unlocks a mutex object.
static uint32 getMillisecondCounter() noexcept
Returns the number of millisecs since a fixed event (usually system startup).
void sendBlockOfMessagesNow(const MidiBuffer &buffer)
Sends out a sequence of MIDI messages immediately.