mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Lilypond import works, without repeats & lyrics
This commit is contained in:
parent
698d9964a8
commit
0433ef8fb3
|
@ -16,7 +16,7 @@ OUTPUT = {'measures' => []}
|
||||||
tokens = []
|
tokens = []
|
||||||
$stdin.each do |line|
|
$stdin.each do |line|
|
||||||
line.chomp!.sub!(/%.*/, "")
|
line.chomp!.sub!(/%.*/, "")
|
||||||
line.scan(/\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|#'|#\(|##t|##f|\\\w+|\".*?\"|[-+\w\d.',:]+|.)/) do |token|
|
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
||||||
tokens.push(token[0])
|
tokens.push(token[0])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -51,7 +51,7 @@ PITCH = {
|
||||||
}
|
}
|
||||||
|
|
||||||
def lyPitch(pitch, base=-1)
|
def lyPitch(pitch, base=-1)
|
||||||
if !pitch || pitch =~ /[rs]/
|
if !pitch || pitch =~ /^[rs]/
|
||||||
return VL::NoPitch
|
return VL::NoPitch
|
||||||
end
|
end
|
||||||
p = PITCH[pitch[0]] || 0
|
p = PITCH[pitch[0]] || 0
|
||||||
|
@ -63,7 +63,7 @@ def lyPitch(pitch, base=-1)
|
||||||
end
|
end
|
||||||
$RELPITCH = p
|
$RELPITCH = p
|
||||||
else
|
else
|
||||||
p += 60
|
p += 48
|
||||||
end
|
end
|
||||||
pitch.scan(/'/) {|c| p += 12}
|
pitch.scan(/'/) {|c| p += 12}
|
||||||
pitch.scan(/,/) {|c| p -= 12}
|
pitch.scan(/,/) {|c| p -= 12}
|
||||||
|
@ -78,12 +78,18 @@ def lyPitch(pitch, base=-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def lyDur(dur)
|
def lyDur(dur)
|
||||||
dur =~ /^(\d+)(?:\*(\d+).(\d+))?/
|
dur =~ /^(\d+)(\.*)(?:\*(\d+).(\d+))?/
|
||||||
num = 1
|
num = 1
|
||||||
den = $1.to_i
|
den = $1.to_i
|
||||||
if $2
|
if $2.length > 0
|
||||||
num *= $2.to_i
|
(0...$2.length).each do |x|
|
||||||
den *= $3.to_i
|
den = 2*den
|
||||||
|
num = 2*num+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if $3
|
||||||
|
num *= $3.to_i
|
||||||
|
den *= $4.to_i
|
||||||
end
|
end
|
||||||
return [num,den]
|
return [num,den]
|
||||||
end
|
end
|
||||||
|
@ -147,20 +153,20 @@ MINORKEY = [
|
||||||
];
|
];
|
||||||
|
|
||||||
def lySteps(steps)
|
def lySteps(steps)
|
||||||
steps =~ /^(|m|maj|dim7?|aug|sus[42]?)/
|
steps =~ /^(maj|dim7?|aug|sus[42]?|m|)/
|
||||||
s = STEPS[$1]
|
s = STEPS[$1]
|
||||||
steps = $'
|
steps = $'
|
||||||
if !($1 =~ /\d/) && steps =~ /^(7|9|11|13)/
|
if !($1 =~ /\d$/) && steps =~ /^(7|9|11|13)/
|
||||||
if !(s & VL::Maj7th)
|
if (s & VL::Maj7th) == 0
|
||||||
s |= VL::Min7th
|
s |= VL::Min7th
|
||||||
end
|
end
|
||||||
case $1
|
case $1
|
||||||
when '9'
|
when '9'
|
||||||
s |= VL::Maj9th
|
s |= VL::Maj9th
|
||||||
when '11'
|
when '11'
|
||||||
s |= VL::Maj9th+VL::Maj11th
|
s |= VL::Maj9th+VL::Eleventh
|
||||||
when '13'
|
when '13'
|
||||||
s |= VL::Maj9th+VL::Maj11th+VL::Maj13th
|
s |= VL::Maj9th+VL::Eleventh+VL::Maj13th
|
||||||
end
|
end
|
||||||
steps = $'
|
steps = $'
|
||||||
end
|
end
|
||||||
|
@ -213,7 +219,7 @@ while tokens.length > 0
|
||||||
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
||||||
)
|
)
|
||||||
(\d+ # 1, 2, 4, 8, 16 ...
|
(\d+ # 1, 2, 4, 8, 16 ...
|
||||||
(?:\*\d+/\d+)? # *3/4
|
\.*(?:\*\d+/\d+)? # ., *3/4
|
||||||
)?
|
)?
|
||||||
(?:\:([-+^:.a-z\d]+))? # :maj9.7-^2
|
(?:\:([-+^:.a-z\d]+))? # :maj9.7-^2
|
||||||
(?:/\+( # /+
|
(?:/\+( # /+
|
||||||
|
@ -242,11 +248,11 @@ while tokens.length > 0
|
||||||
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
[a-g](?:[ei]?s)? # g, ges, fis, es, as
|
||||||
[',]* # g'''
|
[',]* # g'''
|
||||||
)
|
)
|
||||||
(\d+ # 1, 2, 4, 8, 16 ...
|
(\d+\.* # 1, 2, 4, 8, 16 ...
|
||||||
(?:\*\d+/\d+)? # *3/4
|
(?:\*\d+/\d+)? # *3/4
|
||||||
)?
|
)?
|
||||||
$}x
|
$}x
|
||||||
pitch = lyPitch($1, 60)
|
pitch = lyPitch($1)
|
||||||
dur = $2 || lastDur
|
dur = $2 || lastDur
|
||||||
lastDur = dur
|
lastDur = dur
|
||||||
d = lyDur(dur)
|
d = lyDur(dur)
|
||||||
|
@ -295,8 +301,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
|
timeNum = $1.to_i
|
||||||
timeDenom = $2
|
timeDenom = $2.to_i
|
||||||
tokens[0..0] = nil
|
tokens[0..0] = nil
|
||||||
end
|
end
|
||||||
if block != 'voice'
|
if block != 'voice'
|
||||||
|
@ -315,6 +321,63 @@ while tokens.length > 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
measureLen = VL::Fract.new(timeNum, timeDenom)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make measures
|
||||||
|
#
|
||||||
|
measCount= -1
|
||||||
|
measures = []
|
||||||
|
|
||||||
|
while notes.size > 0 || chords.size > 0
|
||||||
|
measCount += 1
|
||||||
|
meas = {}
|
||||||
|
meas['measure'] = measCount
|
||||||
|
meas['properties'] = 0
|
||||||
|
if chords.size > 0
|
||||||
|
mchords = []
|
||||||
|
len = VL::Fract.new(0, 1)
|
||||||
|
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
|
||||||
|
meas['chords'] = mchords
|
||||||
|
end
|
||||||
|
if notes.size > 0
|
||||||
|
mnotes = []
|
||||||
|
len = VL::Fract.new(0, 1)
|
||||||
|
while len < measureLen && notes.size > 0
|
||||||
|
note = notes.shift
|
||||||
|
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
||||||
|
if len+noteLen > measureLen
|
||||||
|
remLen = len+noteLen-measureLen
|
||||||
|
noteLen -= remLen
|
||||||
|
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
|
||||||
|
mnotes.push(note)
|
||||||
|
len += noteLen
|
||||||
|
end
|
||||||
|
meas['melody'] = mnotes
|
||||||
|
end
|
||||||
|
measures.push(meas)
|
||||||
|
end
|
||||||
|
|
||||||
|
OUTPUT['measures'] = measures
|
||||||
OUTPUT['properties'] = [{
|
OUTPUT['properties'] = [{
|
||||||
'divisions' => divisions,
|
'divisions' => divisions,
|
||||||
'key' => key,
|
'key' => key,
|
||||||
|
|
|
@ -79,4 +79,53 @@ class VL
|
||||||
Sus4 = VL::Unison+VL::Fourth+VL::Fifth
|
Sus4 = VL::Unison+VL::Fourth+VL::Fifth
|
||||||
Sus2 = VL::Unison+VL::Maj2nd+VL::Fifth
|
Sus2 = VL::Unison+VL::Maj2nd+VL::Fifth
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Fract
|
||||||
|
include Comparable
|
||||||
|
|
||||||
|
def initialize(num, denom)
|
||||||
|
@num = num
|
||||||
|
@denom = denom
|
||||||
|
|
||||||
|
normalize()
|
||||||
|
end
|
||||||
|
|
||||||
|
def num
|
||||||
|
return @num
|
||||||
|
end
|
||||||
|
|
||||||
|
def denom
|
||||||
|
return @denom
|
||||||
|
end
|
||||||
|
|
||||||
|
def _gcd(x, y)
|
||||||
|
while y != 0
|
||||||
|
x,y = [y, x % y]
|
||||||
|
end
|
||||||
|
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize
|
||||||
|
g = _gcd(@num, @denom)
|
||||||
|
@num /= g
|
||||||
|
@denom /= g
|
||||||
|
end
|
||||||
|
|
||||||
|
def -()
|
||||||
|
return Fract.new(-@num, @denom)
|
||||||
|
end
|
||||||
|
|
||||||
|
def +(other)
|
||||||
|
return Fract.new(@num*other.denom+other.num*@denom, @denom*other.denom)
|
||||||
|
end
|
||||||
|
|
||||||
|
def -(other)
|
||||||
|
return Fract.new(@num*other.denom-other.num*@denom, @denom*other.denom)
|
||||||
|
end
|
||||||
|
|
||||||
|
def <=>(other)
|
||||||
|
return @num*other.denom <=> other.num*@denom
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#import "VLMMADocument.h"
|
#import "VLMMADocument.h"
|
||||||
#import "VLMIDIDocument.h"
|
#import "VLMIDIDocument.h"
|
||||||
#import "VLPDFDocument.h"
|
#import "VLPDFDocument.h"
|
||||||
|
#import "VLPListDocument.h"
|
||||||
#import "VLPDFWindow.h"
|
#import "VLPDFWindow.h"
|
||||||
#import "VLLogWindow.h"
|
#import "VLLogWindow.h"
|
||||||
#import "VLSheetWindow.h"
|
#import "VLSheetWindow.h"
|
||||||
|
@ -352,6 +353,12 @@
|
||||||
|
|
||||||
if ([typeName isEqual:@"VLNativeType"] || [typeName isEqual:@"VLMusicXMLType"]) {
|
if ([typeName isEqual:@"VLNativeType"] || [typeName isEqual:@"VLMusicXMLType"]) {
|
||||||
return [self readFromXMLFileWrapper:wrapper error:outError];
|
return [self readFromXMLFileWrapper:wrapper error:outError];
|
||||||
|
} else if ([typeName isEqual:@"VLLilypondType"]) {
|
||||||
|
if ([self readFromFileWrapper:wrapper withFilter:typeName error:outError]) {
|
||||||
|
[self setFileURL:nil];
|
||||||
|
return YES;
|
||||||
|
} else
|
||||||
|
return NO;
|
||||||
} else {
|
} else {
|
||||||
if (outError)
|
if (outError)
|
||||||
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
|
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
|
||||||
|
|
|
@ -432,7 +432,7 @@ advanceAt:
|
||||||
[NSException raise:NSInvalidArgumentException
|
[NSException raise:NSInvalidArgumentException
|
||||||
format:@"Filter %@: %@", filterName, errStr];
|
format:@"Filter %@: %@", filterName, errStr];
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,9 +469,9 @@ advanceAt:
|
||||||
mutabilityOption:NSPropertyListImmutable
|
mutabilityOption:NSPropertyListImmutable
|
||||||
format:NULL errorDescription:&errString];
|
format:NULL errorDescription:&errString];
|
||||||
if (!outPlist)
|
if (!outPlist)
|
||||||
return NO;
|
[NSException raise:NSInvalidArgumentException
|
||||||
else
|
format:@"Plist %@: %@", filterName, errString];
|
||||||
return [self readFromPlist:outPlist error:outError];
|
return [self readFromPlist:outPlist error:outError];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
95049CF30BDC32EB0015EE6E /* installLilypond.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049CF20BDC32CD0015EE6E /* installLilypond.scpt */; };
|
95049CF30BDC32EB0015EE6E /* installLilypond.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049CF20BDC32CD0015EE6E /* installLilypond.scpt */; };
|
||||||
95049D020BDC436A0015EE6E /* installPython.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049D010BDC43510015EE6E /* installPython.scpt */; };
|
95049D020BDC436A0015EE6E /* installPython.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049D010BDC43510015EE6E /* installPython.scpt */; };
|
||||||
950795E10B4A34D9008911A6 /* stop.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 950795E00B4A34D9008911A6 /* stop.tiff */; };
|
950795E10B4A34D9008911A6 /* stop.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 950795E00B4A34D9008911A6 /* stop.tiff */; };
|
||||||
|
95140E3C0C944F7F00966576 /* VLLilypondType.reader in Copy Filters */ = {isa = PBXBuildFile; fileRef = 95140E3B0C944F7F00966576 /* VLLilypondType.reader */; };
|
||||||
9524DAFB0BE569C50002AC03 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 9524DAF70BE569C50002AC03 /* Help */; };
|
9524DAFB0BE569C50002AC03 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 9524DAF70BE569C50002AC03 /* Help */; };
|
||||||
9524DB390BE5CA070002AC03 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9524DB380BE5CA070002AC03 /* Carbon.framework */; };
|
9524DB390BE5CA070002AC03 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9524DB380BE5CA070002AC03 /* Carbon.framework */; };
|
||||||
952CBB9C095FD1CA00434E43 /* VLSoundOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952CBB9A095FD1CA00434E43 /* VLSoundOut.cpp */; };
|
952CBB9C095FD1CA00434E43 /* VLSoundOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952CBB9A095FD1CA00434E43 /* VLSoundOut.cpp */; };
|
||||||
|
@ -136,6 +137,7 @@
|
||||||
dstPath = Filters;
|
dstPath = Filters;
|
||||||
dstSubfolderSpec = 7;
|
dstSubfolderSpec = 7;
|
||||||
files = (
|
files = (
|
||||||
|
95140E3C0C944F7F00966576 /* VLLilypondType.reader in Copy Filters */,
|
||||||
95795CE60C88B25D00E4A21F /* vl.rb in Copy Filters */,
|
95795CE60C88B25D00E4A21F /* vl.rb in Copy Filters */,
|
||||||
95795CE70C88B25D00E4A21F /* VLMusicXMLType.reader in Copy Filters */,
|
95795CE70C88B25D00E4A21F /* VLMusicXMLType.reader in Copy Filters */,
|
||||||
95EF921A0C786CB90093E5F4 /* plistReader.rb in Copy Filters */,
|
95EF921A0C786CB90093E5F4 /* plistReader.rb in Copy Filters */,
|
||||||
|
@ -174,6 +176,7 @@
|
||||||
95049CF20BDC32CD0015EE6E /* installLilypond.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installLilypond.scpt; path = Resources/installLilypond.scpt; sourceTree = "<group>"; };
|
95049CF20BDC32CD0015EE6E /* installLilypond.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installLilypond.scpt; path = Resources/installLilypond.scpt; sourceTree = "<group>"; };
|
||||||
95049D010BDC43510015EE6E /* installPython.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installPython.scpt; path = Resources/installPython.scpt; sourceTree = "<group>"; };
|
95049D010BDC43510015EE6E /* installPython.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installPython.scpt; path = Resources/installPython.scpt; sourceTree = "<group>"; };
|
||||||
950795E00B4A34D9008911A6 /* stop.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = stop.tiff; path = Resources/stop.tiff; sourceTree = "<group>"; };
|
950795E00B4A34D9008911A6 /* stop.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = stop.tiff; path = Resources/stop.tiff; sourceTree = "<group>"; };
|
||||||
|
95140E3B0C944F7F00966576 /* VLLilypondType.reader */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = VLLilypondType.reader; sourceTree = "<group>"; };
|
||||||
9524DAF70BE569C50002AC03 /* Help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Help; path = Resources/Help; sourceTree = "<group>"; };
|
9524DAF70BE569C50002AC03 /* Help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Help; path = Resources/Help; sourceTree = "<group>"; };
|
||||||
9524DB380BE5CA070002AC03 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
9524DB380BE5CA070002AC03 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||||
952CBB98095FD19D00434E43 /* TVLSoundOut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLSoundOut; sourceTree = BUILT_PRODUCTS_DIR; };
|
952CBB98095FD19D00434E43 /* TVLSoundOut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLSoundOut; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -539,6 +542,7 @@
|
||||||
95795CE40C88B25D00E4A21F /* vl.rb */,
|
95795CE40C88B25D00E4A21F /* vl.rb */,
|
||||||
95795CE50C88B25D00E4A21F /* VLMusicXMLType.reader */,
|
95795CE50C88B25D00E4A21F /* VLMusicXMLType.reader */,
|
||||||
95EF92270C78E9390093E5F4 /* VLMusicXMLType.writer */,
|
95EF92270C78E9390093E5F4 /* VLMusicXMLType.writer */,
|
||||||
|
95140E3B0C944F7F00966576 /* VLLilypondType.reader */,
|
||||||
95EF92120C786B2C0093E5F4 /* plistReader.rb */,
|
95EF92120C786B2C0093E5F4 /* plistReader.rb */,
|
||||||
95EF92130C786B2C0093E5F4 /* plistWriter.rb */,
|
95EF92130C786B2C0093E5F4 /* plistWriter.rb */,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user