void handleNoteOn (juce::MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override
//Called when one of the MidiKeyboardState's keys is pressed.
{
if (! isAddingFromMidiInput)
{
auto m = juce::MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity);
m.setTimeStamp (juce::Time::getMillisecondCounterHiRes() * 0.001);
postMessageToList (m, "On-Screen Keyboard");
}
}
void postMessageToList (const juce::MidiMessage& message, const juce::String& source)
{
(new IncomingMessageCallback (this, message, source))->post();
}
void handleIncomingMidiMessage (juce::MidiInput* source, const juce::MidiMessage& message) override //MidiInputCallback::handleIncomingMidiMessage()
{
const juce::ScopedValueSetter<bool> scopedInputFlag (isAddingFromMidiInput, true);
keyboardState.processNextMidiEvent (message);
//Looks at a key-up/down event and uses it to update the state of this object.
postMessageToList (message, source->getName());
}
The handleNoteOn is called from MidiKeyboardState. handleIncomingMidiMessage would be called from the MidiInput.
in a plugin you should not talk to the MidiInput directly, because they are managed from the host.
the host needs to add the timestamps according to the timeline. MidiInput is asynchronous to the audio playback.
The preferred way is to send the MidiBuffer from the processBlock() call to the MidiKeyboardState, which takes also care of thread safety between GUI thread and the audio thread.
While this tutorial is not a plugin, the MidiKeyboardComponent relies on the MidiKeyboardState, so it makes sense to use its interface for the handleNoteOn and handleNoteOff.
Why should not talk to the MidiInput directly because they are managed from the host ?
If a note is played by a midi keyboard, it will send 2 lines to log?(one is velocity, source, and the other one is the played note of on-screen keyboard)