kickratt: krlogo new (Default)
My introduction to generating music 1988-1992

ROGUE was a program developed between 1988 - 1991 for the Apple IIe. ROGUE, a BASIC written program, generated a text file that could be converted into midi. Other published programs that contributed to the development were rpg character generating programs, a program that attempted to create weather patterns that was in BYTE magazine, code for a Traveller game add-on that generated planets. From time to time programs in BASIC & machine language would appear in magazines like; BYTE, Creative Computing & Dragon. When the Lotto first showed up there was a BASIC program that would generate numerous random lottery choices based on previous drawings. These types of programs all employed a random (RND) function which conjured up numerous ways as to how to generate numerical notes.

Posted below is a segment of the original ROGUE BASIC code that I have managed to hold on to. I have gone through numerous hard drive crashes and disks, moved around alot & thrown a zillion disks away since. This portion of the program's code is all that remains of this early attempt to generate music using an Apple IIe. This generative music process started with another BASIC program (not shown here) which would randomly chose a scale from 10 scales of difference entered into data strings. Then this BASIC program, ROGUE, would generate the midi notes based off the notes from the chosen scale determined by the first program, and would create this one large text file or print out. After parsing the file in Lotus123 on a MacSE30, and adding a velocity & length to each of the generated notes. You could then convert the text file to a midi file with a C program found in the Macintosh Programmer's Workshop environment. Passport's MasterTrax, the sequencer software package I used back on the Se30 could open the resulting 4 track midi file created originally by the AppleII ROGUE program. This rather cumbersome 3 program system, worked very well in generating a midi score & removing the long hours having to recompose or to reenter mass midi notes manually from a text file or line printer output that I periodically did in testing the modules of my program. The versions of ROGUE that actually created the midi notes for the ROGUE tracks, employed many GOTO & GOSUB routines that branched off of this portion of the program that I have included in the KicKRaTT Journal post "ROGUE". Sub routine branches that would create melodies, store drum patterns, and calculated chords into the data strings, to be used routinely in the compositions process. Once in MasterTrax, I made numerous edits to carve the song out of the mass midi note blitz and remove out of key notes that had gone rogue. The end result was 4 tracks of midi in key with one another. Whether it created a moving piece of music is best left to the listener. I was proud that as a completely generated composition, the four tracks of midi notes stayed in the key of the chosen scale for the duration of the song and didn't somehow shift in some part of the conversion process. That was all the effort back then.

The ROGUE tracks posted to SoundCloud...

On my SoundCloud page I will put in the song's description "ROGUE" along with the date. The first ROGUE track presented is "Ducks Pond" recorded in 1989. The second ROGUE track is "Elephant, 1991". The third ROGUE track, "Swamp Gas", also from 1991.

As for this piece of the original ROGUE program.

If you are so inclined and want to program this code into an existing BASIC language emulator, I would suggest you use the JUST BASIC application or the Win-Apple emulator. This Apple BASIC code should work just fine in any of these soft-wares. Take note that the version of ROGUE here is a retype from a dot-matrix print out that I found. It represents just a section of the code that spanned three programs to create this music generating system of mine back then. It serves this project as an early example of programs coded to generate music.

These days, you will be much happier with the results achieved in pure data (purr) & I will be using only pure data (purr) in the near future for generating compositions in audio or music. I have since 1988, worked on generating music with BASIC, C, Csound, MAX, pd, MAX5MSP, purr data & last, back to pure data. It's a fantastic programming environment for music audio & compositional development. Many thanks to Miller Puckette & the contributing programmers at the Institut de Recherche et Coordination Acoustique/Musique (IRCAM) in Paris and the many creators, developers & online contributors of these fantastic type of audio & midi programming environments. Though I did not become acquainted with MAX until after the fact.

Here is a rewriting of ROGUE, this lost music generating program.

PROGRAM: ROGUE
Description: Random Music Composition Program
Date: November 22, 1990
Language: Apple BASIC
Location: Clearwater Florida

ROGUE DESCRIPTION

This program takes the notes from another program that has generated a scale.
The program then randomly determines notes that fall into 4 measures of 4 tracks.
The notes will be broken up into 4 track listings; bass, mid, high & chord.
Bass, mid & high are three note generators based off of conditions.
Chord is a summing of key notes from bass, mid & high and then random generated.
One condition that certainly determines the outcome, is that no two notes are the same at the key points. If this is true then the program regenerates new notes to satisfy the condition. Key points are at divisions of two & based on the max number of notes allowed in the total track. Bass has a max number of notes equal to 4, mid is 8 & high is 16 max notes per track. Octaves are fixed but randomly determined and velocity is grouped into two random generators.

