27#ifdef JUCE_VSTINTERFACE_H_INCLUDED
43 template <
typename Events>
44 static auto& getEvent (Events& events,
int index)
46 using EventType =
decltype (&*events.events);
52 return static_cast<EventType
> (events.events)[index];
55 Vst2::VstEvent*
const& getEvent (
int index)
const {
return getEvent (*events, index); }
56 Vst2::VstEvent* & getEvent (
int index) {
return getEvent (*events, index); }
61 : numEventsUsed (0), numEventsAllocated (0)
75 if (events !=
nullptr)
76 events->numEvents = 0;
79 void addEvent (
const void*
const midiData,
int numBytes,
int frameOffset)
81 ensureSize (numEventsUsed + 1);
83 void*
const ptr = getEvent (numEventsUsed);
84 events->numEvents = ++numEventsUsed;
88 auto*
const e =
static_cast<Vst2::VstMidiEvent*
> (ptr);
90 if (e->type == Vst2::kVstSysExType)
92 delete[]
reinterpret_cast<Vst2::VstMidiSysexEvent*
> (e)->sysexDump;
93 e->type = Vst2::kVstMidiType;
94 e->byteSize =
sizeof (Vst2::VstMidiEvent);
98 e->noteOffVelocity = 0;
101 e->deltaFrames = frameOffset;
102 memcpy (e->midiData, midiData, (
size_t) numBytes);
106 auto*
const se =
static_cast<Vst2::VstMidiSysexEvent*
> (ptr);
108 if (se->type == Vst2::kVstSysExType)
109 delete[] se->sysexDump;
111 se->sysexDump =
new char [(
size_t) numBytes];
112 memcpy (se->sysexDump, midiData, (
size_t) numBytes);
114 se->type = Vst2::kVstSysExType;
115 se->byteSize =
sizeof (Vst2::VstMidiSysexEvent);
116 se->deltaFrames = frameOffset;
118 se->dumpBytes = numBytes;
127 static void addEventsToMidiBuffer (
const Vst2::VstEvents* events, MidiBuffer& dest)
129 for (
int i = 0; i < events->numEvents; ++i)
131 const auto*
const e = getEvent (*events, i);
135 const void*
const ptr = e;
137 if (e->type == Vst2::kVstMidiType)
139 dest.addEvent ((
const juce::uint8*)
static_cast<const Vst2::VstMidiEvent*
> (ptr)->midiData,
142 else if (e->type == Vst2::kVstSysExType)
144 const auto* se =
static_cast<const Vst2::VstMidiSysexEvent*
> (ptr);
154 void ensureSize (
int numEventsNeeded)
156 if (numEventsNeeded > numEventsAllocated)
158 numEventsNeeded = (numEventsNeeded + 32) & ~31;
160 const size_t size = 20 + (
size_t) numEventsNeeded *
sizeof (Vst2::VstEvent*);
162 if (events ==
nullptr)
163 events.calloc (size, 1);
165 events.realloc (size, 1);
167 for (
int i = numEventsAllocated; i < numEventsNeeded; ++i)
168 getEvent (i) = allocateVSTEvent();
170 numEventsAllocated = numEventsNeeded;
176 if (events !=
nullptr)
178 for (
int i = numEventsAllocated; --i >= 0;)
179 freeVSTEvent (getEvent (i));
183 numEventsAllocated = 0;
188 HeapBlock<Vst2::VstEvents> events;
191 int numEventsUsed, numEventsAllocated;
193 static Vst2::VstEvent* allocateVSTEvent()
195 constexpr auto size =
jmax (
sizeof (Vst2::VstMidiEvent),
sizeof (Vst2::VstMidiSysexEvent));
197 if (
auto* e =
static_cast<Vst2::VstEvent*
> (
std::calloc (1, size)))
199 e->type = Vst2::kVstMidiType;
200 e->byteSize =
sizeof (Vst2::VstMidiEvent);
207 static void freeVSTEvent (Vst2::VstEvent* e)
209 if (e->type == Vst2::kVstSysExType)
211 delete[] (
reinterpret_cast<Vst2::VstMidiSysexEvent*
> (e)->sysexDump);
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.