Class: Musa::Sequencer::Sequencer

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/musa-dsl/sequencer/sequencer-dsl.rb

Overview

High-level DSL wrapper for BaseSequencer.

Provides user-friendly interface with block context management via with method. Wraps BaseSequencer methods to automatically evaluate blocks in DSL context, enabling clean musical composition code.

DSL Context

Blocks passed to scheduling methods (now, at, wait, play, every, move) are evaluated in DSL context via with, providing access to sequencer methods and allowing for cleaner composition syntax.

Delegation

Delegates most methods to either BaseSequencer or DSLContext:

  • Timing: beats_per_bar, ticks_per_beat, position, tick, reset
  • Scheduling: now, at, wait, play, play_timed, every, move
  • Events: launch, on
  • Inspection: size, empty?, everying, playing, moving

Musical Applications

Provides composer-friendly API for:

  • Musical composition scripts
  • Interactive sequencing
  • Live coding
  • Algorithmic composition

Examples:

Basic DSL usage

log = []

sequencer = Musa::Sequencer::Sequencer.new(4, 96) do
  at(1r) { log << "Bar 1" }
  at(2r) { log << "Bar 2" }

  every(1r, duration: 4r) do
    log << "Every beat"
  end
end

sequencer.run

log
# => ["Every beat", "Bar 1", "Every beat", "Bar 2",
#     "Every beat", "Every beat"]

# The first "Every beat" comes BEFORE "Bar 1". An `every` written at the
# top of the block starts pulsing from the sequencer's own position,
# which is one tick before bar 1 -- so its pulses land a tick before
# each bar rather than on it. Put it inside an `at(1r)` and it lands on
# the bars.

DSL context access

log = []

sequencer = Musa::Sequencer::Sequencer.new(4, 96) do
  at(1r) do
    log << position  # DSL context method

    wait(1r) { log << position }  # Nested scheduling
  end
end

sequencer.run

log  # => [(1/1), (2/1)]

# `position` and `wait` are available inside the block without a
# receiver, and `wait` counts from where the block is running: one bar
# after 1 is 2, not one bar after the sequencer started.

Defined Under Namespace

Classes: DSLContext

Instance Method Summary collapse

Constructor Details

#initialize(beats_per_bar = nil, ticks_per_beat = nil, offset: nil, sequencer: nil, logger: nil, do_log: nil, do_error_log: nil, log_position_format: nil, dsl_context_class: nil, keep_block_context: nil) { ... } ⇒ Sequencer

Creates sequencer with optional initialization block.

Examples:

Tick-based sequencer

seq = Sequencer.new(4, 96) do
  at(1r) { puts "Start" }
end

Tickless sequencer

seq = Sequencer.new do
  at(1r) { puts "Start" }
end

Parameters:

  • beats_per_bar (Integer, nil) (defaults to: nil)

    beats per bar (tick-based mode)

  • ticks_per_beat (Integer, nil) (defaults to: nil)

    ticks per beat (tick-based mode)

  • offset (Rational, nil) (defaults to: nil)

    starting position offset

  • sequencer (BaseSequencer, nil) (defaults to: nil)

    use existing sequencer

  • logger (Logger, nil) (defaults to: nil)

    logger instance

  • do_log (Boolean, nil) (defaults to: nil)

    enable logging

  • do_error_log (Boolean, nil) (defaults to: nil)

    enable error logging

  • log_position_format (Symbol, nil) (defaults to: nil)

    position format for logs

  • dsl_context_class (Class, nil) (defaults to: nil)

    custom DSL context class

  • keep_block_context (Boolean, nil) (defaults to: nil)

    preserve block's original binding

Yields:

  • initialization block evaluated in DSL context



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 395

def initialize(beats_per_bar = nil,
               ticks_per_beat = nil,
               offset: nil,
               sequencer: nil,
               logger: nil,
               do_log: nil, do_error_log: nil, log_position_format: nil,
               dsl_context_class: nil,
               keep_block_context: nil,
               &block)

  @sequencer = sequencer
  @sequencer ||= BaseSequencer.new beats_per_bar, ticks_per_beat,
                                   offset: offset,
                                   logger: logger,
                                   do_log: do_log,
                                   do_error_log: do_error_log,
                                   log_position_format: log_position_format

  dsl_context_class ||= DSLContext

  @dsl = dsl_context_class.new @sequencer, keep_block_context: keep_block_context

  @dsl.with &block if block_given?
end

Instance Method Details

#at(position, *value_parameters, **key_parameters) { ... } ⇒ EventHandler

Schedules block to execute at specified position.

Delegated from Musa::Sequencer::Sequencer::DSLContext#at.

Parameters:

  • position (Numeric, Rational)

    bar position

  • value_parameters (Array)

    parameters to pass to block

  • key_parameters (Hash)

    keyword parameters

