Skip to content

Instantly share code, notes, and snippets.

@vinniefalco
Created April 23, 2012 06:26
Show Gist options
  • Save vinniefalco/2469123 to your computer and use it in GitHub Desktop.
Save vinniefalco/2469123 to your computer and use it in GitHub Desktop.
Explanation of juce::MidiOutput methods
void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
const double millisecondCounterToStartAt,
double samplesPerSecondForBuffer)
{
// You've got to call startBackgroundThread() for this to actually work..
jassert (isThreadRunning());
// this needs to be a value in the future - RTFM for this method!
jassert (millisecondCounterToStartAt > 0);
const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer;
MidiBuffer::Iterator i (buffer);
const uint8* data;
int len, time;
while (i.getNextEvent (data, len, time))
{
const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time;
PendingMessage* const m = new PendingMessage (data, len, eventTime);
const ScopedLock sl (lock);
if (firstMessage == nullptr || firstMessage->message.getTimeStamp() > eventTime)
{
m->next = firstMessage;
firstMessage = m;
}
else
{
PendingMessage* mm = firstMessage;
while (mm->next != nullptr && mm->next->message.getTimeStamp() <= eventTime)
mm = mm->next;
m->next = mm->next;
mm->next = m;
}
}
notify();
}
void MidiOutput::run()
{
while (! threadShouldExit())
{
uint32 now = Time::getMillisecondCounter();
uint32 eventTime = 0;
uint32 timeToWait = 500;
PendingMessage* message;
{
const ScopedLock sl (lock);
message = firstMessage;
if (message != nullptr)
{
eventTime = (uint32) roundToInt (message->message.getTimeStamp());
if (eventTime > now + 20)
{
timeToWait = eventTime - (now + 20);
message = nullptr;
}
else
{
firstMessage = message->next;
}
}
}
if (message != nullptr)
{
const ScopedPointer<PendingMessage> messageDeleter (message);
if (eventTime > now)
{
Time::waitForMillisecondCounter (eventTime);
if (threadShouldExit())
break;
}
if (eventTime > now - 200)
sendMessageNow (message->message);
}
else
{
jassert (timeToWait < 1000 * 30);
wait ((int) timeToWait);
}
}
clearAllPendingMessages();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment