Class: MusaLCEServer::Daw Abstract
- Inherits:
-
Object
- Object
- MusaLCEServer::Daw
- Defined in:
- lib/daw.rb
Overview
Subclass and implement #daw_initialize and #track
Base class for DAW (Digital Audio Workstation) controllers.
This class provides the common infrastructure for communicating with DAWs like Ableton Live and Bitwig Studio. It manages:
- OSC server/client for communication with DAW controller extensions
- MIDI clock synchronization
- Musa-DSL sequencer integration
- MIDI device management
- Transport controls (play, stop, record, etc.)
Subclasses must implement #daw_initialize to set up DAW-specific handlers and track management.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#clock ⇒ Musa::Clock::InputMidiClock
readonly
The MIDI clock for synchronization.
-
#sequencer ⇒ Musa::Sequencer::Sequencer
readonly
The Musa-DSL sequencer instance.
-
#surface ⇒ Object
readonly
Returns the value of attribute surface.
-
#tracks ⇒ Object
readonly
The DAW-specific tracks collection.
-
#transport ⇒ Musa::Transport::Transport
readonly
The transport driving the sequencer.
Class Method Summary collapse
-
.daw_controller_for(daw_id) ⇒ Daw
Creates and returns a new DAW controller instance for the given identifier.
-
.register(daw_id, daw_class) ⇒ void
Registers a DAW driver class for a given identifier.
Instance Method Summary collapse
-
#continue ⇒ void
Continues playback from current position.
-
#goto(position) ⇒ void
Moves playhead to specified position.
-
#initialize ⇒ Daw
constructor
Creates a new DAW controller instance.
-
#panic! ⇒ void
Sends All Notes Off to all tracks.
-
#play ⇒ void
Starts playback in the DAW.
-
#record ⇒ void
Starts recording in the DAW.
-
#reload ⇒ void
Requests the DAW controller extension to reload.
-
#stop ⇒ void
Stops playback in the DAW.
-
#sync ⇒ void
Requests track synchronization from the DAW.
-
#track(name, all: false) ⇒ Object+
abstract
Retrieves a track by name.
Constructor Details
#initialize ⇒ Daw
Creates a new DAW controller instance.
Sets up OSC server (port 11011) and client (port 10001), initializes the Musa-DSL sequencer, MIDI clock, and transport. Calls #daw_initialize for DAW-specific setup.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/daw.rb', line 59 def initialize osc_server = OSC::EMServer.new(11_011) osc_client = OSC::Client.new('localhost', 10_001) Thread.new { osc_server.run } @sequencer = Musa::Sequencer::Sequencer.new 4, 24, dsl_context_class: MusaLCE_Context, do_log: true @clock = Musa::Clock::InputMidiClock.new do_log: true, logger: @sequencer.logger @transport = Musa::Transport::Transport.new @clock, sequencer: @sequencer @transport.after_stop do sequencer.reset end @midi_devices = MIDIDevices.new(@sequencer) # Build the surface side: inbound +/musalce/surface/*+ # messages land on the EM reactor thread, are enqueued by the # bridge, then drained on the sequencer tick thread via # +before_tick+ — guaranteeing that inventory mutations and # user-defined trigger handlers can safely use any DSL method # (+play+, +at+, +launch+, …). Drainer latency is one tick # (≈20 ms at 120 BPM / 24 PPQN). surface_bridge = SurfaceBridge.new(osc_client, @sequencer, logger: @sequencer.logger) @surface = Surface.new(bridge: surface_bridge, logger: @sequencer.logger) surface_bridge.surface = @surface surface_bridge.register_inbound(osc_server) MusaLCEServer.surface = @surface @sequencer.before_tick do |_position| surface_bridge.drain end @tracks, @handler = daw_initialize(midi_devices: @midi_devices, clock: @clock, osc_server: osc_server, osc_client: osc_client, logger: @sequencer.logger) @handler.version @handler.sync # Ask Pulso Bridge (through the DAW extension) to dump its # current inventory. The reply re-establishes # +@surface.controls+ from scratch and triggers a full state # re-emit. Sent after +@handler.sync+ so the DAW extension is # known to be alive. surface_bridge.request_sync Thread.new { @transport.start } end |
Instance Attribute Details
#clock ⇒ Musa::Clock::InputMidiClock (readonly)
Returns the MIDI clock for synchronization.
125 126 127 |
# File 'lib/daw.rb', line 125 def clock @clock end |
#sequencer ⇒ Musa::Sequencer::Sequencer (readonly)
Returns the Musa-DSL sequencer instance.
125 |
# File 'lib/daw.rb', line 125 attr_reader :clock, :sequencer, :transport, :tracks, :surface |
#surface ⇒ Object (readonly)
Returns the value of attribute surface.
125 |
# File 'lib/daw.rb', line 125 attr_reader :clock, :sequencer, :transport, :tracks, :surface |
#tracks ⇒ Object (readonly)
Returns the DAW-specific tracks collection.
125 |
# File 'lib/daw.rb', line 125 attr_reader :clock, :sequencer, :transport, :tracks, :surface |
#transport ⇒ Musa::Transport::Transport (readonly)
Returns the transport driving the sequencer. Exposed so REPL users can register callbacks (Musa::Transport::Transport#on_start, Musa::Transport::Transport#after_stop, Musa::Transport::Transport#before_begin) that survive across DAW Stop/Play cycles — useful for re-installing +on :event+ handlers, +every+ loops or +at+ schedules that are wiped by the built-in +after_stop { sequencer.reset }+ callback.
125 |
# File 'lib/daw.rb', line 125 attr_reader :clock, :sequencer, :transport, :tracks, :surface |
Class Method Details
.daw_controller_for(daw_id) ⇒ Daw
Creates and returns a new DAW controller instance for the given identifier.
50 51 52 |
# File 'lib/daw.rb', line 50 def self.daw_controller_for(daw_id) @@daws[daw_id].new end |
.register(daw_id, daw_class) ⇒ void
This method returns an undefined value.
Registers a DAW driver class for a given identifier.
41 42 43 44 |
# File 'lib/daw.rb', line 41 def self.register(daw_id, daw_class) @@daws ||= {} @@daws[daw_id] = daw_class end |
Instance Method Details
#continue ⇒ void
This method returns an undefined value.
Continues playback from current position.
162 |
# File 'lib/daw.rb', line 162 def continue; end |
#goto(position) ⇒ void
This method returns an undefined value.
Moves playhead to specified position.
167 |
# File 'lib/daw.rb', line 167 def goto(position); end |
#panic! ⇒ void
This method returns an undefined value.
Sends All Notes Off to all tracks.
Use this to stop stuck notes after errors or interruptions.
177 178 179 180 181 |
# File 'lib/daw.rb', line 177 def panic! @tracks.each do |track| track.out.all_notes_off end end |
#play ⇒ void
This method returns an undefined value.
Starts playback in the DAW.
154 |
# File 'lib/daw.rb', line 154 def play; end |
#record ⇒ void
This method returns an undefined value.
Starts recording in the DAW.
171 |
# File 'lib/daw.rb', line 171 def record; end |
#reload ⇒ void
This method returns an undefined value.
Requests the DAW controller extension to reload.
191 192 193 |
# File 'lib/daw.rb', line 191 def reload @handler.reload end |
#stop ⇒ void
This method returns an undefined value.
Stops playback in the DAW.
158 |
# File 'lib/daw.rb', line 158 def stop; end |
#sync ⇒ void
This method returns an undefined value.
Requests track synchronization from the DAW.
185 186 187 |
# File 'lib/daw.rb', line 185 def sync @handler.sync end |
#track(name, all: false) ⇒ Object+
Retrieves a track by name.
148 149 150 |
# File 'lib/daw.rb', line 148 def track(name, all: false) raise NotImplementedError end |