[SOLVED] How to show pressed Midi Notes from Midi Device on KeyboardComponent inside VST Plugin?

// PluginEditor.h

...
private:
    ...
    MidiKeyboardState keyboardState;
    MidiKeyboardComponent keyboardComponent;
    ...
// PluginEditor.cpp

EightAudioProcessorEditor::EightAudioProcessorEditor (EightAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p), keyboardComponent(keyboardState, MidiKeyboardComponent::horizontalKeyboard)
{
    ...
    addAndMakeVisible(keyboardComponent);
    ...
// PluginProcessor.cpp

void EightAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
    ...
    mSampler.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());

    // Show pressed Midi Input Device Keys on `keyboardComponent`
    ...
}

The MidiKeyboardComponent and MidiKeyboardState are separate, so the state can live in the AudioProcessor and the Component lives in the AudioProcessorEditor.

You simply need to call processNextMidiBuffer (midi) on the state, and a connected MidiKeyboardComponent will show the pressed keys.

You can decide, if events from the screen keyboard shall be added to the MidiBuffer or not by setting a flag.

1 Like

How can I access the keyboardState inside the AudioProcessor ?

Make it a member of the AudioProcessor in the first place. There is no point having a MidiKeyboardState in the editor.

Thanks. I tried that but the keyboardState is mandatory in the Editor:

// PluginEditor.cpp

EightAudioProcessorEditor::EightAudioProcessorEditor (EightAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p), keyboardComponent(**keyboardState**, MidiKeyboardComponent::horizontalKeyboard)
{
    mLoadButton.onClick = [&]() { processor.loadFile(); };
    addAndMakeVisible(mLoadButton);

    mReleaseSlider.onValueChange = [&]() { processor.changeSamplerRelease(); };
    addAndMakeVisible(mReleaseSlider);

    mReleaseAttachment = std::make_unique<AudioProcessorValueTreeState::SliderAttachment>(processor.getAPVTS(), "RELEASE", mReleaseSlider);

    //mMidiData.setText(processor.midi)

    addAndMakeVisible(keyboardComponent);

    setSize (800, 500);
}

You need access to the state, but it doesn’t have to be owned by the editor.

The state is the backend, that is continuously getting midi events. Imagine you hold a key down on your physical keyboard and open then the editor. You would have missed the noteOn event, if the state was defined in the editor.

Make the keyboardState a member of the processor. Either make it public or define an access method returning a reference to the state.
You use that reference to connect your MidiKeyboardComponent in the editor to it.

1 Like

Thank’s a lot!

Solution:

// PluginEditor.h

...
private:
    ...
    MidiKeyboardComponent keyboardComponent;
    ...
// PluginEditor.cpp

EightAudioProcessorEditor::EightAudioProcessorEditor (EightAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p), keyboardComponent(p.keyboardState, MidiKeyboardComponent::horizontalKeyboard)
{
    ...
    addAndMakeVisible(keyboardComponent);
    ...
// PluginProcessor.h

public:
    MidiKeyboardState keyboardState;
// PluginProcessor.cpp

void EightAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
    ...
    mSampler.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
    keyboardState.processNextMidiBuffer(midiMessages, 0, midiMessages.getNumEvents(), false);
    ...
}