26 namespace MidiBufferHelpers
28 inline int getEventTime (
const void* d) noexcept
30 return readUnaligned<int32> (d);
33 inline uint16 getEventDataSize (
const void* d) noexcept
35 return readUnaligned<uint16> (
static_cast<const char*
> (d) +
sizeof (int32));
38 inline uint16 getEventTotalSize (
const void* d) noexcept
40 return (uint16) (getEventDataSize (d) +
sizeof (int32) +
sizeof (uint16));
43 static int findActualEventLength (
const uint8* data,
int maxBytes) noexcept
45 auto byte = (
unsigned int) *data;
47 if (byte == 0xf0 || byte == 0xf7)
52 if (data[i++] == 0xf7)
65 return jmin (maxBytes, n + 2 + bytesLeft);
74 static uint8* findEventAfter (uint8* d, uint8* endData,
int samplePosition) noexcept
76 while (d < endData && getEventTime (d) <= samplePosition)
77 d += getEventTotalSize (d);
97 addEvent (message, 0);
107 auto start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1);
108 auto end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1);
110 data.removeRange ((
int) (start - data.begin()), (
int) (end - data.begin()));
120 auto numBytes = MidiBufferHelpers::findActualEventLength (static_cast<const uint8*> (newData), maxBytes);
124 auto newItemSize = (size_t) numBytes +
sizeof (int32) +
sizeof (uint16);
125 auto offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin());
127 data.insertMultiple (offset, 0, (
int) newItemSize);
129 auto* d = data.begin() + offset;
130 writeUnaligned<int32> (d, sampleNumber);
132 writeUnaligned<uint16> (d,
static_cast<uint16
> (numBytes));
133 d +=
sizeof (uint16);
134 memcpy (d, newData, (
size_t) numBytes);
139 int startSample,
int numSamples,
int sampleDeltaToAdd)
144 const uint8* eventData;
145 int eventSize, position;
148 && (position < startSample + numSamples || numSamples < 0))
150 addEvent (eventData, eventSize, position + sampleDeltaToAdd);
157 auto end = data.end();
159 for (
auto d = data.begin(); d < end; ++n)
160 d += MidiBufferHelpers::getEventTotalSize (d);
167 return data.size() > 0 ? MidiBufferHelpers::getEventTime (data.begin()) : 0;
172 if (data.size() == 0)
175 auto endData = data.end();
177 for (
auto d = data.begin();;)
179 auto nextOne = d + MidiBufferHelpers::getEventTotalSize (d);
181 if (nextOne >= endData)
182 return MidiBufferHelpers::getEventTime (d);
190 : buffer (b), data (b.data.begin())
198 data = buffer.data.begin();
199 auto dataEnd = buffer.data.end();
201 while (data < dataEnd && MidiBufferHelpers::getEventTime (data) < samplePosition)
202 data += MidiBufferHelpers::getEventTotalSize (data);
207 if (data >= buffer.data.end())
210 samplePosition = MidiBufferHelpers::getEventTime (data);
211 auto itemSize = MidiBufferHelpers::getEventDataSize (data);
213 midiData = data +
sizeof (int32) +
sizeof (uint16);
214 data +=
sizeof (int32) +
sizeof (uint16) + (size_t) itemSize;
221 if (data >= buffer.data.end())
224 samplePosition = MidiBufferHelpers::getEventTime (data);
225 auto itemSize = MidiBufferHelpers::getEventDataSize (data);
226 result =
MidiMessage (data +
sizeof (int32) +
sizeof (uint16), itemSize, samplePosition);
227 data +=
sizeof (int32) +
sizeof (uint16) + (size_t) itemSize;
MidiBuffer & operator=(const MidiBuffer &) noexcept
void setNextSamplePosition(int samplePosition) noexcept
void swapWith(MidiBuffer &) noexcept
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
int getFirstEventTime() const noexcept
int getRawDataSize() const noexcept
Iterator(const MidiBuffer &) noexcept
bool isEmpty() const noexcept
int getNumEvents() const noexcept
static int getMessageLengthFromFirstByte(uint8 firstByte) noexcept
static int readVariableLengthVal(const uint8 *data, int &numBytesUsed) noexcept
const uint8 * getRawData() const noexcept
int getLastEventTime() const noexcept
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
void addEvents(const MidiBuffer &otherBuffer, int startSample, int numSamples, int sampleDeltaToAdd)
void ensureSize(size_t minimumNumBytes)