mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Started writing lilypond reader
This commit is contained in:
parent
8d78730f5e
commit
c70a2d734e
232
Filters/VLLilypondType.reader
Executable file
232
Filters/VLLilypondType.reader
Executable file
|
@ -0,0 +1,232 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
#
|
||||||
|
# VLLilypondType.reader - Import lilypond files
|
||||||
|
#
|
||||||
|
|
||||||
|
require File.dirname($0)+'/plistWriter'
|
||||||
|
require File.dirname($0)+'/vl'
|
||||||
|
|
||||||
|
OUTPUT = {'measures' => []}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Lex
|
||||||
|
#
|
||||||
|
tokens = []
|
||||||
|
$stdin.each do |line|
|
||||||
|
line.chomp!.sub!(/%.*/, "")
|
||||||
|
line.scan(/\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|#'|#\(|##t|##f|\\\w+|\".*?\"|[-+\w\d.',:]+|.)/) do |token|
|
||||||
|
tokens.push(token[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#
|
||||||
|
# Parse
|
||||||
|
#
|
||||||
|
nestLevel = 0
|
||||||
|
block = nil
|
||||||
|
level = -1
|
||||||
|
stack = []
|
||||||
|
chords = []
|
||||||
|
notes = []
|
||||||
|
lyrics = []
|
||||||
|
lastDur = 1
|
||||||
|
|
||||||
|
$RELPITCH = 0
|
||||||
|
|
||||||
|
PITCH = {
|
||||||
|
?c => 0,
|
||||||
|
?d => 2,
|
||||||
|
?e => 4,
|
||||||
|
?f => 5,
|
||||||
|
?g => 7,
|
||||||
|
?a => 9,
|
||||||
|
?b => 11
|
||||||
|
}
|
||||||
|
|
||||||
|
def lyPitch(pitch, base=0)
|
||||||
|
if !pitch || pitch =~ /r/
|
||||||
|
return VL::NoPitch
|
||||||
|
end
|
||||||
|
p = PITCH[pitch[0]] || 0
|
||||||
|
if base > 0
|
||||||
|
p += base
|
||||||
|
elsif $RELPITCH > 0
|
||||||
|
while $RELPITCH-p > 5
|
||||||
|
p += 12
|
||||||
|
end
|
||||||
|
$RELPITCH = p
|
||||||
|
else
|
||||||
|
p += 60
|
||||||
|
end
|
||||||
|
pitch.scan(/'/) {|c| p += 12}
|
||||||
|
pitch.scan(/,/) {|c| p -= 12}
|
||||||
|
if pitch =~ /^[ea]s/
|
||||||
|
p -= 1
|
||||||
|
pitch[0..1] = ""
|
||||||
|
end
|
||||||
|
pitch.scan('is') { |x| p += 1 }
|
||||||
|
pitch.scan('es') { |x| p -= 1 }
|
||||||
|
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
def lyDur(dur)
|
||||||
|
dur =~ /^(\d+)(?:\*(\d+).(\d+))?/
|
||||||
|
num = 1
|
||||||
|
den = $1.to_i
|
||||||
|
if $2
|
||||||
|
num *= $2.to_i
|
||||||
|
den *= $3.to_i
|
||||||
|
end
|
||||||
|
return [num,den]
|
||||||
|
end
|
||||||
|
|
||||||
|
STEPS = {
|
||||||
|
'' => VL::Chord::Maj,
|
||||||
|
'm' => VL::Chord::Min,
|
||||||
|
'maj' => VL::Chord::Maj7,
|
||||||
|
'dim7' => VL::Chord::Dim7,
|
||||||
|
'dim' => VL::Chord::Dim,
|
||||||
|
'aug' => VL::Chord::Aug,
|
||||||
|
'sus4' => VL::Chord::Sus4,
|
||||||
|
'sus2' => VL::Chord::Sus2,
|
||||||
|
'sus' => VL::Chord::Sus4
|
||||||
|
}
|
||||||
|
|
||||||
|
DEGREE = [
|
||||||
|
[VL::Unison, VL::Unison],
|
||||||
|
[VL::Min2nd+VL::Maj2nd, VL::Maj2nd],
|
||||||
|
[VL::Min3rd+VL::Maj3rd, VL::Maj3rd],
|
||||||
|
[VL::Fourth, VL::Fourth],
|
||||||
|
[VL::Fifth, VL::Fifth],
|
||||||
|
[VL::Aug5th+VL::Dim7th, VL::Dim7th],
|
||||||
|
[VL::Min7th+VL::Maj7th, VL::Min7th],
|
||||||
|
[VL::Octave, VL::Octave],
|
||||||
|
[VL::Min9th+VL::Maj9th, VL::Maj9th],
|
||||||
|
[VL::Aug9th+VL::Dim11th, VL::Dim11th],
|
||||||
|
[VL::Eleventh, VL::Eleventh],
|
||||||
|
[VL::Aug11th+VL::Dim13th, VL::Dim13th],
|
||||||
|
[VL::Min13th+VL::Maj13th, VL::Maj13th]
|
||||||
|
];
|
||||||
|
|
||||||
|
def lySteps(steps)
|
||||||
|
steps =~ /^(|m|maj|dim7?|aug|sus[42]?)/
|
||||||
|
s = STEPS[$1]
|
||||||
|
steps = $'
|
||||||
|
if !($1 =~ /\d/) && steps =~ /^(7|9|11|13)/
|
||||||
|
if !(s & VL::Maj7th)
|
||||||
|
s |= VL::Min7th
|
||||||
|
end
|
||||||
|
case $1
|
||||||
|
when '9'
|
||||||
|
s |= VL::Maj9th
|
||||||
|
when '11'
|
||||||
|
s |= VL::Maj9th+VL::Maj11th
|
||||||
|
when '13'
|
||||||
|
s |= VL::Maj9th+VL::Maj11th+VL::Maj13th
|
||||||
|
end
|
||||||
|
steps = $'
|
||||||
|
end
|
||||||
|
steps.scan(/(\^)?(\d+)([-+])?/) do |ext|
|
||||||
|
degree = DEGREE[$2.to_i-1]
|
||||||
|
if $1 == '^'
|
||||||
|
s &= ~degree[0]
|
||||||
|
else
|
||||||
|
step = degree[1]
|
||||||
|
if $3 == '+'
|
||||||
|
step <<= 1
|
||||||
|
elsif $3 == '-'
|
||||||
|
step >>= 1
|
||||||
|
end
|
||||||
|
s = (s & ~degree[0]) | step
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
while tokens.length > 0
|
||||||
|
# puts "#{tokens.length}:#{nestLevel}[#{block}] #{tokens[0]} #{tokens[1]} #{tokens[2]}"
|
||||||
|
token = tokens.shift
|
||||||
|
#
|
||||||
|
# Title, composer, etc.
|
||||||
|
#
|
||||||
|
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'
|
||||||
|
#
|
||||||
|
# Possibly chords
|
||||||
|
#
|
||||||
|
if token.downcase =~ %r{^
|
||||||
|
(r | # Rest
|
||||||
|
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
||||||
|
[',]* # g'''
|
||||||
|
)
|
||||||
|
(\d+ # 1, 2, 4, 8, 16 ...
|
||||||
|
(?:\*\d+/\d+)? # *3/4
|
||||||
|
)?
|
||||||
|
(?:\:([-+^:.a-z\d]+))? # :maj9.7-^2
|
||||||
|
(?:/\+( # /+
|
||||||
|
[a-g](?:[ei]?s)? # Root: a, bes, fis, as
|
||||||
|
))?
|
||||||
|
$}x
|
||||||
|
pitch = lyPitch($1, 60)
|
||||||
|
dur = $2 || lastDur
|
||||||
|
ext = $3 ? lySteps($3) : 0
|
||||||
|
root = lyPitch($4, 48)
|
||||||
|
lastDur = dur
|
||||||
|
d = lyDur(dur)
|
||||||
|
|
||||||
|
chord = {'pitch' => pitch, 'root' => root, 'steps' => ext,
|
||||||
|
'durNum'=> d[0], 'durDenom' => d[1]}
|
||||||
|
p token, chord
|
||||||
|
chords.push(chord)
|
||||||
|
redo
|
||||||
|
end
|
||||||
|
else
|
||||||
|
#
|
||||||
|
# Possibly notes
|
||||||
|
#
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Nesting levels
|
||||||
|
#
|
||||||
|
case token
|
||||||
|
when '{', '<<'
|
||||||
|
nestLevel += 1
|
||||||
|
when '}', '>>'
|
||||||
|
nestLevel -= 1
|
||||||
|
if nestLevel <= level
|
||||||
|
if lv = stack.pop
|
||||||
|
block = lv[0]
|
||||||
|
level = lv[1]
|
||||||
|
else
|
||||||
|
block = nil
|
||||||
|
level = -1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when '\chords', '\header', '\paper'
|
||||||
|
block = token
|
||||||
|
level = nestLevel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
writePlist($stdout, OUTPUT)
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode:ruby
|
||||||
|
# End:
|
Loading…
Reference in New Issue
Block a user