mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 19:23:59 +00:00
Better error propagation
This commit is contained in:
parent
2ac1ed067c
commit
d530d4ae38
|
@ -3,45 +3,20 @@
|
||||||
# VLLilypondType.reader - Import lilypond files
|
# VLLilypondType.reader - Import lilypond files
|
||||||
#
|
#
|
||||||
|
|
||||||
DEBUG = false
|
|
||||||
|
|
||||||
require File.dirname($0)+'/plistWriter'
|
require File.dirname($0)+'/plistWriter'
|
||||||
require File.dirname($0)+'/vl'
|
require File.dirname($0)+'/vl'
|
||||||
|
|
||||||
OUTPUT = {'measures' => []}
|
OUTPUT = {'measures' => []}
|
||||||
|
CHORDS = []
|
||||||
#
|
NOTES = []
|
||||||
# Lex
|
STANZAS= []
|
||||||
#
|
MEAS = []
|
||||||
tokens = []
|
|
||||||
INFILE.each do |line|
|
|
||||||
line.chomp!.sub!(/%.*/, "")
|
|
||||||
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|--|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
|
||||||
tokens.push(token[0])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
#
|
|
||||||
# Parse
|
|
||||||
#
|
|
||||||
nestLevel = 0
|
|
||||||
block = nil
|
|
||||||
level = -1
|
|
||||||
stack = []
|
|
||||||
repeats = []
|
|
||||||
chords = []
|
|
||||||
notes = []
|
|
||||||
lyrics = []
|
|
||||||
stanzas = []
|
|
||||||
lastDur = 1
|
|
||||||
tied = false
|
|
||||||
repeat = 0
|
|
||||||
timeNum = 4
|
|
||||||
timeDenom = 4
|
|
||||||
key = 0
|
|
||||||
mode = 'minor'
|
|
||||||
lyricFlags= 0
|
|
||||||
|
|
||||||
$RELPITCH = 0
|
$RELPITCH = 0
|
||||||
|
$timeNum = 4
|
||||||
|
$timeDenom= 4
|
||||||
|
$key = 0
|
||||||
|
$mode = '\major'
|
||||||
|
|
||||||
PITCH = {
|
PITCH = {
|
||||||
?c => 0,
|
?c => 0,
|
||||||
|
@ -202,6 +177,31 @@ def lySteps(steps)
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parseLilypond
|
||||||
|
#
|
||||||
|
# Lex
|
||||||
|
#
|
||||||
|
tokens = []
|
||||||
|
INFILE.each do |line|
|
||||||
|
line.chomp!.sub!(/%.*/, "")
|
||||||
|
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|--|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
||||||
|
tokens.push(token[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#
|
||||||
|
# Parse
|
||||||
|
#
|
||||||
|
nestLevel = 0
|
||||||
|
block = nil
|
||||||
|
level = -1
|
||||||
|
stack = []
|
||||||
|
repeats = []
|
||||||
|
lyrics = []
|
||||||
|
lastDur = 1
|
||||||
|
tied = false
|
||||||
|
repeat = 0
|
||||||
|
lyricFlags= 0
|
||||||
|
|
||||||
while tokens.length > 0
|
while tokens.length > 0
|
||||||
token = tokens.shift
|
token = tokens.shift
|
||||||
#
|
#
|
||||||
|
@ -249,8 +249,8 @@ while tokens.length > 0
|
||||||
|
|
||||||
chord = {'pitch' => pitch, 'root' => root, 'steps' => ext,
|
chord = {'pitch' => pitch, 'root' => root, 'steps' => ext,
|
||||||
'durNum'=> d[0], 'durDenom' => d[1]}
|
'durNum'=> d[0], 'durDenom' => d[1]}
|
||||||
p token, chord if DEBUG
|
p token, chord if $DEBUG
|
||||||
chords.push(chord)
|
CHORDS.push(chord)
|
||||||
redo
|
redo
|
||||||
end
|
end
|
||||||
when 'voice'
|
when 'voice'
|
||||||
|
@ -273,12 +273,12 @@ while tokens.length > 0
|
||||||
|
|
||||||
note = {'pitch' => pitch, 'durNum'=> d[0], 'durDenom' => d[1]}
|
note = {'pitch' => pitch, 'durNum'=> d[0], 'durDenom' => d[1]}
|
||||||
note['tied'] = VL::TiedWithPrev if tied
|
note['tied'] = VL::TiedWithPrev if tied
|
||||||
p token, note if DEBUG
|
p token, note if $DEBUG
|
||||||
notes.push(note)
|
NOTES.push(note)
|
||||||
tied = false
|
tied = false
|
||||||
redo
|
redo
|
||||||
elsif token == '~'
|
elsif token == '~'
|
||||||
if note = notes.last
|
if note = NOTES.last
|
||||||
note['tied'] ||= 0
|
note['tied'] ||= 0
|
||||||
note['tied'] |= VL::TiedWithNext
|
note['tied'] |= VL::TiedWithNext
|
||||||
end
|
end
|
||||||
|
@ -289,7 +289,7 @@ while tokens.length > 0
|
||||||
level = nestLevel
|
level = nestLevel
|
||||||
repeats.push(repeat)
|
repeats.push(repeat)
|
||||||
repeat = tokens[1].to_i
|
repeat = tokens[1].to_i
|
||||||
notes.push({'begin-repeat' => true, 'times' => repeat})
|
NOTES.push({'begin-repeat' => true, 'times' => repeat})
|
||||||
tokens[0..1] = nil
|
tokens[0..1] = nil
|
||||||
redo
|
redo
|
||||||
elsif token == '\alternative'
|
elsif token == '\alternative'
|
||||||
|
@ -298,7 +298,7 @@ while tokens.length > 0
|
||||||
level = nestLevel+1
|
level = nestLevel+1
|
||||||
voltas = 0
|
voltas = 0
|
||||||
curVoltas = nil
|
curVoltas = nil
|
||||||
notes.push({'begin-ending' => true})
|
NOTES.push({'begin-ending' => true})
|
||||||
elsif token == '\times' && tokens[0] =~ %r|^(\d+)/(\d+)|
|
elsif token == '\times' && tokens[0] =~ %r|^(\d+)/(\d+)|
|
||||||
$timesNum = $1.to_i
|
$timesNum = $1.to_i
|
||||||
$timesDen = $2.to_i
|
$timesDen = $2.to_i
|
||||||
|
@ -310,22 +310,22 @@ while tokens.length > 0
|
||||||
lyrics.last[1] |= VL::TiedWithNext if lyrics.size > 0
|
lyrics.last[1] |= VL::TiedWithNext if lyrics.size > 0
|
||||||
lyricFlags = VL::TiedWithPrev
|
lyricFlags = VL::TiedWithPrev
|
||||||
elsif token == '\skip'
|
elsif token == '\skip'
|
||||||
p ["", 0] if DEBUG
|
p ["", 0] if $DEBUG
|
||||||
lyrics.push ["", 0]
|
lyrics.push ["", 0]
|
||||||
lyricFlags = 0
|
lyricFlags = 0
|
||||||
if tokens[0] =~ /\d+/
|
if tokens[0] =~ /\d+/
|
||||||
tokens[0..0] = nil
|
tokens[0..0] = nil
|
||||||
end
|
end
|
||||||
elsif token =~ /\\skip\d+/
|
elsif token =~ /\\skip\d+/
|
||||||
p ["", 0] if DEBUG
|
p ["", 0] if $DEBUG
|
||||||
lyrics.push ["", 0]
|
lyrics.push ["", 0]
|
||||||
lyricFlags = 0
|
lyricFlags = 0
|
||||||
elsif token =~ /"(.*)"/
|
elsif token =~ /"(.*)"/
|
||||||
p [$1, lyricFlags] if DEBUG
|
p [$1, lyricFlags] if $DEBUG
|
||||||
lyrics.push [$1, lyricFlags]
|
lyrics.push [$1, lyricFlags]
|
||||||
lyricFlags = 0
|
lyricFlags = 0
|
||||||
elsif token =~ /^\w.*/
|
elsif token =~ /^\w.*/
|
||||||
p [token, lyricFlags] if DEBUG
|
p [token, lyricFlags] if $DEBUG
|
||||||
lyrics.push [token, lyricFlags]
|
lyrics.push [token, lyricFlags]
|
||||||
lyricFlags = 0
|
lyricFlags = 0
|
||||||
end
|
end
|
||||||
|
@ -350,7 +350,7 @@ while tokens.length > 0
|
||||||
end
|
end
|
||||||
if type == "repeat"
|
if type == "repeat"
|
||||||
if tokens[0] != '\alternative'
|
if tokens[0] != '\alternative'
|
||||||
notes.push({'end-repeat' => true})
|
NOTES.push({'end-repeat' => true})
|
||||||
repeat = repeats.pop
|
repeat = repeats.pop
|
||||||
end
|
end
|
||||||
elsif type == "endings"
|
elsif type == "endings"
|
||||||
|
@ -363,14 +363,14 @@ while tokens.length > 0
|
||||||
curVoltas <<= 1
|
curVoltas <<= 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
notes.push({'end-ending' => true, 'volta' => curVoltas,
|
NOTES.push({'end-ending' => true, 'volta' => curVoltas,
|
||||||
'last'=>last})
|
'last'=>last})
|
||||||
voltas |= curVoltas
|
voltas |= curVoltas
|
||||||
curVoltas = 0
|
curVoltas = 0
|
||||||
if last
|
if last
|
||||||
repeat = repeats.pop
|
repeat = repeats.pop
|
||||||
else
|
else
|
||||||
notes.push({'begin-ending' => true})
|
NOTES.push({'begin-ending' => true})
|
||||||
stack.push([block, level, "endings"])
|
stack.push([block, level, "endings"])
|
||||||
level = nestLevel
|
level = nestLevel
|
||||||
end
|
end
|
||||||
|
@ -383,7 +383,7 @@ while tokens.length > 0
|
||||||
stack.push([block, level, ""])
|
stack.push([block, level, ""])
|
||||||
block = token
|
block = token
|
||||||
level = nestLevel
|
level = nestLevel
|
||||||
stanzas.push(lyrics= []) if block == '\lyricmode'
|
STANZAS.push(lyrics= []) if block == '\lyricmode'
|
||||||
when '\chordmode'
|
when '\chordmode'
|
||||||
stack.push([block, level, ""])
|
stack.push([block, level, ""])
|
||||||
block = '\chords'
|
block = '\chords'
|
||||||
|
@ -395,7 +395,7 @@ while tokens.length > 0
|
||||||
stack.push([block, level, ""])
|
stack.push([block, level, ""])
|
||||||
block = '\lyricmode'
|
block = '\lyricmode'
|
||||||
level = nestLevel
|
level = nestLevel
|
||||||
stanzas.push(lyrics= [])
|
STANZAS.push(lyrics= [])
|
||||||
tokens[0..0] = nil
|
tokens[0..0] = nil
|
||||||
end
|
end
|
||||||
when '\relative'
|
when '\relative'
|
||||||
|
@ -410,8 +410,8 @@ while tokens.length > 0
|
||||||
level = nestLevel
|
level = nestLevel
|
||||||
when '\time'
|
when '\time'
|
||||||
if tokens[0] =~ %r{(\d+)/(\d+)}
|
if tokens[0] =~ %r{(\d+)/(\d+)}
|
||||||
timeNum = $1.to_i
|
$timeNum = $1.to_i
|
||||||
timeDenom = $2.to_i
|
$timeDenom = $2.to_i
|
||||||
tokens[0..0] = nil
|
tokens[0..0] = nil
|
||||||
end
|
end
|
||||||
if block != 'voice'
|
if block != 'voice'
|
||||||
|
@ -421,8 +421,8 @@ while tokens.length > 0
|
||||||
end
|
end
|
||||||
when '\key'
|
when '\key'
|
||||||
p = lyPitch(tokens[0], 0)
|
p = lyPitch(tokens[0], 0)
|
||||||
mode = tokens[1]
|
$mode = tokens[1]
|
||||||
key = mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
$key = $mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
||||||
tokens[0..1] = nil
|
tokens[0..1] = nil
|
||||||
if block != 'voice'
|
if block != 'voice'
|
||||||
stack.push([block, level, ""])
|
stack.push([block, level, ""])
|
||||||
|
@ -434,37 +434,38 @@ while tokens.length > 0
|
||||||
when '\alternative'
|
when '\alternative'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
measureLen = VL::Fract.new(timeNum, timeDenom)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Make measures
|
|
||||||
#
|
|
||||||
measCount= -1
|
|
||||||
measures = []
|
|
||||||
|
|
||||||
def peek(where, what)
|
def peek(where, what)
|
||||||
return where.first && where.first[what]
|
return where.first && where.first[what]
|
||||||
end
|
end
|
||||||
|
|
||||||
while notes.size > 0 || chords.size > 0
|
def makeMeasures
|
||||||
|
measureLen = VL::Fract.new($timeNum, $timeDenom)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make measures
|
||||||
|
#
|
||||||
|
measCount= -1
|
||||||
|
|
||||||
|
while NOTES.size > 0 || CHORDS.size > 0
|
||||||
measCount += 1
|
measCount += 1
|
||||||
meas = {}
|
meas = {}
|
||||||
meas['measure'] = measCount
|
meas['measure'] = measCount
|
||||||
meas['properties'] = 0
|
meas['properties'] = 0
|
||||||
if peek(notes, 'begin-repeat')
|
if peek(NOTES, 'begin-repeat')
|
||||||
rep = notes.shift
|
rep = NOTES.shift
|
||||||
meas['begin-repeat'] = {'times' => rep['times']}
|
meas['begin-repeat'] = {'times' => rep['times']}
|
||||||
end
|
end
|
||||||
if peek(notes, 'begin-ending')
|
if peek(NOTES, 'begin-ending')
|
||||||
notes.shift
|
NOTES.shift
|
||||||
meas['begin-ending'] = {}
|
meas['begin-ending'] = {}
|
||||||
end
|
end
|
||||||
if chords.size > 0
|
if CHORDS.size > 0
|
||||||
mchords = []
|
mchords = []
|
||||||
len = VL::Fract.new(0, 1)
|
len = VL::Fract.new(0, 1)
|
||||||
while len < measureLen && chords.size > 0
|
while len < measureLen && CHORDS.size > 0
|
||||||
chord = chords.shift
|
chord = CHORDS.shift
|
||||||
chordLen = VL::Fract.new(chord['durNum'], chord['durDenom'])
|
chordLen = VL::Fract.new(chord['durNum'], chord['durDenom'])
|
||||||
if len+chordLen > measureLen
|
if len+chordLen > measureLen
|
||||||
remLen = len+chordLen-measureLen
|
remLen = len+chordLen-measureLen
|
||||||
|
@ -472,18 +473,18 @@ while notes.size > 0 || chords.size > 0
|
||||||
remChord = chord.dup
|
remChord = chord.dup
|
||||||
remChord['durNum'] = remLen.num
|
remChord['durNum'] = remLen.num
|
||||||
remChord['durDenom'] = remLen.denom
|
remChord['durDenom'] = remLen.denom
|
||||||
chords.unshift(remChord)
|
CHORDS.unshift(remChord)
|
||||||
end
|
end
|
||||||
mchords.push(chord)
|
mchords.push(chord)
|
||||||
len += chordLen
|
len += chordLen
|
||||||
end
|
end
|
||||||
meas['chords'] = mchords
|
meas['chords'] = mchords
|
||||||
end
|
end
|
||||||
if notes.size > 0
|
if NOTES.size > 0
|
||||||
mnotes = []
|
mnotes = []
|
||||||
len = VL::Fract.new(0, 1)
|
len = VL::Fract.new(0, 1)
|
||||||
while len < measureLen && notes.size > 0
|
while len < measureLen && NOTES.size > 0
|
||||||
note = notes.shift
|
note = NOTES.shift
|
||||||
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
||||||
if len+noteLen > measureLen
|
if len+noteLen > measureLen
|
||||||
remLen = len+noteLen-measureLen
|
remLen = len+noteLen-measureLen
|
||||||
|
@ -493,14 +494,14 @@ while notes.size > 0 || chords.size > 0
|
||||||
remNote['durDenom'] = remLen.denom
|
remNote['durDenom'] = remLen.denom
|
||||||
remNote['tied'] = (remNote['tied'] || 0) | VL::TiedWithPrev
|
remNote['tied'] = (remNote['tied'] || 0) | VL::TiedWithPrev
|
||||||
note['tied'] = (note['tied'] || 0) | VL::TiedWithNext
|
note['tied'] = (note['tied'] || 0) | VL::TiedWithNext
|
||||||
notes.unshift(remNote)
|
NOTES.unshift(remNote)
|
||||||
end
|
end
|
||||||
if note['pitch'] != VL::NoPitch &&
|
if note['pitch'] != VL::NoPitch &&
|
||||||
(!note['tied'] || (note['tied'] & VL::TiedWithPrev) == 0)
|
(!note['tied'] || (note['tied'] & VL::TiedWithPrev) == 0)
|
||||||
ly = []
|
ly = []
|
||||||
stanza = 0
|
stanza = 0
|
||||||
stanzas.each_index do |i|
|
STANZAS.each_index do |i|
|
||||||
lyrics = stanzas[i]
|
lyrics = STANZAS[i]
|
||||||
if lyrics.size > 0
|
if lyrics.size > 0
|
||||||
stanza = i+1
|
stanza = i+1
|
||||||
syll = lyrics.shift
|
syll = lyrics.shift
|
||||||
|
@ -519,26 +520,34 @@ while notes.size > 0 || chords.size > 0
|
||||||
end
|
end
|
||||||
meas['melody'] = mnotes
|
meas['melody'] = mnotes
|
||||||
end
|
end
|
||||||
if peek(notes, 'end-ending')
|
if peek(NOTES, 'end-ending')
|
||||||
ending = notes.shift
|
ending = NOTES.shift
|
||||||
meas['end-ending'] = {'last' => ending['last'], 'volta' => ending['volta']}
|
meas['end-ending'] = {'last' => ending['last'], 'volta' => ending['volta']}
|
||||||
end
|
end
|
||||||
if peek(notes, 'end-repeat')
|
if peek(NOTES, 'end-repeat')
|
||||||
notes.shift
|
NOTES.shift
|
||||||
meas['end-repeat'] = {}
|
meas['end-repeat'] = {}
|
||||||
end
|
end
|
||||||
measures.push(meas)
|
MEAS.push(meas)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
OUTPUT['measures'] = measures
|
begin
|
||||||
|
parseLilypond
|
||||||
|
makeMeasures
|
||||||
|
|
||||||
|
OUTPUT['measures'] = MEAS
|
||||||
OUTPUT['properties'] = [{
|
OUTPUT['properties'] = [{
|
||||||
'key' => key,
|
'key' => $key,
|
||||||
'mode' => mode == '\minor' ? -1 : 1,
|
'mode' => $mode == '\minor' ? -1 : 1,
|
||||||
'timeNum' => timeNum,
|
'timeNum' => $timeNum,
|
||||||
'timeDenom' => timeDenom
|
'timeDenom' => $timeDenom
|
||||||
}]
|
}]
|
||||||
|
|
||||||
writePlist($stdout, OUTPUT)
|
writePlist($stdout, OUTPUT)
|
||||||
|
rescue => except
|
||||||
|
$stderr.print except.message, "\n", except.backtrace.join("\n"), "\n"
|
||||||
|
end
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# mode:ruby
|
# mode:ruby
|
||||||
|
|
Loading…
Reference in New Issue
Block a user