Python API Reference¶
Plugin¶
Load and process audio through VST3, AudioUnit, or LV2 plugins.
Constructor¶
Plugin(
path: str,
sample_rate: float = 48000.0,
max_block_size: int = 512,
in_channels: int = 2,
out_channels: int = 2,
sidechain_channels: int = 0,
)
Properties¶
| Property | Type | Writable | Description |
|---|---|---|---|
num_params |
int |
No | Number of parameters |
num_input_channels |
int |
No | Number of input channels |
num_output_channels |
int |
No | Number of output channels |
latency_samples |
int |
No | Processing latency in samples |
tail_seconds |
float |
No | Reverb/delay tail length in seconds |
sidechain_channels |
int |
No | Configured sidechain channel count |
num_input_buses |
int |
No | Number of input buses |
num_output_buses |
int |
No | Number of output buses |
num_programs |
int |
No | Number of factory presets |
accepts_midi |
bool |
No | Whether plugin accepts MIDI input |
produces_midi |
bool |
No | Whether plugin produces MIDI output |
is_midi_effect |
bool |
No | Whether plugin is a MIDI effect |
supports_mpe |
bool |
No | Whether plugin supports MPE |
supports_double |
bool |
No | Whether plugin supports 64-bit processing |
sample_rate |
float |
Yes | Current sample rate (preserves parameter state on change) |
program |
int |
Yes | Current factory preset index |
bypass |
bool |
Yes | Bypass state |
non_realtime |
bool |
Yes | Non-realtime mode (higher-quality offline algorithms) |
processing_precision |
int |
Yes | MH_PRECISION_SINGLE or MH_PRECISION_DOUBLE |
Audio Processing¶
| Method | Description |
|---|---|
process(input, output) |
Process audio. Arrays shape: (channels, frames), dtype: float32 |
process_midi(input, output, midi_in) |
Process with MIDI. Returns list of output MIDI events |
process_auto(input, output, midi_in, param_changes) |
Process with sample-accurate automation and MIDI |
process_sidechain(main_in, main_out, sidechain_in) |
Process with sidechain input |
process_double(input, output) |
Process with 64-bit double precision. Arrays dtype: float64 |
MIDI events are tuples of (sample_offset, status, data1, data2).
Parameter changes are tuples of (sample_offset, param_index, value).
Parameters¶
| Method | Description |
|---|---|
get_param(index) |
Get normalized value (0.0--1.0) |
set_param(index, value) |
Set normalized value (0.0--1.0) |
get_param_info(index) |
Get metadata dict (name, label, default, num_steps, id, category) |
param_to_text(index, value) |
Convert normalized value to display string (e.g. "2500 Hz") |
param_from_text(index, text) |
Convert display string to normalized value |
begin_param_gesture(index) |
Signal start of parameter change gesture |
end_param_gesture(index) |
Signal end of parameter change gesture |
State Management¶
| Method | Description |
|---|---|
get_state() |
Save full plugin state as bytes |
set_state(data) |
Restore full plugin state from bytes |
get_program_state() |
Save current program state as bytes |
set_program_state(data) |
Restore current program state from bytes |
get_program_name(index) |
Get factory preset name by index |
Transport and Playback¶
| Method | Description |
|---|---|
set_transport(bpm, time_sig_num=4, time_sig_denom=4, position_samples=0, position_beats=0.0, is_playing=True, is_recording=False, is_looping=False, loop_start=0, loop_end=0) |
Set transport info |
clear_transport() |
Clear transport info |
reset() |
Reset internal state (clears delay lines, filter states) |
Bus Layout¶
| Method | Description |
|---|---|
get_bus_info(is_input, bus_index) |
Get bus info dict (name, channels, is_main, is_enabled) |
check_buses_layout(input_channels, output_channels) |
Check if a bus layout is supported |
Change Notifications¶
| Method | Description |
|---|---|
set_change_callback(callback) |
Register callback (change_flags: int) -> None for processor-level changes |
set_param_value_callback(callback) |
Register callback (index: int, value: float) -> None for plugin-initiated value changes |
set_param_gesture_callback(callback) |
Register callback (index: int, is_begin: bool) -> None for gesture begin/end |
Change flag constants: MH_CHANGE_LATENCY, MH_CHANGE_PARAM_INFO, MH_CHANGE_PROGRAM, MH_CHANGE_NON_PARAM_STATE.
Miscellaneous¶
| Method | Description |
|---|---|
set_track_properties(name=None, colour=None) |
Set track name and/or color metadata |
PluginChain¶
Chain multiple plugins for sequential processing.
Constructor¶
All plugins must share the same sample rate.
Properties¶
| Property | Type | Description |
|---|---|---|
num_plugins |
int |
Number of plugins in chain |
latency_samples |
int |
Total chain latency (sum of all plugins) |
num_input_channels |
int |
Input channels (from first plugin) |
num_output_channels |
int |
Output channels (from last plugin) |
sample_rate |
float |
Shared sample rate |
tail_seconds |
float |
Maximum tail length (max of all plugins) |
Methods¶
| Method | Description |
|---|---|
process(input, output) |
Process audio through chain |
process_midi(input, output, midi_events) |
Process with MIDI (MIDI goes to first plugin). Returns output MIDI events |
process_auto(input, output, midi_in, param_changes) |
Process with sample-accurate automation and MIDI |
get_plugin(index) |
Get plugin by index |
reset() |
Reset all plugins |
set_non_realtime(enabled) |
Set non-realtime mode for all plugins |
MIDI events are tuples of (sample_offset, status, data1, data2).
Chain parameter changes are tuples of (sample_offset, plugin_index, param_index, value) -- the extra plugin_index field (0-based) targets a specific plugin in the chain.
AudioDevice¶
Real-time audio device for plugin playback. Supports context manager protocol.
Constructor¶
AudioDevice(
plugin: Plugin | PluginChain,
sample_rate: float = 0.0, # 0 = use system default
buffer_frames: int = 0, # 0 = use system default
output_channels: int = 0, # 0 = use plugin channels
midi_input_port: int = -1, # -1 = no MIDI input
midi_output_port: int = -1, # -1 = no MIDI output
capture: bool = False, # True = duplex mode (system audio input)
)
When capture=True, the audio device opens in duplex mode: system audio input is captured, processed through the plugin, and played back through speakers. Useful for guitar amp sims, vocal effects, and live processing.
Properties¶
| Property | Type | Description |
|---|---|---|
is_playing |
bool |
Whether audio is currently playing |
sample_rate |
float |
Actual device sample rate |
buffer_frames |
int |
Actual buffer size in frames |
channels |
int |
Number of output channels |
midi_input_port |
int |
Connected MIDI input port index (-1 if none) |
midi_output_port |
int |
Connected MIDI output port index (-1 if none) |
is_midi_input_virtual |
bool |
Whether MIDI input is a virtual port |
is_midi_output_virtual |
bool |
Whether MIDI output is a virtual port |
input_available |
int |
Frames available in input ring buffer (0 if not enabled) |
Methods¶
| Method | Description |
|---|---|
start() |
Start audio playback |
stop() |
Stop audio playback |
send_midi(status, data1, data2) |
Send MIDI event programmatically |
connect_midi_input(port_index) |
Connect MIDI input port |
connect_midi_output(port_index) |
Connect MIDI output port |
disconnect_midi_input() |
Disconnect MIDI input |
disconnect_midi_output() |
Disconnect MIDI output |
create_virtual_midi_input(port_name) |
Create virtual MIDI input port |
create_virtual_midi_output(port_name) |
Create virtual MIDI output port |
enable_input(capacity_frames=0) |
Enable ring buffer audio input. capacity_frames=0 uses ~0.5s default |
disable_input() |
Disable ring buffer audio input (revert to silence) |
write_input(data) |
Write numpy array (channels, frames) into input ring buffer. Returns frames written. Thread-safe |
MidiFile¶
MIDI file reader/writer.
Constructor¶
Properties¶
| Property | Type | Writable | Description |
|---|---|---|---|
num_tracks |
int |
No | Number of tracks |
ticks_per_quarter |
int |
Yes | Ticks per quarter note (resolution) |
duration_seconds |
float |
No | Total duration in seconds |
Methods¶
| Method | Description |
|---|---|
load(path) |
Load MIDI file. Returns True on success |
save(path) |
Save MIDI file. Returns True on success |
add_track() |
Add a new track. Returns track index |
add_tempo(track, tick, bpm) |
Add tempo event |
add_note_on(track, tick, channel, pitch, velocity) |
Add note on event |
add_note_off(track, tick, channel, pitch, velocity=0) |
Add note off event |
add_control_change(track, tick, channel, controller, value) |
Add CC event |
add_program_change(track, tick, channel, program) |
Add program change |
add_pitch_bend(track, tick, channel, value) |
Add pitch bend event |
get_events(track) |
Get all events from track as list of dicts |
make_absolute_ticks() |
Convert delta ticks to absolute |
make_delta_ticks() |
Convert absolute ticks to delta |
join_tracks() |
Merge all tracks into one |
split_tracks() |
Split tracks by MIDI channel |
Event Dict Keys¶
Events returned by get_events() have these keys depending on type:
| Key | Types | Description |
|---|---|---|
type |
all | Event type: note_on, note_off, control_change, program_change, pitch_bend, tempo |
tick |
all | Tick position |
seconds |
all | Time in seconds |
channel |
note/CC/program/pitch_bend | MIDI channel (0-15) |
pitch |
note_on, note_off | MIDI note number (0-127) |
velocity |
note_on, note_off | Velocity (0-127) |
controller |
control_change | CC number (0-127) |
value |
control_change, pitch_bend | Value |
program |
program_change | Program number (0-127) |
bpm |
tempo | Tempo in BPM |
MidiIn¶
Standalone MIDI input for monitoring raw MIDI messages without loading a plugin.
Static Methods¶
| Method | Description |
|---|---|
MidiIn.open(port_index, callback) |
Open hardware MIDI input port. Callback receives bytes |
MidiIn.open_virtual(name, callback) |
Create virtual MIDI input port. Callback receives bytes |
Methods¶
| Method | Description |
|---|---|
close() |
Close the MIDI input |
Supports context manager: with MidiIn.open(0, cb) as m: ...
MIDI Rendering¶
Render MIDI files through plugins to produce audio.
Functions¶
render_midi(
plugin: Plugin | PluginChain,
midi_file: MidiFile | str,
block_size: int = 512,
tail_seconds: float | str | None = None,
dtype: type | None = None,
tail_threshold: float = 1e-4,
max_tail_seconds: float = 30.0,
) -> np.ndarray
Render MIDI to numpy array. Returns shape (channels, total_samples).
render_midi_stream(
plugin: Plugin | PluginChain,
midi_file: MidiFile | str,
block_size: int = 512,
tail_seconds: float | str | None = None,
tail_threshold: float = 1e-4,
max_tail_seconds: float = 30.0,
) -> Iterator[np.ndarray]
Generator yielding audio blocks of shape (channels, block_size).
render_midi_to_file(
plugin: Plugin | PluginChain,
midi_file: MidiFile | str,
output_path: str,
block_size: int = 512,
tail_seconds: float | str | None = None,
bit_depth: int = 24,
tail_threshold: float = 1e-4,
max_tail_seconds: float = 30.0,
) -> int
Render MIDI to WAV file. Returns number of samples written.
Auto-tail Detection¶
Pass tail_seconds="auto" to automatically detect when the plugin's output (reverb/delay tail) has decayed below a threshold, instead of using a fixed tail duration:
audio = render_midi(plugin, "song.mid", tail_seconds="auto")
audio = render_midi(plugin, "song.mid", tail_seconds="auto", tail_threshold=1e-2) # -40 dB
tail_threshold: peak amplitude threshold in linear (default:1e-4, ~-80 dB)max_tail_seconds: safety cap (default: 30s)- Rendering stops after 4 consecutive blocks below threshold
MidiRenderer Class¶
MidiRenderer(
plugin: Plugin | PluginChain,
midi_file: MidiFile | str,
block_size: int = 512,
tail_seconds: float | str | None = None,
tail_threshold: float = 1e-4,
max_tail_seconds: float = 30.0,
)
Stateful renderer for fine-grained control. Supports tail_seconds="auto".
| Property | Type | Description |
|---|---|---|
duration_seconds |
float |
Total duration including tail |
midi_duration_seconds |
float |
MIDI content duration (excluding tail) |
total_samples |
int |
Total samples to render |
current_sample |
int |
Current sample position |
current_time |
float |
Current time in seconds |
progress |
float |
Progress fraction (0.0--1.0) |
is_finished |
bool |
Whether rendering is complete |
channels |
int |
Number of output channels |
| Method | Description |
|---|---|
render_block() |
Render next block. Returns ndarray or None if finished |
render_all(dtype=None) |
Render all remaining audio. Returns ndarray |
reset() |
Reset renderer to beginning |
For all rendering functions: tail_seconds=None uses the plugin's reported tail length (clamped to 2s default if 0 or >30s). tail_seconds="auto" enables auto-detection. A numeric value uses that exact duration.
Audio File I/O¶
Read and write audio files via miniaudio.
Functions¶
Read audio file. Returns (data, sample_rate) where data has shape (channels, samples), dtype float32.
Supported formats: WAV, FLAC, MP3, Vorbis.
Write WAV file. Data shape: (channels, samples). Bit depth 16 and 24 write integer PCM; 32 writes IEEE float.
Get file metadata without decoding. Returns dict with keys: channels, sample_rate, frames, duration.
Supported Formats¶
| Format | Read | Write |
|---|---|---|
| WAV | Yes | Yes (16/24/32-bit) |
| FLAC | Yes | Yes (16/24-bit) |
| MP3 | Yes | No |
| Vorbis | Yes | No |
Resampling¶
Resample audio data to a different sample rate. Input/output shape: (channels, frames), dtype float32. Uses miniaudio's linear resampler with 4th-order low-pass anti-aliasing. Returns a copy when rates are equal.
Automation¶
Utilities for parameter automation and CLI parameter parsing.
Functions¶
Find parameter index by name (case-insensitive). Raises ValueError if not found.
Parse CLI --param argument string. Formats: "Name:value", "Name:value:n" (normalized), "Name:TextValue". Returns (param_index, normalized_value).
parse_automation_file(
path: str | Path,
plugin: Plugin,
sample_rate: int,
total_length_samples: int,
block_size: int = 512,
) -> list[tuple[int, int, float]]
Parse JSON automation file into parameter change events compatible with Plugin.process_auto(). Returns sorted list of (sample_offset, param_index, value) tuples.
Automation File Format¶
Keyframe time formats: "1000" (sample offset), "1.5s" (seconds), "50%" (percentage of total length). Linear interpolation between keyframes at block boundaries.
VST3 Presets¶
Parse and load Steinberg .vstpreset files.
VstPreset Class¶
| Attribute | Type | Description |
|---|---|---|
class_id |
str |
Processor component FUID (32-char ASCII) |
component_state |
bytes | None |
Raw processor state (Comp chunk) |
controller_state |
bytes | None |
Raw controller state (Cont chunk) |
Functions¶
Read and parse a .vstpreset file.
Load a .vstpreset file into a plugin via plugin.set_state().
Plugin Discovery¶
Functions¶
Get plugin metadata without full instantiation. Returns dict with plugin info.
Recursively scan a directory for plugins (VST3, AudioUnit). Returns list of plugin info dicts.
MIDI Port Enumeration¶
Functions¶
Get list of available MIDI input ports. Each dict has index and name.
Get list of available MIDI output ports. Each dict has index and name.
Constants¶
| Constant | Description |
|---|---|
MH_CHANGE_LATENCY |
Change flag: plugin latency changed |
MH_CHANGE_PARAM_INFO |
Change flag: parameter info changed |
MH_CHANGE_PROGRAM |
Change flag: current program changed |
MH_CHANGE_NON_PARAM_STATE |
Change flag: non-parameter state changed |
MH_PRECISION_SINGLE |
32-bit float processing |
MH_PRECISION_DOUBLE |
64-bit double processing |