The IPlugMidiEffect example demonstrates how to build a plugin that processes MIDI messages. This example shows a simple MIDI effect with a gain control that passes MIDI through and allows triggering MIDI notes from the UI.
This plugin has a channel configuration of 0-0, meaning no audio inputs or outputs - itβs a pure MIDI effect.
The ProcessMidiMsg method filters which MIDI messages to pass through:
void IPlugMidiEffect::ProcessMidiMsg(const IMidiMsg& msg){ int status = msg.StatusMsg(); switch (status) { case IMidiMsg::kNoteOn: case IMidiMsg::kNoteOff: case IMidiMsg::kPolyAftertouch: case IMidiMsg::kControlChange: case IMidiMsg::kProgramChange: case IMidiMsg::kChannelAftertouch: case IMidiMsg::kPitchWheel: { goto handle; } default: return; }handle: SendMidiMsg(msg);}
Only channel voice messages are passed through. System messages and other MIDI data are filtered out.
MIDI effects may need to declare a tail time for proper plugin behavior:
#if IPLUG_DSP SetTailSize(4410000); // Large tail to keep plugin alive#endif
Setting a very large tail size (like 4410000 samples = ~100 seconds at 44.1kHz) keeps the plugin processing even when no audio is present. This is important for MIDI effects that need to respond to incoming MIDI.
void ProcessMidiMsg(const IMidiMsg& msg){ int status = msg.StatusMsg(); // Note On, Note Off, etc. int noteNumber = msg.NoteNumber(); // 0-127 int velocity = msg.Velocity(); // 0-127 int channel = msg.Channel(); // 0-15 int offset = msg.mOffset; // Sample offset in block}