11namespace tracktion {
inline namespace engine
14MidiNoteDispatcher::MidiNoteDispatcher()
18MidiNoteDispatcher::~MidiNoteDispatcher()
23void MidiNoteDispatcher::dispatchPendingMessagesForDevices (TimePosition editTime)
27 for (
auto state : devices)
28 dispatchPendingMessages (*state, editTime);
31void MidiNoteDispatcher::masterTimeUpdate (TimePosition editTime)
34 masterTime = editTime;
38void MidiNoteDispatcher::prepareToPlay (TimePosition editTime)
40 masterTimeUpdate (editTime);
43TimePosition MidiNoteDispatcher::getCurrentTime()
const
49void MidiNoteDispatcher::dispatchPendingMessages (DeviceState& state, TimePosition editTime)
52 auto& pendingBuffer = state.device.getPendingMessages();
53 state.device.context.masterLevels.processMidi (pendingBuffer,
nullptr);
54 const auto delay = state.device.getMidiOutput().getDeviceDelay();
56 if (! state.device.sendMessages (pendingBuffer, editTime - delay))
57 state.buffer.mergeFromAndClear (pendingBuffer);
65 for (
auto d : newList)
66 newDevices.add (new DeviceState (*d));
71 bool startTimerFlag =
false;
75 newDevices.swapWith (devices);
76 startTimerFlag = ! devices.
isEmpty();
83void MidiNoteDispatcher::hiResTimerCallback()
87 MidiOutputDeviceInstance* device;
97 for (
auto d : devices)
99 auto& device = d->device;
100 auto& buffer = d->buffer;
101 auto& midiOut = device.getMidiOutput();
103 if (buffer.isAllNotesOff)
104 midiOut.sendNoteOffMessages();
106 while (buffer.isNotEmpty())
108 auto& message = buffer[0];
110 auto noteTime = TimePosition::fromSeconds (message.getTimeStamp());
111 auto currentTime = getCurrentTime();
113 if (noteTime > currentTime + TimeDuration::fromSeconds (0.25))
117 else if (noteTime <= currentTime)
119 messagesToSend.
add ({ &device, message });
130 for (
auto& m : messagesToSend)
131 m.device->getMidiOutput().fireMessage (m.message);
void ensureStorageAllocated(int minNumElements)
void add(const ElementType &newElement)
void startTimer(int intervalInMilliseconds)
bool isEmpty() const noexcept
static double getMillisecondCounterHiRes() noexcept
#define CRASH_TRACER
This macro adds the current location to a stack which gets logged if a crash happens.