MIDI channel filter in standalone plugin host

Is there a way to filter out MIDI Channels when using the AudioProcessorPlayer in a way that the plugin only receives messages from MIDI Channel 1 for example?

It’s a common request by iOS users to filter out MIDI channels. This way they can control different instruments with the same MIDI device.

Any ideas welcome.

Would it work to override AudioProcessorPlayer::handleIncomingMidiMessage and use it to filter by midi channel?

Thanks. I will try that.

It already feels like i overwrote the whole juce framework for this standalone app :slight_smile:

I looked at the actual code today, and it looks workable, if you subclass AudioProcessorPlayer and override handleIncomingMidiMessage like this:

void handleIncomingMidiMessage (MidiInput*, const MidiMessage& message) override
{
	if (message.isForChannel (1))
		getMidiMessageCollector().addMessageToQueue (message);
}

Presumably you’d replace the hardcoded “1” with a class member that held the MIDI channel you were screening for.

This may not be applicable to your use case, but I’m working on a multi-MidiChannel arpeggiator/plugin host, and what I do (simplified explanation) is take the incoming MIDI buffer, iterate through it and copy messages for a particular MidiChannel to a copyBuffer, then replace the incoming MIDI buffer with my copy and continue:

            for (const MidiMessageMetadata meta : midiMessages)
            {
                const auto msg = meta.getMessage();
                
                if (msg.isForChannel (midiChannel))
                    copyBuffer.addEvent (msg, meta.samplePosition);
            }
            // replace the incoming MIDI buffer with a copy of this one
            // that only has a certain MIDI channel for passing down the chain
            midiMessages = copyBuffer;
1 Like

Thanks for the additional code. I endet up with something like this:

void handleIncomingMidiMessage (MidiInput * midiInput, const MidiMessage &message) override
{
    if (message.isForChannel (midiChannel))
    {
        AudioProcessorPlayer::handleIncomingMidiMessage(midiInput, message);
    }
}
1 Like

Oh, right, calling the base class method (instead of re-creating it, as I did) is probably easier and more future-proof.