From 0dbbf74640c366256f5cbe869de5a4b9d3d621d0 Mon Sep 17 00:00:00 2001 From: Matthias Neeracher Date: Sun, 26 Aug 2007 22:57:18 +0000 Subject: [PATCH] Writes chords and notes in original format --- Filters/VLMusicXMLType.writer | 165 +++++++++++++++++++++++++++++++++- Filters/plistReader.rb | 1 + Filters/vl.rb | 11 +++ 3 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 Filters/vl.rb diff --git a/Filters/VLMusicXMLType.writer b/Filters/VLMusicXMLType.writer index 449249b..f4b016c 100644 --- a/Filters/VLMusicXMLType.writer +++ b/Filters/VLMusicXMLType.writer @@ -3,11 +3,15 @@ # VLMusicXMLType.write - Translate plist into MusicXML # -require File.dirname($0)+'plistReader' +require File.dirname($0)+'/plistReader' +require File.dirname($0)+'/vl' require 'rexml/document' INPUT = readPlist($stdin) +$USE_FLATS = false +$DIVISIONS = 3 + def _work work = REXML::Element.new('work') title = REXML::Element.new('work-title') @@ -26,10 +30,10 @@ def _identification poet = REXML::Element.new('creator') poet.add_attribute('type', 'poet') poet.add_text(INPUT['lyricist']) - ident.add_element(lyricist) + ident.add_element(poet) encoding = REXML::Element.new('encoding') date = REXML::Element.new('encoding-date') - date.add_text(INPUT['saved'].strftime("%Y-%m-%d") + date.add_text(INPUT['saved'].strftime("%Y-%m-%d")) encoding.add_element(date) software = REXML::Element.new('software') software.add_text(INPUT['software']) @@ -57,20 +61,175 @@ def _part_list return part_list end +def _attributes(prop) + $USE_FLATS = prop['key'] < 0 + $DIVISIONS = prop['divisions'] + attr = REXML::Element.new('attributes') + div = REXML::Element.new('divisions') + div.add_text(prop['divisions'].to_s) + attr.add_element(div) + key = REXML::Element.new('key') + fifths = REXML::Element.new('fifths') + fifths.add_text(prop['key'].to_s) + key.add_element(fifths) + mode = REXML::Element.new('mode') + mode.add_text(prop['mode'] > 0 ? "major" : "minor") + key.add_element(mode) + attr.add_element(key) + time = REXML::Element.new('time') + beats = REXML::Element.new('beats') + beats.add_text(prop['timeNum'].to_s) + time.add_element(beats) + beatType = REXML::Element.new('beat-type') + beatType.add_text(prop['timeDenom'].to_s) + time.add_element(beatType) + attr.add_element(time) + clef = REXML::Element.new('clef') + sign = REXML::Element.new('sign') + sign.add_text('G') + clef.add_element(sign) + line = REXML::Element.new('line') + line.add_text('2') + clef.add_element(line) + attr.add_element(clef) + + return attr +end + +STEPS = 'C DbD EbE F GbG AbA BbB ' + +def _note(pitch, dur, tied=0) + note = REXML::Element.new('note') + if pitch == VL::NoPitch + note.add_element(REXML::Element.new('rest')) + else + oct = pitch/12 - 1 + stp = 2*(pitch%12) + step = STEPS[stp] + alt = STEPS[stp+1] == ?b + if alt + if $USE_FLATS + alt = "-1" + else + step = step == ?A ? ?G : step-1 + alt = "1" + end + end + if (tied & VL::InChord) != 0 + note.add_element 'chord' + end + pitch= REXML::Element.new('pitch') + st = REXML::Element.new('step') + st.add_text(step.chr) + pitch.add_element(st) + if alt + a = REXML::Element.new('alter') + a.add_text(alt) + pitch.add_element(a) + end + o = REXML::Element.new('octave') + o.add_text(oct.to_s) + pitch.add_element(o) + note.add_element(pitch) + end + d = REXML::Element.new('duration') + d.add_text(dur.to_s) + note.add_element(d) + if (tied & VL::TiedWithPrev) != 0 + t = REXML::Element.new('tie') + t.add_attribute('type', 'stop') + note.add_element(t) + end + if (tied & VL::TiedWithNext) != 0 + t = REXML::Element.new('tie') + t.add_attribute('type', 'start') + note.add_element(t) + end + voice = REXML::Element.new('voice') + voice.add_text("1") + note.add_element(voice) + + return note +end + def _chords chords = REXML::Element.new('part') chords.add_attribute('id', 'HARM') + lastProp = -1 + measNum = 0 INPUT['measures'].each do |meas| + measNum += 1 + m = REXML::Element.new('measure') + m.add_attribute('number', measNum.to_s); + if meas['properties'] != lastProp + lastProp = meas['properties'] + m.add_element(_attributes(INPUT['properties'][lastProp])) + end + meas['chords'].each do |chord| + dur = (chord['durNum'] * $DIVISIONS * 4) / chord['durDenom'] + if chord['pitch'] == VL::NoPitch + m.add_element _note(VL::NoPitch, dur) + else + seenNote = 0 + if chord['root'] != VL::NoPitch + m.add_element _note(chord['root'], dur) + seenNote = VL::InChord + end + pitch = chord['pitch'] + steps = chord['steps'] + (0..25).each do |step| + if (steps & (1<