From cee5a771239bcbc6bee4841bd9c9291c60c06635 Mon Sep 17 00:00:00 2001 From: jules Date: Mon, 14 Sep 2015 09:49:15 +0100 Subject: [PATCH] Added a velocity parameter to note-off handling in MidiKeyboardState --- examples/Demo/Source/Demos/MidiDemo.cpp | 4 ++-- .../midi/juce_MidiKeyboardState.cpp | 14 ++++++------- .../midi/juce_MidiKeyboardState.h | 6 +++--- .../midi_io/juce_MidiMessageCollector.cpp | 10 ++++----- .../midi_io/juce_MidiMessageCollector.h | 2 +- .../gui/juce_MidiKeyboardComponent.cpp | 21 ++++++++----------- .../gui/juce_MidiKeyboardComponent.h | 2 +- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/examples/Demo/Source/Demos/MidiDemo.cpp b/examples/Demo/Source/Demos/MidiDemo.cpp index da176cc42f..96e0c93d2a 100644 --- a/examples/Demo/Source/Demos/MidiDemo.cpp +++ b/examples/Demo/Source/Demos/MidiDemo.cpp @@ -215,11 +215,11 @@ private: } } - void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) override + void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override { if (! isAddingFromMidiInput) { - MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber)); + MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber, velocity)); m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001); postMessageToList (m); } diff --git a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp index 287a4fa4d1..ef6e97e56d 100644 --- a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp @@ -81,7 +81,7 @@ void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNo } } -void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber) +void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber, const float velocity) { const ScopedLock sl (lock); @@ -91,18 +91,18 @@ void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow); eventsToAdd.clear (0, timeNow - 500); - noteOffInternal (midiChannel, midiNoteNumber); + noteOffInternal (midiChannel, midiNoteNumber, velocity); } } -void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber) +void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber, const float velocity) { if (isNoteOn (midiChannel, midiNoteNumber)) { noteStates [midiNoteNumber] &= ~(1 << (midiChannel - 1)); for (int i = listeners.size(); --i >= 0;) - listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber); + listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber, velocity); } } @@ -118,7 +118,7 @@ void MidiKeyboardState::allNotesOff (const int midiChannel) else { for (int i = 0; i < 128; ++i) - noteOff (midiChannel, i); + noteOff (midiChannel, i, 0.0f); } } @@ -130,12 +130,12 @@ void MidiKeyboardState::processNextMidiEvent (const MidiMessage& message) } else if (message.isNoteOff()) { - noteOffInternal (message.getChannel(), message.getNoteNumber()); + noteOffInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity()); } else if (message.isAllNotesOff()) { for (int i = 0; i < 128; ++i) - noteOffInternal (message.getChannel(), i); + noteOffInternal (message.getChannel(), i, 0.0f); } } diff --git a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h index 520dfec4df..8ac030ce10 100644 --- a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h +++ b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h @@ -64,7 +64,7 @@ public: careful not to block, and avoid any UI activity in the callback. */ virtual void handleNoteOff (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber) = 0; + int midiChannel, int midiNoteNumber, float velocity) = 0; }; @@ -135,7 +135,7 @@ public: But if the note isn't acutally down for the given channel, this method will in fact do nothing. */ - void noteOff (int midiChannel, int midiNoteNumber); + void noteOff (int midiChannel, int midiNoteNumber, float velocity); /** This will turn off any currently-down notes for the given midi channel. @@ -196,7 +196,7 @@ private: Array listeners; void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity); - void noteOffInternal (int midiChannel, int midiNoteNumber); + void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) }; diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp index f4b9525342..11b4dd94a1 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp @@ -33,12 +33,12 @@ MidiMessageCollector::~MidiMessageCollector() } //============================================================================== -void MidiMessageCollector::reset (const double sampleRate_) +void MidiMessageCollector::reset (const double newSampleRate) { - jassert (sampleRate_ > 0); + jassert (newSampleRate > 0); const ScopedLock sl (midiCallbackLock); - sampleRate = sampleRate_; + sampleRate = newSampleRate; incomingMessages.clear(); lastCallbackTime = Time::getMillisecondCounterHiRes(); } @@ -139,9 +139,9 @@ void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, in addMessageToQueue (m); } -void MidiMessageCollector::handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) +void MidiMessageCollector::handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) { - MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber)); + MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber, velocity)); m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001); addMessageToQueue (m); diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h index c77401a7f0..75bcc81ff6 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h @@ -86,7 +86,7 @@ public: /** @internal */ void handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override; /** @internal */ - void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) override; + void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override; /** @internal */ void handleIncomingMidiMessage (MidiInput*, const MidiMessage&) override; diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp index 13fda79f95..2422c625ce 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp @@ -664,7 +664,7 @@ void MidiKeyboardComponent::handleNoteOn (MidiKeyboardState*, int /*midiChannel* shouldCheckState = true; // (probably being called from the audio thread, so avoid blocking in here) } -void MidiKeyboardComponent::handleNoteOff (MidiKeyboardState*, int /*midiChannel*/, int /*midiNoteNumber*/) +void MidiKeyboardComponent::handleNoteOff (MidiKeyboardState*, int /*midiChannel*/, int /*midiNoteNumber*/, float /*velocity*/) { shouldCheckState = true; // (probably being called from the audio thread, so avoid blocking in here) } @@ -676,7 +676,7 @@ void MidiKeyboardComponent::resetAnyKeysInUse() { for (int i = 128; --i >= 0;) if (keysPressed[i]) - state.noteOff (midiChannel, i); + state.noteOff (midiChannel, i, 0.0f); keysPressed.clear(); } @@ -687,7 +687,7 @@ void MidiKeyboardComponent::resetAnyKeysInUse() if (noteDown >= 0) { - state.noteOff (midiChannel, noteDown); + state.noteOff (midiChannel, noteDown, 0.0f); mouseDownNotes.set (i, -1); } @@ -705,6 +705,8 @@ void MidiKeyboardComponent::updateNoteUnderMouse (Point pos, bool isDown, i float mousePositionVelocity = 0.0f; const int newNote = xyToNote (pos, mousePositionVelocity); const int oldNote = mouseOverNotes.getUnchecked (fingerNum); + const int oldNoteDown = mouseDownNotes.getUnchecked (fingerNum); + const float eventVelocity = useMousePositionForVelocity ? mousePositionVelocity * velocity : 1.0f; if (oldNote != newNote) { @@ -713,8 +715,6 @@ void MidiKeyboardComponent::updateNoteUnderMouse (Point pos, bool isDown, i mouseOverNotes.set (fingerNum, newNote); } - const int oldNoteDown = mouseDownNotes.getUnchecked (fingerNum); - if (isDown) { if (newNote != oldNoteDown) @@ -724,15 +724,12 @@ void MidiKeyboardComponent::updateNoteUnderMouse (Point pos, bool isDown, i mouseDownNotes.set (fingerNum, -1); if (! mouseDownNotes.contains (oldNoteDown)) - state.noteOff (midiChannel, oldNoteDown); + state.noteOff (midiChannel, oldNoteDown, eventVelocity); } if (newNote >= 0 && ! mouseDownNotes.contains (newNote)) { - if (! useMousePositionForVelocity) - mousePositionVelocity = 1.0f; - - state.noteOn (midiChannel, newNote, mousePositionVelocity * velocity); + state.noteOn (midiChannel, newNote, eventVelocity); mouseDownNotes.set (fingerNum, newNote); } } @@ -742,7 +739,7 @@ void MidiKeyboardComponent::updateNoteUnderMouse (Point pos, bool isDown, i mouseDownNotes.set (fingerNum, -1); if (! mouseDownNotes.contains (oldNoteDown)) - state.noteOff (midiChannel, oldNoteDown); + state.noteOff (midiChannel, oldNoteDown, eventVelocity); } } @@ -892,7 +889,7 @@ bool MidiKeyboardComponent::keyStateChanged (const bool /*isKeyDown*/) if (keysPressed [note]) { keysPressed.clearBit (note); - state.noteOff (midiChannel, note); + state.noteOff (midiChannel, note, 0.0f); keyPressUsed = true; } } diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h index 300435460d..caa8483ba9 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h @@ -287,7 +287,7 @@ public: /** @internal */ void handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override; /** @internal */ - void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) override; + void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override; /** @internal */ void colourChanged() override;