class Musicality::Note
Constants
- CONVERSION_METHOD
- PARSER
- SMALLEST_PIECE
Attributes
articulation[RW]
duration[R]
links[R]
marks[R]
pitches[R]
Public Class Methods
add_note_method(name, dur)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 126 def self.add_note_method(name, dur) self.class.send(:define_method,name.to_sym) do |pitches = [], links: {}, articulation: Articulations::NORMAL, marks: []| Note.new(dur, pitches, articulation: articulation, links: links, marks: marks) end end
new(duration, pitches = [], links: {})
click to toggle source
# File lib/musicality/notation/model/note.rb, line 12 def initialize duration, pitches = [], links: {}, articulation: Articulations::NORMAL, marks: [] self.duration = duration if !pitches.is_a? Enumerable pitches = [ pitches ] end @pitches = Set.new(pitches).sort @links = links @articulation = articulation @marks = marks end
Public Instance Methods
==(other)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 40 def == other return (@duration == other.duration) && (self.pitches == other.pitches) && (@links.to_a.sort == other.links.to_a.sort) && (@articulation == other.articulation) && (@marks == marks) end
begins_slur?()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 92 def begins_slur? marks.count {|m| m.is_a?(Mark::Slur::Begin) } > 0 end
check_duration()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 27 def check_duration if duration <= 0 raise RangeError, "Duration is non-positive: #{duration}" end end
check_methods()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 23 def check_methods [ :check_duration, :check_pitches ] end
check_pitches()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 33 def check_pitches non_pitches = @pitches.select {|p| !p.is_a?(Pitch) } if non_pitches.any? raise TypeError, "Found non-pitches: #{non_pitches}" end end
clone()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 48 def clone Marshal.load(Marshal.dump(self)) end
duration=(duration)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 52 def duration= duration raise NonPositiveError, "duration #{duration} is not positive" unless duration > 0 #@duration = duration.is_a?(Duration) ? duration : duration.to_dur @duration = duration end
ends_slur?()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 96 def ends_slur? marks.count {|m| m.is_a?(Mark::Slur::End) } > 0 end
fractional_subdurs(smallest_piece)
click to toggle source
# File lib/musicality/printing/lilypond/note_engraving.rb, line 77 def fractional_subdurs smallest_piece remaining = @duration - @duration.to_i pieces = [] i = 0 while((current_dur = Rational(1,2<<i)) >= smallest_piece) if remaining >= current_dur pieces.push current_dur remaining -= current_dur end i += 1 end unless remaining.zero? raise RuntimeError, "Non-zero remainder #{remaining}" end return pieces end
mark_accented!()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 76 def mark_accented! @articulation = Articulations::ACCENT end
resize(duration)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 58 def resize duration new_note = self.clone new_note.duration = duration return new_note end
tie_to(pitches)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 64 def tie_to pitches new_note = self.clone if pitches.is_a? Pitch pitches = [pitches] end pitches.each do |pitch| new_note.links[pitch] = Link::Tie.new end return new_note end
to_lilypond(sharpit = false, begins_triplet: false, ends_triplet: false)
click to toggle source
# File lib/musicality/printing/lilypond/note_engraving.rb, line 6 def to_lilypond sharpit = false, begins_triplet: false, ends_triplet: false subdurs = [1]*@duration.to_i + fractional_subdurs(SMALLEST_PIECE) piece_strs = [] pitches_to_strs = Hash[ pitches.map {|p| [p,p.to_lilypond(sharpit)] }] while subdurs.any? subdur = subdurs.shift dur_str = subdur.denominator.to_s if subdurs.any? && subdur == subdurs.first*2 dur_str += "." subdurs.shift end last = subdurs.empty? piece_str = if pitches.any? if last # figure if ties are needed on per-pitch basis, based on note links if pitches_to_strs.size == 1 p, p_str = pitches_to_strs.first needs_tie = links.include?(p) && links[p].is_a?(Link::Tie) p_str + dur_str + (needs_tie ? "~" : "") else p_strs = pitches_to_strs.map do |p,p_str| if links.include?(p) && links[p].is_a?(Link::Tie) p_str + "~" else p_str end end "<#{p_strs.join(" ")}>" + dur_str end else str = if pitches.size == 1 pitches_to_strs.values.first else "<#{pitches_to_strs.values.join(" ")}>" end str + dur_str + "~" end else "r" + dur_str end piece_strs.push piece_str end if pitches.any? if articulation != Articulations::NORMAL piece_strs[0] += "-" + ARTICULATION_SYMBOLS[articulation] end if begins_slur? piece_strs[-1] += MARK_SYMBOLS[Mark::Slur::Begin] end if ends_slur? piece_strs[-1] += MARK_SYMBOLS[Mark::Slur::End] end end if begins_triplet piece_strs[0].prepend("\\tuplet 3/2 {") end if ends_triplet piece_strs[-1].concat("}") end return piece_strs.join(" ") end
to_s()
click to toggle source
# File lib/musicality/notation/model/note.rb, line 100 def to_s d = @duration.to_r if d.denominator == 1 dur_str = "#{d.numerator}" elsif d.numerator == 1 dur_str = "/#{d.denominator}" else dur_str = d.to_s end pitch_links_str = @pitches.map do |p| if @links.has_key?(p) p.to_s + @links[p].to_s else p.to_s end end.join(",") art_str = ARTICULATION_SYMBOLS[@articulation] || "" begin_marks_str = marks.select {|m| m.begins? }.map {|m| m.to_s }.join end_marks_str = marks.select {|m| m.ends? }.map {|m| m.to_s }.join return begin_marks_str + dur_str + pitch_links_str + art_str + end_marks_str end
transpose(diff)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 80 def transpose diff self.clone.transpose! diff end
transpose!(diff)
click to toggle source
# File lib/musicality/notation/model/note.rb, line 84 def transpose! diff @pitches = @pitches.map {|pitch| pitch.transpose(diff) } @links = Hash[ @links.map do |k,v| [ k.transpose(diff), v.transpose(diff) ] end ] return self end
Private Instance Methods
figure_pitch_and_joipiece_str(sharpit)
click to toggle source
# File lib/musicality/printing/lilypond/note_engraving.rb, line 119 def figure_pitch_and_joipiece_str sharpit if pitches.any? if pitches.size == 1 p_str = pitches.first.to_lilypond(sharpit) else p_str = "<" + pitches.map {|p| p.to_lilypond(sharpit) }.join(" ") + ">" end joipiece_str = "~ " else p_str = "r" joipiece_str = " " end return [ p_str, joipiece_str ] end
pieces_to_dur_strs(pieces)
click to toggle source
# File lib/musicality/printing/lilypond/note_engraving.rb, line 99 def pieces_to_dur_strs pieces dur_strs = [] while pieces.any? piece = pieces.shift triplet = piece.denominator % 3 == 0 piece_str = (triplet ? (piece * 1.5.to_r) : piece).denominator.to_s if pieces.any? && piece == pieces.first*2 piece_str += "." pieces.shift end if triplet piece_str = "\\tuplet 3/2 { #{piece_str} }" end dur_strs.push piece_str end return dur_strs end