This version of Rogue will allow the user to input a scale of 7 notes & calculate 4 tracks of random generated midi notes, over a number of measures. Depending on your vintage PC or emulator setup, this program will present the output onto a terminal screen, printer or both.

This example of the ROGUE code I have found, was used for testing before it joined the larger automated code & will give the user the ability to see the generation process in action. From the beginning where the scale's notes are entered to, the notes generated per track. If you really pick apart the code you will find that I am working on incorporating velocity. The random calculation is there, it's just not incorporated in the code and therefor no velocity value is presented in the execution.

PROGRAM LISTING # NOTES

010 ML = 1 # ML = Measure Length, manually set this in the code
020 ? "ENTER THE NOTES IN THE SCALE"
030 ? "ENTER BLANK OR DOUBLE FOR 8TH NOTE"
040 ? " "
050 INPUT " NOTE 1 = "; N1$ # enter the midi note numbers 30.31,32
060 INPUT " NOTE 2 = "; N2$ # not the note identifier A,B,C..
070 INPUT " NOTE 3 = "; N3$ # note can be entered in alpha or numera
080 INPUT " NOTE 4 = "; N4$
090 INPUT " NOTE 5 = "; N5$
100 INPUT " NOTE 6 = "; N6$
110 INPUT " NOTE 7 = "; N7$
120 INPUT " NOTE 8 = "; N8$
130 ? " " # in BASIC a "?" is a print command

140 ? "BASS TRACK"
150 ? "MEASURE: " ML "TRACK 1" # ML sets the global loop
160 ? "OCTAVE# NOTE VELOCITY"
170 ? "+-------------------------+"
175 F = 0
180 FOR M = 1 TO 4
190 N = INT ( 8 * RND (1)) + 1
200 IF N = F THEN 180
210 IF N = 1 THEN BN$ = N1$ : GOTO 300
220 IF N = 2 THEN BN$ = N2$ : GOTO 300
230 IF N = 3 THEN BN$ = N3$ : GOTO 300
240 IF N = 4 THEN BN$ = N4$ : GOTO 300
250 IF N = 5 THEN BN$ = N5$ : GOTO 300
260 IF N = 6 THEN BN$ = N6$ : GOTO 300
270 IF N = 7 THEN BN$ = N7$ : GOTO 300
280 IF N = 8 THEN BN$ = N8$

300 IF M = 1 THEN B1$ = BN$
310 IF M = 1 THEN CB1$ = BN$
320 IF M = 2 THEN B2$ = BN$
330 IF M = 3 THEN B3$ = BN$
340 IF M = 3 THEN CB2$ = BN$
350 IF M = 4 THEN B4$ = BN$
360 O$ = "OCTAVE 3" # The octave of the notes is predetermined
370 GOSUB 2000
380 ? O$" "BN$" "V
385 F = N
390 NEXT M
395 ? " "

400 INPUT "READY FOR THE MID TRACK ";YN$
# I put these breaks in the process so I too could take a break
# these types of input moments would halt the process if needed

410 ? "MID TRACK"
420 ? "MEASURE: " ML "TRACK 2"
430 ? "OCTAVE# NOTE VELOCITY"
440 ? "+-------------------------+"
450 F = 0
460 FOR M = 1 TO 8
470 N = INT ( 8 * RND (1)) + 1
480 IF N = 1 THEN MN$ = N1$ : GOTO 570
490 IF N = 2 THEN MN$ = N2$ : GOTO 570
500 IF N = 3 THEN MN$ = N3$ : GOTO 570
510 IF N = 4 THEN MN$ = N4$ : GOTO 570
520 IF N = 5 THEN MN$ = N5$ : GOTO 570
530 IF N = 6 THEN MN$ = N6$ : GOTO 570
540 IF N = 7 THEN MN$ = N7$ : GOTO 570
550 IF N = 8 THEN MN$ = N8$

570 IF M = 1 THEN H$ = MN$ : IF H$ = B1$ THEN GOTO 470
580 IF M = 3 THEN H$ = MN$ : IF H$ = B2$ THEN GOTO 470
590 IF M = 5 THEN H$ = MN$ : IF H$ = B3$ THEN GOTO 470
600 IF M = 7 THEN H$ = MN$ : IF H$ = B4$ THEN GOTO 470

