Skip to content

Instantly share code, notes, and snippets.

@tylerlwsmith
Created April 26, 2020 00:50
Show Gist options
  • Save tylerlwsmith/36a622930dfe56f71735865cce9b3e9c to your computer and use it in GitHub Desktop.
Save tylerlwsmith/36a622930dfe56f71735865cce9b3e9c to your computer and use it in GitHub Desktop.

I wrote this in around 2010 because I had some QBasic books that my mom gave me when I was a child. The code is hardly readable but it has sentimental value to me.

DECLARE SUB noopen ()
DECLARE SUB showfiles ()
DECLARE SUB printmatrix ()
DECLARE SUB exporttotext ()
DECLARE SUB openfromfile ()
DECLARE SUB savetofile ()
DECLARE SUB background ()
DECLARE SUB CLEARBOTTOM ()
DECLARE SUB menu ()
DECLARE SUB centertext (inputtext$)
DECLARE SUB undonote ()
DECLARE SUB inputerror (errormessage!)
DECLARE FUNCTION MATRIXADD% (Originalnote AS INTEGER, interval AS INTEGER)
DECLARE FUNCTION PRINTNOTE$ (notenumber%)
DECLARE SUB testadd ()
DECLARE FUNCTION ADDINTERVAL% (Originalnote AS INTEGER, interval AS INTEGER)
DECLARE SUB buildmatrix ()
DECLARE SUB printprime (numbertoprint%)
DECLARE SUB inputscreen ()
DECLARE SUB getnotes ()
DECLARE FUNCTION cleannote$ (notetobecleaned$)
DECLARE FUNCTION Notetonumber% (notename$)
DECLARE SUB inputscreen ()
DIM SHARED notenames7(7) AS STRING
DIM SHARED notenumbers(7) AS INTEGER
DIM SHARED accidental(-1 TO 1) AS STRING
DIM SHARED notenames12(12) AS STRING
DIM SHARED inputnotes12(12) AS STRING * 5
DIM SHARED currentnote AS SINGLE
DIM SHARED prime(12) AS INTEGER
DIM SHARED inverse(12) AS INTEGER
DIM SHARED matrix(12, 12) AS INTEGER
DIM SHARED primeformula(12) AS INTEGER
DIM SHARED inverseformula(12) AS INTEGER
DIM SHARED openedfile AS INTEGER '0 for no, 1 for yes
openedfile = 0 'controlled in build matrix
DIM SHARED errorflag AS INTEGER '0 for no error, 1 for error
DATA "C", "D", "E", "F", "G", "A", "B"
DATA "b", "", "#"
DATA 1, 3, 5, 6, 8, 10, 12
FOR I = 1 TO 7
READ notenames7(I)
NEXT I
FOR I = -1 TO 1
READ accidental(I)
NEXT I
FOR I = 1 TO 7
READ notenumbers(I)
NEXT I
ON ERROR GOTO handler
background
menu
handler:
errorflag = 1
errortype = ERR
LOCATE 23, 1
PRINT "Error number"; errortype; ": ";
SELECT CASE errortype
CASE 53
PRINT "File Not found"
CASE ELSE
PRINT "Error on line "; ERL
END SELECT
RESUME NEXT
FUNCTION ADDINTERVAL% (Originalnote AS INTEGER, interval AS INTEGER)
newnote% = Originalnote + interval
DO UNTIL newnote% >= 0 AND newnote% <= 12
IF newnote% > 12 THEN
newnote% = newnote% - 12
ELSEIF newnote% < 1 THEN
newnote% = newnote% + 12
END IF
LOOP
ADDINTERVAL% = newnote%
END FUNCTION
SUB background
CLS
CLEARBOTTOM
LOCATE 1, 1
PRINT STRING$(80, 205)
LOCATE 1, 10
PRINT "TLWS Martrix Generator Version 0.1"
LOCATE 17, 1
PRINT STRING$(80, 205)
END SUB
SUB buildmatrix
'despite the names of the formulas, somehow the code for prime formula
'and inverse formula got mixed up. due to nothing other than pure laziness,
'i do not really intend to fix it. just making note of this for the future.
'As a side note, I now discover I may have had it right. we shall see.
openedfile = 1
FOR I = 1 TO 12 'loads notenames12 with usable notenames for the matrix
notenames12(Notetonumber(inputnotes12(I))) = inputnotes12(I)
NEXT I
FOR I = 1 TO 12 'loads prime with notenumbers from the user input notes
prime(I) = Notetonumber(inputnotes12(I))
NEXT I
FOR I = 1 TO 12 'create primes formula by subtracting notes following the
'root from the root
primeformula(I) = ADDINTERVAL(prime(1), -prime(I))
NEXT I
FOR I = 1 TO 12 'creates inverse by adding the prime formula
' and i have NO idea how this works but it does
inverse(I) = ADDINTERVAL(prime(1), primeformula(I))
NEXT I
FOR I = 1 TO 12
inverseformula(I) = ADDINTERVAL(inverse(1), -inverse(I))
NEXT I
FOR y = 1 TO 12 'loads the matrix with note numbers by subtracting prime
FOR x = 1 TO 12 'formula from inverse. i don't know why it doesn't use adding
matrix(x, y) = MATRIXADD(inverse(y), -primeformula(x))
NEXT x
NEXT y
printmatrix
END SUB
SUB centertext (inputtext$)
indent = (80 - LEN(inputtext$)) / 2
PRINT TAB(indent); inputtext$
END SUB
FUNCTION cleannote$ (notetobecleaned$)
note$ = UCASE$(LEFT$(notetobecleaned$, 1))
accidental$ = LCASE$(MID$(notetobecleaned$, 2, 1))
newnote$ = note$ + accidental$
IF note$ < "A" OR note$ > "G" THEN newnote$ = "NN"
IF accidental$ <> "b" AND accidental$ <> "#" AND accidental$ <> "" AND accidental$ <> " " THEN newnote$ = "NN"
cleannote$ = newnote$
END FUNCTION
SUB CLEARBOTTOM
LOCATE 18, 1
PRINT STRING$(80, " ")
PRINT STRING$(80, " ")
PRINT STRING$(80, " ")
PRINT STRING$(80, " ")
PRINT STRING$(80, " ")
PRINT STRING$(80, " ")
END SUB
SUB exporttotext
CLEARBOTTOM
LOCATE 18
PRINT "Name you would like to save the file as? Leave blank to go back."
INPUT filename$
IF filename$ = "" THEN noopen
OPEN filename$ FOR OUTPUT AS #1
FOR I = 1 TO 12 'prints rows on top
PRINT #1, TAB((5 * I) + 3); "I" + LTRIM$(STR$(inverseformula(I)));
NEXT I
PRINT #1, ""
PRINT #1, ""
FOR y = 1 TO 12
PRINT #1, "P " + LTRIM$(STR$(primeformula(y))); TAB(8); 'prints columns
FOR x = 1 TO 12 'on side
PRINT #1, PRINTNOTE(matrix(x, y));
NEXT x
PRINT #1,
NEXT y
CLOSE #1
menu
END SUB
SUB getnotes
DIM subinput AS STRING * 4
'currentnote variable controls the counter, and has nothing to do with
'note values 1 - 12.
ERASE inputnotes12
currentnote = 0
CLEARBOTTOM
LOCATE 17, 60
PRINT "Type the notes in sequence. If you wish to undo a note, type UNDO. If you"
PRINT "would like to quit before the sequence is complete, type QUIT."
PRINT
DO
currentnote = currentnote + 1
loopstart:
LOCATE 22, 1
PRINT STRING$(80, " ") 'clears last user input from screen
PRINT STRING$(80, " ") 'clears whatever the computer may have yelled at the
'when they entered crappy input.
inputerror (errormessage) 'prints message if user screws up
LOCATE 21, 1 'lines up for user input
PRINT " � Note"; currentnote; "of 12"
INPUT " ", subinput
IF UCASE$(subinput) = "QUIT" THEN
END
ELSEIF UCASE$(subinput) = "UNDO" AND currentnote > 1 THEN
undonote
GOTO loopstart
ELSEIF cleannote$(subinput) = "NN" THEN
errormessage = 1
GOTO loopstart
END IF
subinput = cleannote$(subinput)
IF currentnote > 1 THEN 'checks to see if note has been used
FOR I = 1 TO currentnote - 1 'minus 1 so it wont read the empty spaces as Bs
IF MATRIXADD(Notetonumber(inputnotes12(I)), 0) = MATRIXADD(Notetonumber(subinput), 0) THEN
errormessage = 2
GOTO loopstart
END IF
NEXT I
END IF
inputnotes12(currentnote) = cleannote$(subinput) 'puts note in array
printprime (currentnote)
errormessage = 0 'clears error message
LOOP UNTIL currentnote = 12
END SUB
SUB inputerror (errormessage)
LOCATE 23, 1
SELECT CASE errormessage
CASE 0
EXIT SUB
CASE 1
PRINT "Must enter a note A through G! (Example: C, F#, Bb, D)"
CASE 2
PRINT "You have already used that note or an enharmonic spelling of it!"
END SELECT
END SUB
SUB inputscreen
background
getnotes
buildmatrix
menu
END SUB
FUNCTION MATRIXADD% (Originalnote AS INTEGER, interval AS INTEGER)
newnote% = Originalnote + interval
DO UNTIL newnote% >= 1 AND newnote% <= 12
IF newnote% > 12 THEN
newnote% = newnote% - 12
ELSEIF newnote% < 1 THEN
newnote% = newnote% + 12
END IF
LOOP
MATRIXADD% = newnote%
END FUNCTION
SUB menu
DIM menuoption(5) AS STRING
cursor = 1
CLEARBOTTOM
menuoption(1) = "New 12 tone matrix"
menuoption(2) = "Load existing 12 tone matrix"
menuoption(3) = "Save current 12 tone matrix"
menuoption(4) = "Export current 12 tone matrix"
menuoption(5) = "Exit"
top:
COLOR 7
CLEARBOTTOM
LOCATE 18, 1
PRINT
FOR I = 1 TO 5
LOCATE 18 + I, 30
PRINT (menuoption(I))
NEXT I
COLOR 15
LOCATE 18 + cursor, 28
PRINT CHR$(16); " ";
PRINT (menuoption(cursor))
DO
option$ = INKEY$
IF option$ <> "" AND option$ <> CHR$(13) THEN
IF ASC(RIGHT$(option$, 1)) = 80 AND ASC(option$) = 0 THEN
cursor = cursor + 1
IF cursor > 5 THEN
cursor = 1
ELSEIF openedfile = 0 AND cursor = 3 THEN
cursor = 5
END IF
ELSEIF ASC(RIGHT$(option$, 1)) = 72 AND ASC(option$) = 0 THEN
cursor = cursor - 1
IF cursor < 1 THEN
cursor = 5
ELSEIF openedfile = 0 AND cursor = 4 THEN
cursor = 2
END IF
END IF
GOTO top
END IF
LOOP UNTIL option$ = CHR$(13)'chr13 is enter
COLOR 7 'changes color back to white
SELECT CASE cursor
CASE 1
inputscreen
CASE 2
openfromfile
CASE 3
savetofile
CASE 4
exporttotext
CASE 5
END
END SELECT
END SUB
SUB noopen
IF openedfiles = 0 THEN
menu
ELSEIF openefiles = 1 THEN
inputscreen
PRINT matrix
menu
END IF
END SUB
FUNCTION Notetonumber% (notename$)
'note numbers is a shared global variable that contains values for C(1) D(3)
'G(8) ect
DIM newnote12 AS INTEGER
note$ = UCASE$(LEFT$(notename$, 1))
accidental$ = LCASE$(MID$(notename$, 2, 1))
FOR I = 1 TO 7
IF note$ = notenames7(I) THEN
newnote12 = notenumbers(I)
EXIT FOR
ELSE
newnote12 = 0
END IF
NEXT I
SELECT CASE accidental$
CASE "#"
newnote12 = newnote12 + 1
CASE "b"
newnote12 = newnote12 - 1
END SELECT
Notetonumber = newnote12
END FUNCTION
SUB openfromfile
CLEARBOTTOM
'ON ERROR GOTO errorhandle
topofopenfromfile:
LOCATE 18
PRINT "Name is the name of the file you would like to open? Leave blank to go back."
INPUT filename$
IF filename$ = "" THEN noopen
OPEN filename$ FOR INPUT AS #1
IF errorflag = 0 THEN
INPUT #1, TLWS$ 'checks to see if its a matrix file
IF TLWS$ = "TLWS" THEN
FOR I = 1 TO 12
INPUT #1, inputnotes12(I)
NEXT I
CLS
background
buildmatrix
menu
ELSE
CLOSE #1
CLEARBOTTOM
LOCATE 18
PRINT "Not a TLWS matrix file type"
SLEEP 1
GOTO topofopenfromfile
END IF
CLOSE #1
ELSEIF errorflag = 1 THEN
CLOSE #1
LOCATE 19
PRINT STRING$(80, " ")
errorflag = 0
GOTO topofopenfromfile
END IF
END SUB
SUB printmatrix
FOR y = 1 TO 12
LOCATE y + 3, 16 'Prints matrix of notes
FOR x = 1 TO 12
PRINT PRINTNOTE(matrix(x, y));
NEXT x
PRINT
NEXT y
LOCATE 2 'prints the transpositions across the top, for some reason
FOR I = 1 TO 12 'the formulas came out backwards, but don't worry, it works
PRINT TAB(11 + 5 * I); "I" + LTRIM$(STR$(inverseformula(I)));
NEXT I
FOR I = 1 TO 12
LOCATE 3 + I, 9 'prints inversions along the side
PRINT "P " + LTRIM$(STR$(primeformula(I)))
NEXT I
'FOR i = 1 TO 12
' PRINT inputnotes12(i), PRINTNOTE(prime(i)), PRINTNOTE(inverse(i)), primeformula(i)
' PRINT inputnotes12(i), prime(i), inverse(i), primeformula(i)
'NEXT i
END SUB
FUNCTION PRINTNOTE$ (notenumber%)
PRINTNOTE$ = notenames12(notenumber%)
END FUNCTION
SUB printprime (numbertoprint%)
LOCATE 4, 16
FOR I = 1 TO numbertoprint%
PRINT inputnotes12(I);
NEXT I
END SUB
SUB savetofile
CLEARBOTTOM
LOCATE 18
PRINT "Name you would like to save the file as? Leave blank to go back"
INPUT filename$
IF filename$ = "" THEN noopen
OPEN filename$ FOR OUTPUT AS #1
WRITE #1, "TLWS"
FOR I = 1 TO 12
WRITE #1, inputnotes12(I)
NEXT I
CLOSE #1
menu
END SUB
SUB showfiles
'LOCATE 2
'FILES
END SUB
SUB testadd
CLS
INPUT number1$
centertext (number1$)
END
END SUB
SUB undonote
currentnote = currentnote - 1
inputnotes12(currentnote) = ""
printprime (currentnote)
END SUB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment