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
Makes a copy of another MidiBuffer.
void setNextSamplePosition(int samplePosition) noexcept
Repositions the iterator so that the next event retrieved will be the first one whose sample position...
void swapWith(MidiBuffer &) noexcept
Exchanges the contents of this buffer with another one.
Encapsulates a MIDI message.
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
Retrieves a copy of the next event from the buffer.
~Iterator() noexcept
Destructor.
int getFirstEventTime() const noexcept
Returns the sample number of the first event in the buffer.
int getRawDataSize() const noexcept
Returns the number of bytes of data in the message.
Iterator(const MidiBuffer &) noexcept
Creates an Iterator for this MidiBuffer.
bool isEmpty() const noexcept
Returns true if the buffer is empty.
MidiBuffer() noexcept
Creates an empty MidiBuffer.
int getNumEvents() const noexcept
Counts the number of events in the buffer.
static int getMessageLengthFromFirstByte(uint8 firstByte) noexcept
Based on the first byte of a short midi message, this uses a lookup table to return the message lengt...
Holds a sequence of time-stamped midi events.
static int readVariableLengthVal(const uint8 *data, int &numBytesUsed) noexcept
Reads a midi variable-length integer.
const uint8 * getRawData() const noexcept
Returns a pointer to the raw midi data.
Array< uint8 > data
The raw data holding this buffer.
int getLastEventTime() const noexcept
Returns the sample number of the last event in the buffer.
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
Adds an event to the buffer.
Used to iterate through the events in a MidiBuffer.
void addEvents(const MidiBuffer &otherBuffer, int startSample, int numSamples, int sampleDeltaToAdd)
Adds some events from another buffer to this one.
void clear() noexcept
Removes all events from the buffer.
void ensureSize(size_t minimumNumBytes)
Preallocates some memory for the buffer to use.