Game Audio Plugin Implementation Guide
Steps apply to both Wwise and FMOD unless noted.
Step 1 — Choose middleware and plugin type
| Middleware | Effect plugin | Source plugin | Mixer plugin |
|---|---|---|---|
| Wwise | IAkInPlaceEffectPlugin or IAkOutOfPlaceEffectPlugin | IAkSourcePlugin | IAkMixerEffectPlugin |
| FMOD | FMOD_DSP_DESCRIPTION (process callback) | FMOD_DSP_DESCRIPTION (generatetone or read) | FMOD_DSP_DESCRIPTION on a bus |
- Effect plugins modify an existing signal in place or out of place.
- Source plugins generate audio from scratch (synthesisers, procedural audio).
- Mixer plugins operate on a mix bus and see the summed signal from all inputs.
- Confirm the plugin type before writing any code — changing it later requires reworking the descriptor and callback signatures.
Step 2 — Set up the plugin descriptor
Wwise:
- Declare an
AkPluginInfostruct with your company ID, plugin ID, and plugin type. - Implement
GetPluginInfo()to return it from your plugin class. - Provide a
CreateXxxfactory function and register it withAK::SoundEngine::RegisterPlugin. - Implement a matching
AkPluginParamBasesubclass for parameter storage.
FMOD:
- Declare an
FMOD_DSP_DESCRIPTIONstruct with name, version, channel counts, and all callback pointers. - Fill
FMOD_DSP_PARAMETER_DESCentries for every parameter the DSP exposes. - Export a
FMODGetDSPDescription()function (or pass the struct directly toFMOD::System::createDSP). - Keep the description in static storage — FMOD holds a pointer to it for the lifetime of the DSP.
Step 3 — Implement the audio callback
Wwise (Execute):
- Read channel count and frame count from
AkAudioBufferat runtime — never hardcode. - Use
io_pBuffer->GetChannel(ch)to access per-channel float pointers. - Allocate during
Initwith theAK::IAkPluginMemAlloc*allocator; never allocate insideExecute. - Return early if
uValidFrames == 0to avoid processing silent tail unnecessarily.
FMOD (read or process):
- Use
inchannelsandoutchannelsfrom the callback signature — do not assume stereo. - Allocate during create/reset with
dsp_state->functions->alloc/free; never allocate insideread/process. - Never block, lock, or perform I/O; FMOD calls this from a mixer thread with a hard deadline.
- Return
FMOD_OKafter producing valid output; returnFMOD_ERR_DSP_SILENCEonly when the DSP intentionally produces silence.
Step 4 — Handle parameters
Wwise RTPC binding:
- Declare parameter IDs as an enum in your plugin header.
- Implement
SetParamon yourAkPluginParamBasesubclass to copy incoming values into your struct. - Wwise copies the parameter struct before calling
Execute— read from the struct, not fromSetParamdirectly. - Clamp every RTPC value to its valid range before feeding it to DSP computation.
FMOD parameter system:
- Define one
FMOD_DSP_PARAMETER_DESCper parameter in yourFMOD_DSP_DESCRIPTION. - Implement
setparameterfloat/getparameterfloatcallbacks to read/write from your plugin state. - Use a fixed enum for parameter indices and keep it in the same order as
paramdesc; do not rely on magic numbers. - Use
FMOD_DSP_PARAMETER_DESCwithFMOD_DSP_PARAMETER_TYPE_FLOATand the appropriate float mapping (LINEAR,AUTO, or piecewise linear) so Studio renders controls correctly.
Step 5 — Register, test, and package
- Wwise: call
AK::SoundEngine::RegisterPluginduring engine init before loading banks; ship a.dll/.soplus a.xmlauthoring descriptor. - FMOD: pass the
FMOD_DSP_DESCRIPTIONtocreateDSPor load vialoadPlugin; ship as.plugin.dll/.so. - Unit-test with known input buffers outside the engine; cover channel counts 1, 2, and 6.
- Test bypass, all-zeros input, and extreme parameter values.
- Guard debug logging behind
#ifndef AK_OPTIMIZED(Wwise) or equivalent release flag (FMOD).