Yields:

  • block to execute at position

Returns:

  • (EventHandler)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 249

#beats_per_barInteger?

Returns beats per bar (time signature numerator).

Delegated from BaseSequencer#beats_per_bar.

Returns:

  • (Integer, nil)

    beats per bar, or nil for tickless mode



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 84

#before_tick { ... } ⇒ Object

Registers handler called before each tick.

Delegated from BaseSequencer#before_tick.

Yields:

  • block executed before tick processing



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 154

#debugBoolean

Returns or enables debug mode.

Delegated from Musa::Sequencer::Sequencer::DSLContext#debug.

Returns:

  • (Boolean)

    debug mode status



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 232

#empty?Boolean

Checks if sequencer has no scheduled events.

Delegated from BaseSequencer#empty?.

Returns:

  • (Boolean)

    true if no events scheduled



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 126

#event_handlerEventHandler

Returns the event handler for launch/on events.

Delegated from BaseSequencer#event_handler.

Returns:

  • (EventHandler)

    event handler instance



197
198
199
200
201
202
203
204
205
206
# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 197

def_delegators :@sequencer,
:beats_per_bar, :ticks_per_beat, :ticks_per_bar, :tick_duration,
:offset,
:size, :empty?,
:on_debug_at, :on_error, :on_fast_forward, :before_tick,
:raw_at,
:tick,
:reset,
:position=,
:event_handler

#every(interval, duration: nil, till: nil, **options) { ... } ⇒ EveryControl

Executes block repeatedly at interval.

Delegated from Musa::Sequencer::Sequencer::DSLContext#every.

Parameters:

  • interval (Numeric, Rational)

    repetition interval in bars

  • duration (Numeric, Rational, nil) (defaults to: nil)

    total duration

  • till (Numeric, Rational, nil) (defaults to: nil)

    end position

  • options (Hash)

    additional options

Yields:

  • block to execute each interval

Returns:

  • (EveryControl)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 293

#everyingEveryingControl

Returns control for active every loops.

Delegated from Musa::Sequencer::Sequencer::DSLContext#everying.

Returns:

  • (EveryingControl)

    control for active loops



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 318

#launch(event_name, *parameters, **key_parameters) ⇒ void

This method returns an undefined value.

Triggers an event by name.

Delegated from Musa::Sequencer::Sequencer::DSLContext#launch.

Parameters:

  • event_name (Symbol)

    event identifier

  • parameters (Array)

    event parameters

  • key_parameters (Hash)

    event keyword parameters



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 339

#loggerLogger?

Returns the sequencer's logger instance.

Delegated from Musa::Sequencer::Sequencer::DSLContext#logger.

Returns:

  • (Logger, nil)

    logger instance



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 225

#move(from: nil, to: nil, duration: nil, step: nil, **options) {|value| ... } ⇒ MoveControl

Interpolates values over time.

Delegated from Musa::Sequencer::Sequencer::DSLContext#move.

Parameters:

  • from (Numeric, nil) (defaults to: nil)

    starting value

  • to (Numeric, nil) (defaults to: nil)

    ending value

  • duration (Numeric, Rational, nil) (defaults to: nil)

    interpolation duration

  • step (Numeric, Rational, nil) (defaults to: nil)

    time step

  • options (Hash)

    additional options

Yields:

  • (value)

    block receiving interpolated values

Returns:

  • (MoveControl)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 305

#movingMovingControl

Returns control for active move interpolations.

Delegated from Musa::Sequencer::Sequencer::DSLContext#moving.

Returns:

  • (MovingControl)

    control for active moves



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 332

#now(*value_parameters, **key_parameters) { ... } ⇒ EventHandler

Executes block immediately at current position.

Delegated from Musa::Sequencer::Sequencer::DSLContext#now.

Parameters:

  • value_parameters (Array)

    parameters to pass to block

  • key_parameters (Hash)

    keyword parameters

Yields:

  • block to execute now

Returns:

  • (EventHandler)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 239

#offsetRational?

Returns the sequencer's starting position offset.

Delegated from BaseSequencer#offset.

Returns:



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 112

#on(event_name) { ... } ⇒ void

This method returns an undefined value.

Registers handler for named event.

Delegated from Musa::Sequencer::Sequencer::DSLContext#on.

Parameters:

  • event_name (Symbol)

    event identifier

Yields:

  • block to execute when event fires



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 349

#on_debug_at { ... } ⇒ Object

Registers debug handler for specific position.

Delegated from BaseSequencer#on_debug_at.

Yields:

  • block to execute when position is reached in debug mode



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 133

#on_error {|Exception| ... } ⇒ Object

Registers error handler for sequencer errors.

Delegated from BaseSequencer#on_error.

Yields:

  • (Exception)

    block to handle errors



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 140

#on_fast_forward { ... } ⇒ Object

