class Diamond::Sequence
The note event sequence from where the arpeggiator output is derived
Public Class Methods
# File lib/diamond/sequence.rb, line 10 def initialize @parameter = nil # realtime @changed = false @input_queue = [] @queue = [] end
Public Instance Methods
Add inputted note_messages @param [Array<MIDIMessage::NoteOn>, MIDIMessage::NoteOn, *MIDIMessage::NoteOn] note_messages @return [Boolean]
# File lib/diamond/sequence.rb, line 39 def add(*note_messages) messages = [note_messages].flatten.compact @input_queue.concat(messages) mark_changed true end
The bucket of messages for the given pointer @param [Fixnum] pointer @return [Array<MIDIMessage>]
# File lib/diamond/sequence.rb, line 21 def at(pointer) if changed? && (pointer % @parameter.rate == 0) update end enqueue_next(pointer) messages = @queue.shift || [] messages end
Has the sequence changed since the last update? @return [Boolean]
# File lib/diamond/sequence.rb, line 32 def changed? @changed end
Mark the sequence as changed @return [Boolean]
# File lib/diamond/sequence.rb, line 78 def mark_changed @changed = true end
All NoteOff messages in the queue @return [Array<MIDIMessage::NoteOff>]
# File lib/diamond/sequence.rb, line 67 def pending_note_offs messages = @queue.map do |bucket| unless bucket.nil? bucket.select { |m| m.class == MIDIMessage::NoteOff } end end messages.flatten.compact end
Remove input note messages with the same note value @param [Array<MIDIMessage::NoteOn, MIDIMessage::NoteOff>, MIDIMessage::NoteOff, MIDIMessage::NoteOn, *MIDIMessage::NoteOff, *MIDIMessage::NoteOn] note_messages @return [Boolean]
# File lib/diamond/sequence.rb, line 49 def remove(*note_messages) messages = [note_messages].flatten deletion_queue = messages.map(&:note) @input_queue.delete_if { |message| deletion_queue.include?(message.note) } mark_changed true end
Remove all input note messages @return [Boolean]
# File lib/diamond/sequence.rb, line 59 def remove_all @input_queue.clear mark_changed true end
Protected Instance Methods
Apply the given parameters object @param [SequenceParameters] parameters @return [SequenceParameters]
# File lib/diamond/sequence.rb, line 87 def use_parameters(parameters) @parameter = parameters update end
Private Instance Methods
Create a bucket/note event for the given note message @param [MIDIMessage::NoteOn] note_message @return [Array<NoteEvent>]
# File lib/diamond/sequence.rb, line 159 def create_bucket(note_message) event = MIDIInstrument::NoteEvent.new(note_message, @parameter.gate) [event] end
Prepare the given event bucket for performance, moving note messages to the queue @param [Array<NoteEvent>] bucket @return [Array<NoteEvent>]
# File lib/diamond/sequence.rb, line 106 def enqueue(bucket) bucket.map do |event| @queue[0] ||= [] @queue[0] << event.start float_length = (event.length.to_f / 100) * @parameter.duration.to_f length = float_length.to_i @queue[length] ||= [] @queue[length] << event.finish event end end
Enqueue next bucket for the given pointer @param [Fixnum] pointer @return [Array<NoteEvent>]
# File lib/diamond/sequence.rb, line 97 def enqueue_next(pointer) bucket = @sequence[pointer] enqueue(bucket) unless bucket.nil? bucket end
The input queue as note messages @return [Array<MIDIMessage::NoteOn>]
# File lib/diamond/sequence.rb, line 166 def get_note_sequence notes = @parameter.computed_pattern.map do |degree| @input_queue.map do |message| note = message.note + degree + @parameter.transpose MIDIMessage::NoteOn.new(message.channel, note, message.velocity) end end notes.flatten.compact end
(Re)initialize the sequence with the given length @param [Fixnum] length @return [Array]
# File lib/diamond/sequence.rb, line 131 def initialize_sequence(length) sequence_length_in_ticks = length * @parameter.duration @sequence = Array.new(sequence_length_in_ticks, []) end
Populate the bucket for index with the given note message @param [Fixnum] index @param [MIDIMessage::NoteOn] note_message @return [Array<NoteEvent>]
# File lib/diamond/sequence.rb, line 152 def populate_bucket(index, note_message) @sequence[index] = create_bucket(note_message) end
Populate the sequence with the given notes @param [Array<MIDIMessage::NoteOn>] notes @return [Array<Array<NoteEvent>>]
# File lib/diamond/sequence.rb, line 139 def populate_sequence(notes) @parameter.pattern_offset.times { notes.push(notes.shift) } notes.each_with_index do |note, i| index = i * @parameter.duration populate_bucket(index, note) unless @sequence[index].nil? end @sequence end
Commit changes to the sequence @return [ArpeggiatorSequence]
# File lib/diamond/sequence.rb, line 120 def update notes = get_note_sequence initialize_sequence(notes.length) populate_sequence(notes) unless notes.empty? @changed = false @sequence end