Standalone REPL and MusaLCE Server Suite for MusaDSL
Open Source
LGPL 3.0 License
Standalone REPL + Server Suite
About MusaLCE
MusaLCE is the live coding side of MusaDSL. Where
MusaDSL gives you the tools to compose music algorithmically in Ruby, MusaLCE lets you do
that work live — sending fragments of code from your editor into a running
session, watching the music reshape as you type, without ever stopping the clock.
There are two ways to use it, and they suit very different situations.
The toolkit way
At its core, MusaLCE is a toolkit: a TCP-based REPL server (Musa::REPL,
shipped inside the MusaDSL gem) that you wrap around a Ruby session of your own
making. You set up the sequencer, the clock, the voices and any other inputs and
outputs your piece needs; you start the REPL inside that context; and from that point
on, anything you can talk to from Ruby — in either direction —
becomes part of the session. MIDI hardware (synths you play, controllers
that feed parameters), OSC applications like SuperCollider or Max/MSP, sockets to
custom electronics or mechanical instruments — anything you can wire up. The
price is that you assemble the pieces yourself; the gain is that nothing is
off-limits. This is where the deeper experimentation happens.
The MusaLCE Server Suite
For the most common case — driving Bitwig Studio or Ableton Live from a code
editor — MusaLCE ships the MusaLCE Server Suite, a ready-made
version of that assembly. The musalce-server gem packages the sequencer,
transport, surface and DAW link into a single command; a small DAW connector (one for
Bitwig, one for Live) bridges to your DAW; the VSCode extension is your editor client.
Tracks are exposed by symbolic name, the sequencer locks to the DAW's clock
automatically, and a daw object gives you transport, voices and —
with an elgato Stream Deck — physical surface controls. Internally the suite is
the toolkit pre-wired for you; you skip the assembly step.
Both paths use the same VSCode extension as editor client. The protocol it speaks is
generic, so it works against the toolkit you built yourself just as well as against the
MusaLCE Server Suite.
MusaLCE in detail
The two paths above are sketches. Below, the three building blocks of MusaLCE —
the toolkit, the MusaLCE Server Suite, and the optional Pulso surface — get a
closer look, each illustrated with real Ruby code that makes the APIs concrete.
The toolkit — Musa::REPL
The toolkit is centred on Musa::REPL, a small server that ships inside the
MusaDSL gem.
It listens on TCP port 1327 and waits for the editor to send
Ruby code; when code arrives, it evaluates it in the context you've given the REPL
— the same context where your sequencer, voices and helpers live. Everything that
was running keeps running: the sequencer doesn't pause between evaluations, your scales
and patterns stay in scope, and your puts calls echo back into the editor's
status panel so you can debug while the music plays.
What you build is the frame around the REPL: a sequencer, a clock (timer-based,
locked to an inbound MIDI clock, or driven externally), voices for whatever instruments
you're playing, and the DSL helpers and scales your piece uses. Then you open the REPL
inside the sequencer DSL context, like this:
require'musa-dsl'require'midi-communications'includeMusa::Alloutput=MIDICommunications::Output.gets# or any other destinationclock=Musa::Clock::TimerClock.new(bpm: 120,ticks_per_beat: 24)transport=Musa::Transport::Transport.new(clock,4,24)voices=Musa::MIDIVoices.new(sequencer: transport.sequencer,output: output,channels: [0])transport.sequencer.withdo# Define any helpers, scales, patterns and DSL methods your piece needs…# everything visible here will be reachable from the REPL.Musa::REPL::REPL.new(binding)# opens TCP/1327 in this contextendtransport.start
Connect from VSCode and you have a custom live
coding environment, tuned to whatever you're building.
The MusaLCE Server Suite — musalce-server + DAW connector
The MusaLCE Server Suite takes that same toolkit and pre-builds it
for you — and adds a daw object that gives you direct, named
access to your DAW. You install three components (the musalce-server
gem, a small DAW connector for Bitwig or Live, and the VSCode extension), launch
the server with one command, and the REPL is ready on port 1327. From the editor
you can now talk to your DAW like this:
# Sent from VSCode while the server runs and Bitwig (or Live) is open:# In Live, point the clock-receiving virtual bus:daw.midi_sync('IAC Driver Bus 1')# Tracks by their symbolic name (configured on the DAW connector side):daw.track('Drums').out.note36,duration: 1/4r,velocity: 100# Schedule and loop — the sequencer is already running:at4dodaw.track('Bass').out.note48,duration: 1rendevery1do|i|daw.track('Synth').out.note60+(i%7),duration: 1/8rend# Callbacks that survive Stop/Play (after_stop wipes the sequencer state# by default; on_start/after_stop/before_begin re-install your scaffolding):daw.transport.on_startdoputs'Transport started!'end# Stuck notes? Hit panic — All Notes Off to every track.daw.panic!
Two practical notes specific to each DAW:
On Bitwig (the preferred DAW today), the connector extension can
launch the server for you. A toggle in its preferences (Start Server) spawns
and supervises a child process, so you don't need a separate terminal open. The
extension also forwards Bitwig's MIDI clock to the server (Clock Sender) and
exposes per-project symbolic names for the 16 MIDI channels it manages on each virtual
port. If you need more than 16 named channels, enable a second instance of the
extension and you get another 16.
On Ableton Live, Live's MIDI Remote Script API doesn't expose the
transport directly to the server, so MusaLCE has to send MIDI clock through a virtual
bus (IAC Driver on macOS) that Live then syncs to. The Live connector currently has a
narrower feature set than the Bitwig one — feature parity is on the roadmap.
Optional — Stream Deck control via Pulso
If you have an elgato Stream Deck, Pulso can wire physical buttons
and encoders into your live coding session. Pulso is yeste.studio's
upcoming Stream Deck workflow system for DAWs (Bitwig today; Ableton planned), and
most of what it does has nothing to do with MusaLCE — it controls transport,
track navigation, devices, parameters, the browser. One of Pulso's features is the
MusaLCE Surface protocol, exposed through the Pulso Workflow
plugin: physical buttons and encoders that fire MusaDSL Sequencer
Events in your running score, and that receive their display state (labels,
on/off state, encoder values) back from your code.
Each control is identified by an event name. That same event
is what the sequencer launches when the user touches the control — so you
subscribe to it from your score with on :event do |parameters| … end.
And surface[:event].set … pushes label, state, value and range
back to the physical button or encoder:
# Set up a toggle (rendered with on / off / inactive palettes on the Stream Deck):surface[:launch_chorus].set(message: 'Chorus',enabled: :inactive)on:launch_chorusdo|payload|surface[:launch_chorus].toggle!# … fire your section, swap a pattern, whateverend# Encoder with a range:surface[:cutoff].set(range: 0..127,value: 64,message: 'Cutoff')on:cutoffdo|value|# value is the encoder's current integerend
Three control types live in this protocol: Toggle (on / off /
inactive states), Trigger (momentary press), and
Encoder (integer in a range, like a fader value). The MusaLCE Surface
relay ships in MusaLCEforBitwig today; the Live connector doesn't have it yet, so
Stream Deck integration with MusaLCE is Bitwig-only at the moment. Pulso itself is in
private development and the public release is still pending.
Key features
Across both paths, MusaLCE gives you:
Microsecond-precise sequencer locked to the DAW's MIDI clock (suite) or to any clock source you choose (toolkit).
Hot reload of score code — the sequencer keeps playing while you send fragments from the editor.
daw.* API in the MusaLCE Server Suite — tracks by symbolic name, transport, panic, surface, MIDI sync.
Transport callbacks that survive Stop/Play — on_start, after_stop, before_begin for re-installing schedules and handlers wiped by the default sequencer.reset on stop.
Auto-launch of the server from Bitwig — no terminal needed; one toggle in the extension preferences.
Multi-instance MusaLCEforBitwig — more than 16 named MIDI channels by activating extra extension instances.
Editor-agnostic protocol — VSCode extension on the Marketplace today; any client that speaks the line-based REPL protocol works.
Surface controls via surface[:event] and on :event — physical buttons / encoders integrated with Pulso (Bitwig today).
Licensed under LGPL 3.0.
Main Components
REPL Server
Musa::REPL
The server side of the live coding protocol. Lives inside the musa-dsl
gem (no separate install). TCP on port 1327, line-based protocol, multi-threaded with a
class-level mutex serializing executions. Hooks into the bound sequencer's
on_error to deliver async failures back to the editor.
Visual Studio Code extension acting as the client side of the REPL protocol. Send the
current selection or line with Ctrl+Alt+Enter, toggle the status panel
with Ctrl+Alt+M. Available on the VSCode Marketplace. Works with both
paths (toolkit and suite) — the extension does not know which server is on the other
end.
Atom editor plugin, the original client. Atom itself was sunset by GitHub in December
2022. The plugin is kept in the repository for historical and academic reference. New users
should install the VSCode client.
The Ruby gem that turns Musa::REPL into
a turnkey DAW-aware environment. Pre-builds sequencer + MIDI clock + transport + surface
+ OSC link to the DAW connector, exposes the daw.* object, runs the REPL
on TCP/1327.
The Bitwig connector can auto-launch it from its Start Server preference.
If you prefer you can run it manually as musalce-server bitwig.
With Live connector you should run it manually as musalce-server live.
Controller extension for Bitwig Studio 5+ (Java, Bitwig Extension API 18). Bridges
Bitwig and musalce-server over OSC, can auto-launch the server, exposes
symbolic names for per-port MIDI channels, and includes the
MusaLCESurfaceRelay for Pulso integration.
Ableton Live MIDI Remote Script (Python) for Live 11+. Bridges Live and
musalce-server over OSC. Requires a virtual MIDI bus (IAC Driver on
macOS) for clock sync, because Live's MIDI Remote Script API does not expose transport
directly. Currently offers a narrower feature set than the Bitwig connector — feature
parity is on the roadmap.
Visual Studio Code — the supported editor client (see Editor Clients above).
For the MusaLCE Server Suite path:Bitwig Studio 5+ or Ableton Live 11+; macOS today (auto-launch and IAC bus setup are macOS-specific).
For the toolkit path: whatever Ruby libraries match your target (MIDI, OSC, sockets, custom protocols, …).
For MIDI you can use midi-communications (see musadsl.yeste.studio).
For OSC you can use osc-ruby (see osc-ruby).
Path 1 — Standalone REPL (toolkit)
The toolkit path is shorter to install but longer to set up — most of the work
is in the main.rb you write yourself.
Write your own main.rb with the sequencer, clock, transport, the I/O
your piece needs (MIDI voices, OSC clients, sockets, whatever you target) and any
DSL helpers; then start the REPL inside the sequencer DSL context as shown in
MusaLCE in detail above.
Run ruby main.rb in a terminal. Open the same file in VSCode; code
sent with Ctrl+Alt+Enter lands in the running session.
In Bitwig: Settings → Controllers → + Add Controller → yeste.studio → MusaLCE.
In Settings → Controllers → MusaLCE → Settings → Configuration enable
Osc Host and Clock Sender;
In Server enable Start Server — the extension launches
musalce-server bitwig automatically.
Assign the MIDI input that will act as the clock source.
In Studio I/O Panel → MusaLCE, name each MIDI channel to expose (these
become daw.track('Name').out from the score). Wire each Bitwig track
to receive notes from the corresponding
<PortName>: <ChannelName> input — until programmatic
routing is implemented, this is a manual step.
Open a .rb file in VSCode; code sent with Ctrl+Alt+Enter
lands in the running session.
Ableton Live
On Ableton Live the connector is narrower in scope; the server is launched manually,
and clock reaches Live through a virtual MIDI bus.
In Live: Preferences → Link/Tempo/MIDI → MIDI, set Control
Surface to MusaLCEforLive (leave Input/Output at
"(None)").
Enable an IAC Driver bus in Audio MIDI Setup → MIDI Studio.
In Live's MIDI preferences, enable Sync on that IAC bus input.
Start the server manually in a terminal — the Live connector does not
auto-launch:
musalce-server live
From the score, daw.midi_sync('IAC Driver Bus 1') tells the server
which bus to send clock through. Code sent from VSCode then lands in the running
session.
MusaDSL — Ruby framework for algorithmic sound and musical composition.
MusaLCE — live coding for MusaDSL: a toolkit to build your own Live Coding environment targeting any MIDI/OSC/other destination, or ready-made for Bitwig Studio and Ableton Live.
Nota — Claude Code plugin for AI-assisted MusaDSL composition.
Pulso — elgato Stream Deck control for music DAWs (Bitwig today; Ableton planned), with MusaLCE Surface integration (upcoming).
Author
MusaLCE is created and maintained by
yeste.studio,
exploring the intersection of sound, music, technology, and algorithmic composition.
It is part of the MusaDSL family of projects.