Live Performance¶
Real-time MIDI synthesis. See the Live Performance guide for a tutorial.
Note
Live MIDI input requires python-rtmidi — install with
pip install "pytheory[live]".
Ableton Link sync (LiveEngine.enable_link()) requires
LinkPython-extern — install with
pip install "pytheory[link]".
Real-time MIDI-driven synthesis engine.
Listens for MIDI input (e.g. from an OP-XY, keyboard, or DAW) and synthesizes audio in real-time through pytheory’s synth engine.
Usage:
from pytheory.live import LiveEngine
engine = LiveEngine()
engine.channel(1, instrument="electric_piano")
engine.channel(2, instrument="bass_guitar", lowpass=800)
engine.channel(10, drums=True)
engine.start() # blocks until Ctrl-C
Notes are pre-rendered to a 3-second wavetable. Sustaining instruments (organ, pads, strings — any envelope with a nonzero sustain level) loop seamlessly inside the wavetable, so held keys ring for as long as you hold them. Percussive instruments (piano, plucks) decay naturally and end.
Effects (lowpass, reverb, chorus, delay, tremolo, distortion, saturation) run on each channel’s bus in real time, so MIDI CC sweeps are smooth and instant — no wavetable re-rendering.
To play in time with Ableton Live, iOS apps, or anything else that
speaks Ableton Link (requires pip install pytheory[link]):
engine.enable_link()
engine.start()
Tempo, the drum-pattern beat grid, and transport start/stop all sync with the Link session — peer-to-peer, no master.
- class pytheory.live.LiveEngine(buffer_size=512, sample_rate=44100)[source]¶
Bases:
objectReal-time MIDI-to-audio engine.
Maps MIDI channels to pytheory instruments and synthesizes audio in real-time via sounddevice.
Example:
engine = LiveEngine() engine.channel(1, instrument="electric_piano") engine.channel(2, instrument="bass_guitar") engine.channel(10, drums=True) engine.start()
- channel(ch, *, instrument=None, synth=None, envelope=None, drums=False, **kwargs)[source]¶
Configure a MIDI channel.
- Parameters:
ch – MIDI channel number (1-16). Channel 10 = drums by convention.
instrument – Instrument preset name (e.g. “electric_piano”).
synth – Synth waveform name (overrides instrument).
envelope – Envelope name (overrides instrument).
drums – If True, this channel triggers drum sounds by MIDI note.
**kwargs – Any Part parameter (lowpass, reverb, volume, etc.)
- drums(pattern_name, *, volume=0.5)[source]¶
Add a drum pattern that syncs to MIDI clock.
The pattern plays in sync with the OP-XY’s transport - starts on Start, stops on Stop, tempo from MIDI clock.
- Parameters:
pattern_name – Drum pattern preset name (e.g. “rock”, “house”).
volume – Drum volume (0.0-1.0).
- cc(cc_number, param, *, min_val=0.0, max_val=1.0, ch=None)[source]¶
Map a MIDI CC to a channel parameter.
- Parameters:
cc_number – MIDI CC number (0-127).
param – Parameter name (“volume”, “lowpass”, “reverb”, etc.)
min_val – Value when CC = 0.
max_val – Value when CC = 127.
ch – MIDI channel (None = all channels).
Example:
>>> engine.cc(11, "lowpass", min_val=200, max_val=8000) >>> engine.cc(12, "volume", min_val=0.0, max_val=1.0) >>> engine.cc(13, "reverb", min_val=0.0, max_val=0.8) >>> engine.cc(14, "distortion", min_val=0.0, max_val=0.8)
- enable_link(*, quantum=4.0, start_stop_sync=True)[source]¶
Sync with an Ableton Link session on the local network.
Tempo follows the session (and the session follows you — Link is peer-to-peer), the drum pattern locks to the shared beat grid, and transport start/stop syncs with peers that support it (Ableton Live, most iOS apps).
- Parameters:
quantum – Bar length in beats for phase alignment (default 4 — drums land on the same downbeat as everyone else’s bar).
start_stop_sync – Follow Link transport start/stop.
Requires the
linkextra:pip install pytheory[link]
- start(port=None)[source]¶
Start the engine - opens MIDI input and audio output.
- Parameters:
port – MIDI port index or name. None = first available.
Blocks until Ctrl-C or stop() is called.
- keyboard_note(key, on=True)[source]¶
Translate a keyboard key to a MIDI note and play it.
- QWERTY layout: ZSXDCVGBHNJM = C through B (lower octave)
Q2W3ER5T6Y7U = C through B (upper octave)