123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- * VstEventQueue.h
- * ---------------
- * Purpose: Event queue for VST events.
- * Notes : Modelled after an idea from https://www.kvraudio.com/forum/viewtopic.php?p=3043807#p3043807
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include <deque>
- #include "mpt/mutex/mutex.hpp"
- #include "VstDefinitions.h"
- OPENMPT_NAMESPACE_BEGIN
- class VstEventQueue : public Vst::VstEvents
- {
- protected:
- // Although originally all event types were apparently supposed to be of the same size, this is not the case on 64-Bit systems.
- // VstMidiSysexEvent contains 3 pointers, so the struct size differs between 32-Bit and 64-Bit systems.
- union Event
- {
- Vst::VstEvent event;
- Vst::VstMidiEvent midi;
- Vst::VstMidiSysexEvent sysex;
- };
- // Here we store our events which are then inserted into the fixed-size event buffer sent to the plugin.
- std::deque<Event> eventQueue;
- // Since plugins can also add events to the queue (even from a different thread than the processing thread),
- // we need to ensure that reading and writing is never done in parallel.
- mpt::mutex criticalSection;
- public:
- VstEventQueue()
- {
- numEvents = 0;
- reserved = 0;
- std::fill(std::begin(events), std::end(events), nullptr);
- }
- // Get the number of events that are currently queued, but not in the output buffer.
- size_t GetNumQueuedEvents()
- {
- return eventQueue.size() - numEvents;
- }
- // Add a VST event to the queue. Returns true on success.
- // Set insertFront to true to prioritise this event (i.e. add it at the front of the queue instead of the back)
- bool Enqueue(const Vst::VstEvent *event, bool insertFront = false)
- {
- MPT_ASSERT(event->type != Vst::kVstSysExType || event->byteSize == sizeof(Vst::VstMidiSysexEvent));
- MPT_ASSERT(event->type != Vst::kVstMidiType || event->byteSize == sizeof(Vst::VstMidiEvent));
- Event copyEvent;
- size_t copySize;
- // randomid by Insert Piz Here sends events of type kVstMidiType, but with a claimed size of 24 bytes instead of 32.
- // Hence, we enforce the size of known events.
- if(event->type == Vst::kVstSysExType)
- copySize = sizeof(Vst::VstMidiSysexEvent);
- else if(event->type == Vst::kVstMidiType)
- copySize = sizeof(Vst::VstMidiEvent);
- else
- copySize = std::min(size_t(event->byteSize), sizeof(copyEvent));
- memcpy(©Event, event, copySize);
- if(event->type == Vst::kVstSysExType)
- {
- // SysEx messages need to be copied, as the space used for the dump might be freed in the meantime.
- auto &e = copyEvent.sysex;
- auto sysexDump = new (std::nothrow) std::byte[e.dumpBytes];
- if(sysexDump == nullptr)
- return false;
- memcpy(sysexDump, e.sysexDump, e.dumpBytes);
- e.sysexDump = sysexDump;
- }
- mpt::lock_guard<mpt::mutex> lock(criticalSection);
- if(insertFront)
- eventQueue.push_front(copyEvent);
- else
- eventQueue.push_back(copyEvent);
- return true;
- }
- // Set up the queue for transmitting to the plugin. Returns number of elements that are going to be transmitted.
- int32 Finalise()
- {
- mpt::lock_guard<mpt::mutex> lock(criticalSection);
- numEvents = static_cast<int32>(std::min(eventQueue.size(), MAX_EVENTS));
- for(int32 i = 0; i < numEvents; i++)
- {
- events[i] = &eventQueue[i].event;
- }
- return numEvents;
- }
- // Remove transmitted events from the queue
- void Clear()
- {
- mpt::lock_guard<mpt::mutex> lock(criticalSection);
- if(numEvents)
- {
- // Release temporarily allocated buffer for SysEx messages
- for(auto e = eventQueue.begin(); e != eventQueue.begin() + numEvents; ++e)
- {
- if(e->event.type == Vst::kVstSysExType)
- {
- delete[] e->sysex.sysexDump;
- }
- }
- eventQueue.erase(eventQueue.begin(), eventQueue.begin() + numEvents);
- numEvents = 0;
- }
- }
- };
- OPENMPT_NAMESPACE_END
|