mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-02 03:20:06 +00:00
Updated MidiKeyboardState to use nested Listener and fixed some thread safety issues
This commit is contained in:
parent
3a9e26b26c
commit
5467c57e23
5 changed files with 50 additions and 64 deletions
|
|
@ -65,7 +65,7 @@ struct MidiDeviceListEntry : ReferenceCountedObject
|
|||
//==============================================================================
|
||||
class MidiDemo : public Component,
|
||||
private Timer,
|
||||
private MidiKeyboardStateListener,
|
||||
private MidiKeyboardState::Listener,
|
||||
private MidiInputCallback,
|
||||
private AsyncUpdater
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@ void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNo
|
|||
if (isPositiveAndBelow (midiNoteNumber, 128))
|
||||
{
|
||||
noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] | (1 << (midiChannel - 1)));
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
listeners.getUnchecked(i)->handleNoteOn (this, midiChannel, midiNoteNumber, velocity);
|
||||
listeners.call ([&] (Listener& l) { l.handleNoteOn (this, midiChannel, midiNoteNumber, velocity); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,9 +99,7 @@ void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiN
|
|||
if (isNoteOn (midiChannel, midiNoteNumber))
|
||||
{
|
||||
noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] & ~(1 << (midiChannel - 1)));
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber, velocity);
|
||||
listeners.call ([&] (Listener& l) { l.handleNoteOff (this, midiChannel, midiNoteNumber, velocity); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,16 +162,16 @@ void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer,
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void MidiKeyboardState::addListener (MidiKeyboardStateListener* const listener)
|
||||
void MidiKeyboardState::addListener (Listener* listener)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
listeners.addIfNotAlreadyThere (listener);
|
||||
listeners.add (listener);
|
||||
}
|
||||
|
||||
void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listener)
|
||||
void MidiKeyboardState::removeListener (Listener* listener)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
listeners.removeFirstMatchingValue (listener);
|
||||
listeners.remove (listener);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -23,51 +23,6 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
class MidiKeyboardState;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Receives events from a MidiKeyboardState object.
|
||||
|
||||
@see MidiKeyboardState
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API MidiKeyboardStateListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
MidiKeyboardStateListener() = default;
|
||||
virtual ~MidiKeyboardStateListener() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Called when one of the MidiKeyboardState's keys is pressed.
|
||||
|
||||
This will be called synchronously when the state is either processing a
|
||||
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
||||
when a note is being played with its MidiKeyboardState::noteOn() method.
|
||||
|
||||
Note that this callback could happen from an audio callback thread, so be
|
||||
careful not to block, and avoid any UI activity in the callback.
|
||||
*/
|
||||
virtual void handleNoteOn (MidiKeyboardState* source,
|
||||
int midiChannel, int midiNoteNumber, float velocity) = 0;
|
||||
|
||||
/** Called when one of the MidiKeyboardState's keys is released.
|
||||
|
||||
This will be called synchronously when the state is either processing a
|
||||
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
||||
when a note is being played with its MidiKeyboardState::noteOff() method.
|
||||
|
||||
Note that this callback could happen from an audio callback thread, so be
|
||||
careful not to block, and avoid any UI activity in the callback.
|
||||
*/
|
||||
virtual void handleNoteOff (MidiKeyboardState* source,
|
||||
int midiChannel, int midiNoteNumber, float velocity) = 0;
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a piano keyboard, keeping track of which keys are currently pressed.
|
||||
|
|
@ -180,27 +135,62 @@ public:
|
|||
bool injectIndirectEvents);
|
||||
|
||||
//==============================================================================
|
||||
/** Receives events from a MidiKeyboardState object. */
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
virtual ~Listener() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Called when one of the MidiKeyboardState's keys is pressed.
|
||||
|
||||
This will be called synchronously when the state is either processing a
|
||||
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
||||
when a note is being played with its MidiKeyboardState::noteOn() method.
|
||||
|
||||
Note that this callback could happen from an audio callback thread, so be
|
||||
careful not to block, and avoid any UI activity in the callback.
|
||||
*/
|
||||
virtual void handleNoteOn (MidiKeyboardState* source,
|
||||
int midiChannel, int midiNoteNumber, float velocity) = 0;
|
||||
|
||||
/** Called when one of the MidiKeyboardState's keys is released.
|
||||
|
||||
This will be called synchronously when the state is either processing a
|
||||
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
||||
when a note is being played with its MidiKeyboardState::noteOff() method.
|
||||
|
||||
Note that this callback could happen from an audio callback thread, so be
|
||||
careful not to block, and avoid any UI activity in the callback.
|
||||
*/
|
||||
virtual void handleNoteOff (MidiKeyboardState* source,
|
||||
int midiChannel, int midiNoteNumber, float velocity) = 0;
|
||||
};
|
||||
|
||||
/** Registers a listener for callbacks when keys go up or down.
|
||||
@see removeListener
|
||||
*/
|
||||
void addListener (MidiKeyboardStateListener* listener);
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a listener.
|
||||
@see addListener
|
||||
*/
|
||||
void removeListener (MidiKeyboardStateListener* listener);
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
CriticalSection lock;
|
||||
uint16 noteStates[128];
|
||||
std::atomic<uint16> noteStates[128];
|
||||
MidiBuffer eventsToAdd;
|
||||
Array <MidiKeyboardStateListener*> listeners;
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
|
||||
void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
|
||||
void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState)
|
||||
};
|
||||
|
||||
using MidiKeyboardStateListener = MidiKeyboardState::Listener;
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ namespace juce
|
|||
Collects incoming realtime MIDI messages and turns them into blocks suitable for
|
||||
processing by a block-based audio callback.
|
||||
|
||||
The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback
|
||||
The class can also be used as either a MidiKeyboardState::Listener or a MidiInputCallback
|
||||
so it can easily use a midi input or keyboard component as its source.
|
||||
|
||||
@see MidiMessage, MidiInput
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener,
|
||||
class JUCE_API MidiMessageCollector : public MidiKeyboardState::Listener,
|
||||
public MidiInputCallback
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace juce
|
|||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API MidiKeyboardComponent : public Component,
|
||||
public MidiKeyboardStateListener,
|
||||
public MidiKeyboardState::Listener,
|
||||
public ChangeBroadcaster,
|
||||
private Timer
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue