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,33 +177,58 @@ def lySteps(steps)
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
while tokens.length > 0
|
def parseLilypond
|
||||||
token = tokens.shift
|
|
||||||
#
|
#
|
||||||
# Title, composer, etc.
|
# Lex
|
||||||
#
|
#
|
||||||
if tokens[0] == '='
|
tokens = []
|
||||||
case token
|
INFILE.each do |line|
|
||||||
when 'title','composer','poet'
|
line.chomp!.sub!(/%.*/, "")
|
||||||
key = token=='poet' ? 'lyricist' : token
|
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|--|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
||||||
value = tokens[1]
|
tokens.push(token[0])
|
||||||
value.sub!(/"(.*)"/, '\1')
|
|
||||||
|
|
||||||
OUTPUT[key] = value
|
|
||||||
tokens[0..1]= nil
|
|
||||||
|
|
||||||
redo
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
#
|
||||||
|
# Parse
|
||||||
|
#
|
||||||
|
nestLevel = 0
|
||||||
|
block = nil
|
||||||
|
level = -1
|
||||||
|
stack = []
|
||||||
|
repeats = []
|
||||||
|
lyrics = []
|
||||||
|
lastDur = 1
|
||||||
|
tied = false
|
||||||
|
repeat = 0
|
||||||
|
lyricFlags= 0
|
||||||
|
|
||||||
case block
|
while tokens.length > 0
|
||||||
when '\header', '\paper'
|
token = tokens.shift
|
||||||
# Ignore
|
|
||||||
when '\chords', '\chordmode'
|
|
||||||
#
|
#
|
||||||
# Possibly chords
|
# Title, composer, etc.
|
||||||
#
|
#
|
||||||
if token.downcase =~ %r{^
|
if tokens[0] == '='
|
||||||
|
case token
|
||||||
|
when 'title','composer','poet'
|
||||||
|
key = token=='poet' ? 'lyricist' : token
|
||||||
|
value = tokens[1]
|
||||||
|
value.sub!(/"(.*)"/, '\1')
|
||||||
|
|
||||||
|
OUTPUT[key] = value
|
||||||
|
tokens[0..1]= nil
|
||||||
|
|
||||||
|
redo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
case block
|
||||||
|
when '\header', '\paper'
|
||||||
|
# Ignore
|
||||||
|
when '\chords', '\chordmode'
|
||||||
|
#
|
||||||
|
# Possibly chords
|
||||||
|
#
|
||||||
|
if token.downcase =~ %r{^
|
||||||
([rs] | # Rest
|
([rs] | # Rest
|
||||||
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
||||||
)
|
)
|
||||||
|
@ -240,24 +240,24 @@ while tokens.length > 0
|
||||||
[a-g](?:[ei]?s)? # Root: a, bes, fis, as
|
[a-g](?:[ei]?s)? # Root: a, bes, fis, as
|
||||||
))?
|
))?
|
||||||
$}x
|
$}x
|
||||||
pitch = lyPitch($1, 60)
|
pitch = lyPitch($1, 60)
|
||||||
dur = $2 || lastDur
|
dur = $2 || lastDur
|
||||||
ext = $3 ? lySteps($3) : 0
|
ext = $3 ? lySteps($3) : 0
|
||||||
root = lyPitch($4, 48)
|
root = lyPitch($4, 48)
|
||||||
lastDur = dur
|
lastDur = dur
|
||||||
d = lyDur(dur)
|
d = lyDur(dur)
|
||||||
|
|
||||||
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'
|
||||||
#
|
#
|
||||||
# Possibly notes
|
# Possibly notes
|
||||||
#
|
#
|
||||||
if token.downcase =~ %r{^
|
if token.downcase =~ %r{^
|
||||||
([rs] | # Rest
|
([rs] | # Rest
|
||||||
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
||||||
[',]* # g'''
|
[',]* # g'''
|
||||||
|
@ -266,279 +266,288 @@ while tokens.length > 0
|
||||||
(?:\*\d+/\d+)? # *3/4
|
(?:\*\d+/\d+)? # *3/4
|
||||||
)?
|
)?
|
||||||
$}x
|
$}x
|
||||||
pitch = lyPitch($1)
|
pitch = lyPitch($1)
|
||||||
dur = $2 || lastDur
|
dur = $2 || lastDur
|
||||||
lastDur = dur
|
lastDur = dur
|
||||||
d = lyDur(dur)
|
d = lyDur(dur)
|
||||||
|
|
||||||
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
|
||||||
|
tied = true
|
||||||
|
elsif token == '\repeat' && (tokens[0] == 'volta' || tokens[0] == fold) &&
|
||||||
|
tokens[1] =~ /^\d+$/
|
||||||
|
stack.push([block, level, "repeat"])
|
||||||
|
level = nestLevel
|
||||||
|
repeats.push(repeat)
|
||||||
|
repeat = tokens[1].to_i
|
||||||
|
NOTES.push({'begin-repeat' => true, 'times' => repeat})
|
||||||
|
tokens[0..1] = nil
|
||||||
|
redo
|
||||||
|
elsif token == '\alternative'
|
||||||
|
inEndings = true
|
||||||
|
stack.push([block, level, "endings"])
|
||||||
|
level = nestLevel+1
|
||||||
|
voltas = 0
|
||||||
|
curVoltas = nil
|
||||||
|
NOTES.push({'begin-ending' => true})
|
||||||
|
elsif token == '\times' && tokens[0] =~ %r|^(\d+)/(\d+)|
|
||||||
|
$timesNum = $1.to_i
|
||||||
|
$timesDen = $2.to_i
|
||||||
|
stack.push([block, level, "times"])
|
||||||
|
level = nestLevel
|
||||||
|
end
|
||||||
|
when '\lyricmode'
|
||||||
|
if token == '--'
|
||||||
|
lyrics.last[1] |= VL::TiedWithNext if lyrics.size > 0
|
||||||
|
lyricFlags = VL::TiedWithPrev
|
||||||
|
elsif token == '\skip'
|
||||||
|
p ["", 0] if $DEBUG
|
||||||
|
lyrics.push ["", 0]
|
||||||
|
lyricFlags = 0
|
||||||
|
if tokens[0] =~ /\d+/
|
||||||
|
tokens[0..0] = nil
|
||||||
|
end
|
||||||
|
elsif token =~ /\\skip\d+/
|
||||||
|
p ["", 0] if $DEBUG
|
||||||
|
lyrics.push ["", 0]
|
||||||
|
lyricFlags = 0
|
||||||
|
elsif token =~ /"(.*)"/
|
||||||
|
p [$1, lyricFlags] if $DEBUG
|
||||||
|
lyrics.push [$1, lyricFlags]
|
||||||
|
lyricFlags = 0
|
||||||
|
elsif token =~ /^\w.*/
|
||||||
|
p [token, lyricFlags] if $DEBUG
|
||||||
|
lyrics.push [token, lyricFlags]
|
||||||
|
lyricFlags = 0
|
||||||
end
|
end
|
||||||
tied = true
|
|
||||||
elsif token == '\repeat' && (tokens[0] == 'volta' || tokens[0] == fold) &&
|
|
||||||
tokens[1] =~ /^\d+$/
|
|
||||||
stack.push([block, level, "repeat"])
|
|
||||||
level = nestLevel
|
|
||||||
repeats.push(repeat)
|
|
||||||
repeat = tokens[1].to_i
|
|
||||||
notes.push({'begin-repeat' => true, 'times' => repeat})
|
|
||||||
tokens[0..1] = nil
|
|
||||||
redo
|
|
||||||
elsif token == '\alternative'
|
|
||||||
inEndings = true
|
|
||||||
stack.push([block, level, "endings"])
|
|
||||||
level = nestLevel+1
|
|
||||||
voltas = 0
|
|
||||||
curVoltas = nil
|
|
||||||
notes.push({'begin-ending' => true})
|
|
||||||
elsif token == '\times' && tokens[0] =~ %r|^(\d+)/(\d+)|
|
|
||||||
$timesNum = $1.to_i
|
|
||||||
$timesDen = $2.to_i
|
|
||||||
stack.push([block, level, "times"])
|
|
||||||
level = nestLevel
|
|
||||||
end
|
end
|
||||||
when '\lyricmode'
|
|
||||||
if token == '--'
|
#
|
||||||
lyrics.last[1] |= VL::TiedWithNext if lyrics.size > 0
|
# Nesting levels
|
||||||
lyricFlags = VL::TiedWithPrev
|
#
|
||||||
elsif token == '\skip'
|
case token
|
||||||
p ["", 0] if DEBUG
|
when '{', '<<'
|
||||||
lyrics.push ["", 0]
|
nestLevel += 1
|
||||||
lyricFlags = 0
|
when '}', '>>'
|
||||||
if tokens[0] =~ /\d+/
|
nestLevel -= 1
|
||||||
|
if nestLevel <= level
|
||||||
|
if lv = stack.pop
|
||||||
|
block = lv[0]
|
||||||
|
level = lv[1]
|
||||||
|
type = lv[2]
|
||||||
|
else
|
||||||
|
block = nil
|
||||||
|
level = -1
|
||||||
|
end
|
||||||
|
if type == "repeat"
|
||||||
|
if tokens[0] != '\alternative'
|
||||||
|
NOTES.push({'end-repeat' => true})
|
||||||
|
repeat = repeats.pop
|
||||||
|
end
|
||||||
|
elsif type == "endings"
|
||||||
|
last = tokens[0] == '}'
|
||||||
|
if last
|
||||||
|
curVoltas = ((1<<repeat) - 1) & ~voltas
|
||||||
|
elsif !curVoltas
|
||||||
|
curVoltas = 1
|
||||||
|
while (voltas&curVoltas) != 0
|
||||||
|
curVoltas <<= 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
NOTES.push({'end-ending' => true, 'volta' => curVoltas,
|
||||||
|
'last'=>last})
|
||||||
|
voltas |= curVoltas
|
||||||
|
curVoltas = 0
|
||||||
|
if last
|
||||||
|
repeat = repeats.pop
|
||||||
|
else
|
||||||
|
NOTES.push({'begin-ending' => true})
|
||||||
|
stack.push([block, level, "endings"])
|
||||||
|
level = nestLevel
|
||||||
|
end
|
||||||
|
elsif type == "times"
|
||||||
|
$timesNum = 1
|
||||||
|
$timesDen = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when '\chords', '\header', '\paper', '\lyricmode'
|
||||||
|
stack.push([block, level, ""])
|
||||||
|
block = token
|
||||||
|
level = nestLevel
|
||||||
|
STANZAS.push(lyrics= []) if block == '\lyricmode'
|
||||||
|
when '\chordmode'
|
||||||
|
stack.push([block, level, ""])
|
||||||
|
block = '\chords'
|
||||||
|
level = nestLevel
|
||||||
|
when '\lyricsto'
|
||||||
|
tokens[0..3] = nil
|
||||||
|
when '\new'
|
||||||
|
if tokens[0] == "Lyrics"
|
||||||
|
stack.push([block, level, ""])
|
||||||
|
block = '\lyricmode'
|
||||||
|
level = nestLevel
|
||||||
|
STANZAS.push(lyrics= [])
|
||||||
tokens[0..0] = nil
|
tokens[0..0] = nil
|
||||||
end
|
end
|
||||||
elsif token =~ /\\skip\d+/
|
when '\relative'
|
||||||
p ["", 0] if DEBUG
|
stack.push([block, level, ""])
|
||||||
lyrics.push ["", 0]
|
if tokens[0] =~ /[a-g](?:[ei]?s)?[',]*/
|
||||||
lyricFlags = 0
|
$RELPITCH = lyPitch(tokens[0], 48)
|
||||||
elsif token =~ /"(.*)"/
|
tokens[0..0] = nil
|
||||||
p [$1, lyricFlags] if DEBUG
|
|
||||||
lyrics.push [$1, lyricFlags]
|
|
||||||
lyricFlags = 0
|
|
||||||
elsif token =~ /^\w.*/
|
|
||||||
p [token, lyricFlags] if DEBUG
|
|
||||||
lyrics.push [token, lyricFlags]
|
|
||||||
lyricFlags = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Nesting levels
|
|
||||||
#
|
|
||||||
case token
|
|
||||||
when '{', '<<'
|
|
||||||
nestLevel += 1
|
|
||||||
when '}', '>>'
|
|
||||||
nestLevel -= 1
|
|
||||||
if nestLevel <= level
|
|
||||||
if lv = stack.pop
|
|
||||||
block = lv[0]
|
|
||||||
level = lv[1]
|
|
||||||
type = lv[2]
|
|
||||||
else
|
else
|
||||||
block = nil
|
$RELPITCH = 60
|
||||||
level = -1
|
|
||||||
end
|
end
|
||||||
if type == "repeat"
|
block = 'voice'
|
||||||
if tokens[0] != '\alternative'
|
level = nestLevel
|
||||||
notes.push({'end-repeat' => true})
|
when '\time'
|
||||||
repeat = repeats.pop
|
if tokens[0] =~ %r{(\d+)/(\d+)}
|
||||||
end
|
$timeNum = $1.to_i
|
||||||
elsif type == "endings"
|
$timeDenom = $2.to_i
|
||||||
last = tokens[0] == '}'
|
tokens[0..0] = nil
|
||||||
if last
|
|
||||||
curVoltas = ((1<<repeat) - 1) & ~voltas
|
|
||||||
elsif !curVoltas
|
|
||||||
curVoltas = 1
|
|
||||||
while (voltas&curVoltas) != 0
|
|
||||||
curVoltas <<= 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
notes.push({'end-ending' => true, 'volta' => curVoltas,
|
|
||||||
'last'=>last})
|
|
||||||
voltas |= curVoltas
|
|
||||||
curVoltas = 0
|
|
||||||
if last
|
|
||||||
repeat = repeats.pop
|
|
||||||
else
|
|
||||||
notes.push({'begin-ending' => true})
|
|
||||||
stack.push([block, level, "endings"])
|
|
||||||
level = nestLevel
|
|
||||||
end
|
|
||||||
elsif type == "times"
|
|
||||||
$timesNum = 1
|
|
||||||
$timesDen = 1
|
|
||||||
end
|
end
|
||||||
|
if block != 'voice'
|
||||||
|
stack.push([block, level, ""])
|
||||||
|
block = 'voice'
|
||||||
|
level = nestLevel-1
|
||||||
|
end
|
||||||
|
when '\key'
|
||||||
|
p = lyPitch(tokens[0], 0)
|
||||||
|
$mode = tokens[1]
|
||||||
|
$key = $mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
||||||
|
tokens[0..1] = nil
|
||||||
|
if block != 'voice'
|
||||||
|
stack.push([block, level, ""])
|
||||||
|
block = 'voice'
|
||||||
|
level = nestLevel-1
|
||||||
|
end
|
||||||
|
when '\repeat'
|
||||||
|
tokens[0..1] = nil
|
||||||
|
when '\alternative'
|
||||||
end
|
end
|
||||||
when '\chords', '\header', '\paper', '\lyricmode'
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
block = token
|
|
||||||
level = nestLevel
|
|
||||||
stanzas.push(lyrics= []) if block == '\lyricmode'
|
|
||||||
when '\chordmode'
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
block = '\chords'
|
|
||||||
level = nestLevel
|
|
||||||
when '\lyricsto'
|
|
||||||
tokens[0..3] = nil
|
|
||||||
when '\new'
|
|
||||||
if tokens[0] == "Lyrics"
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
block = '\lyricmode'
|
|
||||||
level = nestLevel
|
|
||||||
stanzas.push(lyrics= [])
|
|
||||||
tokens[0..0] = nil
|
|
||||||
end
|
|
||||||
when '\relative'
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
if tokens[0] =~ /[a-g](?:[ei]?s)?[',]*/
|
|
||||||
$RELPITCH = lyPitch(tokens[0], 48)
|
|
||||||
tokens[0..0] = nil
|
|
||||||
else
|
|
||||||
$RELPITCH = 60
|
|
||||||
end
|
|
||||||
block = 'voice'
|
|
||||||
level = nestLevel
|
|
||||||
when '\time'
|
|
||||||
if tokens[0] =~ %r{(\d+)/(\d+)}
|
|
||||||
timeNum = $1.to_i
|
|
||||||
timeDenom = $2.to_i
|
|
||||||
tokens[0..0] = nil
|
|
||||||
end
|
|
||||||
if block != 'voice'
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
block = 'voice'
|
|
||||||
level = nestLevel-1
|
|
||||||
end
|
|
||||||
when '\key'
|
|
||||||
p = lyPitch(tokens[0], 0)
|
|
||||||
mode = tokens[1]
|
|
||||||
key = mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
|
||||||
tokens[0..1] = nil
|
|
||||||
if block != 'voice'
|
|
||||||
stack.push([block, level, ""])
|
|
||||||
block = 'voice'
|
|
||||||
level = nestLevel-1
|
|
||||||
end
|
|
||||||
when '\repeat'
|
|
||||||
tokens[0..1] = nil
|
|
||||||
when '\alternative'
|
|
||||||
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
|
||||||
measCount += 1
|
measureLen = VL::Fract.new($timeNum, $timeDenom)
|
||||||
meas = {}
|
|
||||||
meas['measure'] = measCount
|
#
|
||||||
meas['properties'] = 0
|
# Make measures
|
||||||
if peek(notes, 'begin-repeat')
|
#
|
||||||
rep = notes.shift
|
measCount= -1
|
||||||
meas['begin-repeat'] = {'times' => rep['times']}
|
|
||||||
end
|
while NOTES.size > 0 || CHORDS.size > 0
|
||||||
if peek(notes, 'begin-ending')
|
measCount += 1
|
||||||
notes.shift
|
meas = {}
|
||||||
meas['begin-ending'] = {}
|
meas['measure'] = measCount
|
||||||
end
|
meas['properties'] = 0
|
||||||
if chords.size > 0
|
if peek(NOTES, 'begin-repeat')
|
||||||
mchords = []
|
rep = NOTES.shift
|
||||||
len = VL::Fract.new(0, 1)
|
meas['begin-repeat'] = {'times' => rep['times']}
|
||||||
while len < measureLen && chords.size > 0
|
|
||||||
chord = chords.shift
|
|
||||||
chordLen = VL::Fract.new(chord['durNum'], chord['durDenom'])
|
|
||||||
if len+chordLen > measureLen
|
|
||||||
remLen = len+chordLen-measureLen
|
|
||||||
chordLen -= remLen
|
|
||||||
remChord = chord.dup
|
|
||||||
remChord['durNum'] = remLen.num
|
|
||||||
remChord['durDenom'] = remLen.denom
|
|
||||||
chords.unshift(remChord)
|
|
||||||
end
|
|
||||||
mchords.push(chord)
|
|
||||||
len += chordLen
|
|
||||||
end
|
end
|
||||||
meas['chords'] = mchords
|
if peek(NOTES, 'begin-ending')
|
||||||
end
|
NOTES.shift
|
||||||
if notes.size > 0
|
meas['begin-ending'] = {}
|
||||||
mnotes = []
|
end
|
||||||
len = VL::Fract.new(0, 1)
|
if CHORDS.size > 0
|
||||||
while len < measureLen && notes.size > 0
|
mchords = []
|
||||||
note = notes.shift
|
len = VL::Fract.new(0, 1)
|
||||||
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
while len < measureLen && CHORDS.size > 0
|
||||||
if len+noteLen > measureLen
|
chord = CHORDS.shift
|
||||||
remLen = len+noteLen-measureLen
|
chordLen = VL::Fract.new(chord['durNum'], chord['durDenom'])
|
||||||
noteLen -= remLen
|
if len+chordLen > measureLen
|
||||||
remNote = note.dup
|
remLen = len+chordLen-measureLen
|
||||||
remNote['durNum'] = remLen.num
|
chordLen -= remLen
|
||||||
remNote['durDenom'] = remLen.denom
|
remChord = chord.dup
|
||||||
remNote['tied'] = (remNote['tied'] || 0) | VL::TiedWithPrev
|
remChord['durNum'] = remLen.num
|
||||||
note['tied'] = (note['tied'] || 0) | VL::TiedWithNext
|
remChord['durDenom'] = remLen.denom
|
||||||
notes.unshift(remNote)
|
CHORDS.unshift(remChord)
|
||||||
|
end
|
||||||
|
mchords.push(chord)
|
||||||
|
len += chordLen
|
||||||
end
|
end
|
||||||
if note['pitch'] != VL::NoPitch &&
|
meas['chords'] = mchords
|
||||||
(!note['tied'] || (note['tied'] & VL::TiedWithPrev) == 0)
|
end
|
||||||
ly = []
|
if NOTES.size > 0
|
||||||
stanza = 0
|
mnotes = []
|
||||||
stanzas.each_index do |i|
|
len = VL::Fract.new(0, 1)
|
||||||
lyrics = stanzas[i]
|
while len < measureLen && NOTES.size > 0
|
||||||
if lyrics.size > 0
|
note = NOTES.shift
|
||||||
stanza = i+1
|
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
||||||
syll = lyrics.shift
|
if len+noteLen > measureLen
|
||||||
ly.push({'text' => syll[0].gsub('_', ' '), 'kind' => syll[1]})
|
remLen = len+noteLen-measureLen
|
||||||
else
|
noteLen -= remLen
|
||||||
ly.push({'text' => '', 'kind' => 0})
|
remNote = note.dup
|
||||||
|
remNote['durNum'] = remLen.num
|
||||||
|
remNote['durDenom'] = remLen.denom
|
||||||
|
remNote['tied'] = (remNote['tied'] || 0) | VL::TiedWithPrev
|
||||||
|
note['tied'] = (note['tied'] || 0) | VL::TiedWithNext
|
||||||
|
NOTES.unshift(remNote)
|
||||||
|
end
|
||||||
|
if note['pitch'] != VL::NoPitch &&
|
||||||
|
(!note['tied'] || (note['tied'] & VL::TiedWithPrev) == 0)
|
||||||
|
ly = []
|
||||||
|
stanza = 0
|
||||||
|
STANZAS.each_index do |i|
|
||||||
|
lyrics = STANZAS[i]
|
||||||
|
if lyrics.size > 0
|
||||||
|
stanza = i+1
|
||||||
|
syll = lyrics.shift
|
||||||
|
ly.push({'text' => syll[0].gsub('_', ' '), 'kind' => syll[1]})
|
||||||
|
else
|
||||||
|
ly.push({'text' => '', 'kind' => 0})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
if stanza < ly.size
|
||||||
|
ly[stanza..-1] = nil
|
||||||
|
end
|
||||||
|
note['lyrics'] = ly if stanza > 0
|
||||||
end
|
end
|
||||||
if stanza < ly.size
|
mnotes.push(note)
|
||||||
ly[stanza..-1] = nil
|
len += noteLen
|
||||||
end
|
|
||||||
note['lyrics'] = ly if stanza > 0
|
|
||||||
end
|
end
|
||||||
mnotes.push(note)
|
meas['melody'] = mnotes
|
||||||
len += noteLen
|
|
||||||
end
|
end
|
||||||
meas['melody'] = mnotes
|
if peek(NOTES, 'end-ending')
|
||||||
|
ending = NOTES.shift
|
||||||
|
meas['end-ending'] = {'last' => ending['last'], 'volta' => ending['volta']}
|
||||||
|
end
|
||||||
|
if peek(NOTES, 'end-repeat')
|
||||||
|
NOTES.shift
|
||||||
|
meas['end-repeat'] = {}
|
||||||
|
end
|
||||||
|
MEAS.push(meas)
|
||||||
end
|
end
|
||||||
if peek(notes, 'end-ending')
|
|
||||||
ending = notes.shift
|
|
||||||
meas['end-ending'] = {'last' => ending['last'], 'volta' => ending['volta']}
|
|
||||||
end
|
|
||||||
if peek(notes, 'end-repeat')
|
|
||||||
notes.shift
|
|
||||||
meas['end-repeat'] = {}
|
|
||||||
end
|
|
||||||
measures.push(meas)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
OUTPUT['measures'] = measures
|
begin
|
||||||
OUTPUT['properties'] = [{
|
parseLilypond
|
||||||
'key' => key,
|
makeMeasures
|
||||||
'mode' => mode == '\minor' ? -1 : 1,
|
|
||||||
'timeNum' => timeNum,
|
|
||||||
'timeDenom' => timeDenom
|
|
||||||
}]
|
|
||||||
|
|
||||||
writePlist($stdout, OUTPUT)
|
OUTPUT['measures'] = MEAS
|
||||||
|
OUTPUT['properties'] = [{
|
||||||
|
'key' => $key,
|
||||||
|
'mode' => $mode == '\minor' ? -1 : 1,
|
||||||
|
'timeNum' => $timeNum,
|
||||||
|
'timeDenom' => $timeDenom
|
||||||
|
}]
|
||||||
|
|
||||||
|
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