|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2013 - Raw Material Software Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- #ifndef JUCE_MIDIBUFFER_H_INCLUDED
- #define JUCE_MIDIBUFFER_H_INCLUDED
-
-
- //==============================================================================
- /**
- 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& other) 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 isn't a
- safe operation.
-
- @see MidiBuffer
- */
- class JUCE_API Iterator
- {
- public:
- //==============================================================================
- /** Creates an Iterator for this MidiBuffer. */
- Iterator (const MidiBuffer&) noexcept;
-
- /** 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 not set)
- @param samplePosition on return, this will be the position of the event
- @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
- @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;
-
- JUCE_DECLARE_NON_COPYABLE (Iterator)
- };
-
- private:
- //==============================================================================
- friend class MidiBuffer::Iterator;
- MemoryBlock data;
- int bytesUsed;
-
- uint8* getData() const noexcept;
- uint8* findEventAfter (uint8*, int samplePosition) const noexcept;
-
- JUCE_LEAK_DETECTOR (MidiBuffer)
- };
-
-
- #endif // JUCE_MIDIBUFFER_H_INCLUDED
|