class MTK::Sequencers::Sequencer

A Sequencer produces {Events::Timeline}s from a collection of {Patterns::Pattern}s.

@abstract Subclass and override {#advance} to implement a Sequencer.

Attributes

event_builder[R]

Used by {#to_timeline} to builds event lists from the results of {Patterns::Pattern#next} for the {Patterns::Pattern}s in this Sequencer.

max_steps[RW]

The maximum number of [time,event_list] entries that will be generated for the {Events::Timeline}. nil means no maximum (be careful of infinite loops!)

max_time[RW]

The maximum time (key) that will be generated for the {Events::Timeline}. nil means no maximum (be careful of infinite loops!)

patterns[R]
step[R]

The current sequencer step index (the number of times-1 that {#next} has been called), or -1 if the sequencer has not yet started.

time[R]

The current time offset for the sequencer. Used for the {Events::Timeline} times.

Public Class Methods

new(patterns, options={}) click to toggle source

@param patterns [Array] the list of patterns to be sequenced into a {Events::Timeline} @param options [Hash] the options to create a message with. @option options [String] :max_steps set {#max_steps} @option options [String] :max_time set {#max_time} @option options [Proc] :filter a Proc that will replace the events generated by {#next} with the results of the Proc @option options [Class] :event_builder replace the {Sequencers::EventBuilder} with a custom Event pattern

# File lib/mtk/sequencers/sequencer.rb, line 35
def initialize(patterns, options={})
  @patterns = patterns
  @max_steps = options[:max_steps]
  @max_time = options[:max_time]
  @filter = options[:filter]

  event_builder_class = options.fetch :event_builder, ::MTK::Sequencers::EventBuilder
  @event_builder = event_builder_class.new(patterns, options)

  rewind
end

Protected Class Methods

inherited(subclass) click to toggle source
# File lib/mtk/sequencers/sequencer.rb, line 97
def self.inherited(subclass)
  # Define a convenience method like MTK::Patterns.Sequence()
  # that can handle varargs or a single array argument, plus any Hash options
  classname = subclass.name.sub /.*::/, '' # Strip off module prefixes
  MTK::Sequencers.define_singleton_method classname do |*args|
    options  = (args[-1].is_a? Hash) ? args.pop : {}
    args = args[0] if args.length == 1 and args[0].is_a? Array
    subclass.new(args,options)
  end
end

Public Instance Methods

next() click to toggle source

Advanced the step index and time, and return the next list of events built from the sequencer patterns. @note this is called automatically by {#to_timeline},

so you can ignore this method unless you want to hack on sequencers at a lower level.
# File lib/mtk/sequencers/sequencer.rb, line 66
def next
  if @step >= 0
    advance
    raise StopIteration if @max_time and @time > @max_time
  end
  @step += 1
  raise StopIteration if @max_steps and @step >= @max_steps
  events = @event_builder.next
  events = @filter[events] if @filter
  events
end
rewind() click to toggle source

Reset the sequencer and all its patterns. @note this is called automatically at the beginning of {#to_timeline},

so you can ignore this method unless you want to hack on sequencers at a lower level.
# File lib/mtk/sequencers/sequencer.rb, line 82
def rewind
  @time = 0
  @step = -1
  @event_builder.rewind
end
to_timeline() click to toggle source

Produce a {Events::Timeline} from the {Patterns::Pattern}s in this Sequencer.

# File lib/mtk/sequencers/sequencer.rb, line 49
def to_timeline
  rewind
  timeline =  MTK::Events::Timeline.new
  loop do
    events = self.next
    if events
      events = events.reject{|e| e.rest? }
      timeline[@time] = events unless events.empty?
    end
  end
  timeline
end

Protected Instance Methods

advance() click to toggle source

Advance @time to the next time for the {Events::Timeline} being produced by {#to_timeline}

# File lib/mtk/sequencers/sequencer.rb, line 93
def advance
  @time += 1 # default behavior simply advances one beat at a time
end