class Musicality::PartEngraver
Constants
- CLEF_RANGES
- INDENT
- MAX_LINE_LEN
Public Class Methods
best_clef(notes, allowed_clefs)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 93 def self.best_clef notes, allowed_clefs raise ArgumentError unless notes.any? raise ArgumentError unless allowed_clefs.any? ranges = CLEF_RANGES.select {|clef,range| allowed_clefs.include?(clef) } range_scores = Hash.new(0) notes.each do |note| note.pitches.each do |p| ranges.each do |name,range| if p >= range.min && p <= range.max range_scores[name] += note.duration end end end end range_score = range_scores.max_by {|range,score| score} range_score.nil? ? allowed_clefs.first : range_score[0] end
new(part, title)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 7 def initialize part, title if part.invalid? raise ArgumentError, "given part contains errors: #{part.errors}" end @transpose_interval = part.lilypond_settings.transpose_interval @clefs = part.lilypond_settings.clefs @part = (@transpose_interval == 0) ? part : part.transpose(@transpose_interval) @title = title @indent = INDENT @triplet_flags = @part.notes.map do |note| note.duration.to_r.denominator % 3 == 0 end end
Public Instance Methods
decrease_indent()
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 27 def decrease_indent @indent = @indent[0...-INDENT.size] end
increase_indent()
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 23 def increase_indent @indent += INDENT end
make_body(sharpit)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 56 def make_body sharpit i = 0 pieces = @part.notes.map do |n| str = if @triplet_flags[i] n.resize(n.duration * Rational(3,2)).to_lilypond(sharpit, begins_triplet: i == 0 || !@triplet_flags[i-1], ends_triplet: i == (@triplet_flags.size-1) || !@triplet_flags[i+1]) else n.to_lilypond(sharpit) end i += 1 str end output = "" while pieces.any? line = @indent + pieces.shift until pieces.empty? || (line.size + 1 + pieces.first.size) > MAX_LINE_LEN line += " " + pieces.shift end output += line + "\n" end return output end
make_final()
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 81 def make_final decrease_indent return @indent + "}\n" end
make_lilypond(start_key, start_meter, key_changes: {})
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 31 def make_lilypond start_key, start_meter, key_changes: {}, meter_changes: {}, master: false if @transpose_interval != 0 start_key = transpose_start_key(start_key) key_changes = transpose_key_changes(key_changes) end sharpit = start_key.sharp? return make_preliminary(start_meter, start_key, master) + make_body(sharpit) + make_final() end
make_preliminary(start_meter, start_key, master)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 42 def make_preliminary start_meter, start_key, master clef = self.class.best_clef(@part.notes, @clefs) output = @indent + "\\new Staff {\n" increase_indent output += @indent + "\\set Staff.instrumentName = \\markup { \"#{@title}\" }\n" output += @indent + "\\clef #{clef}\n" if master output += @indent + start_meter.to_lilypond + "\n" end output += @indent + start_key.to_lilypond + "\n" return output end
Private Instance Methods
transpose_key_changes(key_changes)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 119 def transpose_key_changes key_changes Hash[ key_changes.map do |off,change| change.clone {|v| v.transpose(@transpose_interval) } end ] end
transpose_start_key(start_key)
click to toggle source
# File lib/musicality/printing/lilypond/part_engraver.rb, line 115 def transpose_start_key start_key start_key.transpose(@transpose_interval) end