OpenShot Library | libopenshot-audio  0.1.9
juce_MidiKeyboardState.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 class MidiKeyboardState;
31 
32 
33 //==============================================================================
34 /**
35  Receives events from a MidiKeyboardState object.
36 
37  @see MidiKeyboardState
38 
39  @tags{Audio}
40 */
42 {
43 public:
44  //==============================================================================
45  MidiKeyboardStateListener() = default;
46  virtual ~MidiKeyboardStateListener() = default;
47 
48  //==============================================================================
49  /** Called when one of the MidiKeyboardState's keys is pressed.
50 
51  This will be called synchronously when the state is either processing a
52  buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
53  when a note is being played with its MidiKeyboardState::noteOn() method.
54 
55  Note that this callback could happen from an audio callback thread, so be
56  careful not to block, and avoid any UI activity in the callback.
57  */
58  virtual void handleNoteOn (MidiKeyboardState* source,
59  int midiChannel, int midiNoteNumber, float velocity) = 0;
60 
61  /** Called when one of the MidiKeyboardState's keys is released.
62 
63  This will be called synchronously when the state is either processing a
64  buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
65  when a note is being played with its MidiKeyboardState::noteOff() method.
66 
67  Note that this callback could happen from an audio callback thread, so be
68  careful not to block, and avoid any UI activity in the callback.
69  */
70  virtual void handleNoteOff (MidiKeyboardState* source,
71  int midiChannel, int midiNoteNumber, float velocity) = 0;
72 };
73 
74 
75 //==============================================================================
76 /**
77  Represents a piano keyboard, keeping track of which keys are currently pressed.
78 
79  This object can parse a stream of midi events, using them to update its idea
80  of which keys are pressed for each individiual midi channel.
81 
82  When keys go up or down, it can broadcast these events to listener objects.
83 
84  It also allows key up/down events to be triggered with its noteOn() and noteOff()
85  methods, and midi messages for these events will be merged into the
86  midi stream that gets processed by processNextMidiBuffer().
87 
88  @tags{Audio}
89 */
91 {
92 public:
93  //==============================================================================
96 
97  //==============================================================================
98  /** Resets the state of the object.
99 
100  All internal data for all the channels is reset, but no events are sent as a
101  result.
102 
103  If you want to release any keys that are currently down, and to send out note-up
104  midi messages for this, use the allNotesOff() method instead.
105  */
106  void reset();
107 
108  /** Returns true if the given midi key is currently held down for the given midi channel.
109 
110  The channel number must be between 1 and 16. If you want to see if any notes are
111  on for a range of channels, use the isNoteOnForChannels() method.
112  */
113  bool isNoteOn (int midiChannel, int midiNoteNumber) const noexcept;
114 
115  /** Returns true if the given midi key is currently held down on any of a set of midi channels.
116 
117  The channel mask has a bit set for each midi channel you want to test for - bit
118  0 = midi channel 1, bit 1 = midi channel 2, etc.
119 
120  If a note is on for at least one of the specified channels, this returns true.
121  */
122  bool isNoteOnForChannels (int midiChannelMask, int midiNoteNumber) const noexcept;
123 
124  /** Turns a specified note on.
125 
126  This will cause a suitable midi note-on event to be injected into the midi buffer during the
127  next call to processNextMidiBuffer().
128 
129  It will also trigger a synchronous callback to the listeners to tell them that the key has
130  gone down.
131  */
132  void noteOn (int midiChannel, int midiNoteNumber, float velocity);
133 
134  /** Turns a specified note off.
135 
136  This will cause a suitable midi note-off event to be injected into the midi buffer during the
137  next call to processNextMidiBuffer().
138 
139  It will also trigger a synchronous callback to the listeners to tell them that the key has
140  gone up.
141 
142  But if the note isn't acutally down for the given channel, this method will in fact do nothing.
143  */
144  void noteOff (int midiChannel, int midiNoteNumber, float velocity);
145 
146  /** This will turn off any currently-down notes for the given midi channel.
147 
148  If you pass 0 for the midi channel, it will in fact turn off all notes on all channels.
149 
150  Calling this method will make calls to noteOff(), so can trigger synchronous callbacks
151  and events being added to the midi stream.
152  */
153  void allNotesOff (int midiChannel);
154 
155  //==============================================================================
156  /** Looks at a key-up/down event and uses it to update the state of this object.
157 
158  To process a buffer full of midi messages, use the processNextMidiBuffer() method
159  instead.
160  */
161  void processNextMidiEvent (const MidiMessage& message);
162 
163  /** Scans a midi stream for up/down events and adds its own events to it.
164 
165  This will look for any up/down events and use them to update the internal state,
166  synchronously making suitable callbacks to the listeners.
167 
168  If injectIndirectEvents is true, then midi events to produce the recent noteOn()
169  and noteOff() calls will be added into the buffer.
170 
171  Only the section of the buffer whose timestamps are between startSample and
172  (startSample + numSamples) will be affected, and any events added will be placed
173  between these times.
174 
175  If you're going to use this method, you'll need to keep calling it regularly for
176  it to work satisfactorily.
177 
178  To process a single midi event at a time, use the processNextMidiEvent() method
179  instead.
180  */
181  void processNextMidiBuffer (MidiBuffer& buffer,
182  int startSample,
183  int numSamples,
184  bool injectIndirectEvents);
185 
186  //==============================================================================
187  /** Registers a listener for callbacks when keys go up or down.
188  @see removeListener
189  */
190  void addListener (MidiKeyboardStateListener* listener);
191 
192  /** Deregisters a listener.
193  @see addListener
194  */
195  void removeListener (MidiKeyboardStateListener* listener);
196 
197 private:
198  //==============================================================================
199  CriticalSection lock;
200  uint16 noteStates [128];
201  MidiBuffer eventsToAdd;
203 
204  void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
205  void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity);
206 
207  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState)
208 };
209 
210 } // namespace juce
211 
212 /** @}*/
Receives events from a MidiKeyboardState object.
#define JUCE_API
This macro is added to all JUCE public class declarations.
Encapsulates a MIDI message.
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
Holds a sequence of time-stamped midi events.
A re-entrant mutex.
Represents a piano keyboard, keeping track of which keys are currently pressed.