class PicoTune::Phrase
Attributes
beats[R]
melodies[R]
name[R]
simultaneous_melodies[R]
subbeats[R]
tempo[R]
tune[RW]
Public Class Methods
new(name, tempo, beats, subbeats, melodies)
click to toggle source
# File lib/picotune.rb, line 214 def initialize name, tempo, beats, subbeats, melodies @name = name @tempo = tempo.to_i @beats = beats.to_i @subbeats = subbeats.to_i @melodies = melodies @simultaneous_melodies = @melodies.count @melodies.each do |m| m.instrument.phrase = self end end
Public Instance Methods
buffer()
click to toggle source
# File lib/picotune.rb, line 239 def buffer @buffer ||= begin samples = Array.new(buffer_size) { PicoTune::Sample.new } @melodies.each do |melody| temp = Array.new(buffer_size) { PicoTune::Sample.new } if melody.instrument.reverb? sub_buffer_size = buffer_size / (@beats * @subbeats) last_step_number = -1 carry_over = 0 if melody.pattern.steps.count != @beats * @subbeats raise "Mismatch between Pattern \"#{melody.pattern.name}\", which has #{melody.pattern.steps.count} steps, and Phrase \"#{@name}\", which has #{@beats} beats and #{subbeats} subbeats (meaning any pattern it uses should have #{@beats * @subbeats} steps). Please check your pattern and phrase definitions to find the discrepancy!" end melody.pattern.steps.each_with_index do |note, step_number| unless note == '.' buffer_pointer = step_number * sub_buffer_size local_index = 0 wave_index = 0 length_offset = (1 - melody.instrument.length_value) * sub_buffer_size if step_number == last_step_number + 1 local_index = carry_over end carry_over = 0 while local_index + length_offset < sub_buffer_size || !wave_index.zero? current_sample = (temp ? temp : samples)[buffer_pointer + local_index] || PicoTune::Sample.new new_sample = melody.instrument.wave wave_index, note current_sample.add new_sample (temp ? temp : samples)[buffer_pointer + local_index] = current_sample wave_index += 1 local_index += 1 last_step_number = step_number carry_over += 1 if local_index + length_offset >= sub_buffer_size wave_index = 0 if wave_index >= melody.instrument.samples_per_wave(note) end if melody.instrument.reverb? i = 0 while i < temp.size if i + melody.instrument.reverb_offset < temp.size verb_sample = temp[i + melody.instrument.reverb_offset] verb_sample.modify_left :+, temp[i].left * melody.instrument.decay verb_sample.modify_right :+, temp[i].right * melody.instrument.decay temp[i + melody.instrument.reverb_offset] = verb_sample end samples[i] = (samples[i] || PicoTune::Sample.new).add temp[i] i += 1 end end end end end samples end end
buffer_size()
click to toggle source
# File lib/picotune.rb, line 235 def buffer_size (seconds_per_measure * PicoTune::SAMPLE_RATE).to_i end
seconds_per_beat()
click to toggle source
# File lib/picotune.rb, line 227 def seconds_per_beat 60.0 / @tempo end
seconds_per_measure()
click to toggle source
# File lib/picotune.rb, line 231 def seconds_per_measure seconds_per_beat * @beats end