610 IF M = 1 THEN M1$ = MN$
620 IF M = 1 THEN CM1$ = MN$
630 IF M = 2 THEN M2$ = MN$
640 IF M = 3 THEN M3$ = MN$
650 IF M = 4 THEN M4$ = MN$
660 IF M = 5 THEN M5$ = MN$
670 IF M = 5 THEN CM2$ = MN$
680 IF M = 6 THEN M6$ = MN$
690 IF M = 7 THEN M7$ = MN$
700 IF M = 8 THEN M8$ = MN$

710 O = INT ( 3 * RND (1)) + 1
720 IF O = 2 THEN GOTO 710
730 IF O = 1 THEN O$ = "OCTAVE 4"
740 IF O = 3 THEN O$ = "OCTAVE 5"
750 GOSUB 2100
760 ? O$" "MN$" "V
770 F = N
780 NEXT M
790 ? " "

800 INPUT "READY FOR THE HIGH TRACK ";YN$

810 ? "HIGH TRACK"
820 ? "MEASURE: " ML "TRACK 3"
830 ? "OCTAVE# NOTE VELOCITY"
840 ? "+-------------------------+"
850 F = 0
860 FOR M = 1 TO 16
870 N = INT ( 8 * RND (1)) + 1
880 IF N = 1 THEN HN$ = N1$ : GOTO 970
890 IF N = 2 THEN HN$ = N2$ : GOTO 970
900 IF N = 3 THEN HN$ = N3$ : GOTO 970
910 IF N = 4 THEN HN$ = N4$ : GOTO 970
920 IF N = 5 THEN HN$ = N5$ : GOTO 970
930 IF N = 6 THEN HN$ = N6$ : GOTO 970
940 IF N = 7 THEN HN$ = N7$ : GOTO 970
950 IF N = 8 THEN HN$ = N8$

970 IF M = 1 THEN H$ = HN$ : IF H$ = M1$ THEN 870 : IF H$ = B1$ THEN 870
980 IF M = 1 THEN CH1$ = HN$
990 IF M = 3 THEN H$ = HN$ : IF H$ = M2$ THEN 870
1000 IF M = 5 THEN H$ = HN$ : IF H$ = M3$ THEN 870 : IF H$ = B2$ THEN 870
1010 IF M = 7 THEN H$ = HN$ : IF H$ = M4$ THEN 870
1020 IF M = 9 THEN H$ = HN$ : IF H$ = M5$ THEN 870 : IF H$ = B3$ THEN 870
1030 IF M = 9 THEN CH2$ = HN$
1040 IF M = 11 THEN H$ = HN$ : IF H$ = M6$ THEN 870
1050 IF M = 13 THEN H$ = HN$ : IF H$ = M7$ THEN 870 : IF H$ = B4$ THEN 870
1060 IF M = 15 THEN H$ = HN$ : IF H$ = M8$ THEN 870

1070 O = INT ( 3 * RND (1)) + 1
1080 IF O = 2 THEN GOTO 1070
1090 IF O = 1 THEN O$ = "OCTAVE 6"
1100 IF O = 3 THEN O$ = "OCTAVE 7"
1110 GOSUB 2100
1120 ? O$" "HN$" "V
1130 F = N
1140 NEXT M
1150 ? " "

1160 INPUT"READY FOR THE CHORD TRACK";YN$
1170 ? " "

1200 ? "CHORD TRACK"
1210 ? "MEASURE: " ML "TRACK 4"
1220 FOR M = 1 TO 6
1230 N = INT ( 8 * RND (1)) + 1
1240 IF N = 1 THEN CN$ = N1$ : GOTO 1330
1250 IF N = 2 THEN CN$ = N2$ : GOTO 1330
1260 IF N = 3 THEN CN$ = N3$ : GOTO 1330
1270 IF N = 4 THEN CN$ = N4$ : GOTO 1330
1280 IF N = 5 THEN CN$ = N5$ : GOTO 1330
1290 IF N = 6 THEN CN$ = N6$ : GOTO 1330
1300 IF N = 7 THEN CN$ = N7$ : GOTO 1330
1310 IF N = 8 THEN CN$ = N8$

