This script is designed to be interpreted by mmscript.exe version 2002 by Ken Johnson. For that ourpose it only contains :subroutines used for music annotation. halt :init :initialize # initialize defaults needed for subroutine library ... call initialize lst-svg.txt # these are these are abbreviations for routines on this page... set do.drawnote.name true set wordloopcommand call word2command set OD call octavedown set OU call octaveup set drawnote call drawnote %me set wordloop call wordloop %me set drawstaff call drawstaff %me set tabulate call tabulate %me set tab-title call tab-title %me set whitenote set fill white set blacknote set fill lightgrey set tab-row 1 set tab-count 0 set tab-duration 0 set seconds-per-measure 1 # durations set d1 96 set d2. 72 set d2 48 set d4. 36 set d4 24 set d8. 18 set d4t 16 set d8 12 set d16. 9 set d8t 8 set d16 6 set d32 3 set measure.width %d1 # musical alphabet logical order set .B# 0 set .B 10 set .Bb 20 set .A 30 set .Ab 40 set .G 50 set .Gb 60 set .F 70 set .E 80 set .Eb 90 set .D 100 set .Db 110 set .C 120 set .Cb 130 set octave.size 120 set octave.negativesize -120 set .C# %.Db set .D# %.Eb set .E# %.F set .Fb %.E set .F# %.Gb set .G# %.Ab set .A# %.Bb set .rest %.B exit :tabulate set key %1 sum msec %2 0.01 set lyric %3 %4 %5 %6 %7 %8 %9 #calibrate with the first 8 beats... if %tab-count >= 8 goto skip sum tab-duration %tab-duration %msec inc tab-count 1 if %tab-count <> 8 exit # scale to 800 pixels div tab-scale 800 %beats-per-box div tab-scale %tab-scale %tab-duration set tab-duration 0.001 call :data %tab-file exit :skip mul box-width %msec %tab-scale call tab-adjust sum test %nextx %box-width # check for center margin crossing to calibrate if %nextx < 400 goto next if %nextx > 440 goto next div tab-scale 400 %tab-duration mul box-width %msec %tab-scale call tab-adjust goto ok :next # check for right margin collision, end or row if %nextx < 710 goto ok if %test < 840 goto ok # otherwise prep for the next row # first show some stats for this row set text %tab-duration sec %drawtext 850 %texty # adjust scale for predicting the next row div tab-scale 800 %tab-duration set tab-duration 0.001 set nextx %left-margin mul box-width %msec %tab-scale call tab-adjust # move to next row set nextx %left-margin set y %nexty inc tab-row 1 # double space every 4th row if %tab-row =< 4 goto ok set tab-row 1 sum y %y %gapy %gapy :ok # sum up the widths for recalibration set text %lyric xmul font-size %box-width 0.167 %beats-per-box sum texty %y %box-height 12 %drawtext %nextx %texty %drawbox %key %nextx %y sum tab-duration %tab-duration %msec exit :tab-adjust xexit if 320 < %box-width if %box-width =< 480 set box-width 400 if 240 < %box-width if %box-width =< 320 set box-width 100 if 160 < %box-width if %box-width =< 240 set box-width 200 if 80 < %box-width if %box-width =< 160 set box-width 100 if 40 < %box-width if %box-width =< 80 set box-width 50 if 15 < %box-width if %box-width =< 40 set box-width 25 if 0 < %box-width if %box-width =< 15 set box-width 12.5 exit :wordloop set word %1 set wordsremaining %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 null if %word == null exit %wordloopcommand goto wordloop . %wordsremaining :word2command xyesno "word? %word " | ifno halt # durations if %word == chord set word d0 if %word == d0 goto dur if %word == d1 goto dur if %word == d2. goto dur if %word == d2 goto dur if %word == d4. goto dur if %word == d4 goto dur if %word == d8. goto dur if %word == d4t goto dur if %word == d8 goto dur if %word == d16 goto dur if %word == d8t goto dur if %word == d16 goto dur if %word == d32 goto dur # musical alphabet logical order if %word == C# set word Db if %word == D# set word Eb if %word == E# set word F if %word == Fb set word E if %word == F# set word Gb if %word == G# set word Ab if %word == A# set word Bb if %word == B# goto make if %word == B goto make if %word == Bb goto make if %word == A goto make if %word == Ab goto make if %word == G goto make if %word == Gb goto make if %word == F goto make if %word == E goto make if %word == Eb goto make if %word == D goto make if %word == Db goto make if %word == C goto make if %word == Cb goto make if %word == rest goto make if %word == OU goto octaveup if %word == OD goto octavedown goto lyric :dur point word %word set dur %word exit :make %drawnote %word exit :lyric set text %word %drawtext %note.x %lyric.y exit :drawNote text set text " %1 " #lookup notes position concat note.y . %text point note.y %note.y sum note.y %note.y %top-line -1 if %text == rest set note.y %last.note.y sum next.note.x %note.x %dur set fill blue set fill-opacity 0.4 set stroke blue set stroke-width 1 %drawline %note.x %note.y %note.x %lyric.top set drawboxtext false set stroke none set stroke-width 0 set box.width %dur set box.height -8 %drawbox %text %note.x %note.y %drawtext %note.x %note.y set last.note.x %note.x set last.note.y %note.y set note.x %next.note.x exit :OctaveDown sum top-line %top-line %octave.size exit :octaveUp sum top-line %top-line %octave.negativesize exit :drawstaff staff.x staff.y measures.across octaves.down set staff.x %1 set staff.y %2 set measures.across %3 set octaves.down %4 set measure.x %staff.x set measure.y %staff.y set measure.count 1 set measures.made 0 :loop.measures.across call drawlyricBar set octaves.made 0 :loop.octaves.down call drawOneOctaveMeasure sum octaves.made %octaves.made 1 if %octaves.made != %octaves.down goto loop.octaves.down sum measures.made %measures.made 1 if %measures.made == %measures.across exit sum measure.x %measure.x %measure.width sum measure.count %measure.count 1 goto :loop.measures.across :drawLyricBar xset $ %drawbox set box.width %measure.width set box.height 10 set gapY 0 set stroke lightblue set stroke-width 1 set text-anchor left set font-size 2 mul y %box.height -1 sum y %y %measure.y %drawbox %measure.count %measure.x %y sum lyric.y %measure.y -1 sum lyric.top %measure.y -10 exit :drawOneOctaveMeasure xyesno ":drawmeasure %measure.x %measure.y " | ifno halt set stroke white %whitenote %drawbox B %measure.x %nexty %blacknote %drawbox . %measure.x %nexty %whitenote %drawbox A %measure.x %nexty %blacknote %drawbox . %measure.x %nexty %whitenote %drawbox G %measure.x %nexty %blacknote %drawbox . %measure.x %nexty %whitenote %drawbox F %measure.x %nexty %whitenote %drawbox E %measure.x %nexty %blacknote %drawbox . %measure.x %nexty %whitenote %drawbox D %measure.x %nexty %blacknote %drawbox . %measure.x %nexty %whitenote %drawbox C %measure.x %nexty exit :tab-title set text %1 %2 %3 %4 %5 %6 %7 %8 %9 set svg-width 1200 set svg-height 1400 %writesvg set font-Size 20 %drawtext 20 20 set font-Size 12 set text Ken Johnson 2004 %drawtext 20 40 # draw a time line of 8 measures (boxes) set box-height 20 set gapy 40 set gapx 0 set left-margin 20 set top-line 100 set box-width 100 set text-anchor middle %drawbox 1 %left-margin %top-line %drawbox 2 %nextx %top-line %drawbox 3 %nextx %top-line %drawbox 4 %nextx %top-line %drawbox 5 %nextx %top-line %drawbox 6 %nextx %top-line %drawbox 7 %nextx %top-line %drawbox 8 %nextx %top-line # get ready to draw tab stuff set beats-per-box 1 set fill blue set fill-opacity 0.1 set stroke blue set stroke-width 0.8 set stroke-opacity 0.5 set text-anchor left set nextx %left-margin sum y %nexty # reset the row datafile xdel tab-row.tmp xsave tab-row.tmp :top set tab-adjust call tab-adjust %me set close-tab-file call close-tab-file %me exit :close-tab-file set text %tab-duration sec %drawtext 850 %texty %close-svg-file halt :misc lost routines %drawstaff %left-margin %top-line 8 3 set font-size 10 set stroke blue set stroke-opacity 0.2 set note.x %left-margin set measure.width %d1 # as with a 4/4 time signature # use %d2. for 3/4 # now we're done so lets wrap it up and see what it looks like... :end