Back to the main page for Mozart's Musikalisches Wuerfelspiel.
This computer program called WSPIEL generates waltzes from Mozart's Musikalisches Wuerfelspiel. It is written in BASIC. Specifically, it was originally written for GW-BASIC 3.23 (1988). In Mar 2008 I revisited it with my more up-to-date computing setup. I now have QBASIC on my computer with the Windows XP system, and, lo and behold, WSPIEL still runs like a champ!
It shouldn't be hard to use. (Of course, that's easy for me to say.) The first thing you need to do is extract the WSPIEL source code from this web page and create a WSPIEL.BAS somewhere on your computer. In Internet Explorer, click View and then click Source. That brings up this web page in Notepad. Delete everything above and below the WSPIEL code, and save it as WSPIEL.BAS anywhere you'd like. If you have QBASIC, you're ready to go.
For your first run, just hit carriage return for every prompt except for the filename. That will give you a file with 11 never-before-heard Mozart waltzes, using each of Mozart's measures composed for the Musikalisches Wuerfelspiel exactly one time. This is called the D = "Disallow reuse of measures" mode.
Then try the A = "Allow reuse of measures" mode. The only additional step is specifying the number of walzer, up to 11, that you want.
There is the S mode for Specifying, or Selecting, the precise measures you want in a Single waltz. It's also a cinch to use, but you wouldn't have much use for it at this point since you don't know what you're choosing from. (See the page with the index to all the measures.) Still, you might use the digits of your social security number, or some lucky number, to generate your own personal Mozart waltz.
The R = Redo mode. Sounds a bit scarier. You can probably live without it, but it's not so bad, and it might come in handy. What you need to know is that one run of WSPIEL creates two disk files. They both use the name you supplied at the prompt for the filename. The file with extension .WTZ contains the guitar tablature for all of the waltzes generated by that run. The file with extension .PLN contains the "plan" for that run, that is, all the "dice tosses" used in each of the waltzes in that run. Take a look at the .PLN file to see there's nothing scary there, just a table of "dice tosses" 1 to 11.
All the R = Redo mode does is reuse the measure numbers in the specified .PLN file. The main use for it is to simply regenerate the exact same batch waltzes, but with the output format changed - either a change in the length of the tablature lines, or a switch from frets-in-the-spaces to frets-on-the-lines tablature, say. Or maybe you want to regenerate a batch of walzes after making your own changes to WSPIEL.BAS, such as a change to the tablature of a particular measure, say. If you ever have use for the R = Redo mode, don't be terrorized by the "File already exists. Are you sure?" prompt. Just answer "Y" - yes, you are sure. The older .WTZ file will be over-written, which is what you want, presumably.
Another use for the R = Redo mode is to generate a batch of customized waltzes specified in a .PLN file which you edited by hand. (In this case, "Redo" is a misnomer.) The layout of the .PLN file is simple, and you might edit an existing one or create one from scratch. (The randomizer seed, which is written to the .PLN file is not used in any way in the R = Redo mode, so you can stick any number there.)
After converting from GW-BASIC to QBASIC I could have spent some time and effort making the code look like a million bucks and read like a thriller, but I decided that it really wasn't worth the effort. It works fine; why not just leave well enough alone?
It would give me the greatest pleasure to hear from someone who successfully runs WSPIEL.BAS. Best of luck! although none is really needed. Please let me know if I've said anything unclearly in this introduction. Unfortunately, I'm afraid I can't answer any further questions about getting WSPIEL to work on your computer.
Contact Donald Sauter: send an email; view guestbook; sign guestbook.
Back to Donald Sauter's main page.
Rather shop than think? Please visit My Little Shop of Rare and Precious Commodities.
Parents, if you're considering tutoring or supplemental education for your child, you may be interested in my observations on Kumon.
'*** DIRE WARNING!!! Do NOT extract the WSPIEL code by selecting '*** the text in this web page. You MUST work with the source HTML. '*** In Internet Explorer, click View and then click Source. 'WSPIEL.BAS - generates walzer using Mozart's Musikalisches Wuerfelspiel. IF NEVER THEN 4750 :'Add staff column subroutines. IF NEVER THEN 4950 :'RHYTHM_123 Subroutine. IF NEVER THEN 5160 :'RHYTHM_567 Subroutine. IF NEVER THEN 5560 :'LOAD_CHORD Subroutine. IF NEVER THEN 5710 :'PRINT_STAFF Subroutine. IF NEVER THEN 6280 :'Rhythm and chord DATA. IF NEVER THEN 8370 :'Last line. 'NOTE: Default tablature presentation is Frets-in-Spaces. ' For Frets-on-Lines, manually break during prompts and set SPACEFL=0. DIM STF$(9) :'9 printer lines for the tablature staff; 2 for rhythms, ' 7 lines for 6-string staff. DIM PLAN(11,15) :'11 waltzes, 15 bars (not including 1st/2nd endings.) DIM PLAN17(11,17) :'11 waltzes, 17 bars (including 1st/2nd endings.) DIM USED(15,11) :'Mozart's 15 bars have 11 alternatives each. DIM RHYTHMS(11,10) :'11 different rhythm patterns. See DATA statements. BARCODE=99 TSAV$=TIME$ DSAV$=DATE$ SECS=TIMER RANDOMIZE SECS PRINT PRINT "WSPIEL - Mozart's Musikalisches Wuerfelspiel." PRINT PRINT "Reminder: For an HTML file, supply beginning HTML in WAM.HT1. PRINT SPACEFL=-1 INPUT "Frets-in-the-spaces tablature? (=yes; N=frets-on-the-lines): ",ANS$ IF ANS$<>"" THEN SPACEFL=0 300 PRINT 310 INPUT "Filename (waltzes will be in filename.WTZ): ",FLNAM$ IF FLNAM$="" THEN BEEP : GOTO 310 IF INSTR(FLNAM$,".")<>0 THEN BEEP : GOTO 310 'IF file already exists ON ERROR GOTO 440 OPEN "I",#2,FLNAM$+".WTZ" CLOSE #2 390 PRINT FLNAM$+".WTZ already exists. Are you sure you want "+FLNAM$; INPUT "? (Y or N): ",ANS$ IF NOT(ANS$="N" OR ANS$="n" OR ANS$="Y" OR ANS$="y") THEN 390 IF ANS$="N" OR ANS$="n" THEN 300 GOTO 470 440 'ELSE file doesn't exist yet RESUME 460 460 ON ERROR GOTO 0 470 'ENDIF output file MAXPOS=78 INPUT "Tablature line length? (Recommend 76-80, =78): ",ANS IF ANS<>0 THEN MAXPOS=ANS PRINT "Program modes: PRINT " D = DISALLOW reuse of measures. Selected measures are removed PRINT " from the selection pool. Produces a batch of 11 randomly PRINT " generated waltzes exhausting all of Mozart's measures. PRINT " A = ALLOW reuse of measures. Selected measures are left in the PRINT " selection pool. You specify the number (1-11) of randomly PRINT " generated waltzes. PRINT " S = non-random mode. You SPECIFY the desired alternative for each PRINT " measure in a single waltz. PRINT " R = REDO (repeat, rerun) a waltz or batch of waltzes previously PRINT " generated. ANS$="D" 650 INPUT "Desired mode (D, A, S, R. =D): ",ANS$ IF ANS$="" THEN ANS$="D" IF ANS$="d" THEN ANS$="D" IF ANS$="a" THEN ANS$="A" IF ANS$="s" THEN ANS$="S" IF ANS$="r" THEN ANS$="R" IF ANS$<>"D" AND ANS$<>"A" AND ANS$<>"S" AND ANS$<>"R" THEN 650 MODE$=ANS$ 'IF measure reuse disallowed IF NOT(MODE$="D") THEN 990 'Load "used" grid with 1s. FOR U1=1 TO 15 : FOR U2=1 TO 11 : USED(U1,U2)=1 : NEXT U2 : NEXT U1 NOW=11 FOR W=1 TO NOW :'Loop through waltzes. NOALTR=11-W+1 :'Number of (remaining) alternatives for each measure. FOR B=1 TO 15 :'Loop through bars of waltz W. RNDM=INT(RND*(NOALTR))+1 :'Gives 1-11 for 11 alternatives, for example. SUM=0 U2=0 870 'DO UNTIL sum is same as our random number U2=U2+1 SUM=SUM+USED(B,U2) IF NOT(SUM=RNDM) THEN 870 'ENDDO USED(B,U2)=0 PLAN(W,B)=U2 NEXT B NEXT W GOTO 1410 990 'IF measure reuse allowed IF NOT(MODE$="A") THEN 1150 NOW=11 1030 INPUT "Number of waltzes to generate? (1-11. =11): ",ANS IF ANS<>0 THEN NOW=ANS IF NOW<1 OR NOW>11 THEN BEEP : GOTO 1030 FOR W=1 TO NOW :'Loop through waltzes. FOR B=1 TO 15 :'Loop through bars within waltz. RNDM=INT(RND*11)+1 :'Gives random number 1-11. PLAN(W,B)=RNDM NEXT B NEXT W GOTO 1410 1150 'ELSEIF user selects desired measures IF NOT(MODE$="S") THEN 1280 NOW=1 FOR B=1 TO 15 IF B=8 THEN PRINT "No choice for bars 8 and 9 (the 1st and 2nd endings). BINW=B : IF B>7 THEN BINW=B+2 1210 PRINT "For bar";BINW;", choose from 11 alternatives "; INPUT "(1-11): ",C% IF C%<1 OR C%>11 THEN BEEP : GOTO 1210 PLAN(1,B)=C% NEXT B GOTO 1410 1280 'ELSE repeat previously done waltzes. Get measure info from .PLN OPEN "I",#1,FLNAM$+".PLN" INPUT #1, DSAV$ INPUT #1, TSAV$ INPUT #1, SECS NOW=1 : B=0 1340 'DO UNTIL end of .PLN file is reached B=B+1 IF B>15 THEN B=1 : NOW=NOW+1 INPUT #1, PLAN(NOW,B) IF NOT EOF(1) THEN 1340 'ENDDO CLOSE #1 1410 'ENDIF PRINT PRINT "Table of ";CHR$(34);"dice tosses";CHR$(34);" for each waltz: PRINT PRINT " -- Measure number -- PRINT "Waltz 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 PRINT "----- -------------------------------------------------- REM 1. nn nn nn nn nn nn nn - - nn nn nn nn nn nn nn nn FOR W=1 TO NOW PRINT USING "###";W; PRINT ". "; FOR B=1 TO 7 PRINT USING "###";PLAN(W,B); NEXT B PRINT " - -"; FOR B=8 TO 15 PRINT USING "###";PLAN(W,B); NEXT B PRINT NEXT W IF NOT(MODE$<>"R") THEN 1760 :'Write to disk if not already there. OPEN "O",#1,FLNAM$+".PLN" PRINT #1, DSAV$ PRINT #1, TSAV$ PRINT #1, SECS FOR W=1 TO NOW FOR B=1 TO 15 PRINT #1, USING "###";PLAN(W,B); IF B<15 THEN PRINT #1, " ,"; NEXT B PRINT #1, NEXT W CLOSE #1 1760 'ENDIF TSTART$=TIME$ S3$="_" : L$="_" IF NOT SPACEFL THEN S3$=" " : L$="-" 'Open file for tablature output. OPEN "O",#3,FLNAM$+".WTZ" 'IF html starter file ON ERROR GOTO 1970 OPEN "I",#2,"WAM.HT1" HTMLFL=-1 1890 'DO UNTIL end of .HT1 file is reached LINE INPUT #2, HTM$ PRINT #3, HTM$ IF NOT EOF(2) THEN 1890 'ENDDO CLOSE #2 GOTO 2010 1970 'ELSE no html file to open HTMLFL=0 RESUME 2000 2000 ON ERROR GOTO 0 2010 'ENDIF html starter file PRINT #3, "Date = ";DSAV$ PRINT #3, "Time = ";TSAV$ PRINT #3, "Seconds from midnight (used as randomizer seed) = ";SECS PRINT #3, PRINT #3, "Table of ";CHR$(34);"dice tosses";CHR$(34);" for each waltz: PRINT #3, PRINT #3, " -- Measure number -- PRINT #3, "Waltz 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 PRINT #3, "----- -------------------------------------------------- REM 1. nn nn nn nn nn nn nn - - nn nn nn nn nn nn nn nn FOR W=1 TO NOW PRINT #3, USING "###";W; PRINT #3, ". "; FOR B=1 TO 7 PRINT #3, USING "###";PLAN(W,B); NEXT B PRINT #3, " - -"; FOR B=8 TO 15 PRINT #3, USING "###";PLAN(W,B); NEXT B PRINT #3, NEXT W PRINT #3, PRINT #3, PRINT #3,"Explanation of symbols (see the main page): PRINT #3," ";CHR$(34);" = trill. Starts on the main note. PRINT #3," ~ = turn. Main note -> upper neighbor -> main -> lower -> main. PRINT #3," ^ = arrowhead indicating strum or arpeggiation. PRINT #3, PRINT #3,"*** Download and edit out all material above and below the tablature. PRINT #3,"*** See the main Musikalisches Wuerfelspiel page for printing advice. PRINT #3, TTLF$="Walzer - Musikalisches Wuerfelspiel" COMPF$="W. A. Mozart." TUNING$="E A D F# B E." PAGENO=1 :'Page counter. 'Convert PLAN to PLAN17 (adding measures 8 and 9.) FOR W=1 TO NOW FOR B=1 TO 7 : PLAN17(W,B)=PLAN(W,B) : NEXT B PLAN17(W,8)=1 'Choose measure 9 fingering based on what comes next. M10=PLAN(W,8) IF M10=1 THEN PLAN17(W,9)=1 :'Ends in position 1. IF M10=2 THEN PLAN17(W,9)=1 IF M10=4 THEN PLAN17(W,9)=1 IF M10=5 THEN PLAN17(W,9)=1 IF M10=7 THEN PLAN17(W,9)=3 :'Ends in position 3. IF M10=11 THEN PLAN17(W,9)=3 IF M10=3 THEN PLAN17(W,9)=4 :'Ends in position 4. IF M10=6 THEN PLAN17(W,9)=4 IF M10=8 THEN PLAN17(W,9)=4 IF M10=9 THEN PLAN17(W,9)=4 IF M10=10 THEN PLAN17(W,9)=4 FOR B=10 TO 17 : PLAN17(W,B)=PLAN(W,B-2) : NEXT B NEXT W 'DO FOR all waltzes. This is the biggest loop. FOR W=1 TO NOW 'Need to start at the beginning of the DATA statements for every waltz. RESTORE FOR I=1 TO 3 :READ RHYTHMS(1,I) :NEXT I FOR I=1 TO 6 :READ RHYTHMS(2,I) :NEXT I FOR I=1 TO 5 :READ RHYTHMS(3,I) :NEXT I FOR I=1 TO 4 :READ RHYTHMS(4,I) :NEXT I FOR I=1 TO 5 :READ RHYTHMS(5,I) :NEXT I FOR I=1 TO 4 :READ RHYTHMS(6,I) :NEXT I FOR I=1 TO 5 :READ RHYTHMS(7,I) :NEXT I FOR I=1 TO 4 :READ RHYTHMS(8,I) :NEXT I FOR I=1 TO 10 :READ RHYTHMS(9,I) :NEXT I FOR I=1 TO 7 :READ RHYTHMS(10,I) :NEXT I FOR I=1 TO 5 :READ RHYTHMS(11,I) :NEXT I 'Clear staff and start with 4 empty columns. FOR JS=1 TO 9 : STF$(JS)="" : NEXT JS GOSUB 4750 : GOSUB 4750 : GOSUB 4750 : GOSUB 4750 CURPOS=4 PREVRHY=BARCODE EMPTYFL=-1 :'Flag says to add empty column after barline. PVFL=0 :'Flag says we had to go back to PREVBRK. KNUM$="K516f." FOR I=1 TO 15 KCHR$=MID$(STR$(PLAN(W,I)),2) IF PLAN(W,I)=10 THEN KCHR$="A" IF PLAN(W,I)=11 THEN KCHR$="B" KNUM$=KNUM$+KCHR$ NEXT I 'DO FOR all bars in the waltz FOR B=1 TO 17 'IF this is the beginning of a waltz, need to print title, etc. IF NOT(B=1) THEN 3300 'IF this is the first waltz IF NOT(W=1) THEN 3160 W1$="1 of"+STR$(NOW)+"." OFFST%=(MAXPOS-LEN(TTLF$))/2 IF OFFST%<1 THEN BEEP : OFFST%=1 PRTLN$=SPACE$(OFFST%)+TTLF$ OFFST%=MAXPOS-LEN(PRTLN$)-LEN(W1$)-2 IF OFFST%<1 THEN BEEP : OFFST%=1 PRTLN$=PRTLN$+SPACE$(OFFST%)+W1$ PRINT #3, PRTLN$ 'Work up line 2 info for 1st waltz. PRTLN$=" "+TUNING$ OFFST%=(MAXPOS-LEN(KNUM$))/2-LEN(PRTLN$) IF OFFST%<1 THEN BEEP : OFFST%=1 PRTLN$=PRTLN$+SPACE$(OFFST%)+KNUM$ OFFST%=MAXPOS-LEN(PRTLN$)-LEN(COMPF$)-2 IF OFFST%<1 THEN BEEP : OFFST%=1 PRTLN$=PRTLN$+SPACE$(OFFST%)+COMPF$ PRINT #3, PRTLN$ LINENO=2 :'Line count initialized. GOTO 3290 3160 'ELSE not 1st waltz 'IF this title line and associated staff will overflow page IF NOT(LINENO+10>62) THEN 3210 GOSUB 6140 :'Set up new page. 3210 'ENDIF PRTLN$=" Walzer"+STR$(W)+" of"+STR$(NOW)+". "+KNUM$ OFFST%=MAXPOS-LEN(PRTLN$)-LEN(COMPF$)-2 IF OFFST%<1 THEN BEEP : OFFST%=1 PRTLN$=PRTLN$+SPACE$(OFFST%)+COMPF$ PRINT #3, PRTLN$ LINENO=LINENO+1 3290 'ENDIF 1st waltz 3300 'ENDIF starting new waltz ALTRNO=PLAN17(W,B) :'Which alternative, out of 11, to use. 'Spin through DATA to chosen alternative. FOR I=1 TO ALTRNO-1 READ JNK : READ JNK : READ JNK : READ JNK : READ NOCH FOR J=1 TO NOCH+1 : READ JNK$ : NEXT J NEXT I 'Now we're at desired DATA line. READ JNK : READ JNK : READ JNK READ RIDX READ NOCH 'DO FOR all chords in bar (including the bar line) FOR ICH=1 TO NOCH+1 READ CHORD$ 'DEBUG PRINT "W,B,ICH,CHORD$=";W;B;ICH;CHORD$ 'BEGIN-CASE 'CASE barline IF NOT(LEFT$(CHORD$,1)="*") THEN 3830 'IF single bar line IF NOT(MID$(CHORD$,1,2)<>"**") THEN 3590 'Eliminate empty column before barline. FOR I=1 TO 9 : STF$(I)=LEFT$(STF$(I),CURPOS-1) : NEXT I CURPOS=CURPOS-1 3590 'ENDIF IF INSTR(CHORD$,"A")>0 THEN GOSUB 4870 : CURPOS=CURPOS+1 :'Add repeat dots. GOSUB 4810 : CURPOS=CURPOS+1 :'Put in barline. IF INSTR(CHORD$,"**")>0 THEN GOSUB 4810 : CURPOS=CURPOS+1 :'Add barline. 'CASE1 ends with barline IF NOT(INSTR(CHORD$,"B")=0) THEN 3700 IF CURPOS MAXPOS THEN BRKPT=PREVBRK : PVFL=-1 : GOSUB 4750 : CURPOS=CURPOS+1 GOTO 3790 3700 'CASE2 ends with repeat sign GOSUB 4870 : CURPOS=CURPOS+1 :'Add repeat dots. 'BEGIN-CASE CURPOS relative to end of staff IF CURPOS MAXPOS+2 THEN BRKPT=PREVBRK : PVFL=-1 : GOSUB 4750 :CURPOS=CURPOS+1 :GOTO 3790 3790 'ENDCASE PREVRHY=BARCODE GOTO 4470 3830 'CASE real chord data RHYCODE=RHYTHMS(RIDX,ICH) 'debug PRINT "W,B,ICH,CHORD$,RHYCODE=";W;B;ICH;CHORD$,RHYCODE IF RHYCODE>=200 THEN RHYCODE=RHYCODE-200 : DNSTRUM=-1 IF RHYCODE>=100 THEN RHYCODE=RHYCODE-100 : UPSTRUM=-1 'BEGIN-CASE rhythm code 'CASE rhythm code 9, no stem, no empty column IF NOT(RHYCODE=9) THEN 4030 STF$(1)=STF$(1)+" " STF$(2)=STF$(2)+" " STF$(3)=STF$(3)+S3$ GOSUB 5560 :'Load chord into staff. CURPOS=CURPOS+1 IF CURPOS>MAXPOS THEN GOSUB 5710 :'Print out staff. PREVRHY=9 GOTO 4450 4030 'CASE rhythm code 0, 4er note IF NOT(RHYCODE=0) THEN 4170 STF$(1)=STF$(1)+" " STF$(2)=STF$(2)+"|" STF$(3)=STF$(3)+S3$ GOSUB 5560 :'Load chord into staff. GOSUB 5430 :'Put strum, if indicated. CURPOS=CURPOS+1 GOSUB 4750 :'Empty column. CURPOS=CURPOS+1 IF CURPOS>MAXPOS THEN GOSUB 5710 :'Print out staff. PREVRHY=0 : PREVBRK=BRKPT : BRKPT=CURPOS GOTO 4450 4170 'CASE rhythm code 1, start 8th note IF NOT(RHYCODE=1) THEN 4280 IF NOT(PREVRHY=10) THEN 4220 IF CURPOS>MAXPOS THEN GOSUB 5710 :'Print out staff. PREVBRK=BRKPT : BRKPT=CURPOS 4220 'ENDIF INBEAM$=" " GOSUB 4950 :'Start or continue group. PREVRHY=1 GOTO 4450 4280 'CASE rhythm code 5, stop 8th note IF NOT(RHYCODE=5) THEN 4350 INBEAM$=" " GOSUB 5160 :'Stop group. PREVRHY=5 GOTO 4450 4350 'CASE rhythm code 10, dotted 4er IF NOT(RHYCODE=10) THEN 4450 IF UPSTRUM THEN UPS10=-1 INBEAM$="." GOSUB 4950 :'Start or continue group. MID$(STF$(1),LEN(STF$(1))-1,2)=" " :'Clobbers ^ arrowhead, if any. IF UPS10 THEN MID$(STF$(1),LEN(STF$(1))-1,1)="^" : UPS10=0 GOSUB 4750 :'Empty column. CURPOS=CURPOS+1 PREVRHY=10 :'Whether or not this is a break point is handled by next code. 4450 'END-CASE rhythm codes 4470 'ENDCASE repeat, barline or chord NEXT ICH 'Spin through remaining alternatives for this bar FOR I=ALTRNO+1 TO 11 READ JNK : READ JNK : READ JNK : READ JNK : READ NOCH FOR J=1 TO NOCH+1 : READ JNK$ : NEXT J NEXT I NEXT B IF CURPOS 1 THEN BRKPT=CURPOS : GOSUB 5710 :'Print out remainder. NEXT W 'ENDDO waltzes IF HTMLFL THEN PRINT #3, "