Class: Musicality::NoteFIFO
- Inherits:
-
Object
- Object
- Musicality::NoteFIFO
- Defined in:
- lib/musicality/composition/sequencing/note_fifo.rb
Instance Attribute Summary collapse
-
#duration ⇒ Object
readonly
Returns the value of attribute duration.
-
#notes ⇒ Object
readonly
Returns the value of attribute notes.
Instance Method Summary collapse
- #add_note(note) ⇒ Object
- #add_notes(notes) ⇒ Object
- #empty? ⇒ Boolean
-
#initialize(initial_notes = []) ⇒ NoteFIFO
constructor
A new instance of NoteFIFO.
-
#remove_notes(target_duration) ⇒ Object
Return a sequence of notes with total duration equal to the given target duration, and remove the same notes from the accumulator.
Constructor Details
#initialize(initial_notes = []) ⇒ NoteFIFO
Returns a new instance of NoteFIFO.
5 6 7 8 9 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 5 def initialize initial_notes = [] @notes = [] @duration = 0 add_notes(initial_notes) if initial_notes.any? end |
Instance Attribute Details
#duration ⇒ Object (readonly)
Returns the value of attribute duration.
4 5 6 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 4 def duration @duration end |
#notes ⇒ Object (readonly)
Returns the value of attribute notes.
4 5 6 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 4 def notes @notes end |
Instance Method Details
#add_note(note) ⇒ Object
15 16 17 18 19 20 21 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 15 def add_note note if note.duration <= 0 raise ArgumentError, "note have non-positive duration: #{note}" end @notes.push note @duration += note.duration end |
#add_notes(notes) ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 23 def add_notes notes nonpositive = notes.select {|x| x.duration <= 0} if nonpositive.any? raise ArgumentError, "one or more notes have non-positive duration: #{notes}" end @notes += notes @duration += notes.inject(0) {|sum, note| sum + note.duration } end |
#empty? ⇒ Boolean
11 12 13 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 11 def empty? @notes.empty? end |
#remove_notes(target_duration) ⇒ Object
Return a sequence of notes with total duration equal to the given target duration, and remove the same notes from the accumulator. Any notes beyond the given target duration are left in the accumulator. Split a note into two tied notes if needed.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/musicality/composition/sequencing/note_fifo.rb', line 35 def remove_notes target_duration raise ArgumentError, "negative target duration #{target_duration}" if target_duration < 0 if target_duration > duration raise ArgumentError, "target duration #{target_duration} is greater than duration of accumulated notes #{duration}" end removed_notes = if target_duration == 0 [] elsif target_duration == duration notes.shift(notes.size) else dur_so_far = 0.to_r num_notes_taking = 0 @notes.each_with_index do |note, idx| dur_so_far += note.duration num_notes_taking += 1 break if dur_so_far >= target_duration end notes_taking = notes.shift(num_notes_taking) excess_dur = dur_so_far - target_duration if excess_dur > 0 @notes.unshift(notes_taking[-1].resize(excess_dur)) notes_taking[-1] = notes_taking[-1].resize(notes_taking[-1].duration - excess_dur) notes_taking[-1].pitches.each do |pitch| notes_taking[-1].links[pitch] = Link::Tie.new end end notes_taking end @duration = @duration - target_duration return removed_notes end |