class MTK::Sequencers::EventBuilder
A special pattern that takes a list of event properties and/or patterns and emits lists of {Events::Event}s
Constants
- DEFAULT_DURATION
- DEFAULT_INTENSITY
- DEFAULT_PITCH
Public Class Methods
new(patterns, options={})
click to toggle source
# File lib/mtk/sequencers/event_builder.rb, line 11 def initialize(patterns, options={}) @patterns = patterns @options = options @default_pitch = if options.has_key? :default_pitch then MTK.Pitch( options[:default_pitch]) else DEFAULT_PITCH end @default_duration = if options.has_key? :default_duration then MTK.Duration( options[:default_duration]) else DEFAULT_DURATION end @default_intensity = if options.has_key? :default_intensity then MTK.Intensity(options[:default_intensity]) else DEFAULT_INTENSITY end @channel = options[:channel] @max_interval = options.fetch(:max_interval, 127) rewind end
Public Instance Methods
next()
click to toggle source
Build a list of events from the next element in each {Patterns::Pattern} @return [Array] an array of events
# File lib/mtk/sequencers/event_builder.rb, line 24 def next pitches = [] intensities = [] duration = nil @patterns.each do |pattern| pattern_value = pattern.next elements = if pattern_value.is_a? Enumerable and not pattern_value.is_a? MTK::Groups::PitchCollection then pattern_value else [pattern_value] end elements.each do |element| return nil if element.nil? or element == :skip case element when ::MTK::Core::Pitch pitches << element @previous_pitch = element when ::MTK::Core::PitchClass pitches += pitches_for_pitch_classes([element], @previous_pitch) @previous_pitch = pitches.last when ::MTK::Groups::PitchClassSet pitches += pitches_for_pitch_classes(element, @previous_pitch) @previous_pitch = pitches.last when ::MTK::Groups::PitchCollection pitches += element.pitches # this must be after the PitchClassSet case, because that is also a PitchCollection @previous_pitch = pitches.last when ::MTK::Core::Duration duration ||= 0 duration += element when ::MTK::Core::Intensity intensities << element when ::MTK::Core::Interval if @previous_pitches pitches += @previous_pitches.map{|pitch| pitch + element } else pitches << (@previous_pitch + element) end @previous_pitch = pitches.last # TODO? String/Symbols for special behaviors like :skip, or :break (something like StopIteration for the current Pattern?) else STDERR.puts "#{self.class}#next: Unexpected type '#{element.class}'" end end end pitches << @previous_pitch if pitches.empty? duration ||= @previous_duration.abs if intensities.empty? intensity = @previous_intensity else intensity = MTK::Core::Intensity[intensities.map{|i| i.to_f }.inject(:+)/intensities.length] # average the intensities end # Not using this yet, maybe later... # return nil if duration==:skip or intensities.include? :skip or pitches.include? :skip constrain_pitch(pitches) @previous_pitch = pitches.last # Consider doing something different, maybe averaging? @previous_pitches = pitches.length > 1 ? pitches : nil @previous_intensity = intensity @previous_duration = duration if duration.rest? [MTK::Events::Rest.new(duration,@channel)] else pitches.map{|pitch| MTK::Events::Note.new(pitch,duration,intensity,@channel) } end end
rewind()
click to toggle source
Reset the EventBuilder
to its initial state
# File lib/mtk/sequencers/event_builder.rb, line 108 def rewind @previous_pitch = @default_pitch @previous_pitches = [@default_pitch] @previous_intensity = @default_intensity @previous_duration = @default_duration @max_pitch = nil @min_pitch = nil @patterns.each{|pattern| pattern.rewind if pattern.is_a? MTK::Patterns::Pattern } end
Private Instance Methods
constrain_pitch(pitches)
click to toggle source
# File lib/mtk/sequencers/event_builder.rb, line 125 def constrain_pitch(pitches) if @max_pitch.nil? or @min_pitch.nil? first_pitch = pitches.first @max_pitch = first_pitch + @max_interval @max_pitch = 127 if @max_pitch > 127 @min_pitch = first_pitch - @max_interval @min_pitch = 0 if @min_pitch < 0 @small_max_span = (@max_pitch - @min_pitch < 12) end pitches.map! do |pitch| if @small_max_span pitch = @max_pitch if pitch > @max_pitch pitch = @min_pitch if pitch < @max_pitch else pitch -= 12 while pitch > @max_pitch pitch += 12 while pitch < @min_pitch end pitch end end
pitches_for_pitch_classes(pitch_classes, previous_pitch)
click to toggle source
# File lib/mtk/sequencers/event_builder.rb, line 121 def pitches_for_pitch_classes(pitch_classes, previous_pitch) pitch_classes.to_a.map{|pitch_class| previous_pitch.nearest(pitch_class) } end