1330 IF M = 1 THEN CA$ = CN$ : IF CA$ = CB1$ THEN 1230 : IF CA$ = CM1$ THEN 1230 : IF CA$ = CH1$ THEN 1230
1340 IF M = 2 THEN CB$ = CN$ : IF CB$ = CA$ THEN 1230 : IF CB$ = CB1$ THEN 1230 : IF CB$ = CM1$ THEN 1230 : IF CB$ = CH1$ THEN 1230
1350 IF M = 3 THEN CC$ = CN$ : IF CC$ = CA$ THEN 1230 : IF CC$ = CB$ THEN 1230 : IF CC$ = CB1$ THEN 1230 : IF CC$ = CM1$ THEN 1230 : IF CC$ = CH1$ THEN 1230
1360 IF M = 4 THEN CD$ = CN$ : IF CD$ = CB2$ THEN 1230 : IF CD$ = CM2$ THEN 1230 : IF CD$ = CH2$ THEN 1230
1370 IF M = 5 THEN CE$ = CN$ : IF CE$ = CD$ THEN 1230 : IF CE$ = CB2$ THEN 1230 : IF CE$ = CM2$ THEN 1230 : IF CE$ = CH2$ THEN 1230
1380 IF M = 6 THEN CF$ = CN$ : IF CF$ = CD$ THEN 1230 : IF CF$ = CE$ THEN 1230 : IF CF$ = CB2$ THEN 1230 : IF CF$ = CM2$ THEN 1230 : IF CF$ = CH2$ THEN 1230
1390 NEXT M

***NOTES***
LINE 1330-1390 MAYBE WRITTEN MORE EASILY WITH...

1330 IF M = 1 THEN CA$ = CN$ : IF CA$ = CB1$ OR CA$ = CM1$ OR CA$ = CH1$ THEN 1230
1340 IF M = 2 THEN CB$ = CN$ : IF CB$ = CA$ OR CB$ = CB1$ OR CB$ = CM1$ OR CB$ = CH1$ THEN 1230
1350 IF M = 3 THEN CC$ = CN$ : IF CC$ = CA$ OR CC$ = CB$ OR CC$ = CB1$ OR CC$ = CM1$ OR CC$ = CH1$ THEN 1230
1360 IF M = 4 THEN CD$ = CN$ : IF CD$ = CB2$ OR CD$ = CM2$ OR CD$ = CH2$ THEN 1230
1370 IF M = 5 THEN CE$ = CN$ : IF CE$ = CD$ OR CE$ = CB2$ OR CE$ = CM2$ OR CE$ = CH2$ THEN 1230
1380 IF M = 6 THEN CF$ = CN$ : IF CF$ = CD$ OR CF$ = CE$ OR CF$ = CB2$ OR CF$ = CM2$ OR CF$ = CH2$ THEN 1230
1390 NEXT M

1400 ? "FIRST CHORD"
1410 ? "OCTAVE 4 "CA$ : GOSUB 2000 : ? "VELOCITY= "V
1420 ? "OCTAVE 5 "CB$ : GOSUB 2000 : ? "VELOCITY= "V
1430 ? "OCTAVE 6 "CC$ : GOSUB 2000 : ? "VELOCITY= "V
1450 ? "SECOND CHORD"
1460 ? "OCTAVE 4 "CD$ : GOSUB 2000 : ? "VELOCITY= "V
1470 ? "OCTAVE 5 "CE$ : GOSUB 2000 : ? "VELOCITY= "V
1480 ? "OCTAVE 6 "CF$ : GOSUB 2000 : ? "VELOCITY= "V
1490 ? " "
1500 INPUT "DO YOU WANT TO DO IT AGAIN?";YN$
1510 ML = ML + 1
1520 IF YN$ = "Y" THEN GOTO 140
1530 END

GOSUBS IN PROGRESS

2000 V = INT ( 5 * RND (1)) + 1 # humanizes the midi notes
2010 IF V = 1 THEN V = 25
2020 IF V = 2 THEN V = 50
2030 IF V = 3 THEN V = 75
2040 IF V = 4 THEN V = 100
2050 IF V = 5 THEN V = 125
2060 RETURN

# velocity values are not being generated in this version of ROGUE
# even though you will see the output attempt to do so

2100 V = INT ( 127 * RND (1)) + 1
2110 IF V < 20 THEN GOTO 2100
2120 RETURN

# most notable difference in today's generating code & this old code
# are the RND (random) equations and pure data's use of percentages.
# the percentages help to create a much more real humanized composition
# much better than the single yield "only choice" RND value generated.

You could spend an entire "pointless" evening dissecting this old code.

* KicKRaTT; MUSIC, ALGORITHMS, DOCUMENTS, GRAPHICS & LOGOS: ISNI# 0000000514284662 *



krapple
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting