Module: Musa::Sequencer::BaseSequencer::TickBasedTiming Private

Defined in:
lib/musa-dsl/sequencer/base-sequencer-tick-based.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Tick-based timing implementation for BaseSequencer.

TickBasedTiming provides quantized time progression where time advances in discrete tick increments. Musical time is divided into bars, beats, and ticks, with position rounded to the nearest tick boundary. This provides a traditional sequencer timing model similar to DAWs and MIDI sequencers.

Tick-Based Time Model

Time is quantized to a grid determined by:

  • beats_per_bar: Time signature numerator (e.g., 4 for 4/4)
  • ticks_per_beat: Subdivisions per beat (resolution)
  • ticks_per_bar: Total ticks = beats_per_bar × ticks_per_beat
  • tick_duration: 1 / ticks_per_bar (Rational)

Position always aligns to tick boundaries. Non-aligned positions are rounded with a warning.

Time Progression

  • Forward only: Position cannot decrease (enforced)
  • Tick advancement: #tick increments by tick_duration
  • Fast-forward: #position= jumps to future position
  • Quantization: All positions rounded to tick grid

Fast-Forward Mechanism

When jumping forward via position=:

  1. Triggers on_fast_forward callbacks with true
  2. Ticks forward until reaching target position
  3. Triggers on_fast_forward callbacks with false
  4. Allows event handlers to skip/optimize during jumps

Musical Applications

  • Traditional MIDI sequencing with quantized timing
  • Grid-aligned rhythmic patterns
  • Time signature-based composition (4/4, 3/4, etc.)
  • Tick-precise event scheduling

Examples:

Creating tick-based sequencer (4/4, 96 ticks per beat)

sequencer = BaseSequencer.new(4, 96)  # 4 beats, 96 ticks/beat
sequencer.ticks_per_bar  # => 384r
sequencer.tick_duration  # => 1/384r
sequencer.position       # => 1r (start of bar 1)

Advancing time with tick

sequencer.tick  # Advance one tick (1/384 of a bar)
sequencer.position  # => 385/384r

Fast-forward to future position

sequencer.position = 2r  # Jump to bar 2
# Triggers on_fast_forward(true), ticks forward, on_fast_forward(false)

Quantization warning

sequencer.at(1.5001r) { puts "event" }
# WARN: rounding position 1.5001 to tick precision: 1.5

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#positionRational

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Current playback position in bars (Rational).

Always aligned to tick boundaries. Bar 1 starts at position 1r.



73
74
75
# File 'lib/musa-dsl/sequencer/base-sequencer-tick-based.rb', line 73

def position
  @position
end

#tick_durationRational (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Duration of one tick in bars (1 / ticks_per_bar).



83
84
85
# File 'lib/musa-dsl/sequencer/base-sequencer-tick-based.rb', line 83

def tick_duration
  @tick_duration
end

#ticks_per_barRational (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Total ticks per bar (beats_per_bar × ticks_per_beat).



78
79
80
# File 'lib/musa-dsl/sequencer/base-sequencer-tick-based.rb', line 78

def ticks_per_bar
  @ticks_per_bar
end

Instance Method Details

#tickvoid

This method returns an undefined value.

Advances sequencer by one tick.

Increments position by tick_duration and executes all events scheduled at the new position. This is the primary time progression method for tick-based sequencers.

If ticks are held (during fast-forward), accumulates ticks in buffer without executing events until released.

Examples:

Normal tick progression

sequencer.position  # => 1r
sequencer.tick
sequencer.position  # => 385/384r (1 + 1/384)


102
103
104
105
106
107
108
# File 'lib/musa-dsl/sequencer/base-sequencer-tick-based.rb', line 102

def tick
  if @hold_public_ticks
    @hold_ticks += 1
  else
    _tick @position_mutex.synchronize { @position += @tick_duration }
  end
end