OpenShot Library | OpenShotAudio  0.2.2
juce_MidiBuffer.h
1 
2 /** @weakgroup juce_audio_basics-midi
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 //==============================================================================
31 /**
32  Holds a sequence of time-stamped midi events.
33 
34  Analogous to the AudioBuffer, this holds a set of midi events with
35  integer time-stamps. The buffer is kept sorted in order of the time-stamps.
36 
37  If you're working with a sequence of midi events that may need to be manipulated
38  or read/written to a midi file, then MidiMessageSequence is probably a more
39  appropriate container. MidiBuffer is designed for lower-level streams of raw
40  midi data.
41 
42  @see MidiMessage
43 
44  @tags{Audio}
45 */
47 {
48 public:
49  //==============================================================================
50  /** Creates an empty MidiBuffer. */
51  MidiBuffer() noexcept;
52 
53  /** Creates a MidiBuffer containing a single midi message. */
54  explicit MidiBuffer (const MidiMessage& message) noexcept;
55 
56  /** Creates a copy of another MidiBuffer. */
57  MidiBuffer (const MidiBuffer&) noexcept;
58 
59  /** Makes a copy of another MidiBuffer. */
60  MidiBuffer& operator= (const MidiBuffer&) noexcept;
61 
62  /** Destructor */
63  ~MidiBuffer();
64 
65  //==============================================================================
66  /** Removes all events from the buffer. */
67  void clear() noexcept;
68 
69  /** Removes all events between two times from the buffer.
70 
71  All events for which (start <= event position < start + numSamples) will
72  be removed.
73  */
74  void clear (int start, int numSamples);
75 
76  /** Returns true if the buffer is empty.
77  To actually retrieve the events, use a MidiBuffer::Iterator object
78  */
79  bool isEmpty() const noexcept;
80 
81  /** Counts the number of events in the buffer.
82 
83  This is actually quite a slow operation, as it has to iterate through all
84  the events, so you might prefer to call isEmpty() if that's all you need
85  to know.
86  */
87  int getNumEvents() const noexcept;
88 
89  /** Adds an event to the buffer.
90 
91  The sample number will be used to determine the position of the event in
92  the buffer, which is always kept sorted. The MidiMessage's timestamp is
93  ignored.
94 
95  If an event is added whose sample position is the same as one or more events
96  already in the buffer, the new event will be placed after the existing ones.
97 
98  To retrieve events, use a MidiBuffer::Iterator object
99  */
100  void addEvent (const MidiMessage& midiMessage, int sampleNumber);
101 
102  /** Adds an event to the buffer from raw midi data.
103 
104  The sample number will be used to determine the position of the event in
105  the buffer, which is always kept sorted.
106 
107  If an event is added whose sample position is the same as one or more events
108  already in the buffer, the new event will be placed after the existing ones.
109 
110  The event data will be inspected to calculate the number of bytes in length that
111  the midi event really takes up, so maxBytesOfMidiData may be longer than the data
112  that actually gets stored. E.g. if you pass in a note-on and a length of 4 bytes,
113  it'll actually only store 3 bytes. If the midi data is invalid, it might not
114  add an event at all.
115 
116  To retrieve events, use a MidiBuffer::Iterator object
117  */
118  void addEvent (const void* rawMidiData,
119  int maxBytesOfMidiData,
120  int sampleNumber);
121 
122  /** Adds some events from another buffer to this one.
123 
124  @param otherBuffer the buffer containing the events you want to add
125  @param startSample the lowest sample number in the source buffer for which
126  events should be added. Any source events whose timestamp is
127  less than this will be ignored
128  @param numSamples the valid range of samples from the source buffer for which
129  events should be added - i.e. events in the source buffer whose
130  timestamp is greater than or equal to (startSample + numSamples)
131  will be ignored. If this value is less than 0, all events after
132  startSample will be taken.
133  @param sampleDeltaToAdd a value which will be added to the source timestamps of the events
134  that are added to this buffer
135  */
136  void addEvents (const MidiBuffer& otherBuffer,
137  int startSample,
138  int numSamples,
139  int sampleDeltaToAdd);
140 
141  /** Returns the sample number of the first event in the buffer.
142  If the buffer's empty, this will just return 0.
143  */
144  int getFirstEventTime() const noexcept;
145 
146  /** Returns the sample number of the last event in the buffer.
147  If the buffer's empty, this will just return 0.
148  */
149  int getLastEventTime() const noexcept;
150 
151  //==============================================================================
152  /** Exchanges the contents of this buffer with another one.
153 
154  This is a quick operation, because no memory allocating or copying is done, it
155  just swaps the internal state of the two buffers.
156  */
157  void swapWith (MidiBuffer&) noexcept;
158 
159  /** Preallocates some memory for the buffer to use.
160  This helps to avoid needing to reallocate space when the buffer has messages
161  added to it.
162  */
163  void ensureSize (size_t minimumNumBytes);
164 
165  //==============================================================================
166  /**
167  Used to iterate through the events in a MidiBuffer.
168 
169  Note that altering the buffer while an iterator is using it will produce
170  undefined behaviour.
171 
172  @see MidiBuffer
173  */
175  {
176  public:
177  //==============================================================================
178  /** Creates an Iterator for this MidiBuffer. */
179  Iterator (const MidiBuffer&) noexcept;
180 
181  /** Creates a copy of an iterator. */
182  Iterator (const Iterator&) = default;
183 
184  /** Destructor. */
185  ~Iterator() noexcept;
186 
187  //==============================================================================
188  /** Repositions the iterator so that the next event retrieved will be the first
189  one whose sample position is at greater than or equal to the given position.
190  */
191  void setNextSamplePosition (int samplePosition) noexcept;
192 
193  /** Retrieves a copy of the next event from the buffer.
194 
195  @param result on return, this will be the message. The MidiMessage's timestamp
196  is set to the same value as samplePosition.
197  @param samplePosition on return, this will be the position of the event, as a
198  sample index in the buffer
199  @returns true if an event was found, or false if the iterator has reached
200  the end of the buffer
201  */
202  bool getNextEvent (MidiMessage& result,
203  int& samplePosition) noexcept;
204 
205  /** Retrieves the next event from the buffer.
206 
207  @param midiData on return, this pointer will be set to a block of data containing
208  the midi message. Note that to make it fast, this is a pointer
209  directly into the MidiBuffer's internal data, so is only valid
210  temporarily until the MidiBuffer is altered.
211  @param numBytesOfMidiData on return, this is the number of bytes of data used by the
212  midi message
213  @param samplePosition on return, this will be the position of the event, as a
214  sample index in the buffer
215  @returns true if an event was found, or false if the iterator has reached
216  the end of the buffer
217  */
218  bool getNextEvent (const uint8* &midiData,
219  int& numBytesOfMidiData,
220  int& samplePosition) noexcept;
221 
222  private:
223  //==============================================================================
224  const MidiBuffer& buffer;
225  const uint8* data;
226  };
227 
228  /** The raw data holding this buffer.
229  Obviously access to this data is provided at your own risk. Its internal format could
230  change in future, so don't write code that relies on it!
231  */
232  Array<uint8> data;
233 
234 private:
235  JUCE_LEAK_DETECTOR (MidiBuffer)
236 };
237 
238 } // namespace juce
239 
240 /** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:60
Used to iterate through the events in a MidiBuffer.
Iterator(const Iterator &)=default
Creates a copy of an iterator.
Holds a sequence of time-stamped midi events.
Encapsulates a MIDI message.
#define JUCE_API
This macro is added to all JUCE public class declarations.