|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2017 - ROLI Ltd.
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- The code included in this file is provided under the terms of the ISC license
- http://www.isc.org/downloads/software-support-policy/isc-license. Permission
- To use, copy, modify, and/or distribute this software for any purpose with or
- without fee is hereby granted provided that the above copyright notice and
- this permission notice appear in all copies.
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce
- {
-
- //==============================================================================
- /**
- Holds a sequence of time-stamped midi events.
-
- Analogous to the AudioSampleBuffer, this holds a set of midi events with
- integer time-stamps. The buffer is kept sorted in order of the time-stamps.
-
- If you're working with a sequence of midi events that may need to be manipulated
- or read/written to a midi file, then MidiMessageSequence is probably a more
- appropriate container. MidiBuffer is designed for lower-level streams of raw
- midi data.
-
- @see MidiMessage
- */
- class JUCE_API MidiBuffer
- {
- public:
- //==============================================================================
- /** Creates an empty MidiBuffer. */
- MidiBuffer() noexcept;
-
- /** Creates a MidiBuffer containing a single midi message. */
- explicit MidiBuffer (const MidiMessage& message) noexcept;
-
- /** Creates a copy of another MidiBuffer. */
- MidiBuffer (const MidiBuffer&) noexcept;
-
- /** Makes a copy of another MidiBuffer. */
- MidiBuffer& operator= (const MidiBuffer&) noexcept;
-
- /** Destructor */
- ~MidiBuffer();
-
- //==============================================================================
- /** Removes all events from the buffer. */
- void clear() noexcept;
-
- /** Removes all events between two times from the buffer.
-
- All events for which (start <= event position < start + numSamples) will
- be removed.
- */
- void clear (int start, int numSamples);
-
- /** Returns true if the buffer is empty.
- To actually retrieve the events, use a MidiBuffer::Iterator object
- */
- bool isEmpty() const noexcept;
-
- /** Counts the number of events in the buffer.
-
- This is actually quite a slow operation, as it has to iterate through all
- the events, so you might prefer to call isEmpty() if that's all you need
- to know.
- */
- int getNumEvents() const noexcept;
-
- /** Adds an event to the buffer.
-
- The sample number will be used to determine the position of the event in
- the buffer, which is always kept sorted. The MidiMessage's timestamp is
- ignored.
-
- If an event is added whose sample position is the same as one or more events
- already in the buffer, the new event will be placed after the existing ones.
-
- To retrieve events, use a MidiBuffer::Iterator object
- */
- void addEvent (const MidiMessage& midiMessage, int sampleNumber);
-
- /** Adds an event to the buffer from raw midi data.
-
- The sample number will be used to determine the position of the event in
- the buffer, which is always kept sorted.
-
- If an event is added whose sample position is the same as one or more events
- already in the buffer, the new event will be placed after the existing ones.
-
- The event data will be inspected to calculate the number of bytes in length that
- the midi event really takes up, so maxBytesOfMidiData may be longer than the data
- that actually gets stored. E.g. if you pass in a note-on and a length of 4 bytes,
- it'll actually only store 3 bytes. If the midi data is invalid, it might not
- add an event at all.
-
- To retrieve events, use a MidiBuffer::Iterator object
- */
- void addEvent (const void* rawMidiData,
- int maxBytesOfMidiData,
- int sampleNumber);
-
- /** Adds some events from another buffer to this one.
-
- @param otherBuffer the buffer containing the events you want to add
- @param startSample the lowest sample number in the source buffer for which
- events should be added. Any source events whose timestamp is
- less than this will be ignored
- @param numSamples the valid range of samples from the source buffer for which
- events should be added - i.e. events in the source buffer whose
- timestamp is greater than or equal to (startSample + numSamples)
- will be ignored. If this value is less than 0, all events after
- startSample will be taken.
- @param sampleDeltaToAdd a value which will be added to the source timestamps of the events
- that are added to this buffer
- */
- void addEvents (const MidiBuffer& otherBuffer,
- int startSample,
- int numSamples,
- int sampleDeltaToAdd);
-
- /** Returns the sample number of the first event in the buffer.
- If the buffer's empty, this will just return 0.
- */
- int getFirstEventTime() const noexcept;
-
- /** Returns the sample number of the last event in the buffer.
- If the buffer's empty, this will just return 0.
- */
- int getLastEventTime() const noexcept;
-
- //==============================================================================
- /** Exchanges the contents of this buffer with another one.
-
- This is a quick operation, because no memory allocating or copying is done, it
- just swaps the internal state of the two buffers.
- */
- void swapWith (MidiBuffer&) noexcept;
-
- /** Preallocates some memory for the buffer to use.
- This helps to avoid needing to reallocate space when the buffer has messages
- added to it.
- */
- void ensureSize (size_t minimumNumBytes);
-
- //==============================================================================
- /**
- Used to iterate through the events in a MidiBuffer.
-
- Note that altering the buffer while an iterator is using it will produce
- undefined behaviour.
-
- @see MidiBuffer
- */
- class JUCE_API Iterator
- {
- public:
- //==============================================================================
- /** Creates an Iterator for this MidiBuffer. */
- Iterator (const MidiBuffer&) noexcept;
-
- /** Creates a copy of an iterator. */
- Iterator (const Iterator&) noexcept = default;
-
- /** Destructor. */
- ~Iterator() noexcept;
-
- //==============================================================================
- /** Repositions the iterator so that the next event retrieved will be the first
- one whose sample position is at greater than or equal to the given position.
- */
- void setNextSamplePosition (int samplePosition) noexcept;
-
- /** Retrieves a copy of the next event from the buffer.
-
- @param result on return, this will be the message. The MidiMessage's timestamp
- is set to the same value as samplePosition.
- @param samplePosition on return, this will be the position of the event, as a
- sample index in the buffer
- @returns true if an event was found, or false if the iterator has reached
- the end of the buffer
- */
- bool getNextEvent (MidiMessage& result,
- int& samplePosition) noexcept;
-
- /** Retrieves the next event from the buffer.
-
- @param midiData on return, this pointer will be set to a block of data containing
- the midi message. Note that to make it fast, this is a pointer
- directly into the MidiBuffer's internal data, so is only valid
- temporarily until the MidiBuffer is altered.
- @param numBytesOfMidiData on return, this is the number of bytes of data used by the
- midi message
- @param samplePosition on return, this will be the position of the event, as a
- sample index in the buffer
- @returns true if an event was found, or false if the iterator has reached
- the end of the buffer
- */
- bool getNextEvent (const uint8* &midiData,
- int& numBytesOfMidiData,
- int& samplePosition) noexcept;
-
- private:
- //==============================================================================
- const MidiBuffer& buffer;
- const uint8* data;
- };
-
- /** The raw data holding this buffer.
- Obviously access to this data is provided at your own risk. Its internal format could
- change in future, so don't write code that relies on it!
- */
- Array<uint8> data;
-
- private:
- JUCE_LEAK_DETECTOR (MidiBuffer)
- };
-
- } // namespace juce
|