Massive UI work
[juce-lv2.git] / juce / source / src / audio / midi / juce_MidiKeyboardState.h
blobceb219ba1dc19d4b98b9b325e6bdd6c688dd7c74
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
27 #define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
29 #include "juce_MidiBuffer.h"
30 #include "../../containers/juce_Array.h"
31 class MidiKeyboardState;
34 //==============================================================================
35 /**
36 Receives events from a MidiKeyboardState object.
38 @see MidiKeyboardState
40 class JUCE_API MidiKeyboardStateListener
42 public:
43 //==============================================================================
44 MidiKeyboardStateListener() noexcept {}
45 virtual ~MidiKeyboardStateListener() {}
47 //==============================================================================
48 /** Called when one of the MidiKeyboardState's keys is pressed.
50 This will be called synchronously when the state is either processing a
51 buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
52 when a note is being played with its MidiKeyboardState::noteOn() method.
54 Note that this callback could happen from an audio callback thread, so be
55 careful not to block, and avoid any UI activity in the callback.
57 virtual void handleNoteOn (MidiKeyboardState* source,
58 int midiChannel, int midiNoteNumber, float velocity) = 0;
60 /** Called when one of the MidiKeyboardState's keys is released.
62 This will be called synchronously when the state is either processing a
63 buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
64 when a note is being played with its MidiKeyboardState::noteOff() method.
66 Note that this callback could happen from an audio callback thread, so be
67 careful not to block, and avoid any UI activity in the callback.
69 virtual void handleNoteOff (MidiKeyboardState* source,
70 int midiChannel, int midiNoteNumber) = 0;
74 //==============================================================================
75 /**
76 Represents a piano keyboard, keeping track of which keys are currently pressed.
78 This object can parse a stream of midi events, using them to update its idea
79 of which keys are pressed for each individiual midi channel.
81 When keys go up or down, it can broadcast these events to listener objects.
83 It also allows key up/down events to be triggered with its noteOn() and noteOff()
84 methods, and midi messages for these events will be merged into the
85 midi stream that gets processed by processNextMidiBuffer().
87 class JUCE_API MidiKeyboardState
89 public:
90 //==============================================================================
91 MidiKeyboardState();
92 ~MidiKeyboardState();
94 //==============================================================================
95 /** Resets the state of the object.
97 All internal data for all the channels is reset, but no events are sent as a
98 result.
100 If you want to release any keys that are currently down, and to send out note-up
101 midi messages for this, use the allNotesOff() method instead.
103 void reset();
105 /** Returns true if the given midi key is currently held down for the given midi channel.
107 The channel number must be between 1 and 16. If you want to see if any notes are
108 on for a range of channels, use the isNoteOnForChannels() method.
110 bool isNoteOn (int midiChannel, int midiNoteNumber) const noexcept;
112 /** Returns true if the given midi key is currently held down on any of a set of midi channels.
114 The channel mask has a bit set for each midi channel you want to test for - bit
115 0 = midi channel 1, bit 1 = midi channel 2, etc.
117 If a note is on for at least one of the specified channels, this returns true.
119 bool isNoteOnForChannels (int midiChannelMask, int midiNoteNumber) const noexcept;
121 /** Turns a specified note on.
123 This will cause a suitable midi note-on event to be injected into the midi buffer during the
124 next call to processNextMidiBuffer().
126 It will also trigger a synchronous callback to the listeners to tell them that the key has
127 gone down.
129 void noteOn (int midiChannel, int midiNoteNumber, float velocity);
131 /** Turns a specified note off.
133 This will cause a suitable midi note-off event to be injected into the midi buffer during the
134 next call to processNextMidiBuffer().
136 It will also trigger a synchronous callback to the listeners to tell them that the key has
137 gone up.
139 But if the note isn't acutally down for the given channel, this method will in fact do nothing.
141 void noteOff (int midiChannel, int midiNoteNumber);
143 /** This will turn off any currently-down notes for the given midi channel.
145 If you pass 0 for the midi channel, it will in fact turn off all notes on all channels.
147 Calling this method will make calls to noteOff(), so can trigger synchronous callbacks
148 and events being added to the midi stream.
150 void allNotesOff (int midiChannel);
152 //==============================================================================
153 /** Looks at a key-up/down event and uses it to update the state of this object.
155 To process a buffer full of midi messages, use the processNextMidiBuffer() method
156 instead.
158 void processNextMidiEvent (const MidiMessage& message);
160 /** Scans a midi stream for up/down events and adds its own events to it.
162 This will look for any up/down events and use them to update the internal state,
163 synchronously making suitable callbacks to the listeners.
165 If injectIndirectEvents is true, then midi events to produce the recent noteOn()
166 and noteOff() calls will be added into the buffer.
168 Only the section of the buffer whose timestamps are between startSample and
169 (startSample + numSamples) will be affected, and any events added will be placed
170 between these times.
172 If you're going to use this method, you'll need to keep calling it regularly for
173 it to work satisfactorily.
175 To process a single midi event at a time, use the processNextMidiEvent() method
176 instead.
178 void processNextMidiBuffer (MidiBuffer& buffer,
179 int startSample,
180 int numSamples,
181 bool injectIndirectEvents);
183 //==============================================================================
184 /** Registers a listener for callbacks when keys go up or down.
186 @see removeListener
188 void addListener (MidiKeyboardStateListener* listener);
190 /** Deregisters a listener.
192 @see addListener
194 void removeListener (MidiKeyboardStateListener* listener);
196 private:
197 //==============================================================================
198 CriticalSection lock;
199 uint16 noteStates [128];
200 MidiBuffer eventsToAdd;
201 Array <MidiKeyboardStateListener*> listeners;
203 void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
204 void noteOffInternal (int midiChannel, int midiNoteNumber);
206 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState);
210 #endif // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__