Sequence MIDI messages using a Flask-style interface.
pip install lucier
lucier is built around three core constructs:
Sequencers: objects that broadcast time data viaticks.MidiControllers: objects that send MIDI messages on a given MIDI channel.- MIDI generator functions:
asyncfunctions that subscribe to time from aSequencerand take aMidiControllerandtickas their arguments, triggering MIDI events for the currenttickusing the givenMIDIController.
Here's a basic example of these three constructs working together to play alternating notes on MIDI channels 1 and 2.
from lucier import Sequencer, MidiController, utils
s = Sequencer()
@s.register([MidiController(0)])
async def low_melody(ctrl: MidiController, tick: int):
"""Trigger a .5-second-long C4 note every 50 ticks."""
if utils.every_n_ticks(50, tick):
await ctrl.play_note(60, 60, .5)
@s.register([MidiController(1)])
async def high_melody(ctrl: MidiController, tick: int):
"""Trigger a .5-second-long C5 note every 50 ticks, starting after 25 ticks."""
if utils.every_n_ticks(50, tick, offset=25):
await ctrl.play_note(72, 60, .5)
# Run the sequencer
s.play()