musalce-server 0.5.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 362aa81c7054d8726ba7f2c76c7a6053235872dd5a01e996ad81ff4356a329af
4
- data.tar.gz: 20c096e30e76eeadecd875ac6eed534ce299a99644150a04f5a3aed1a5592855
3
+ metadata.gz: f29e5cc377ccb9096005b401ae7a65f434d4d2f7793771f2c0cdf8672d649e0f
4
+ data.tar.gz: 3580f96bdbec2b71115b3017e415cfa0cb9dea5a9edb035d86861732a6cd7e65
5
5
  SHA512:
6
- metadata.gz: 7f495fb6fef34ed22b950b0ff4cbef22212b8a4112f23781df2856b760b011110be40bb26e5ba650867af201d5645bc0460985593fbfe78bbcbc61cc501294d5
7
- data.tar.gz: c93cda068c6a8f58797d7b2348c83dbfb2b819c2d0664f16c998ce9870dfe283fb785dbb6881fafcffaab3f0689bb60b6036558cb28389041b20e5f392d8dc6b
6
+ metadata.gz: '01695aeb27c2c3731c474c8a2c610a6d9f7957e203d7dc38b09063aaebb2f899e211fb090c7674619bd7e195ff11c8acae788208bb313603d5907dbd82a9cecd'
7
+ data.tar.gz: 0ee19cbbc2347b90dcf811362e2c01b76eda7a2824ecc35116ab3be09a465f6f9328262fb6b9648a27d914a080115bc298ae446bdb27c0fea9d9622ed6f983ba
@@ -0,0 +1,17 @@
1
+ name: Notify Plugin Rebuild
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ jobs:
8
+ notify:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Trigger nota-plugin-for-claude rebuild
12
+ uses: peter-evans/repository-dispatch@v3
13
+ with:
14
+ token: ${{ secrets.PLUGIN_REBUILD_PAT }}
15
+ repository: javier-sy/nota-plugin-for-claude
16
+ event-type: source-updated
17
+ client-payload: '{"repo": "${{ github.repository }}", "sha": "${{ github.sha }}"}'
data/.gitignore CHANGED
@@ -6,5 +6,8 @@
6
6
  .ruby-gemset
7
7
  .ruby-version
8
8
  Gemfile.lock
9
+ doc/
10
+ .yardoc/
11
+
9
12
 
10
13
 
data/.version ADDED
@@ -0,0 +1,6 @@
1
+ # Configuración de versión para musalce-server
2
+ GEM_NAME="musalce-server"
3
+ MODULE_NAME="MusaLCEServer"
4
+ VERSION_FILE="lib/version.rb"
5
+ GEMSPEC_FILE="musalce-server.gemspec"
6
+ TEST_COMMAND="bundle exec rspec"
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --markup markdown
2
+ --title "MusaLCE Server API"
3
+ --readme README.md
4
+ --no-private
5
+ --embed-mixins
6
+ lib/**/*.rb
data/README.md CHANGED
@@ -1,17 +1,314 @@
1
- # Musa Live Coding Environment (Server for Ableton Live and Bitwig)
1
+ # MusaLCE Server Suite
2
2
 
