class StringyFi::Converter
Constants
- INITIAL_OCTAVE
- OCTAVE_OFFSET
Attributes
filename[RW]
xml_doc[RW]
Public Class Methods
new(filename)
click to toggle source
# File lib/stringyfi/converter.rb, line 10 def initialize(filename) self.filename = filename end
Public Instance Methods
convert!()
click to toggle source
# File lib/stringyfi/converter.rb, line 14 def convert! $stderr.puts "converting #{filename}.." shortest_fractional_duration = measures.shortest_fractional_duration $stderr.puts " shortest_fractional_duration: #{shortest_fractional_duration}" $stderr.puts " octave_range: #{measures.octave_range.inspect}" puts score_preamble puts score_body(shortest_fractional_duration) puts score_coda $stderr.puts ".. done." end
encoding_date()
click to toggle source
# File lib/stringyfi/converter.rb, line 90 def encoding_date xml_doc.xpath('//identification/encoding/encoding-date').text end
encoding_software()
click to toggle source
# File lib/stringyfi/converter.rb, line 94 def encoding_software xml_doc.xpath('//identification/encoding/software').text end
identification()
click to toggle source
# File lib/stringyfi/converter.rb, line 98 def identification { title: title, encoding: { date: encoding_date, software: encoding_software } } end
io_stream()
click to toggle source
# File lib/stringyfi/converter.rb, line 160 def io_stream File.open(filename).read end
measure(measure_id)
click to toggle source
# File lib/stringyfi/converter.rb, line 152 def measure(measure_id) measures[measure_id] end
measures()
click to toggle source
Returns measures for the piece. only converts one part (for now) only includes staff 1
# File lib/stringyfi/converter.rb, line 122 def measures @measures ||= begin measures = StringyFi::Measures.new part = parts.first part.xpath('measure').each_with_index do |part_measure, m| measures[m] ||= [] part_measure.xpath('note').each_with_object(measures[m]) do |note, memo| next unless note.xpath("staff").text == "1" next unless note.xpath("voice").text == "1" pitch = note.xpath("pitch") duration = note.xpath("duration").text.to_i actual_notes = note.xpath("actual-notes").text.to_i normal_notes = note.xpath("normal-notes").text.to_i if actual_notes > 0 and normal_notes > 0 duration = duration * 1.0 * normal_notes / actual_notes end duration_type = note.xpath("type").text memo << StringyFi::Note.new( pitch.xpath('step').text, pitch.xpath('octave').text, pitch.xpath('alter').text, duration, duration_type ) end end measures end end
part_list()
click to toggle source
# File lib/stringyfi/converter.rb, line 107 def part_list xml_doc.xpath('//part-list/score-part').each_with_object([]) do |part,memo| h = {} h[:id] = part.attr('id') memo << h end end
parts()
click to toggle source
# File lib/stringyfi/converter.rb, line 115 def parts xml_doc.xpath('//part') end
score_body(shortest_fractional_duration)
click to toggle source
# File lib/stringyfi/converter.rb, line 47 def score_body(shortest_fractional_duration) lines = [] current_octave = INITIAL_OCTAVE + OCTAVE_OFFSET measures.each_with_index do |measure, measure_index| lines << "\t; measure #{measure_index+1}" measure.each do |note| unless note.rest? if note.octave != current_octave delta = note.octave - current_octave sign = delta > 0 ? "+" : "-" (delta.abs).times do lines << "\ttoctave #{sign}1" end current_octave = note.octave end end short_repeats, medium_repeats, long_repeats, very_long_repeats = note.stringy_durations(shortest_fractional_duration) if note.rest? (short_repeats).times { lines << "\ttrest 1" } (medium_repeats).times { lines << "\ttrest 2" } (long_repeats).times { lines << "\ttrest 3" } (very_long_repeats).times { lines << "\ttrest 4" } else (short_repeats).times { lines << "\ttnote #{note.to_stringy(current_octave)},1,0 ; #{note.to_note_id}" } (medium_repeats).times { lines << "\ttnote #{note.to_stringy(current_octave)},2,0 ; #{note.to_note_id}" } (long_repeats).times { lines << "\ttnote #{note.to_stringy(current_octave)},3,0 ; #{note.to_note_id}" } (very_long_repeats).times { lines << "\ttnote #{note.to_stringy(current_octave)},4,0 ; #{note.to_note_id}" } end end end lines end
score_coda()
click to toggle source
# File lib/stringyfi/converter.rb, line 40 def score_coda <<-EOS \ttrest 8 \ttstop EOS end
score_preamble()
click to toggle source
# File lib/stringyfi/converter.rb, line 27 def score_preamble <<-EOS ;************************************************************************** ;** Title: #{title} ;** Tempo: #{tempo} ;** Encoded: #{encoding_date} with #{encoding_software} ;** Stringyfied: #{Time.now} ;************************************************************************** \ttstart DemoTune EOS end
tempo()
click to toggle source
Simplified - only supports one tempo for the piece assumed for quarter note
# File lib/stringyfi/converter.rb, line 86 def tempo @tempo ||= xml_doc.xpath('//measure/direction/sound/@tempo').to_s.to_i end
title()
click to toggle source
# File lib/stringyfi/converter.rb, line 80 def title xml_doc.xpath('//work/work-title').text end