Overview
The IPlugProcessor class is the base class for audio processing in iPlug2. It handles audio buffers, MIDI messages, channel I/O configurations, sample rate, block size, and transport information. This class knows nothing about parameters, presets, or user interface.
Header: IPlug/IPlugProcessor.h
Methods marked as “realtime-safe” must not perform allocations, file I/O, or blocking operations. They are called on the high-priority audio thread.
Constructor & Destructor
IPlugProcessor
IPlugProcessor ( const Config & config, EAPI plugAPI);
Constructs the processor with plugin configuration.
Plugin configuration struct from config.h
Plugin API type (VST2, VST3, AU, etc.)
~IPlugProcessor
virtual ~ IPlugProcessor ();
Virtual destructor for cleanup.
Core Processing Methods
Override these methods in your plugin class. Do NOT call them directly.
ProcessBlock
virtual void ProcessBlock ( sample ** inputs , sample ** outputs , int nFrames );
Main audio processing method. Override this to implement your DSP.
Two-dimensional array of non-interleaved input buffers. All channels are guaranteed valid pointers (unconnected channels contain zeros).
Two-dimensional array of non-interleaved output buffers for writing processed audio.
Block size: number of samples per channel in this processing block.
REALTIME-SAFE CONTEXT : Do not allocate memory, perform file I/O, or use blocking operations in ProcessBlock.
// Example: Simple gain plugin
void MyPlugin :: ProcessBlock ( sample ** inputs , sample ** outputs , int nFrames )
{
const int nChans = NOutChansConnected ();
const double gain = GetParam (kGain)-> DBToAmp ();
for ( int s = 0 ; s < nFrames; s ++ )
{
for ( int c = 0 ; c < nChans; c ++ )
{
outputs [c][s] = inputs [c][s] * gain;
}
}
}
ProcessMidiMsg
virtual void ProcessMidiMsg ( const IMidiMsg & msg );
Handle incoming MIDI messages. Called before ProcessBlock().
MIDI message with timestamp (mOffset) indicating sample offset in the upcoming block
REALTIME-SAFE CONTEXT : Use IMidiQueue to queue messages for processing at the correct sample offset.
// Example: Queue MIDI messages
void MyPlugin :: ProcessMidiMsg ( const IMidiMsg & msg )
{
mMidiQueue . Add (msg);
}
void MyPlugin :: ProcessBlock ( sample ** inputs , sample ** outputs , int nFrames )
{
for ( int s = 0 ; s < nFrames; s ++ )
{
// Process queued MIDI at the correct sample offset
while ( ! mMidiQueue . Empty ())
{
IMidiMsg & msg = mMidiQueue . Peek ();
if ( msg . mOffset > s) break ;
// Handle the MIDI message
if ( msg . StatusMsg () == IMidiMsg ::kNoteOn)
{
int note = msg . NoteNumber ();
int velocity = msg . Velocity ();
mSynth . NoteOn (note, velocity);
}
mMidiQueue . Remove ();
}
// Process audio...
}
mMidiQueue . Flush (nFrames);
}
ProcessSysEx
virtual void ProcessSysEx ( const ISysEx & msg );
Handle incoming MIDI System Exclusive messages. Called before ProcessBlock().
SysEx message containing offset, size, and data pointer
REALTIME-SAFE CONTEXT : Default implementation does nothing.
OnReset
Called when sample rate changes or transport resets. Use this to clear buffers, update DSP coefficients, etc.
void MyPlugin :: OnReset ()
{
mFilter . SetSampleRate ( GetSampleRate ());
mDelay . Clear ();
mMidiQueue . Resize ( GetBlockSize ());
}
OnActivate
virtual void OnActivate ( bool active );
Called when the plugin is activated/deactivated by the host.
true if plugin is being activated, false if deactivated
Unlike OnReset(), OnActivate() is called when I/O connections change. Different hosts have different interpretations of “activate”.
MIDI Output Methods
SendMidiMsg
virtual bool SendMidiMsg ( const IMidiMsg & msg ) = 0 ;
Send a single MIDI message to the host.
// Example: Send a note on message
IMidiMsg msg;
msg . MakeNoteOnMsg ( 60 , 100 , 0 ); // Middle C, velocity 100, offset 0
SendMidiMsg (msg);
SendMidiMsgs
virtual bool SendMidiMsgs ( WDL_TypedBuf < IMidiMsg > & msgs );
Send multiple MIDI messages.
msgs
WDL_TypedBuf<IMidiMsg>&
required
Buffer of MIDI messages to send
SendSysEx
virtual bool SendSysEx ( const ISysEx & msg );
Send a MIDI System Exclusive message.
true if successful (default implementation returns false)
Audio Context Information
GetSampleRate
double GetSampleRate () const ;
Returns the current sample rate in Hz.
GetBlockSize
int GetBlockSize () const ;
Returns the maximum block size in samples. Actual block size may vary per ProcessBlock() call.
GetLatency
Returns the plugin latency in samples.
SetLatency
virtual void SetLatency ( int latency );
Call this to update plugin latency at runtime.
Not all hosts support dynamic latency changes. Call from OnReset() if latency depends on sample rate.
GetTailSize
Returns the tail size in samples (for reverb, delay, etc.).
GetTailIsInfinite
bool GetTailIsInfinite () const ;
Returns true if the tail size is infinite.
SetTailSize
virtual void SetTailSize ( int tailSize );
Update the tail size at runtime.
New tail size in samples, or kTailInfinite for infinite tail
// Example: Update tail based on reverb decay time
void MyPlugin :: OnParamChange ( int paramIdx )
{
if (paramIdx == kDecayTime)
{
double decaySeconds = GetParam (kDecayTime)-> Value ();
int tailSamples = static_cast < int > (decaySeconds * GetSampleRate ());
SetTailSize (tailSamples);
}
}
TailSize Enum
enum TailSize
{
kTailNone = 0 ,
kTailInfinite = std :: numeric_limits < int >:: max ()
};
GetBypassed
bool GetBypassed () const ;
Returns true if the plugin is currently bypassed.
GetRenderingOffline
bool GetRenderingOffline () const ;
Returns true if rendering offline (e.g., bouncing/freezing).
GetSamplePos
double GetSamplePos () const ;
Returns the number of samples elapsed since the start of the project timeline.
GetTempo
Returns the current tempo in beats per minute (BPM).
GetPPQPos
double GetPPQPos () const ;
Returns the number of beats elapsed since the start of the project (Pulse Per Quarter note position).
GetTransportIsRunning
bool GetTransportIsRunning () const ;
Returns true if the transport is currently playing.
GetSamplesPerBeat
double GetSamplesPerBeat () const ;
Calculates the number of samples in one beat at the current tempo and sample rate.
GetTimeSig
void GetTimeSig ( int& numerator , int& denominator ) const ;
Get the current time signature.
Output: numerator (e.g., 6 in 6/8)
Output: denominator (e.g., 8 in 6/8)
// Example: Tempo-synced LFO
void MyPlugin :: ProcessBlock ( sample ** inputs , sample ** outputs , int nFrames )
{
const double samplesPerBeat = GetSamplesPerBeat ();
const double lfoFreqHz = ( 1.0 / samplesPerBeat) * 4.0 ; // 1/4 note rate
mLFO . SetFrequency (lfoFreqHz, GetSampleRate ());
// Process audio...
}
Channel I/O Configuration
MaxNChannels
int MaxNChannels ( ERoute direction ) const ;
Returns the total number of channel buffers (input or output).
ERoute::kInput or ERoute::kOutput
NChannelsConnected
int NChannelsConnected ( ERoute direction ) const ;
Returns the number of connected channels.
ERoute::kInput or ERoute::kOutput
Assumes consecutive channel connections. Not all hosts guarantee this.
NInChansConnected
inline int NInChansConnected () const ;
Convenience method: returns the number of connected input channels.
NOutChansConnected
inline int NOutChansConnected () const ;
Convenience method: returns the number of connected output channels.
IsChannelConnected
bool IsChannelConnected ( ERoute direction , int chIdx ) const ;
Check if a specific channel is connected.
Input or output direction
LegalIO
bool LegalIO ( int NInputChans , int NOutputChans ) const ;
Check if a channel configuration is valid based on the I/O config string.
Number of input channels (-1 to check outputs only)
Number of output channels (-1 to check inputs only)
SetChannelLabel
void SetChannelLabel ( ERoute direction , int idx , const char* formatStr , bool zeroBased = false );
Label input/output channels (VST2 only).
Input or output direction
Printf-style format string where %i is the channel index
If true, index in format string is zero-based
// Example: Label ambisonic channels
SetChannelLabel ( ERoute ::kInput, 0 , "W" );
SetChannelLabel ( ERoute ::kInput, 1 , "X" );
SetChannelLabel ( ERoute ::kInput, 2 , "Y" );
SetChannelLabel ( ERoute ::kInput, 3 , "Z" );
Bus Configuration
MaxNBuses Get maximum number of buses int MaxNBuses ( ERoute direction , int* pConfigIdxWithTheMostBuses = nullptr ) const ;
MaxNChannelsForBus Get max channels for a specific bus int MaxNChannelsForBus ( ERoute direction , int busIdx ) const ;
HasWildcardBus Check if config has wildcard buses bool HasWildcardBus ( ERoute direction ) const ;
GetBusName Get name for a bus virtual void GetBusName ( ERoute direction , int busIdx , int nBuses , WDL_String & str ) const ;
NIOConfigs
Returns the number of I/O configurations parsed from the channel I/O string.
GetIOConfig
const IOConfig * GetIOConfig ( int idx ) const ;
Get a pointer to an IOConfig at a specific index.
Pointer to IOConfig, or nullptr if index is invalid
bool HasSidechainInput () const ;
Returns true if the plugin has a sidechain input (more than 1 input bus).
IsInstrument
bool IsInstrument () const ;
Returns true if configured as an instrument.
IsMidiEffect
bool IsMidiEffect () const ;
Returns true if configured as a MIDI effect.
DoesMIDIIn
Returns true if the plugin receives MIDI input.
DoesMIDIOut
bool DoesMIDIOut () const ;
Returns true if the plugin produces MIDI output.
DoesMPE
Returns true if the plugin supports MIDI Polyphonic Expression.
GetAUPluginType
int GetAUPluginType () const ;
Returns the 4-char identifier for AudioUnit type (e.g., ‘aufx’ for effect).
Static Utilities
ParseChannelIOStr
static int ParseChannelIOStr ( const char* IOStr ,
WDL_PtrList < IOConfig > & channelIOList ,
int& totalNInChans ,
int& totalNOutChans ,
int& totalNInBuses ,
int& totalNOutBuses );
Parse the channel I/O configuration string from config.h.
Space-separated I/O configs in format “ninchans-noutchans”. Use . for multiple buses (e.g., “1.1-1” for mono in + mono sidechain → mono out)
channelIOList
WDL_PtrList<IOConfig>&
required
Output: list of parsed IOConfig structs
Output: total input channels across all buses
Output: total output channels across all buses
Output: total number of input buses
Output: total number of output buses
Number of configurations detected
Example: Complete Processor Implementation
class MySynth : public iplug :: Plugin
{
public:
MySynth ( const iplug :: InstanceInfo & info )
: Plugin (info, MakeConfig (kNumParams, kNumPresets))
{
// Initialize parameters...
}
void OnReset () override
{
// Update DSP for new sample rate
mOscillator . SetSampleRate ( GetSampleRate ());
mFilter . SetSampleRate ( GetSampleRate ());
// Resize MIDI queue for new block size
mMidiQueue . Resize ( GetBlockSize ());
// Clear delay lines
mEnvelope . Reset ();
}
void ProcessMidiMsg ( const IMidiMsg & msg ) override
{
// Queue all MIDI messages
mMidiQueue . Add (msg);
}
void ProcessBlock ( sample ** inputs , sample ** outputs , int nFrames ) override
{
const int nChans = NOutChansConnected ();
for ( int s = 0 ; s < nFrames; s ++ )
{
// Process MIDI at correct sample offset
while ( ! mMidiQueue . Empty ())
{
IMidiMsg & msg = mMidiQueue . Peek ();
if ( msg . mOffset > s) break ;
switch ( msg . StatusMsg ())
{
case IMidiMsg ::kNoteOn:
if ( msg . Velocity () > 0 )
{
mOscillator . SetFrequency ( 440.0 * pow ( 2.0 , ( msg . NoteNumber () - 69 ) / 12.0 ));
mEnvelope . Trigger ();
}
else
{
mEnvelope . Release ();
}
break ;
case IMidiMsg ::kNoteOff:
mEnvelope . Release ();
break ;
case IMidiMsg ::kPitchWheel:
mOscillator . SetPitchBend ( msg . PitchWheel ());
break ;
}
mMidiQueue . Remove ();
}
// Generate audio
sample output = mOscillator . Process ();
output = mFilter . Process (output);
output *= mEnvelope . Process ();
// Write to all output channels
for ( int c = 0 ; c < nChans; c ++ )
{
outputs [c][s] = output;
}
}
mMidiQueue . Flush (nFrames);
}
private:
IMidiQueue mMidiQueue;
Oscillator mOscillator;
Filter mFilter;
Envelope mEnvelope;
};
See Also