3
- Musa-DSL Live Coding Environment for Ableton Live and Bitwig Studio (Server part)
3
+ [![Ruby Version](https://img.shields.io/badge/ruby-2.7+-red.svg)](https://www.ruby-lang.org/)
4
+ [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html)
4
5
 
5
- **TODO: complete README**
6
+ **Musa-DSL Live Coding Environment Server Suite for Ableton Live 11+ and Bitwig Studio 5+**
6
7
 
7
- ## Install
8
- **TODO**
8
+ This server enables live coding music composition using [Musa-DSL](https://github.com/javier-sy/musa-dsl) with your favorite DAW and code editor.
9
9
 
10
- ## Usage
11
- **TODO**
10
+ ## Overview
12
11
 
13
- ## Documentation
14
- **TODO**
12
+ The MusaLCE Server Suite system allows you to write Ruby code in your editor (Visual Studio Code) and have it executed in real-time, sending MIDI to tracks in your DAW. The typical workflow is:
13
+
14
+ 1. Start the MusaLCE Server Suite with/inside your DAW choice (Bitwig Studio or Ableton Live)
15
+ 2. Open your VS Code editor with the MusaLCE extension (MusaLCEforVSCode)
16
+ 3. Write and execute Musa-DSL code interactively
17
+ 4. The code controls MIDI instruments and transport in your DAW
18
+
19
+ ## Requirements
20
+
21
+ - Ruby 2.7+
22
+ - [Musa-DSL](https://github.com/javier-sy/musa-dsl) (installed automatically as dependency)
23
+ - A supported DAW with its controller extension:
24
+ - **Bitwig Studio 5+** with [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig) Controller Extension
25
+ - **Ableton Live 11+** with [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) MIDI Remote Script
26
+ - A code editor with MusaLCE client extension:
27
+ - **Visual Studio Code** (recommended) with [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)
28
+ - Atom with [MusaLCE Client for Atom](https://github.com/javier-sy/MusaLCEClientForAtom) (not recommended because Atom is discontinued)
29
+
30
+ ## Installation
31
+
32
+ If you're using Bundler, add this line to your application's Gemfile:
33
+
34
+ ```ruby
35
+ gem 'musalce-server'
36
+ ```
37
+
38
+ Otherwise:
39
+
40
+ ```bash
41
+ gem install musalce-server
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ 1. **Install the DAW controller extension** for your DAW (for Bitwig: [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig), for Ableton Live: [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive))
47
+ 2. **Install the VSCode extension** [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)
48
+ 3. **Start your DAW** and ensure the MusaLCE controller is loaded and configured
49
+ 4. **Start the server** (see below)
50
+ 5. **Open VSCode** and create a `.rb` file
51
+ 6. **Execute code** using the MusaLCE extension commands (Ctrl+Alt+Return, Ctrl+Alt+M)
52
+
53
+ ## Starting the Server
54
+
55
+ The `musalce-server` command starts the live coding server:
56
+
57
+ ```bash
58
+ musalce-server <daw>
59
+ ```
60
+
61
+ Where `<daw>` is one of:
62
+ - `bitwig` - for Bitwig Studio
63
+ - `live` - for Ableton Live
64
+
65
+ Examples:
66
+
67
+ ```bash
68
+ musalce-server bitwig # Start server for Bitwig Studio
69
+ musalce-server live # Start server for Ableton Live
70
+ ```
71
+
72
+ The server runs in the foreground and logs activity to the console. Use `Ctrl+C` or the `shutdown` command from the editor to stop it.
73
+
74
+ ## Running Environment
75
+
76
+ A complete MusaLCE Server Suite live coding session requires **three components running simultaneously**:
77
+
78
+ 1. **Code Editor** (Visual Studio Code with MusaLCE extension)
79
+ - Where you write and execute Ruby/Musa-DSL code
80
+ - Connects to musalce-server via TCP port 1327
81
+
82
+ 2. **MusaLCE Server** (`musalce-server` command)
83
+ - Receives code from the editor and executes it
84
+ - Communicates with the DAW via OSC
85
+ - Manages MIDI routing and the Musa-DSL sequencer
86
+
87
+ 3. **DAW** (Bitwig Studio or Ableton Live)
88
+ - With the corresponding MusaLCE controller extension loaded
89
+ - Receives transport and sync commands from the server
90
+ - Routes MIDI from the server to instruments/tracks
91
+
92
+ ## Architecture
93
+
94
+ The MusaLCE system connects three components:
95
+
96
+ ```
97
+ ┌─────────────────────┐ TCP ┌─────────────────────┐
98
+ │ Code Editor │◄──────────────────►│ MusaLCE Server │
99
+ │ (VSCode + Plugin) │ port 1327 │ (Ruby + REPL) │
100
+ └─────────────────────┘ └─────────────────────┘
101
+ │ ▲
102
+ OSC │ │ OSC
103
+ port 10001 │ │ port 11011
104
+ ▼ │
105
+ ┌─────────────────────┐
106
+ │ DAW Controller │
107
+ │ Extension │
108
+ │ (Bitwig or Live) │
109
+ └─────────────────────┘
110
+
111
+ │ MIDI
112
+
113
+ ┌─────────────────────┐
114
+ │ DAW Tracks & │
115
+ │ Instruments │
116
+ └─────────────────────┘
117
+ ```
118
+
119
+ ### Communication Ports
120
+
121
+ | Port | Protocol | Direction | Purpose |
122
+ |------|----------|-----------|---------|
123
+ | 1327 | TCP | Editor ↔ Server | REPL code execution |
124
+ | 10001 | OSC/UDP | Server → DAW | Transport commands, sync requests |
125
+ | 11011 | OSC/UDP | DAW → Server | Track info, controller registration |
126
+
127
+ ## REPL Commands Reference
128
+
129
+ The following commands are available in the REPL context (executed from your editor):
130
+
131
+ ### DAW Access
132
+
133
+ ```ruby
134
+ daw # Access the DAW controller object
135
+ daw.sequencer # Access the Musa-DSL sequencer
136
+ daw.clock # Access the Musa-DSL MIDI clock
137
+ daw.transport # Access the Musa-DSL transport
138
+ daw.tracks # Access all tracks on the daw by name
139
+ daw.surface # Access the control surface (currently elgato Stream Deck)
140
+ ```
141
+
142
+ #### Persistent actions across DAW Stop/Play
143
+
144
+ Every DAW Stop wipes the sequencer (`at`, `every`, `play`, `on :event`
145
+ handlers are all cleared by the built-in `transport.after_stop { sequencer.reset }`).
146
+ Top-level Ruby state (methods, modules, constants) survives, but
147
+ anything you scheduled or subscribed to via the sequencer DSL does
148
+ not. To re-install those on every Play, register an `on_start`
149
+ callback on the transport:
150
+
151
+ ```ruby
152
+ daw.transport.on_start do
153
+ load 'persistent_actions.rb' # rehydrate on :event, every, at, …
154
+ end
155
+ ```
156
+
157
+ `on_start` callbacks accumulate (they're an append-only list), so you
158
+ can register more from the REPL at any time. They run on every Start,
159
+ after the built-in `before_begin`. Use `before_begin` instead if you
160
+ want a callback that runs **only on the very first Start** of the
161
+ session.
162
+
163
+
164
+ ### Track Operations
165
+
166
+ ```ruby
167
+ # Get a track by name
168
+ bass = daw.track('Bass')
169
+
170
+ # Get all tracks with a name (Live only, can have duplicates)
171
+ drums = daw.track('Drums', all: true)
172
+
173
+ # Send MIDI to a track
174
+ bass.out.note(60, velocity: 100, duration: 1)
175
+ bass.out.note_on(60, 100)
176
+ bass.out.note_off(60)
177
+ bass.out.control_change(1, 64)
178
+ bass.out.program_change(5)
179
+ bass.out.all_notes_off
180
+ ```
181
+
182
+ ### Transport Controls
183
+
184
+ Transport controls send commands to the DAW. **Only available for Bitwig Studio** (Live's controller doesn't support transport control by now).
185
+
186
+ ```ruby
187
+ daw.play # Start playback
188
+ daw.stop # Stop playback
189
+ daw.continue # Continue from current position
190
+ daw.goto(5) # Go to bar 5
191
+ daw.record # Start recording
192
+ ```
193
+
194
+ ### Sequencer (Musa-DSL)
195
+
196
+ All [Musa-DSL](https://github.com/javier-sy/musa-dsl) sequencer methods are available:
197
+
198
+ ```ruby
199
+ # Schedule events at specific positions
200
+ at 1 do
201
+ bass.out.note(48, velocity: 80, duration: 0.5)
202
+ end
203
+
204
+ # Wait relative to current position
205
+ wait 2 do
206
+ bass.out.note(52, velocity: 80, duration: 0.5)
207
+ end
208
+
209
+ # Schedule repeating patterns (returns EveryControl)
210
+ pattern = every 4 do
211
+ drums.out.note(36, velocity: 100, duration: 0.25)
212
+ end
213
+
214
+ # Play a series (returns PlayControl)
215
+ serie = S(60, 62, 64, 65, 67)
216
+ melody = play serie do |note|
217
+ bass.out.note(note, velocity: 80, duration: 1)
218
+ end
219
+
220
+ # Animate values over time (returns MoveControl)
221
+ sweep = move from: 0, to: 127, duration: 4 do |value|
222
+ bass.out.control_change(1, value.to_i)
223
+ end
224
+ ```
225
+
226
+ ### Controlling Playback
227
+
228
+ The `play`, `every`, and `move` methods return control objects that allow you to stop, pause, and monitor playback:
229
+
230
+ ```ruby
231
+ # Stop a pattern or playback
232
+ pattern.stop
233
+ melody.stop
234
+
235
+ # Check status
236
+ pattern.stopped? # true if stopped
237
+ melody.paused? # true if paused
238
+
239
+ # Pause and continue (for play)
240
+ melody.pause
241
+ melody.continue
242
+
243
+ # Callback when stopped
244
+ pattern.on_stop do
245
+ puts "Pattern stopped"
246
+ end
247
+
248
+ # Callback after play completes
249
+ melody.after(2) do
250
+ puts "2 bars after melody finished"
251
+ end
252
+ ```
253
+
254
+ ### Utility Commands
255
+
256
+ ```ruby
257
+ reload # Reload DAW controller extension
258
+ daw.sync # Re-synchronize track information
259
+ daw.panic! # Send All Notes Off to all tracks
260
+ shutdown # Stop the server
261
+ ```
262
+
263
+ ### File Require
264
+
265
+ ```ruby
266
+ # Require files relative to your editor's current file
267
+ require_relative 'my_patterns'
268
+ ```
269
+
270
+ ### Module Import
271
+
272
+ ```ruby
273
+ # Import additional modules into the REPL context
274
+ import(MyHelperModule)
275
+ ```
276
+
277
+ ## DAW-Specific Notes
278
+
279
+ ### Bitwig Studio
280
+
281
+ Requires [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig) controller extension.
282
+
283
+ - Full transport control support (play, stop, continue, goto, record)
284
+ - Track names must be unique
285
+ - MIDI clock sync from any controller marked as clock source
286
+ - Controllers and channels should be configured in the Bitwig extension
287
+
288
+ ### Ableton Live
289
+
290
+ Requires [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) MIDI Remote Script.
291
+
292
+ - **No transport control** by now
293
+ - Multiple tracks can have the same name
294
+ - Use `daw.midi_sync('MIDI Device Name')` to set MIDI clock source
295
+ - Track routing configured in Live's preferences
296
+
297
+ ```ruby
298
+ # Set MIDI clock source for Live
299
+ daw.midi_sync('IAC Driver Bus 1')
300
+ ```
301
+
302
+ ## Related Projects
303
+
304
+ | Component | Description |
305
+ | --- | --- |
306
+ | [Musa-DSL](https://github.com/javier-sy/musa-dsl) | Core music composition DSL |
307
+ | [MusaLCE Server](https://github.com/javier-sy/musalce-server) | Live coding server (this gem) |
308
+ | [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig) | Bitwig Studio controller extension |
309
+ | [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) | Ableton Live MIDI Remote Script |
310
+ | [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) | VSCode extension |
311
+ | [MusaLCE Client for Atom](https://github.com/javier-sy/MusaLCEClientForAtom) | Atom plugin (discontinued) |
15
312
 
16
313
  ## Author
17
314
 
@@ -19,4 +316,4 @@ Musa-DSL Live Coding Environment for Ableton Live and Bitwig Studio (Server part
19
316
 
20
317
  ## License
21
318
 
22
- [MusaLCE-Server](https://github.com/javier-sy/MusaLCE-Server) Copyright (c) 2021-2023 [Javier Sánchez Yeste](https://yeste.studio), licensed under GPL 3.0 License
319
+ [MusaLCE Server](https://github.com/javier-sy/musalce-server) Copyright (c) 2021-2026 [Javier Sánchez Yeste](https://yeste.studio), licensed under GPL 3.0 License
@@ -0,0 +1,178 @@
1
+ # MusaLCE Server Suite Architecture
2
+
3
+ This document is the canonical reference for the **musalce-server suite** — running [musalce-server](https://github.com/javier-sy/musalce-server) together with the per-DAW extension to drive Bitwig Studio ([MusaLCEforBitwig](https://github.com/javier-sy/MusaLCEforBitwig)) or Ableton Live ([MusaLCEforLive](https://github.com/javier-sy/MusaLCEforLive)) from a code editor (VSCode + [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)) in real time, optionally with **elgato Stream Deck** integration via **Pulso** — [yeste.studio](https://yeste.studio)'s upcoming Stream Deck workflow system for DAWs.
4
+
5
+ It is a companion to (not a replacement for) the lower-level [musa-dsl REPL component](https://github.com/javier-sy/musa-dsl/blob/master/docs/subsystems/repl.md), which covers the **standalone REPL** workflow. The **musalce-server suite** documented here is **a specialization** of that case — `musalce-server` opens `Musa::REPL::REPL.new(binding)` after pre-building the sequencer, clock, transport, DAW handler and surface, so you don't have to. It also adds the connection to the DAW (Bitwig or Ableton Live) through **MusaLCEforBitwig**/**MusaLCEforLive** and exposes a `daw.*` object to access and to control the DAW from your editor.
6
+
7
+ ## When to use this (vs the standalone REPL)
8
+
9
+ | Use this (suite) | Use the standalone REPL |
10
+ |---|---|
11
+ | Target is Bitwig Studio or Ableton Live | Target is SuperCollider, Max/MSP, OSC apps, custom hardware |
12
+ | You want `daw.*`, `surface[:event]` and DAW transport out of the box | You want full control over the wiring |
13
+ | You want a Stream Deck wired into your score via Pulso's MusaLCE Surface integration (Bitwig only today) | You're prototyping a personal live-coding DSL |
14
+ | Worked example: `_demo-13b-live-coding-suite` (planned) | Worked example: [`_demo-13-live-coding`](https://github.com/javier-sy/musadsl-demo) |
15
+
16
+ Both workflows use VS Code as editor and the same [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) editor extension. The editor extension connects to the server via TCP socket on port 1327.
17
+
18
+ ## The big picture
19
+
20
+ ```
21
+ ┌────────────────────────────┐
22
+ │ Stream Deck plugin │
23
+ │ (Pulso Workflow .sdPlugin) │
24
+ └────────────────────────────┘
25
+ ^
26
+ │ OSC over UDP (Pulso wire)
27
+
28
+ ┌────────────────────┐ TCP 1327 ┌──────────────────┐ ┌─────────────────────────┐ ┌──────────────────┐
29
+ │ VSCode + │ ◀──────────▶ │ musalce-server │ ◀────▶ │ MusaLCEforBitwig │ ◀────▶ │ Bitwig Studio │
30
+ │ MusaLCEClient │ (REPL) │ (Ruby gem) │ │ + Pulso Bridge relay │ └──────────────────┘
31
+ │ ForVSCode │ │ │ UDP └─────────────────────────┘
32
+ └────────────────────┘ │ • REPL │ OSC OR
33
+ │ • Sequencer │
34
+ │ • DAW handler │ ◀────▶ ┌─────────────────────────┐ ┌──────────────────┐
35
+ │ • Surface │ │ MusaLCEforLive │ ◀────▶ │ Ableton Live │
36
+ │ • MIDI out │ │ (Python) │ └──────────────────┘
37
+ └──────────────────┘ └─────────────────────────┘
38
+ ```
39
+
40
+ Two parallel OSC contracts cross the server ↔ extension boundary:
41
+
42
+ - **Handler protocol** — `/musalce4bitwig/*` or `/musalce4live/*` plus a common `/hello`, `/version`, `/reload`. Carries DAW control (transport, track sync, channels). Documented [below](#osc-handler-protocol).
43
+ - **Surface protocol** — `/musalce/surface/*`. Carries elgato Stream Deck control state (inventory, triggers, state propagation). The canonical Pulso-side spec will be linked here once Pulso publishes.
44
+
45
+ ## Component responsibilities
46
+
47
+ | Component | Repo | Role | Language |
48
+ |---|---|---|---|
49
+ | **musa-dsl** | [musa-dsl](https://github.com/javier-sy/musa-dsl) | The composition framework: series, sequencer, neumas, transport, REPL primitive. | Ruby |
50
+ | **musalce-server** | [musalce-server](https://github.com/javier-sy/musalce-server) | Packages the REPL + sequencer + per-DAW handler + surface into a single command (`musalce-server bitwig\|live`). | Ruby |
51
+ | **MusaLCEforBitwig** | [MusaLCEforBitwig](https://github.com/javier-sy/MusaLCEforBitwig) | Bitwig controller extension; bridges Bitwig and musalce-server over OSC, includes the `MusaLCESurfaceRelay` for Pulso. | Java (Bitwig Extension API 18) |
52
+ | **MusaLCEforLive** | [MusaLCEforLive](https://github.com/javier-sy/MusaLCEforLive) | Ableton Live MIDI Remote Script; bridges Live and musalce-server over OSC. | Python |
53
+ | **MusaLCEClientForVSCode** | [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) | VSCode extension that is a REPL client over TCP/1327. | TypeScript |
54
+ | **Pulso Bridge** *(optional)* | *public release pending* | The DAW-side component of [yeste.studio](https://yeste.studio)'s upcoming Pulso, a Stream Deck workflow system for DAWs (Bitwig today; Ableton planned). Pulso's primary scope is generic DAW control (transport, tracks, devices, browser, parameter encoders); Pulso Bridge can also relay user actions and feedback data to/from the Stream Deck through the MusaLCE Surface protocol in MusaLCEforBitwig/Live — that's the integration described in this doc. | --- |
55
+
56
+ ## Accessing the DAW (`daw.*`)
57
+
58
+ **musalce-server** exposes to the user access to the daw through a `daw.*` accessor. Quick reference:
59
+
60
+ | Accessor | Returns | What it's for |
61
+ |---|---|---|
62
+ | `daw` | `Daw` (Bitwig or Live subclass) | Root entry point |
63
+ | `daw.sequencer` | `Musa::Sequencer::Sequencer` | The sequencer, also the implicit DSL host |
64
+ | `daw.clock` | `Musa::Clock::InputMidiClock` | The MIDI clock |
65
+ | `daw.transport` | `Musa::Transport::Transport` | The transport. Exposes `on_start`/`after_stop`/`before_begin` for callbacks that survive Stop/Play (since v0.7.2). |
66
+ | `daw.tracks` | DAW-specific | Track collection (`daw.track('Name')`) |
67
+ | `daw.surface` | `Surface` | Stream Deck / hardware surface object — `surface[:event]` (see below) |
68
+ | `daw.play`, `daw.stop`, `daw.continue`, `daw.goto(bar)`, `daw.record` | — | Transport remote control. **Bitwig only** (Live API limitation). |
69
+ | `daw.panic!` | — | All-notes-off to every track |
70
+
71
+ ## Stop/Play semantics
72
+
73
+ The server registers exactly one built-in callback on the transport:
74
+
75
+ ```ruby
76
+ transport.after_stop { sequencer.reset }
77
+ ```
78
+
79
+ `sequencer.reset` (`musa-dsl/sequencer/base-sequencer.rb`) wipes:
80
+
81
+ - `@timeslots` — all `at`-scheduled events
82
+ - `@everying` — all `every` loops
83
+ - `@playing` — all `play` operations
84
+ - `@moving` — all `move` operations
85
+ - `@event_handlers` — **all `on :event` handlers**
86
+
87
+ What survives a Stop/Play cycle:
88
+
89
+ | | Survives Stop? |
90
+ |---|---|
91
+ | Top-level Ruby (`def`, constants, modules) | ✅ (Ruby process is alive) |
92
+ | `daw.*` (sequencer, transport, tracks, surface) | ✅ (instance state of `Daw`) |
93
+ | `surface[:event]` **control declarations** | ✅ (live on `@surface`) |
94
+ | `surface[:event]` **handler blocks** (`on :event do … end`) | ❌ (wiped with `@event_handlers`) |
95
+ | `at`, `every`, `play`, `move` | ❌ |
96
+
97
+ ### Rehydration pattern
98
+
99
+ Use `daw.transport.on_start` to re-install handlers and schedules on every Play:
100
+
101
+ ```ruby
102
+ daw.transport.on_start do
103
+ load 'persistent_actions.rb' # re-establishes on :event, every, at, …
104
+ end
105
+ ```
106
+
107
+ `on_start` callbacks accumulate (it's an append-only list), so you can register more from the REPL at any time. Use `before_begin` for callbacks that should run **only on the first Start of the session**, and `after_stop` for cleanup (e.g. `voices.panic`).
108
+
109
+ ## Accessing the Stream Deck (`on :event` and `surface[:event]`)
110
+
111
+ In Stream Deck Pulso Workflow plugin the user has several kinds of buttons and encoders that can trigger events on the user MusaDSL code (as MusaDSL Sequencer Events with parameters). This allows the user to control the behaviour of his MusaDSL code in realtime using an elgato Stream Deck device.
112
+
113
+ The buttons and encoders are identified with a `event` name. This `event` name is the one launched on the `musalce-server` **Sequencer** and the one the user can subscribe from his code with `on :event |parameters| do ... end` commands.
114
+
115
+ Also, the user can update the visible content on the buttons and encoders on the Stream Deck device using the `surface[:event].set parameter: value, parameter: value` commands.
116
+
117
+ Pulso Bridge is aware of MusaLCEforBitwig/Live through a pair of configurable OSC ports and both coordinate the bidirectional communication between Stream Deck and MusaDSL code in the user session.
118
+
119
+ ## OSC handler protocol
120
+
121
+ Two unidirectional channels, both UDP:
122
+
123
+ - **server listens** on `127.0.0.1:11011` (extension → server)
124
+ - **server sends** to `127.0.0.1:10001` (server → extension)
125
+
126
+ Both ports are **hardcoded** on the server side (`musalce-server/lib/daw.rb`). The DAW extensions match these defaults.
127
+
128
+ ### Common addresses (both DAWs)
129
+
130
+ | Direction | Address | Args | Purpose |
131
+ |---|---|---|---|
132
+ | ext → server | `/hello` | — | Extension announces itself on init. Server replies with `/version` + a per-DAW sync request. |
133
+ | server → ext | `/version` | `s` (VERSION) | Server announces its gem version. Extension can refuse to talk to incompatible versions. |
134
+ | server → ext | `/reload` | — | Asks the extension to reset and re-sync (used by `reload` REPL command). |
135
+
136
+ ### Bitwig-specific (`/musalce4bitwig/*`)
137
+
138
+ | Direction | Address | Args | Purpose |
139
+ |---|---|---|---|
140
+ | server → ext | `/musalce4bitwig/sync` | — | Ask the extension to re-emit controllers + channels. |
141
+ | server → ext | `/musalce4bitwig/play` | — | Bitwig transport play. |
142
+ | server → ext | `/musalce4bitwig/stop` | — | Bitwig transport stop. |
143
+ | server → ext | `/musalce4bitwig/continue` | — | Bitwig transport continue. |
144
+ | server → ext | `/musalce4bitwig/goto` | `d` (position in beats from bar 1) | Move playhead. |
145
+ | server → ext | `/musalce4bitwig/record` | — | Toggle record. |
146
+ | ext → server | `/musalce4bitwig/controllers` | `s s s …` (names) | Register all controllers in Bitwig. |
147
+ | ext → server | `/musalce4bitwig/controller` | `s s i` (name, port_name, is_clock 0/1) | Register a single controller. |
148
+ | ext → server | `/musalce4bitwig/controller/update` | `s s s i` (old_name, new_name, port_name, is_clock) | Rename / update a controller. |
149
+ | ext → server | `/musalce4bitwig/channels` | `s i i …` (controller_name, channels…) | Register channels for a controller. |
150
+
151
+ ### Live-specific (`/musalce4live/*`)
152
+
153
+ | Direction | Address | Args | Purpose |
154
+ |---|---|---|---|
155
+ | server → ext | `/musalce4live/tracks` | — | Ask the script to re-emit the track registry. |
156
+ | ext → server | `/musalce4live/tracks` | bulk (sliced 10) | Bulk track registry dump. |
157
+ | ext → server | `/musalce4live/track/name` | bulk (sliced 2) | Track names. |
158
+ | ext → server | `/musalce4live/track/midi` | bulk (sliced 3) | MIDI track metadata. |
159
+ | ext → server | `/musalce4live/track/audio` | bulk (sliced 3) | Audio track metadata. |
160
+ | ext → server | `/musalce4live/track/routings` | bulk (sliced 5) | Routing metadata. |
161
+
162
+ ## MusaLCE Surface protocol — elgato Stream Deck via Pulso's MusaLCE integration (Bitwig only)
163
+
164
+ The MusaLCE Surface protocol carries surface inventory, triggers and state between **musalce-server**, **MusaLCEforBitwig** and **Pulso Bridge**.
165
+
166
+ - `/musalce/surface/inventory/{begin,add,remove,end}` — surface inventory (Pulso → server)
167
+ - `/musalce/surface/trigger event payload` — Pulso → server, dispatched to `on :event` via `@sequencer.launch`
168
+ - `/musalce/surface/state/{message,enabled,value,range} event …` — server → Pulso, repaints the Stream Deck
169
+ - `/musalce/surface/sync_request`, `/musalce/surface/state_request` — handshake messages
170
+
171
+ ## Where to go next
172
+
173
+ - Reference the **standalone REPL** workflow: [musa-dsl/docs/subsystems/repl.md](https://github.com/javier-sy/musa-dsl/blob/master/docs/subsystems/repl.md).
174
+ - Reference the **REPL commands** (`daw.*`, transport controls, sequencer DSL) of the suite: [musalce-server README](https://github.com/javier-sy/musalce-server#readme).
175
+ - Configure the **DAW extensions**: [MusaLCEforBitwig README](https://github.com/javier-sy/MusaLCEforBitwig#readme), [MusaLCEforLive README](https://github.com/javier-sy/MusaLCEforLive#readme).
176
+ - Wire the **VSCode editor**: [MusaLCEClientForVSCode README](https://github.com/javier-sy/MusaLCEClientForVSCode#readme).
177
+ - Wire the **Stream Deck** (Bitwig only): pending Pulso's public release.
178
+
data/lib/bitwig/bitwig.rb CHANGED
@@ -4,8 +4,24 @@ require_relative 'handler'
4
4
  require_relative 'controllers'
5
5
 
6
6
  module MusaLCEServer
7
+ # Bitwig Studio integration module.
8
+ #
9
+ # Provides support for live coding with Bitwig Studio 5+ through
10
+ # the MusaLCE for Bitwig controller extension.
11
+ #
12
+ # @see https://github.com/javier-sy/MusaLCEforBitwig Controller extension
7
13
  module Bitwig
14
+ # DAW controller for Bitwig Studio.
15
+ #
16
+ # Implements the {Daw} interface for Bitwig Studio, providing
17
+ # transport control, track management, and MIDI routing through
18
+ # the MusaLCE for Bitwig controller extension.
19
+ #
20
+ # @example
21
+ # # Started via MusaLCEServer.run('bitwig')
22
+ # daw.track('Bass').out.note(60, velocity: 100, duration: 1)
8
23
  class Bitwig < Daw
24
+ # @api private
9
25
  def daw_initialize(midi_devices:, clock:, osc_server:, osc_client:, logger:)
10
26
  super
11
27
 
@@ -17,6 +33,11 @@ module MusaLCEServer
17
33
  return controllers.tracks, handler
18
34
  end
19
35
 
36
+ # Retrieves a track by name.
37
+ #
38
+ # @param name [String] the track name as configured in Bitwig
39
+ # @param all [Boolean] if true, returns array; otherwise returns single track
40
+ # @return [Track, Array<Track>] the track or array containing the track
20
41
  def track(name, all: false)
21
42
  if all
22
43
  [@tracks[name]]
@@ -25,26 +46,37 @@ module MusaLCEServer
25
46
  end
26
47
  end
27
48
 
49
+ # Starts playback in Bitwig.
50
+ # @return [void]
28
51
  def play
29
52
  @handler.play
30
53
  super
31
54
  end
32
55
 
56
+ # Stops playback in Bitwig.
57
+ # @return [void]
33
58
  def stop
34
59
  @handler.stop
35
60
  super
36
61
  end
37
62
 
63
+ # Continues playback from current position.
64
+ # @return [void]
38
65
  def continue
39
66
  @handler.continue
40
67
  super
41
68
  end
42
69
 
70
+ # Moves playhead to specified bar position.
71
+ # @param position [Numeric] the bar number (1-based)
72
+ # @return [void]
43
73
  def goto(position)
44
74
  @handler.goto(position)
45
75
  super
46
76
  end
47
77
 
78
+ # Starts recording in Bitwig.
79
+ # @return [void]
48
80
  def record
49
81
  @handler.record
50
82
  super