diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings index a50de9c..abfd4a5 100644 Binary files a/English.lproj/InfoPlist.strings and b/English.lproj/InfoPlist.strings differ diff --git a/Filters/VLBIABType.reader b/Filters/VLBIABType.reader new file mode 100755 index 0000000..e901552 --- /dev/null +++ b/Filters/VLBIABType.reader @@ -0,0 +1,361 @@ +#!/usr/bin/ruby +# +# VLBIABType.reader - Import Band-in-a-Box files +# +# Reverse engineering by Alf Warnock & Alain Brenzikofer +# + +DEBUG = true + +require File.dirname($0)+'/plistWriter' +require File.dirname($0)+'/vl' + +MEAS = [] +PROP = { + 'divisions' => 3, + 'key' => 0, + 'mode' => 1, + 'timeNum' => 4, + 'timeDenom' => 4 +} +OUTPUT = { + 'measures' => MEAS, + 'properties'=> [PROP] +} + +GROOVE = ['Swing', # Jazz Swing + nil, # Country 12/8 + 'Country', # Country 4/4 + 'BossaNova', # Bossa Nova + nil, # Ethnic + nil, # Blues Shuffle + 'Blues', # Blues Straight + 'Waltz', # Waltz + 'PopBallad', # Pop Ballad + 'Rock', # should be Rock Shuffle + 'Rock', # lite Rock + 'Rock', # medium Rock + 'Rock', # Heavy Rock + 'Rock', # Miami Rock + nil, # Milly Pop + nil, # Funk + 'JazzWaltz', # Jazz Waltz + 'Rhumba', # Rhumba + nil, # Cha Cha + nil, # Bouncy + nil, # Irish + nil, # Pop Ballad 12/8 + nil, # Country12/8 old + nil # Reggae + ] + +KEY = [[ 0, 1], + [ 0, 1], [-5, 1], [ 2, 1], [-3, 1], [ 4, 1], [-1, 1], + [-6, 1], [ 1, 1], [-4, 1], [ 3, 1], [-2, 1], [ 5, 1], + [ 7, 1], [ 9, 1], [ 6, 1], [ 8, 1], [10, 1], + [-3,-1], [ 4,-1], [-1,-1], [-6,-1], [ 1,-1], [-4,-1], + [ 3,-1], [-2,-1], [ 5,-1], [ 0,-1], [-5,-1], [ 2,-1], + [ 4,-1], [ 6,-1], [ 3,-1], [ 5,-1], [ 7,-1]] + +$stdin.read(1) # Skip 1 Byte +titleLen = $stdin.read(1)[0] +OUTPUT['title'] = $stdin.read(titleLen) + +$stdin.read(2) # Skip 2 Bytes +gr = $stdin.read(1)[0] +OUTPUT['groove'] = GROOVE[gr] || "Swing" +key = KEY[$stdin.read(1)[0]] +PROP['key'] = key[0] +PROP['mode'] = key[1] +OUTPUT['tempo'] = $stdin.read(1)[0] + +# +# Style map - not processed yet +# +STYLES = [] +i=0 +while i < 256 + st = $stdin.read(1)[0] + if st > 0 + STYLES[i-1] = st + i += 1 + else + i += $stdin.read(1)[0] + end +end + +# +# Chord extensions +# +EXT = [ + nil, + VL::Chord::Maj, + VL::Chord::Maj, + VL::Unison | VL::Maj3rd | VL::Dim5th, + VL::Chord::Aug, + VL::Chord::Maj6, + VL::Chord::Maj7, + VL::Chord::Maj9, + VL::Chord::Maj9 | VL::Aug11th, + VL::Chord::Maj9 | VL::Aug11th | VL::Maj13th, + VL::Chord::Maj13, # 10 + nil, + VL::Chord::Aug, + VL::Chord::Aug | VL::Maj7th, + VL::Chord::Maj6 | VL::Maj9th, + VL::Chord::Sus2, + VL::Chord::Min, + VL::Unison | VL::Min3rd | VL::Aug5th, + VL::Chord::MMin7, + VL::Chord::Min7, + VL::Chord::Min9, # 20 + VL::Chord::Min11, + VL::Chord::Min13, + VL::Chord::Min6, + VL::Unison | VL::Min3rd | VL::Aug5th, + VL::Unison | VL::Min3rd | VL::Aug5th | VL::Min7th, + VL::Unison | VL::Min3rd | VL::Fifth | VL::Dim7th | VL::Maj9th, + nil, + nil, + nil, + nil, # 30 + nil, + VL::Chord::M7b5, + VL::Chord::Dim, + VL::Chord::M7b5 | VL::Maj9th, + nil, + nil, + nil, + nil, + nil, + VL::Unison | VL::Fifth, # 40 + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, # 50 + nil, + nil, + nil, + nil, + nil, + VL::Chord::Aug7, + VL::Chord::Aug, + VL::Chord::Aug7 | VL::Maj9th | VL::Eleventh | VL::Maj13th, + nil, + nil, # 60 + nil, + nil, + nil, + VL::Chord::Dom7, + VL::Chord::Dom13, + VL::Chord::Dom7 | VL::Min13th, + VL::Chord::Dom7 | VL::Aug11th, + nil, + nil, + VL::Chord::Dom9, # 70 ??? + nil, + VL::Chord::Dom9 | VL::Min13th, + VL::Chord::Dom9 | VL::Aug11th, + VL::Chord::Dom9 | VL::Aug11th | VL::Maj13th, + nil, + VL::Chord::Dom7 | VL::Min9th, + VL::Chord::Dom7 | VL::Min9th | VL::Maj13th, + nil, + VL::Chord::Dom7 | VL::Min9th | VL::Aug11th, + nil, # 80 + nil, + VL::Chord::Dom7 | VL::Aug9th, + VL::Chord::Dom7 | VL::Aug9th | VL::Maj13th, + VL::Chord::Dom7 | VL::Aug9th | VL::Min13th, + VL::Chord::Dom9 | VL::Aug11th, + nil, + nil, + VL::Unison | VL::Maj3rd | VL::Dim5th | VL::Min7th, + VL::Unison | VL::Maj3rd | VL::Dim5th | VL::Min7th | VL::Maj13th, + nil, # 90 + VL::Unison | VL::Maj3rd | VL::Dim5th | VL::Min7th | VL::Maj9th, + nil, + VL::Unison | VL::Maj3rd | VL::Dim5th | VL::Min7th | VL::Min9th, + nil, + nil, + VL::Unison | VL::Maj3rd | VL::Dim5th | VL::Min7th | VL::Aug9th, + nil, + nil, + VL::Chord::Aug7, + nil, # 100 + nil, + nil, + VL::Chord::Aug7 | VL::Maj9th, + nil, + VL::Chord::Aug7 | VL::Min9th, + nil, + nil, + nil, + VL::Chord::Aug7 | VL::Aug9th, + nil, # 110 + nil, + nil, + VL::Unison | VL::Maj3rd | VL::Dim7th | VL::Min7th | VL::Min9th, + nil, + nil, + nil, + nil, + nil, + nil, + nil, # 120 + nil, + nil, + nil, + nil, + nil, + nil, + nil, + VL::Chord::Sus4 | VL::Min7th, + VL::Chord::Sus4 | VL::Min7th | VL::Maj9th | VL::Maj13th, + nil, # 130 + nil, + nil, + nil, + VL::Chord::Dom11, + nil, + nil, + nil, + nil, + nil, + VL::Chord::Sus4 | VL::Min7th | VL::Min9th, # 140 + nil, + nil, + nil, + nil, + nil, + VL::Chord::Sus4 | VL::Min7th | VL::Aug9th, + nil, + nil, + nil, + nil, # 150 + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, + nil, # 160 + nil, + nil, + VL::Unison | VL::Dim5th | VL::Aug5th, + nil, + nil, + nil, + nil, + nil, + nil, + nil, # 170 + nil, + nil, + nil, + nil, + nil, + nil, + VL::Chord::Sus4, + nil, + nil, + nil, # 180 + nil, + nil, + nil, + VL::Chord::Sus4 +]; + +STEPS = [] +i = 1 +while i < 1021 + ex = $stdin.read(1)[0] + if ex > 0 + STEPS[i] = EXT[ex] + i += 1 + else + i += $stdin.read(1)[0] + end +end + +PITCHES = [0, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 61, 63, 66, 68, 70] +CHORDS = [] +ROOTS = [] +i = 1 +while i < 1022 + cr = $stdin.read(1)[0] + if cr > 0 + CHORDS[i] = PITCHES[cr % 18] + if cr > 18 + ROOTS[i] = PITCHES[(cr/18+cr%18) % 12] + end + i += 1 + else + i += $stdin.read(1)[0] + end +end + +$stdin.read(1) # Start measure +numMeasures = $stdin.read(1)[0] +numRepeats = $stdin.read(1)[0] + +biab = $stdin.read + +styleFile = nil +if biab =~ /B.(.{1,8})\.STY/ + styleFile = $1 +end +noteCount = 0 +if biab =~ /\x00\xFF\x00\x0D(..)/ + noteCount = $1.unpack('v')[0] +end +puts "Style #{styleFile}" if DEBUG +RAWNOTES = [] +ONSETS = [0,0,0,0,0,0,0,0,0,0,0,0] +if biab.sub!(/.*?\xA0\xB0\xC1/, '') + (0...noteCount).each do |i| + onset, channel, pitch, velocity, duration = biab[i*12, 12].unpack('VCCCxV') + puts "O #{onset}; C #{channel}; P #{pitch}; V #{velocity}; D #{duration}" if DEBUG + if channel==176 or channel==179 + pitch = -128 + end + onset = (onset / 10.0).round + RAWNOTES.push([onset, pitch]) + ONSETS[onset % 12] += 1 + end +end +p ONSETS if DEBUG + +if ONSETS[1]+ONSETS[5]+ONSETS[7]+ONSETS[11] == 0 + if ONSETS[3]+ONSETS[9] == 0 + if ONSETS[2]+ONSETS[4]+ONSETS[8]+ONSETS[10] == 0 + PROP['divisions'] = 2 + elsif ONSETS[2]+ONSETS[6]+ONSETS[10] == 0 + PROP['divisions'] = 3 + else + PROP['divisions'] = 6 + end + elsif ONSETS[2]+ONSETS[4]+ONSETS[8]+ONSETS[10] == 0 + PROP['divisions'] = 4 + else + PROP['divisions'] = 12 + end +else + PROP['divisions'] = 12 +end + +writePlist($stdout, OUTPUT) + +# Local Variables: +# mode:ruby +# End: diff --git a/Resources/Info.plist b/Resources/Info.plist index c899d2e..82b76f9 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -6,6 +6,29 @@ English CFBundleDocumentTypes + + CFBundleTypeExtensions + + SGU + SG1 + MGU + MG1 + + CFBundleTypeName + VLBIABType + CFBundleTypeOSTypes + + BIAB + + CFBundleTypeRole + Viewer + LSTypeIsPackage + + NSDocumentClass + VLDocument + NSPersistentStoreTypeKey + Binary + CFBundleTypeExtensions diff --git a/Sources/VLDocument.mm b/Sources/VLDocument.mm index 3514ee9..d6c24da 100644 --- a/Sources/VLDocument.mm +++ b/Sources/VLDocument.mm @@ -353,7 +353,7 @@ if ([typeName isEqual:@"VLNativeType"] || [typeName isEqual:@"VLMusicXMLType"]) { return [self readFromXMLFileWrapper:wrapper error:outError]; - } else if ([typeName isEqual:@"VLLilypondType"]) { + } else if ([typeName isEqual:@"VLLilypondType"] || [typeName isEqual:@"VLBIABType"]) { if ([self readFromFileWrapper:wrapper withFilter:typeName error:outError]) { [self setFileURL:nil]; return YES; diff --git a/VocalEasel.xcodeproj/project.pbxproj b/VocalEasel.xcodeproj/project.pbxproj index a1a64cb..452d30d 100644 --- a/VocalEasel.xcodeproj/project.pbxproj +++ b/VocalEasel.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 95140E3C0C944F7F00966576 /* VLLilypondType.reader in Copy Filters */ = {isa = PBXBuildFile; fileRef = 95140E3B0C944F7F00966576 /* VLLilypondType.reader */; }; 9524DAFB0BE569C50002AC03 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 9524DAF70BE569C50002AC03 /* Help */; }; 9524DB390BE5CA070002AC03 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9524DB380BE5CA070002AC03 /* Carbon.framework */; }; + 95297F310C9ADA33007EFD6B /* VLBIABType.reader in Copy Filters */ = {isa = PBXBuildFile; fileRef = 95297F300C9ADA33007EFD6B /* VLBIABType.reader */; }; 952CBB9C095FD1CA00434E43 /* VLSoundOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952CBB9A095FD1CA00434E43 /* VLSoundOut.cpp */; }; 952CBB9D095FD1CA00434E43 /* VLSoundOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952CBB9A095FD1CA00434E43 /* VLSoundOut.cpp */; }; 952CBB9F095FD1D900434E43 /* TVLSoundOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952CBB9E095FD1D900434E43 /* TVLSoundOut.cpp */; }; @@ -137,6 +138,7 @@ dstPath = Filters; dstSubfolderSpec = 7; files = ( + 95297F310C9ADA33007EFD6B /* VLBIABType.reader in Copy Filters */, 95140E3C0C944F7F00966576 /* VLLilypondType.reader in Copy Filters */, 95795CE60C88B25D00E4A21F /* vl.rb in Copy Filters */, 95795CE70C88B25D00E4A21F /* VLMusicXMLType.reader in Copy Filters */, @@ -179,6 +181,7 @@ 95140E3B0C944F7F00966576 /* VLLilypondType.reader */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = VLLilypondType.reader; sourceTree = ""; }; 9524DAF70BE569C50002AC03 /* Help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Help; path = Resources/Help; sourceTree = ""; }; 9524DB380BE5CA070002AC03 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 95297F300C9ADA33007EFD6B /* VLBIABType.reader */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = VLBIABType.reader; sourceTree = ""; }; 952CBB98095FD19D00434E43 /* TVLSoundOut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLSoundOut; sourceTree = BUILT_PRODUCTS_DIR; }; 952CBB9A095FD1CA00434E43 /* VLSoundOut.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = VLSoundOut.cpp; path = Sources/VLSoundOut.cpp; sourceTree = ""; }; 952CBB9B095FD1CA00434E43 /* VLSoundOut.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSoundOut.h; path = Sources/VLSoundOut.h; sourceTree = ""; }; @@ -541,6 +544,7 @@ children = ( 95795CE40C88B25D00E4A21F /* vl.rb */, 95795CE50C88B25D00E4A21F /* VLMusicXMLType.reader */, + 95297F300C9ADA33007EFD6B /* VLBIABType.reader */, 95EF92270C78E9390093E5F4 /* VLMusicXMLType.writer */, 95140E3B0C944F7F00966576 /* VLLilypondType.reader */, 95EF92120C786B2C0093E5F4 /* plistReader.rb */,