Registers handler called during fast-forward operations.

Delegated from BaseSequencer#on_fast_forward.

Yields:

  • block executed during fast-forward



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 147

#play(serie, decoder: nil, mode: nil, **options) {|element| ... } ⇒ PlayControl

Plays a series using the decoder.

Delegated from Musa::Sequencer::Sequencer::DSLContext#play.

Parameters:

  • serie (Serie)

    series to play

  • decoder (Object, nil) (defaults to: nil)

    decoder for series elements

  • mode (Symbol, nil) (defaults to: nil)

    playback mode (:neumalang, etc.)

  • options (Hash)

    additional play options

Yields:

  • (element)

    block to process each element

Returns:

  • (PlayControl)

    control object for the playing series



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 271

#play_timed(timed_serie, **options) {|element, duration| ... } ⇒ PlayControl

Plays a timed series with explicit timing.

Delegated from Musa::Sequencer::Sequencer::DSLContext#play_timed.

Parameters:

  • timed_serie (Serie)

    timed series to play

  • options (Hash)

    play options

Yields:

  • (element, duration)

    block to process elements

Returns:

  • (PlayControl)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 283

#playingPlayingControl

Returns control for active play operations.

Delegated from Musa::Sequencer::Sequencer::DSLContext#playing.

Returns:

  • (PlayingControl)

    control for active plays



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 325

#positionRational

Returns current sequencer position in bars.

Delegated from Musa::Sequencer::Sequencer::DSLContext#position.

Returns:



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 208

#position=(value) ⇒ void

This method returns an undefined value.

Sets the current sequencer position.

Delegated from BaseSequencer#position=.

Parameters:

  • value (Numeric, Rational)

    new position in bars



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 183

#quantize_position(reference, step, offset: nil) ⇒ Rational

Quantizes a position to a grid.

Delegated from Musa::Sequencer::Sequencer::DSLContext#quantize_position.

Parameters:

  • reference (Numeric, Rational)

    reference position

  • step (Numeric, Rational)

    grid step size

  • offset (Numeric, Rational, nil) (defaults to: nil)

    grid offset

Returns:



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 215

#raw_at(position) { ... } ⇒ Object

Schedules block at position without DSL context wrapping.

Delegated from BaseSequencer#raw_at.

Parameters:

  • position (Numeric, Rational)

    bar position

Yields:

  • block to execute at position



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 161

#resetvoid

This method returns an undefined value.

Resets sequencer to initial state.

Delegated from BaseSequencer#reset.



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 176

#runvoid

This method returns an undefined value.

Runs the sequencer until all events complete.

Delegated from Musa::Sequencer::Sequencer::DSLContext#run.



364
# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 364

def_delegators :@dsl, :position, :quantize_position, :logger, :debug

#sizeInteger

Returns number of scheduled events.

Delegated from BaseSequencer#size.

Returns:

  • (Integer)

    count of pending events



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 119

#tickvoid

This method returns an undefined value.

Advances sequencer by one tick and processes events.

Delegated from BaseSequencer#tick.



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 169

#tick_durationRational?

Returns duration of a single tick.

Delegated from BaseSequencer#tick_duration.

Returns:

  • (Rational, nil)

    tick duration in bars, or nil for tickless mode



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 105

#ticks_per_barInteger?

Returns total ticks per bar.

Delegated from BaseSequencer#ticks_per_bar.

Returns:

  • (Integer, nil)

    ticks per bar, or nil for tickless mode



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 98

#ticks_per_beatInteger?

Returns ticks per beat (timing resolution).

Delegated from BaseSequencer#ticks_per_beat.

Returns:

  • (Integer, nil)

    ticks per beat, or nil for tickless mode



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 91

#wait(duration, *value_parameters, **key_parameters) { ... } ⇒ EventHandler

Schedules block after waiting specified duration.

Delegated from Musa::Sequencer::Sequencer::DSLContext#wait.

Parameters:

  • duration (Numeric, Rational)

    wait duration in bars

  • value_parameters (Array)

    parameters to pass to block

  • key_parameters (Hash)

    keyword parameters

Yields:

  • block to execute after wait

Returns:

  • (EventHandler)

    control object



# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 260

#with(*value_parameters, **key_parameters, &block) ⇒ Object

Examples:

Comparison: with DSL context vs external context

seq = Musa::Sequencer::Sequencer.new(4, 96)

# Without 'with': need to reference seq explicitly
seq.at(1) { seq.at(2) { puts "nested" } }

# With 'with': DSL methods available directly
seq.with do
  at(1) { at(2) { puts "nested" } }  # Cleaner syntax
end


490
491
492
# File 'lib/musa-dsl/sequencer/sequencer-dsl.rb', line 490

def with(*value_parameters, **key_parameters, &block)
  @dsl.with(*value_parameters, **key_parameters, &block)
end