Would you like to make this site your homepage? It's fast and easy...
Yes, Please make this my home page!

COMPAKB (B.A.S.I.C.) Program Code
100 REM =========================================================
110 REM 1MATOP
120 REM =========================================================
130 REM These subroutines deal with single 2-d matrix
140 REM operations. MATRIX PRINT sends matrix data to the
150 REM screen in ordered rows and columns, MATRIX SCALAR
160 REM MULTIPLICATION multiplies each matrix element by
170 REM a constant value, and MATRIX TRANSPOSITION exchanges
180 REM matrix rows and columns.
190 REM =========================================================
200 REM Variable Descriptions
210 REM D: full row counter
220 REM F: flag to print transposed matrix
230 REM M: scalar multiplication factor
240 REM X(n,n): matrix 1 to hold primary & multiplied data
250 REM Y(n,n): matrix 2 to hold transposed data
260 REM J1: loop index, pointer to matrix rows
270 REM J2: loop index, pointer to matrix columns
280 REM K9: subroutine loop index
290 REM L9: subroutine loop index
300 REM =========================================================
310 REM ================== DRIVER PROGRAM =======================
320 REM =========================================================
330 DIM X(8,8),Y(8,8)
340 D = 0
350 F = 0
360 M = 8
370 PRINT "A 2-DIMENTIONAL MATRIX OF SEQUENTIAL NUMBERS --"
380 FOR J1 = 1 TO 8
390 FOR J2 = 1 TO 8
400 X(J1,J2) = J2 + D
410 NEXT J2
420 D = D + 8
430 NEXT J1
440 GOSUB 1000 '<< call matrix print
450 PRINT
460 GOSUB 2010 '<< call matrix scalar multiplication
470 PRINT
480 PRINT "MATRIX MULTIPLIED BY 8 --"
490 GOSUB 1000 '<< call matrix print
500 PRINT
510 GOSUB 3010 '<< call matrix transposition
520 PRINT
530 PRINT "TRANSPOSED MATRIX (ROWS & COLUMNS EXCHANGED) --"
540 GOSUB 1000 '<< call matrix print
550 PRINT
560 GOSUB 4000 '<< call matrix reset
570 PRINT "MATRICES RESET TO ZERO --"
580 GOSUB 1000
590 END
1000 REM ========================================================
1010 REM ******************>> MATRIX PRINT <<********************
1020 REM ========================================================
1030 FOR K9 = 1 TO 8
1040 FOR L9 = 1 TO 8
1050 IF F = 0 THEN PRINT TAB(8*(L9-1))X(K9,L9); ELSE PRINT TAB(8*(L9-1))Y(K9,L9);
1060 NEXT L9
1070 PRINT
1080 NEXT K9
1090 RETURN
2000 REM ========================================================
2010 REM **********>> MATRIX SCALAR MULTIPLICATION <<***********
2020 REM ========================================================
2030 FOR K9 = 1 TO 8
2040 FOR L9 = 1 TO 8
2050 X(K9,L9) = X(K9,L9) * M
2060 NEXT L9
2070 NEXT K9
2080 RETURN
3000 REM ========================================================
3010 REM *************>> MATRIX TRANSPOSITION <<****************
3020 REM ========================================================
3030 FOR K9 = 1 TO 8
3040 FOR L9 = 1 TO 8
3050 Y(K9,L9) = X(L9,K9)
3060 NEXT L9
3070 NEXT K9
3080 F = 1
3090 RETURN
4000 REM ========================================================
4010 REM ********************>> ZEROMAT <<***********************
4020 REM ========================================================
4030 REM This subroutine resets all matrix addresses to 0
4040 REM for further processing, or for initialization if
4050 REM required by your particular system.
4060 REM ========================================================
4070 FOR K9 = 1 TO 8
4080 FOR L9 = 1 TO 8
4090 X(K9,L9) = 0
4100 Y(K9,L9) = 0
4110 NEXT L9
4120 NEXT K9
4130 RETURN
100 REM =========================================================
110 REM 2MATOP
120 REM =========================================================
130 REM These subroutines deal with operations on
140 REM two discrete matrices. MATRIX PRINT sends
150 REM each matrix to the screen, ADD MATRICES
160 REM adds corresponding address contents, and
170 REM MULTIPLY MATRICES multiplies address contents.
180 REM =========================================================
190 REM Variable Descriptions
200 REM
210 REM D: full row counter
220 REM X(n,n): matrix 1
230 REM Y(n,n): matrix 2
240 REM Z(n,n): matrix holding operation result
250 REM J1: driver loop index, pointer to matrix rows
260 REM J2: driver loop index, pointer to matrix columns
270 REM K9: subroutine loop index
280 REM L9: subroutine loop index
290 REM
300 REM =========================================================
310 REM ==================== DRIVER PROGRAM =====================
320 REM =========================================================
330 DIM X(10,10),Y(10,10),Z(10,10)
340 D = 0
350 FOR J1 = 1 TO 10
360 FOR J2 = 1 TO 10
370 X(J1,J2) = J2+D '<< fill with numbers 1-100
380 Y(J1,J2) = J2+D+100 '<< fill with nums 101-200
390 NEXT J2
400 D = D + 10
410 NEXT J1
420 GOSUB 1000 '<< print original matrices
430 PRINT
440 GOSUB 2000 '<< add matrix x to matrix y and print
450 PRINT
460 GOSUB 3000 '<< multiply matrix x by matrix y and print
470 END
1000 REM ========================================================
1010 REM ******************>> MATRIX PRINT <<********************
1020 REM ========================================================
1030 PRINT "MATRIX X --"
1040 FOR K9 = 1 TO 10
1050 FOR L9 = 1 TO 10
1060 PRINT TAB(8*(L9-1))X(K9,L9);
1070 NEXT L9
1080 PRINT
1090 NEXT K9
1100 PRINT
1110 PRINT "MATRIX Y --"
1120 FOR K9 = 1 TO 10
1130 FOR L9 = 1 TO 10
1140 PRINT TAB(8*(L9-1))Y(K9,L9);
1150 NEXT L9
1160 PRINT
1170 NEXT K9
1180 RETURN
2000 REM ========================================================
2010 REM ****************>> ADD MATRICES <<**********************
2020 REM ========================================================
2030 PRINT "THE SUM OF MATRICES X & Y --"
2040 FOR K9 = 1 TO 10
2050 FOR L9 = 1 TO 10
2060 Z(K9,L9) = X(K9,L9) + Y(K9,L9)
2070 PRINT TAB(8*(L9-1))Z(K9,L9);
2080 NEXT L9
2090 PRINT
2100 NEXT K9
2110 RETURN
3000 REM ========================================================
3010 REM ****************>> MULTIPLY MATRICES <<*****************
3020 REM ========================================================
3030 PRINT "THE PRODUCT OF MATRICES X AND Y --"
3040 FOR K9 = 1 TO 10
3050 FOR L9 = 1 TO 10
3060 Z(K9,L9) = X(K9,L9) * Y(K9,L9)
3070 PRINT TAB(8*(L9-1))Z(K9,L9);
3080 NEXT L9
3090 NEXT K9
3100 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
111 REM (Addshufl)
120 REM =========================================================
130 DIM TABLE(20),X(20)
140 TOTAL = 20
150 FOR J = 1 TO TOTAL
160 TABLE(J) = J '<< fill array with number sequence
170 X(J) = J '<< load pointer array
180 NEXT J
190 GOSUB 1000
200 FOR J = 1 TO TOTAL
210 PRINT TABLE(X(J));'<<send randomized table to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM *********************>> ADDSHUFL <<*********************
1020 REM ========================================================
1030 REM This subroutine randomizes (shuffles) a list of
1040 REM pointers to a reference array. The original list
1050 REM of values remains unchanged for future access.
1060 REM Thus, many random reorderings may be accomplished
1070 REM without destroying the original list's prime order.
1080 REM =======================================================
1090 REM Variable Descriptions
1100 REM
1110 REM Entering -
1120 REM TOTAL: number of values in the list
1130 REM X(): array of ordered address pointers
1140 REM Exiting -
1150 REM X(): randomized array of pointers to list
1160 REM Local -
1170 REM R9: random number
1180 REM S9: temporary storage variable
1190 REM K9: loop index, pointer to array X()
1200 REM
1210 REM ========================================================
1220 RANDOMIZE
1230 FOR K9 = 1 TO TOTAL
1240 R9 = INT(RND * TOTAL) + 1
1250 S9 = X(K9)
1260 X(K9) = X(R9)
1270 X(R9) = S9
1280 NEXT K9
1290 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (ALINTSEQ)
130 REM =========================================================
140 DIM INTSET(11),PCLASS(12)
150 TOTAL = 5
160 RANDOMIZE(212)
170 FOR J = 1 TO 11
180 INTSET(J) = (J)
190 NEXT J
200 FOR J = 1 TO TOTAL
210 GOSUB 2000 '<< call interval array shuffler
220 PRINT "RANDOM-ORDER INTERVALCLASS SERIES # ";J ":"
230 FOR J1 = 1 TO 11
240 PRINT INTSET(J1);
250 NEXT J1
260 PRINT
270 GOSUB 1000 '<< call interval to pitchclass mapping
280 PRINT "--- MAPPED TO PITCHCLASS NUMBERS ---"
290 FOR J1 = 0 TO 11
300 PRINT PCLASS(J1);
310 NEXT J1
320 PRINT
330 NEXT J
340 END
1000 REM ========================================================
1010 REM ********************>> ALINTSEQ <<**********************
1020 REM ========================================================
1030 REM This subroutine maps a set of 11 unique intervals
1040 REM (in semitones, size 1-11) to the pitchclasses of
1050 REM the chromatic scale. Although the interval set is
1060 REM non-redundant, there is a high probability that
1070 REM the resultant pitchclass sequence will contain at
1080 REM least one repeated tone, thus producing a 12-note
1090 REM sequence rather than a 12-note series.
1100 REM ========================================================
1110 REM Variable Descriptions
1120 REM Entering -
1130 REM INTSET(): array of unique interval-sizes 1-11
1140 REM Exiting -
1150 REM PCLASS(): pitchclass sequence array
1160 REM Local -
1170 REM K9: loop index, pointer to intset(),PCLASS()
1180 REM ========================================================
1190 PCLASS(0)=0
1200 FOR K9 = 1 TO 11
1210 PCLASS(K9) = (PCLASS(K9-1) + INTSET(K9)) MOD 12
1220 NEXT K9
1230 RETURN
2000 REM ========================================================
2010 REM ********************>> CONSHUFL) <<*********************
2020 REM (adapted to program specs)
2030 REM ========================================================
2040 FOR K9 = 1 TO 11
2050 R9 = INT(RND * 11) + 1
2060 S9 = INTSET(K9)
2070 INTSET(K9) = INTSET(R9)
2080 INTSET(R9) = S9
2090 NEXT K9
2100 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (ALINTSET)
130 REM =========================================================
140 DIM PCLASS(12),PCUM(12),ICUM(12),TEMP(12),ALSET$(10)
150 TOTAL = 10
160 SETCOUNT = 0
170 RANDOMIZE(-1923)
180 FOR J = 1 TO TOTAL
190 PRINT "COMPUTING -- ALL-INTERVAL 12-TONE SET #";J
200 GOSUB 1000
210 IF FLAG = 1 THEN PRINT ALSET$(SETCOUNT)ELSE GOSUB 1000
220 NEXT J
230 END
1000 REM =======================================================
1010 REM ********************>> ALINTSET <<*********************
1020 REM =======================================================
1030 REM This subroutine generates all-interval 12-note
1040 REM series by the sample-test-discard/keep method.
1050 REM Although this "brute force" approach is rather
1060 REM slow, it can produce satisfactory results over
1070 REM short runs. Runs approaching 100 output sets
1080 REM can best be achieved by executing a compiled
1090 REM version of the program.
1100 REM =======================================================
1110 REM Variable Descriptions
1120 REM Entering -
1130 REM none
1140 REM Exiting -
1150 REM PCLASS(): array holding all-interval series
1160 REM Local -
1170 REM PCUM(): array of note redundancy flags
1180 REM ICUM(): array of interval redundancy flags
1190 REM TEMP(): array holding temporary trial series
1200 REM INTSIZE: interval (in 1/2-steps) between notes
1210 REM R9: random integer for test series
1220 REM K9: loop index, pointer to TEMP()
1230 REM L9: loop index, pointer to TEMP(), PCLASS()
1240 REM M9: loop index, pointer to TEMP(), PCLASS()
1250 REM =======================================================
1260 PCLASS(1) = 1 : PCLASS(12) = 7
1270 FOR K9 = 2 TO 11
1280 R9 = INT(RND * 11) + 2
1290 IF R9 = 7 THEN 1280
1300 IF PCUM(R9) = 1 THEN 1280
1310 TEMP(K9) = R9
1320 PCUM(R9) = 1
1330 NEXT K9
1340 FOR L9 = 2 TO 12
1350 FOR M9 = 2 TO 11
1360 IF TEMP(M9) > 0
THEN INTSIZE = TEMP(M9) - PCLASS(L9-1)
ELSE 1390
1370 IF INTSIZE < 0 THEN INTSIZE = 12 + INTSIZE
1380 IF ICUM(INTSIZE) < 1
THEN PCLASS(L9) = TEMP(M9) : TEMP(M9) = 0 : ICUM(INTSIZE) = 1 : GOTO 1410
ELSE 1390
1390 NEXT M9
1400 IF PCLASS(L9) = 0
THEN GOSUB 2000 : GOTO 1200
1410 NEXT L9
1420 GOSUB 3000 : GOSUB 2000
1430 RETURN 210
2000 REM ========================================================
2010 REM *********************>> ZEROMAT <<**********************
2020 REM ========================================================
2030 FOR L9 = 1 TO 12
2040 PCUM(L9) = 0 : ICUM(L9) = 0 : PCLASS(L9) = 0
2050 NEXT L9
2060 RETURN
3000 REM ========================================================
3010 REM ********************>> SETSTORE <<**********************
3020 REM ========================================================
3030 REM This subroutine stores and maintains an identity
3040 REM check on the all-interval series generated by the
3050 REM subroutine ALINTSET. Each output set is converted
3060 REM to a character string, tested against all prev-
3070 REM iously stored sets for uniqueness, then put in
3080 REM an character string array.
3090 REM ========================================================
3100 REM Variable Descriptions
3110 REM Entering -
3120 REM PCLASS(): holds current pitchclass (integer) set
3130 REM Exiting -
3140 REM ALSET$(): string array holding all unique sets
3150 REM SETCOUNT: index of unique all-interval sets
3160 REM FLAG: indicator of set uniqueness
3170 REM Local -
3180 REM L9: loop index, pointer to PCLASS()
3190 REM CURSET$: string buffer holding current set
3200 REM ========================================================
3210 CURSET$ = ""
3220 FOR L9=1 TO 12
3230 CURSET$ = CURSET$ + STR$(PCLASS(L9)-1)
3240 NEXT L9
3250 SETCOUNT = SETCOUNT + 1
3260 FOR L9 = 1 TO SETCOUNT - 1
3270 IF ALSET$(L9) = CURSET$ THEN FLAG = 0 : RETURN
3280 NEXT L9
3290 ALSET$(SETCOUNT)=CURSET$
3300 FLAG = 1
3310 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Alterseq)
130 REM =========================================================
140 DIM X(12),Y(12)
150 RANDOMIZE
160 TOTAL = 12
170 LOW = 22
180 HIGH = 66
190 RANGE = HIGH - LOW + 1
200 INTSIZE = 5
210 PRINT "A RANDOM-ORDER SEQUENCE --"
220 FOR J = 1 TO TOTAL
230 X(J) = INT(RND * RANGE)+ LOW
240 PRINT X(J); '<< send prime sequence to screen
250 NEXT J
260 PRINT : PRINT
270 FOR J = 1 TO 2
280 PRINT "PASS";J
290 PRINT "ALTERATION INTEGER =";INTSIZE"
300 PRINT "ALTERED SEQUENCE --"
310 GOSUB 1000
320 FOR J1 = 1 TO TOTAL
330 PRINT Y(J1); '<< send altered sequence to screen
340 NEXT J1
350 INTSIZE = - 5
360 PRINT
370 NEXT J
380 END
1000 REM ========================================================
1010 REM *********************>> ALTERSEQ <<*********************
1020 REM ========================================================
1030 REM This subroutine alters a value sequence by interval
1040 REM expansion or contraction. Positive integers expand
1050 REM the sequence, negative integers contract it.
1060 REM ========================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM X(): primary value sequence
1100 REM TOTAL: length of sequence
1110 REM INTSIZE: size of alteration interval in units
1120 REM Exiting -
1130 REM X(): primary value sequence
1140 REM Y(): altered value sequence
1150 REM Local -
1160 REM INTDIR: direction of alteration
1170 REM INTVAL: altered interval
1180 REM K9: loop index, pointer to X(),Y()
1190 REM ========================================================
1200 Y(1) = X(1)
1210 FOR K9 = 2 TO TOTAL
1220 IF X(K9) <> X(K9-1)THEN 1230 ELSE Y(K9) = Y(K9-1) : GOTO 1270
1230 INTDIR = SGN(X(K9)-X(K9-1))
1240 INTVAL=ABS(X(K9)-X(K9-1))+INTSIZE
1250 IF INTVAL <1 THEN INTVAL = 1
1260 Y(K9)=Y(K9-1)+INTDIR * INTVAL
1270 NEXT K9
1280 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Beta)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 PROB0 = .4
180 PROB1 = .2
190 GOSUB 1000 '<< call Eulerian Beta distribution
200 FOR J = 1 TO TOTAL
210 PRINT X(J); '<< sequence to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM **********************>> BETA <<************************
1020 REM ========================================================
1030 REM The Eulerian Beta Distribution Function
1040 REM generates continuous, random-order values
1050 REM > 0 & < 1. The shape of its curve changes
1060 REM with the values of its controlling parameters
1070 REM PROB0 and PROB1.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM
1110 REM Entering -
1120 REM TOTAL: length of sequence
1130 REM PROB0: controls occurrence of values nearer to 0
1140 REM PROB1: controls occurrence of values nearer to 1
1150 REM Exiting -
1160 REM X(): array holding BETA distribution
1170 REM Local -
1180 REM R8: random number 1
1190 REM R9: random number 2
1200 REM T1: computed probability 1
1210 REM T2: computed probability 2
1220 REM SUM: total of probabilities 1 & 2
1230 REM K9: loop index, pointer to array X()
1240 REM ========================================================
1250 PROB0 = 1 / PROB0
1260 PROB1 = 1 / PROB1
1270 FOR K9 = 1 TO TOTAL
1280 R8 = RND
1290 R9 = RND
1300 T1 = R8 ^ PROB0
1310 T2 = R9 ^ PROB1
1320 SUM = T1 + T2
1330 IF SUM > 1 THEN 1280 ELSE X(K9) = T1 / SUM
1340 NEXT K9
1350 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Bilexp)
130 REM =========================================================
140 DIM X(100)
150 RANDOMIZE
160 TOTAL = 100
170 SPREAD = 1.5
180 GOSUB 1010 '<< bilateral exponential distribution
190 FOR J = 1 TO TOTAL
200 PRINT X(J); '<< sequence to screen
210 NEXT J
220 END
1000 REM ========================================================
1010 REM *********************>> BILEXP <<***********************
1020 REM (D)=====================================================
1030 REM The Bilateral Exponential Distribution Function
1040 REM generates random-order negative and positive
1050 REM real numbers centered about zero. Horizontal
1060 REM scale is controlled by the variable, SPREAD,
1070 REM which increase the range of generated values in
1080 REM inverse proportion to its magnitude (must be > 0).
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM TOTAL: sequence length
1130 REM SPREAD: horizontal scaling value
1140 REM Exiting -
1150 REM X(): array holding BILEXP real numbers sequence
1160 REM Local -
1170 REM R9: random number > 0 & < 2
1180 REM K9: loop index, pointer to array X()
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 R9 = 2 * RND
1220 IF R9 > 1 THEN R9 = 2 - R9
1230 X(K9) = LOG(R9)/SPREAD
1240 NEXT K9
1250 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Cauchy)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
165 SPREAD = 2
170 GOSUB 1000 '<< call Cauchy distribution function
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM *********************>> CAUCHY <<***********************
1020 REM ========================================================
1030 REM The Cauchy Probability Distribution Function
1040 REM generates random-order, continuous, real numbers
1050 REM centered about zero. The variable SPREAD controls
1060 REM the range of generated values.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM TOTAL: length of sequence
1110 REM SPREAD: scaling parameter
1120 REM Exiting -
1130 REM X(): array holding cauchy distribution
1140 REM Local -
1150 REM R9: uniform random number
1160 REM K9: loop index, pointer to array X()
1170 REM ========================================================
1171 PI = 3.1415927#
1180 FOR K9 = 1 TO TOTAL
1200 R9# = RND
1210 IF R9# = .5 THEN 1200
1220 R9# = R9# * PI
1230 X(K9) = SPREAD * TAN(R9#)
1240 NEXT K9
1250 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Combntot)
130 REM =========================================================
140 ELEMENTS = 10
150 MANY = 2
160 FOR J = 1 TO 10
170 GOSUB 1000 '<< call combinations
180 PRINT "COMBINATIONS OF";ELEMENTS;"THINGS TAKEN";MANY;"AT A TIME IS";COMBINS
190 ELEMENTS= ELEMENTS+ 3
200 MANY = MANY + 3
210 NEXT J
220 END
1000 REM SS2ST5 =================================================
1010 REM ********************>> COMBINS <<***********************
1020 REM ========================================================
1030 REM This subroutine computes the number of possible
1040 REM combinations of n elements taken n at a time.
1050 REM It relies on Stirling's approximation to calculate
1060 REM the requisite factorials.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM ELEMENTS: nunber of items
1110 REM MANY: taken at a time
1120 REM Exiting -
1130 REM COMBINS : combination of ELEMENTS, taken MANY at
1140 REM a time
1150 REM Local -
1160 REM NUM:
1170 REM ELEMFACT: log of ELEMENTS factorial
1180 REM MANYFACT: log of MANY factorial
1190 REM DIFFACT : log of (ELEMFACT - MANYFACT) factorial
1200 REM ========================================================
1210 NUM = ELEMENTS
1220 GOSUB 2000 '<< call Stirling's approximation
1230 ELEMFACT = APPR
1240 NUM = MANY
1250 GOSUB 2000 '<< call Stirling's approximation
1260 MANYFACT = APPR
1270 NUM = ELEMENTS - MANY
1280 GOSUB 2000 '<< call Stirling's approximation
1290 DIFFACT = APPR
1300 COMBINS = INT(EXP(ELEMFACT-(MANYFACT+DIFFACT))+.5)
1310 RETURN
2000 REM ========================================================
2010 REM ********************>> STIRLING <<**********************
2020 REM ========================================================
2030 APPR = 1
2040 IF NUM <= 0 THEN APPR = 0 : RETURN
2050 FOR K9 = 1 TO 10
2060 APPR = APPR * K9
2070 IF NUM = K9 THEN APPR = LOG(APPR) : RETURN
2080 NEXT K9
2090 APPR = LOG(6.283186)/2+LOG(NUM)*(NUM+.5)-NUM+1/(12*NUM)
2100 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Conshufl)
130 REM =========================================================
140 DIM X(20)
150 TOTAL = 20
160 FOR J = 1 TO TOTAL
170 X(J) = J '<< fill array with number sequence
180 NEXT J
190 GOSUB 1000
200 FOR J = 1 TO TOTAL
210 PRINT X(J); '<< send shuffled array to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM ********************>> CONSHUFL <<**********************
1020 REM ========================================================
1030 REM This subroutine shuffles array contents by first
1040 REM generating a random sequence of address pointers,
1050 REM then swapping corresponding address contents.
1060 REM However, in the shuffling process, original
1070 REM prime order is destroyed. (See subroutine
1080 REM ADDSHUF for non-disruptive randomization.)
1090 REM =======================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM X(): array of sequential values
1130 REM TOTAL: length of list (array)
1140 REM Exiting -
1150 REM X(): randomized array of values
1160 REM Local -
1170 REM R9: random number
1180 REM S9: temporary storage variable
1190 REM K9: loop index, pointer to array X()
1200 REM ========================================================
1210 RANDOMIZE
1220 FOR K9 = 1 TO TOTAL
1230 R9 = INT(RND * TOTAL) + 1
1240 REM+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1250 REM a more thorough shuffling can be achieved with
1260 REM the next statement substitiuted for line 1250
1270 REM R9 = INT(RND * (TOTAL - (K9 - 1)))+K9
1280 REM Why is this true?
1290 REM+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1300 S9 = X(K9)
1310 X(K9) = X(R9)
1320 X(R9) = S9
1330 NEXT K9
1340 RETURN
100 REM =========================================================
110 REM CURVES
120 REM =========================================================
130 REM The subroutines LINCURVE, EXPCURVE, and LOGCURVE
140 REM return positive values along three discrete curves:
150 REM linear, exponential, and logarithmic. Control
160 REM parameters are starting and ending values, and
170 REM number of values to be included in the curve.
180 REM =========================================================
190 REM Variable Descriptions
200 REM DRIVER
210 REM S: starting curve value
220 REM E: ending curve value
230 REM N: number of values contained in curve
240 REM J1: loop index, pointer to subroutines
250 REM J2: loop index, pointer to array X()
260 REM X(): array holding curve values
270 REM
280 REM SUBROUTINES 1000,2000,3000
290 REM Entering -
300 REM S: starting curve value
310 REM E: ending curve value
320 REM N: number of values contained in curve
330 REM Exiting -
340 REM X(): array holding curve values
350 REM Local -
360 REM K9: loop index
370 REM L9: loop index, pointer to array X()
380 REM =========================================================
390 REM ==================== DRIVER PROGRAM =====================
400 REM =========================================================
410 DIM X(100)
420 S = 1
430 E = 100
440 N = 100
450 FOR J1 = 1 TO 3
460 REM >> sequentially call LINCURVE, EXPCURVE, LOGCURVE subrs.
470 ON J1 GOSUB 1000,2000,3000
480 FOR J2 = 1 TO N
490 PRINT X(J2); '<< send curve values to screen
500 NEXT J2
510 PRINT
520 NEXT J1
530 END
1000 REM ========================================================
1010 REM ********************>> LINCURVE <<**********************
1020 REM ========================================================
1030 PRINT "LINEAR CURVE:"
1040 FOR K9 = 1 TO N STEP 10
1050 FOR L9 = K9 TO K9 + 9
1060 REM >> store current computed curve value
1070 X(L9) = ABS(S + INT(((L9-1)/(N-1)) * (E-S)+.5))
1080 IF L9 = N THEN 1100
1090 NEXT L9
1100 NEXT K9
1110 RETURN
2000 REM ========================================================
2010 REM ********************>> EXPCURVE <<**********************
2020 REM ========================================================
2030 PRINT "EXPONENTIAL CURVE:"
2040 FOR K9 = 1 TO N STEP 10
2050 FOR L9 = K9 TO K9 + 9
2060 REM >> store current computed curve value
2070 X(L9) = ABS(S+INT((((L9-1)^2)/((N-1)^2))*(E-S)+.5))
2080 IF L9 = N THEN 2100
2090 NEXT L9
2100 NEXT K9
2110 RETURN
3000 REM ========================================================
3010 REM ********************>> LOGCURVE <<**********************
3020 REM ========================================================
3030 PRINT "LOGARITHMIC CURVE:"
3040 FOR K9 = 1 TO N STEP 10
3050 FOR L9 = K9 TO K9 + 9
3060 REM >> store current computed curve value
3070 X(L9)=ABS(S + INT(((LOG(L9))/(LOG(N)))*(E-S)+.5))
3080 IF L9 = N THEN 3100
3090 NEXT L9
3100 NEXT K9
3110 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM CYCLTEXT
130 REM =========================================================
140 PRINT "ORIGINAL LINE OF TEXT:"
150 LIN$ = "apples sound beautiful"
160 PRINT LIN$
170 PRINT
180 PNUM = 13 '<< a prime number smaller than length of LIN$
190 NUM2 = 8 '<< an integer between 1 and length of LIN$
200 GOSUB 1000 '<< call cyclical text shifter
210 PRINT "PRIME-SHIFTED TEXT:"
220 PRINT NEWLIN$
230 END
1000 REM ==================================================CTB5.9
1010 REM *********************>> CYCLTEXT <<*********************
1020 REM ========================================================
1030 REM Cyclical (prime number) Text Shift Subroutine
1040 REM ========================================================
1050 REM Variable Desciptions
1060 REM Entering -
1070 REM LIN$: line of text to be shifted
1080 REM PNUM: prime number smaller than length of LIN$
1090 REM NUM2: an integer between 1 and length of LIN$
1100 REM Exiting:
1110 REM NEWLINE$: shifted line of text
1120 REM Local -
1130 REM SHIFTCHAR: LINE$ substring pointer
1140 REM NUMCHARS: length of LIN$
1150 REM POSNUM: loop index, NEWLINE$ substring pointer
1160 REM ========================================================
1170 SHIFTCHAR = NUM2 - PNUM
1180 NUMCHARS = LEN(LIN$)
1190 IF NUMCHARS-INT(NUMCHARS/PNUM)*PNUM = 0
THEN NUMCHARS=NUMCHARS+1
1200 NEWLIN$ = STRING$(NUMCHARS," ")
1210 FOR POSNUM = 1 TO NUMCHARS
1220 SHIFTCHAR = SHIFTCHAR + PNUM
1230 IF SHIFTCHAR > NUMCHARS
THEN SHIFTCHAR = SHIFTCHAR - NUMCHARS
1240 MID$(NEWLIN$,POSNUM,1) = MID$(LIN$,SHIFTCHAR,1)
1250 NEXT POSNUM
1260 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (DecBiDec)
130 REM =========================================================
140 DIM X(10),X$(10)
150 PRINT "AN ARRAY OF DECIMAL NUMBERS --"
160 FOR J = 1 TO 10
170 DECNUM = J * 10
180 X(J) = DECNUM
190 PRINT X(J);" "; '<< send to screen
200 NEXT J
210 PRINT
220 PRINT "THE ARRAY CONVERTED TO BINARY NUMBERS --"
230 GOSUB 1000 '<< call decimal-to-binary conversion
240 FOR J = 1 TO 10
250 PRINT X$(J);" "; '<< send to screen
260 NEXT J
270 PRINT
280 GOSUB 1250 '<< call binary-to-decimal conversion
290 PRINT "THE BINARY NUMBERS CONVERTED BACK TO DECIMAL --"
300 FOR J = 1 TO 10
310 PRINT X(J);" "; '<< send to screen
320 NEXT J
330 END
1000 REM SS1MA1 =================================================
1010 REM ********************>> DEC-BIN <<***********************
1020 REM ========================================================
1030 REM This subroutine converts positive decimal integers
1040 REM to their binary equivalents, which are placed in
1050 REM a character array as successions of "0" and "1"
1060 REM characters.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1091 REM X(): array holding decimal integers
1092 REM Exiting -
1093 REM X$(): array holding string representation of
1094 REM binary numbers corresponding to decimal
1095 REM integers.
1096 REM Local -
1097 REM P9: temporary version of decimal integer,
1098 REM successively divided by 2.
1099 REM Q9: quotient of P9/2
1100 REM R9: remainder of X9/2
1101 REM K9: loop index, pointer to array X$()
1110 REM ========================================================
1120 FOR K9 = 1 TO 10
1130 P9=X(K9)
1140 BINUM$ = ""
1150 Q9 = P9
1160 WHILE Q9 > 0
1170 Q9=INT(P9/2)
1180 R9 = P9 - 2 * Q9
1190 BINUM$=MID$("01",R9+1,1)+BINUM$
1200 P9=Q9
1210 WEND
1220 X$(K9) = BINUM$
1230 NEXT K9
1240 RETURN
1250 REM SS2MA1 =================================================
1260 REM ********************>> BIN-DEC <<***********************
1270 REM ========================================================
1280 REM This subroutine converts binary numbers (stored as
1290 REM character strings) to their decimal equivalents.
1300 REM The INSTR function is used to ascertain the value
1310 REM and location of each binary bit within the number
1320 REM string. Line ----- examines the first bit: if it
1330 REM is "0" then DECNUM is set to 0; if it is "1",
1340 REM DECNUM is 1. The remaining bits are scanned, and
1350 REM as long as there is another bit, DECNUM is doubled
1360 REM and a 1 or 0 is added to it.
1370 REM ========================================================
1380 REM Variable Descriptions
1390 REM Entering -
1400 REM X$(): array of binary numbers stored as character
1410 REM strings of 1s and 0s
1420 REM Exiting -
1430 REM X(): array of converted decimal integers
1440 REM Local -
1450 REM DECNUM: decimal integer
1460 REM K9: loop index, pointer to array X()
1470 REM L9: loop index
1480 REM ========================================================
1490 FOR K9 = 1 TO 10
1500 DECNUM = 0
1510 FOR L9 = 1 TO LEN(X$(K9))
1520 DECNUM = INSTR("01",MID$(X$(K9),L9,1)) - 1 + DECNUM + DECNUM
1530 NEXT L9
1540 X(K9) = DECNUM
1550 NEXT K9
1560 RETURN100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Decfrac)
130 REM =========================================================
140 DIM X(50),FRACTION$(50)
150 RANDOMIZE(22321)
160 TOTAL = 50
170 FOR J = 1 TO TOTAL
180 X(J)= (INT(RND * 99)+1)/100'<<< load decimal values
190 PRINT X(J), '<<< send to screen
200 NEXT J
210 PRINT
220 GOSUB 1000 '<<< call decimal to fraction conversion
230 FOR J = 1 TO TOTAL
240 PRINT FRACTION$(J), '<<< send to screen
250 NEXT J
260 END
1000 REM ========================================================
1010 REM ********************>> DECFRAC <<***********************
1020 REM ========================================================
1030 REM This subroutine converts decimal values (%) to
1040 REM fractions for use as rhythmic durations.
1050 REM ========================================================
1060 REM
1070 REM Variable Descriptions
1080 REM
1090 REM Entering -
1100 REM X(): array of decimal values to be converted
1110 REM
1120 REM Exiting -
1130 REM FRACTION$(): character string array of fractions
1140 REM
1150 REM Local -
1160 REM B9: temporary storage of computation result
1170 REM C9: holds integer computation result
1180 REM D9: holds non-integer portion of decimal value
1190 REM E9: temporary storage of real number result
1200 REM F9: temporary storage of integer computation
1210 REM K9: loop index, pointer to array X()
1220 REM ========================================================
1230 FOR K9 = 1 TO TOTAL
1240 B9= 0
1250 C9 = 1
1260 D9= ABS(X(K9)-INT(X(K9)))
1270 IF D9 = 0 THEN 1340
1280 E9 = 1 / D9
1290 F9 = C9
1300 C9 = INT(E9) * C9 + B9
1310 B9 = F9
1320 D9 = E9 - INT(E9)
1330 IF X(K9) * C9 <> INT(X(K9) * C9) THEN 1280
1340 FRACTION$(K9)=STR$(X(K9) * C9)+"/"+STR$(C9)
1350 NEXT K9
1360 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (DELREPL)
130 REM =========================================================
140 DIM X(50)
150 TOTAL = 50
160 RANDOMIZE
170 PRINT "ARRAY OF RANDOM-ORDER REAL NUMBERS (RANGE 0-1) --"
180 FOR J = 1 TO TOTAL
190 X(J) = RND
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "ARRAY SORTED IN ASCENDING ORDER --"
240 GOSUB 1000 '<< call delayed replacement sort
250 FOR J = 1 TO TOTAL
260 PRINT X(J); '<< list to screen
270 NEXT J
280 END
1000 REM SS2TM1 =================================================
1010 REM *********************>> DELREPL <<**********************
1020 REM ========================================================
1030 REM This Delayed Replacement Sort subroutine is an
1040 REM improved version of the standard replacement sort.
1050 REM In this case, the switch between two items is
1060 REM delayed until that item is confirmed to be the
1070 REM smallest. The savings in time is one-half.
1080 REM However, for long lists either replacement sort
1090 REM is less appropriate than other sorts, because as
1100 REM the number of items to be sorted grows linearly,
1110 REM sorting time increases exponentially.
1120 REM ========================================================
1130 REM Variable Descriptions
1140 REM Entering -
1150 REM X(): array of values to be sorted
1160 REM TOTAL: length of array X()
1170 REM Exiting -
1180 REM X(): array sorted in ascending order
1190 REM Local -
1200 REM K9: loop index, pointer to X()
1210 REM L9: loop index, pointer to X()
1220 REM COMPVAL: indicator for switch of values
1230 REM =======================================================
1240 FOR K9=1 TO TOTAL - 1
1250 COMPVAL= K9
1260 FOR L9=K9+1 TO TOTAL
1270 IF X(L9) < X(COMPVAL) THEN COMPVAL=L9
1280 NEXT L9
1290 IF K9 <> COMPVAL THEN SWAP X(K9),X(COMPVAL)
1300 NEXT K9
1310 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Displace)
130 REM =========================================================
140 DIM P$(84)
150 DIM X(20),Y(20)
160 DIM DISP(20)
170 RANDOMIZE
180 GOSUB 530 '<< call pitch table
190 TOTAL = 10
200 FOR J= 1 TO TOTAL
210 X(J) = INT(RND * 12) + 1 '<< load random pitches
220 DISP(J) = INT(RND * 6)+1'<< load random octave displ.
230 PRINT P$(X(J));" WILL BE DISPLACED BY ";DISP(J);"OCTAVE(S)"
240 NEXT J
250 GOSUB 300 '<< call registral displacement
260 FOR J = 1 TO TOTAL
270 PRINT P$(Y(J));" ";
280 NEXT J
290 END
300 REM =========================================================
310 REM *******************>> DISPLACE <<************************
320 REM =========================================================
330 REM This subroutine (individually) displaces the pitches
340 REM of an input sequence by a specific number of octaves.
350 REM =========================================================
360 REM Variable Descriptions
370 REM Entering -
380 REM X(): array holding undisplaced pitch sequence
390 REM DISP(): array holding individual pitch displacements
400 REM TOTAL: sequence length
430 REM Exiting -
440 REM Y(): array containing octave-displaced pitches
450 REM Local -
460 REM K9: loop index, pointer to DISP(),X(),Y()
470 REM ========================================================
480 REM
490 FOR K9 = 1 TO TOTAL
500 Y(K9)=X(K9) + 12 * DISP(K9)
510 NEXT K9
520 RETURN
530 REM ========================================================
540 REM ********************>> PITCHTAB <<***********************
550 REM =========================================================
560 NOTE$ = " CC# DD# E FF# GG# AA# B"
570 OCTAVE$ = "1234567"
600 FOR K9 = 1 TO 7
610 FOR L9 = 1 TO 12
620 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
630 NEXT L9
640 NEXT K9
650 RETURN
100 REM =========================================================
110 REM =================== DRIVER PROGRAM ======================
120 REM =========================================================
130 DIM X(50),Y(50),FRACTION$(50)
140 TOTAL = 50
150 CLS
160 RANDOMIZE
170 REM >> randomly choose fractions between 1/50 & 50/1
180 FOR J= 1 TO TOTAL
190 X(J) = INT(RND * TOTAL)+1 '<< load numerators
200 Y(J) = 32 '<< load denominators
210 PRINT X(J);"/";Y(J), '<< send to screen
220 NEXT J
230 PRINT:PRINT
240 GOSUB 1000 '<<< call fraction reduction
250 FOR J = 1 TO TOTAL
260 PRINT FRACTION$(J), '<<send fraction to screen
270 NEXT J
280 END
1000 REM ========================================================
1010 REM *****************>> DURRED <<***************************
1020 REM ========================================================
1030 REM This subroutine reduces fractions in a manner
1040 REM consistent with rhythmic pulse subdivision.
1050 REM For instance, a fractional duration such as
1060 REM 6/12 will be reduced to 3/6 (as opposed to
1070 REM 1/2) in order to preserve subdivisional clarity.
1080 REM This results in duration patterns which are
1090 REM metrically simpler to reconcile when output is to be
1100 REM transcribed for standard musical instruments
1110 REM ========================================================
1120 REM Variable Descriptions
1130 REM Entering -
1140 REM X(): array of fraction numerators
1150 REM Y(): array of fraction denominators
1160 REM TOTAL: number of fractions to be converted
1170 REM
1180 REM Exiting -
1190 REM FRACTION$(): character string array of fractions
1210 REM
1220 REM Local -
1230 REM K9: loop index, pointer to arrays X(),Y(),FRACTION$
1240 REM ========================================================
1250 FOR K9 = 1 TO TOTAL
1260 IF X(K9) / 2 <> INT(X(K9) / 2)OR Y(K9) / 2 <> INT(Y(K9) / 2)THEN 1280
1270 X(K9) = X(K9) / 2 : Y(K9) = Y(K9) / 2 : GOTO 1260
1280 FRACTION$(K9) = STR$(X(K9)) + "/" + STR$(Y(K9))
1285 NEXT K9
1290 RETURN
100 REM =========================================================
110 REM =================== DRIVER PROGRAM ======================
120 REM =========================================================
130 DIM X(50),Y(50),FRACTION$(50)
140 TOTAL = 50
150 CLS
160 RANDOMIZE
170 REM >> randomly choose fractions between 1/50 & 50/1
180 FOR J= 1 TO TOTAL
190 X(J) = INT(RND * TOTAL)+1 '<< load numerators
200 Y(J) = 32 '<< load denominators
210 PRINT X(J);"/";Y(J), '<< send fraction to screen
220 NEXT J
230 PRINT
240 GOSUB 1000 '<<< call fraction reduction
250 FOR J = 1 TO TOTAL
260 PRINT FRACTION$(J), '<< send fraction to screen
270 NEXT J
280 END
1000 REM ========================================================
1010 REM ********************>> EUCREDUC <<**********************
1020 REM ========================================================
1030 REM This subroutine uses Euclid's algorithm to reduce
1040 REM rhythmic duration fractions to absolute lowest terms.
1050 REM It does not preserve metrical pulse consistency, in
1060 REM that a fraction such as 9/12 will convert to 3/4.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM X(): array of fraction numerators
1110 REM Y(): array of fraction denominators
1120 REM TOTAL: number of fractions to be reduced
1130 REM
1140 REM Exiting -
1150 REM FRACTION$(): character string array of fractions
1160 REM
1170 REM Local -
1180 REM K9: loop index, pointer to arrays X(),Y(),FRACTION$
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 IF Y(K9) = 1 THEN 1330
1220 A9 = X(K9)
1230 B9 = Y(K9)
1240 IF A9 > B9 THEN SWAP A9,B9
1250 WHILE A9 > 0
1260 C9 = INT(B9/A9)
1270 D9 = B9-A9*C9
1280 B9 = A9
1290 A9 = D9
1300 WEND
1310 REM >> convert fraction to char string and load in array
1320 FRACTION$(K9) = STR$(X(K9)/B9) + "/" + STR$(Y(K9)/B9)
1330 NEXT K9
1340 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Expon)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 SPREAD = 2
180 GOSUB 1000 '<< call exponential distribution function
190 FOR J = 1 TO TOTAL
200 PRINT X(J); '<< sequence to screen
210 NEXT J
220 END
1000 REM ========================================================
1010 REM ********************>> EXPON <<************************
1020 REM (L)=====================================================
1030 REM The Exponential Distribution Function generates
1040 REM continuous, random-order real numbers > 0 & < 1.
1050 REM Results closer to 0 are most likely to occur,
1060 REM with probability of higher numbers falling off
1070 REM exponentially. The variable SPREAD controls
1080 REM horizontal value scaling.
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM SPREAD: horizontal scaling parameter
1130 REM TOTAL: length of sequence
1140 REM Exiting -
1150 REM X(): array holding exponential distribution
1160 REM Local -
1170 REM R9 : uniform random number
1180 REM K9: loop index, pointer to array X()
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 R9 = RND
1220 X(K9) = -LOG(R9) / SPREAD
1230 NEXT K9
1240 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM X(50),Y(50),Z(50)
140 TOTAL = 50
150 CLS
160 RANDOMIZE
170 FOR J= 1 TO TOTAL
180 X(J) = INT(RND * TOTAL)+1 '<< random numerators
190 Y(J) = INT(RND * TOTAL)+1 '<< random denominators
200 NEXT J
210 GOSUB 1000 '<<< call fraction to decimal conversion
220 FOR J = 1 TO TOTAL
230 PRINT X(J);"/";Y(J);"=";'<<send fraction to screen
240 PRINT Z(J) '<<send decimal equivalent to screen
250 NEXT J
260 PRINT "SUM OF DURATIONS =";SUM;"WHOLE NOTES"
270 END
1000 REM ========================================================
1010 REM *******************>> FRACDEC <<***********************
1020 REM ========================================================
1030 REM This subroutine converts fractional values to
1040 REM decimal for use in rhythmic applications. It also
1050 REM computes the total of all durations in whole notes.
1060 REM ========================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM X(): array of fraction numerators
1100 REM Y(): array of fraction denominators
1110 REM TOTAL: number of fractions to be converted
1120 REM Exiting -
1130 REM Z(): array of decimal equivalents
1140 REM SUM: sum of all durations in decimal
1150 REM Local -
1160 REM K9: loop index, pointer to arrays X(),Y()
1170 REM ========================================================
1180 SUM = 0
1190 FOR K9 = 1 TO TOTAL
1200 Z(K9) = X(K9) / Y(K9) '<< load decimal equivalent
1210 SUM = SUM + Z(K9)
1220 NEXT K9
1230 RETURN
100 REM ========================================================
110 REM ================= DRIVER PROGRAM =======================
120 REM ========================================================
130 DIM X(50)
140 TOTAL = 50
150 CLS
160 PRINT "HERE IS A SERIES OF DURATION FRACTIONS:"
170 FOR J = 1 TO TOTAL
180 X(J) = J '<<< load denominators in array
190 PRINT "1/";X(J), '<<< send to screen as fractions
200 NEXT J
210 PRINT : PRINT
220 GOSUB 1000 '<<< call duration tabulation
230 PRINT "SUM OF DURATIONS IS:";SUM#;"WHOLE NOTES"
240 END
1000 REM =======================================================
1010 REM ******************>> FRACTAB <<**********************
1020 REM =======================================================
1030 REM This subroutine tabulates rhythmic duration values
1040 REM in cases where each value can be expressed as a
1050 REM fraction which has 1 as the numerator (e.g. 1/8).
1060 REM The sum of all durations is returned in decimal
1070 REM (e.g., 4.499205391854048 whole notes).
1080 REM =======================================================
1100 REM Variable Descriptions
1120 REM Entering -
1140 REM X(): array of fraction denominators to be summed
1150 REM TOTAL: number of elements in array X()
1160 REM
1170 REM Exiting -
1190 REM SUM#: (double precision) decimal sum of
1200 REM durations, expressed in whole notes
1210 REM
1220 REM Local -
1240 REM K9: loop index, pointer to array X()
1260 REM =======================================================
1280 SUM# = 0
1290 FOR K9 = 1 TO TOTAL
1300 SUM# = SUM# + 1 / X(K9)
1310 NEXT K9
1320 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Fractsum)
130 REM =========================================================
140 REM The subroutines below have a number of individual
150 REM uses; they are grouped together in this program
160 REM for the purpose of totaling a sequence of rhythm
170 REM duration fractions.
180 REM
190 REM An alternative subroutine, FRACDEC, (presented
200 REM elsewhere) sums fractions and expresses the
210 REM the result in decimal in decimal whole note
220 REM values, e.g., 1.23143.
230 REM
240 REM Contrastingly, FRACTSUM places no restriction
250 REM on fraction type, and produces fractional, not
260 REM decimal, output, e.g., 2/1 + 11/16 = 2 11/16.
270 REM The subroutine LCM (Least Common Multiple) is
280 REM coupled with EUCREDUC (which is Euclid's Algorithm
290 REM for finding the Greatest Common Divisor of two
300 REM numbers) to do the work of summing the fraction
310 REM sequence. However, there is one serious drawback
320 REM to FRACTSUM - when a computer with a small word
330 REM size is used, overflow condition is quickly reached.
340 REM =========================================================
350 DIM X(20),Y(20)
360 RANDOMIZE
370 PRINT "ARRAY OF DURATION FRACTIONS TO BE TOTALED -- "
380 FOR J = 0 TO 20
390 X(J) = INT(RND * 10)+1
400 Y(J) = INT(RND * 10)+1
410 PRINT X(J);"/";Y(J), '<< send fraction to screen
420 NEXT J
430 PRINT
440 PRINT
450 FOR J = 1 TO 20
460 GOSUB 1000
470 X(0) = NUM
480 Y(0) = DEN
490 NEXT J
500 IF NUM MOD DEN = 0
THEN PRINT NUM/DEN
ELSE IF NUM > DEN
THEN PRINT INT(NUM/DEN);"+";NUM MOD DEN;"/";DEN;
ELSE PRINT NUM;"/";DEN;
510 END
1000 REM SS1MA5 =================================================
1010 REM ***********************>> LCM <<************************
1020 REM ========================================================
1030 REM This subroutine determines the least common
1040 REM multiple of two integers by calling the
1050 REM greatest common divisor subroutine to supply
1060 REM that value, then divides the product of the
1070 REM two integers by the gcd.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM X(0): current fraction numerator sum
1120 REM X(n): next fraction numerator
1130 REM Y(0): current fraction denominator sum
1140 REM Y(n): next fraction denominator
1150 REM LCM: least common multiple
1160 REM Exiting -
1170 REM NUM: reduced fraction numerator total
1180 REM DEN: reduced fraction denominator total
1190 REM Local -
1200 REM M9: temp storage for denominator total
1210 REM N9: temp storage for next denominator
1220 REM GCD: greatest common divisor
1230 REM LCM: least common multiple
1240 REM ========================================================
1250 M9 = Y(0)
1260 N9 = Y(J)
1270 GOSUB 2000 '<< call Greatest Common Divisor
1280 LCM = M9 * N9 / GCD
1290 M9 = LCM / Y(0)
1300 N9 = LCM / Y(J)
1310 NUM = (X(0) * M9) + (X(J) * N9)
1320 DEN = LCM
1330 M9 = NUM
1340 N9 = DEN
1350 GOSUB 2000 '<< call Greatest Common Divisor
1360 NUM = M9 / GCD
1370 DEN = N9 / GCD
1380 RETURN
2000 REM ========================================================
2010 REM ***********************>> GCD <<************************
2020 REM (EUCREDUC adapted to program specs.)
2030 REM ========================================================
2040 A9 = M9
2050 B9 = N9
2060 IF A9 > B9 THEN SWAP A9,B9
2070 WHILE A9 > 0
2080 C9=INT(B9/A9)
2090 D9 = B9 - A9 * C9
2100 B9 = A9
2110 A9 = D9
2120 WEND
2130 GCD = B9
2140 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
130 REM (Gamma)
140 REM =========================================================
150 DIM X(50)
160 RANDOMIZE
170 TOTAL = 50
180 SPREAD = 5
190 GOSUB 1000 '<< call gamma distribution function
200 FOR J = 1 TO TOTAL
210 PRINT X(J); '<< sequence to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM **********************>> GAMMA <<***********************
1020 REM ========================================================
1030 REM The Gamma Probability Distribution Function returns
1040 REM random-order, continuous real numbers over an
1050 REM assymetrical curve. It has particular usefulness
1060 REM in rhythmic applications, where it can produce a
1070 REM sense of 'rubato'.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM TOTAL: length of sequence
1120 REM SPREAD: control parameter
1130 REM Exiting -
1140 REM X(): array holding gamma distribution
1150 REM Local -
1160 REM SUM: accumulator
1170 REM GAMMA: current distribution value
1180 REM K9: loop index, pointer to array X()
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 SUM = 1
1220 FOR L9 = 1 TO SPREAD
1230 SUM = SUM * RND
1240 NEXT L9
1250 X(K9) = -LOG(SUM)
1260 NEXT K9
1270 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Gauss)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 DEV = 2
180 MEAN = 10
190 GOSUB 1000 '<< call gaussian distribution function
200 FOR J = 1 TO TOTAL
210 PRINT X(J); '<< sequence to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM **********************>> GAUSS <<***********************
1020 REM ========================================================
1030 REM The Gaussian Probability Distribution Function
1040 REM is also referred to as the 'normal distribution'.
1050 REM Its curve is bell-shaped, and is arrived at by
1060 REM an approximation resulting from the summation of
1070 REM uniform random numbers. The standard deviation -
1080 REM DEV - and the mean - MEAN - are the control
1090 REM parameters. It generates random-order real
1100 REM numbers centered about the mean.
1110 REM ========================================================
1120 REM Variable Descriptions
1130 REM Entering -
1140 REM TOTAL: length of sequence
1150 REM DEV: statistical standard deviation
1160 REM MEAN: statistical mean
1170 REM Exiting -
1180 REM X(): array holding gaussian distribution
1190 REM Local -
1200 REM NUM: number of random values used in computation
1210 REM HALFNUM: NUM / 2
1220 REM SCALE: scaling factor (varies with NUM as
1230 REM SCALE = 1 / SQR(NUM/12)
1240 REM K9: loop index, pointer to array X()
1250 REM ========================================================
1260 NUM = 12
1270 HALFNUM = NUM/2
1280 SCALE=1
1290 FOR K9= 1 TO TOTAL
1300 SUM=0
1310 FOR L9 = 1 TO NUM
1320 SUM = SUM + RND
1330 NEXT L9
1340 X(K9) = DEV * SCALE * (SUM - HALFNUM) + MEAN
1350 NEXT K9
1360 RETURN
1 REM in text explain how forms contain info for eol & eop (-1)
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM Gen-con
130 REM =========================================================
140 REM This group of subroutines composes 4 poems (somewhat
150 REM resembling Haiku), then maps the ASCII values of the
160 REM constituent letters onto the pitch domain.
170 REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
180 DIM P$(84),VOCAB$(300),W(15),SET(300)
190 REM >>> assign parts of speech totals (see DATA categories)
200 AR = 2
210 AD = 72
220 NO = 103
230 VE = 55
240 PR = 15
250 WORDTOT = AR + AD + NO + VE + PR
260 GOSUB 4000 '<< initialize pitch data table
270 RANDOMIZE
280 PRINT "EACH LINE OF EACH POEM WILL BE PRINTED, THEN " :
PRINT "CONVERTED TO CORRESPONDING PITCH SEQUENCE"
290 FOR J = 1 TO 4
300 PRINT "POEM ";J
310 GOSUB 1000 '<< call poem generator
320 PRINT:PRINT
330 NEXT J
340 END
1000 REM ================================================== CTB5.8
1010 REM ******************>> GENPOEM <<**************************
1020 REM =========================================================
1030 REM This subroutine generates 3-line poems which bear
1040 REM a resemblance to Haiku. It consults 1 of four
1050 REM poem form schemes to provide proper syntax, then
1060 REM randomly selects conforming words from program
1070 REM vocabulary. Words can be added to the DATA state-
1080 REM ments, but be sure to change DRIVER PROGRAM variable
1090 REM values accordingly (or mayhem will result).
1100 REM =========================================================
1110 REM Variable Descriptions
1120 REM Entering -
1130 REM J: flag from DRIVER to load program vocabulary
1140 REM WORDTOT: vocabulary size
1150 REM AR: number of articles in vocabulary
1160 REM AD: number of adjectives in vocabulary
1170 REM NO: number of nouns in vocabulary
1180 REM VE: number of verbs in vocabulary
1190 REM PR: number of prepositions in vocabulary
1200 REM Exiting -
1210 REM LIN$: full poem line
1220 REM Local -
1230 REM VOCAB$(): array of program vocabulary
1240 REM SET(): flag array to prevent word repetition
1250 REM W(): array storing current poem formal structure
1260 REM W: current part of speech, or blank space
1270 REM L: low end vocabulary delimiter
1280 REM S: range span for parts of speech categories
1290 REM RNDWRD: randomly selected word
1300 REM K9: loop index, pointer to W()
1310 REM ========================================================
1320 LIN$ = ""
1330 IF J > 1 THEN 1370
1340 FOR K9 = 1 TO WORDTOT
1350 READ VOCAB$(K9) '<< load vocabulary
1360 NEXT K9
1370 FOR K9 = 1 TO 15
1380 READ W(K9) '<< load 1 of 4 unique poem forms
1390 NEXT K9
1400 FOR K9 = 1 TO 15
1410 W = W(K9)
1420 REM << if end-of-text (W=-1) or end-of-line (W=0), call >>
1430 REM << article-checking subroutine, print line of text, >>
1440 REM << call text-to-pitch conversion subroutine to print >>
1450 REM << resulting pitch sequence. >>
1460 IF W = -1 THEN GOSUB 2000 :
PRINT LIN$ : GOSUB 3000 :
RETURN
1470 IF W = 0 THEN GOSUB 2000 :
PRINT LIN$ : GOSUB 3000 :
LIN$= "" : GOTO 1550
1480 REM >>> locate vocab range for selected part of speech
1490 IF W=1 THEN L=1:S=AR
ELSE IF W=2 THEN L=AR+1:S=AD
ELSE IF W=3 THEN L=AR+AD+1:S=NO
ELSE IF W=4 THEN L=AR+AD+NO+1:S=VE
ELSE L=AR+AD+NO+VE+1:S=PR
1500 RNDWRD = INT(RND * S) + L
1510 IF RNDWRD <= AR THEN 1540 '<<permit article repetit.
1520 IF SET(RNDWRD) = 1 THEN 1500 '<<prevent word repetit.
1530 SET(RNDWRD) = 1
1540 LIN$ = LIN$ + " " + VOCAB$(RNDWRD) '<< build a line
1550 NEXT K9
1560 RETURN
2000 REM =================================================== CTB5.9
2010 REM ********************>> ARTCHECK <<************************
2020 REM ==========================================================
2030 REM This subroutine checks for article-adjective agreement.
2040 REM It scans the line of poetry most recently created by
2050 REM subroutine GENPOEM. If it finds the article A before
2060 REM a vowel, it changes it to the article AN.
2070 REM ==========================================================
2080 REM Variable Descriptions
2090 REM Entering -
2100 REM LIN$: uncorrected line of text
2110 REM Exiting -
2120 REM LIN$: text line after article checking/correction
2130 REM Local -
2140 REM B$: stores indicator to add letter N to article
2150 REM I: loop index, pointer to LIN$ substring
2160 REM ==========================================================
2170 FOR I = 1 TO LEN(LIN$) - 2
2180 IF MID$(LIN$,I,3) = " A " THEN B$ = MID$(LIN$,I+3,1)ELSE 2200
2190 IF B$="A" OR B$="E" OR B$="I" OR B$="O" OR B$="U"
THEN LIN$ = LEFT$(LIN$,I+1) + "N" + MID$(LIN$,I+2)
2200 NEXT I
2210 RETURN
3000 REM ================================================= CTB5.2
3010 REM ********************>> SNDTEXT2 <<**********************
3020 REM (Adapted to program specs)
3030 REM ========================================================
3040 LINELENGTH = LEN(LIN$)
3050 FOR M9 = 1 TO LINELENGTH
3060 NOTENUM = ASC(MID$(LIN$,M9,1))-32 '<<convert to int
3070 PRINT P$(NOTENUM);" "; '<< convert to pitch
3080 NEXT M9
3090 PRINT
3100 RETURN
4000 REM ================================================= CTB1.3
4010 REM ********************>> PITCHTAB <<**********************
4020 REM (Adapted to program specs)
4030 REM ========================================================
4040 P$(0) = " R " '<< blank spaces will print as rests
4050 NOTE$ = " CC# DD# E FF# GG# AA# B"
4060 OCTAVE$ = "1234567"
4070 FOR K9 = 1 TO 7
4080 FOR L9 = 1 TO 12
4090 P$(L9+(K9-1) * 12) = MID$(NOTE$,(L9*2-1),2) + MID$(OCTAVE$,K9,1)
4100 NEXT L9
4110 NEXT K9
4120 RETURN
4130 REM =========================================================
5000 REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5010 REM PROGRAM VOCABULARY
5020 REM ++++++++++++++++++
5030 REM
5040 REM ARTICLES
5050 REM +++++++++++++++++++
5060 DATA A,THE
5070 REM +++++++++++++++++++
5080 REM ADJECTIVES
5090 REM +++++++++++++++++++
5100 DATA AUTUMN,HIDDEN,BITTER, MISTY,SILENT,EMPTY,VERDANT
5110 DATA DRY,DARK,SUMMER,ICY,DELICATE,QUIET,BEMUSED,DIMPLED
5120 DATA WHITE,COOL,SPRING,WINTER,DAPPLED,MOLTEN,FLORAL,DAMP
5130 DATA TWILIGHT,DAWN,CRIMSON,WISPY,AZURE,FRIGID,ASHEN,WHITE
5140 DATA BLUE,BILLOWING,BROKEN,COLD,DAMP,FALLING,INDIGO,SILKEN
5150 DATA FROSTY,GREEN,LONG,LATE,LINGERING,LIMPID,DUSTY,MIDNIGHT
5160 DATA LITTLE,EVENING,MUDDY,OLD,RED,ROUGH,TRANQUILL,WISTFUL
5170 DATA STILL,SMALL,SPARKLING,THROBBING,VERMILION,SOUR,LEMON
5180 DATA WANDERING,WITHERED,WILD,BLACK,YOUNG,STRICKEN,FLEECY
5190 DATA RADIANT,TENDER,DARK
5200 REM +++++++++++++++++++
5210 REM NOUNS
5220 REM +++++++++++++++++++
5230 DATA WATERFALL,RIVER,BREEZE,MOON,CAVE,MOON,DREAMSCAPE,DEER
5240 DATA RAIN,WIND,SEA,TABLEAU,SNOWFLAKE,LAKE,SUNSET,SAND-GRAIN
5250 DATA PINE,SHADOW,LEAF,DAWN,GROTTO,FOREST,TROUT,POOL,WIND,ASH
5260 DATA HILL,CLOUD,MEADOW,SUN,GLADE,BIRD,BROOK,MILKWEED,WILLOW
5270 DATA BUTTERFLY,BUSH,DEW,STORMCLOUD,FIELD,FIR,BRANCH,FLAME
5280 DATA FLOWER,FIREFLY,FEATHER,GRASSBED,HAZE,MOUNTAIN,HONEYDEW
5290 DATA NIGHT,POND,SHADE,SNOWFLAKE,DRAGONFLY,LAUREL,COMET,STAR
5300 DATA SILENCE,SOUND,SKY,SHAPE,SURF,THUNDERCLAP,MEADOW,GLOW
5310 DATA VIOLET,PLUME,WILDFLOWER,WAVE,SPIRIT,TWILIGHT,HALO,OWL
5320 DATA SPIDER WEB,LONLINESS,MIST,IVY,DREAM,LIGHT,WOOD,SEASHELL
5330 DATA SWAN,CEDAR,ICE,ROSE,THORN,SUNBEAM,BLOSSOM,GULL,PETAL
5340 DATA STONE,BEE,LEAF,HORIZON,SHOWER,AIR,ROOT,LILAC,HEART
5350 DATA WHISPER,BREATH,SCENT
5360 REM ++++++++++++++++++
5370 REM VERBS
5380 REM ++++++++++++++++++
5390 DATA SHAKES,DRIFTS,HAS STOPPED,STRUGGLES,IS DEPARTING
5400 DATA HAS FALLEN,HAS PASSED,SLEEPS,CREEPS,RECLINES,SIGHS
5410 DATA FLUTTERS,HAS RISEN,IS FALLING,IS TRICKLING,DAMPENS
5420 DATA DRINKS IN,TREMBLES,SWALLOWS,TRANSCENDS,MOCKS,LINGERS
5430 DATA MURMURS,IS FLOATING,DREAMS,RETURNS,WAS GLEAMING,RESTS
5440 DATA IS SWEETENING,FLICKERS,SHIVERS,VANISHES,SPARKS,WEAVES
5450 DATA IS GLOWING,HAS EMBARKED,IS PLUNGING,SHINES,IS PRAYING
5460 DATA HAS HIDDEN,DROWNS,BEAMS DOWN,TWITTERS,HAS DANCED,GLIDES
5470 DATA IS WHISPERING,HAS BURNT,BREATHES,EMBRACES,DRONES,DESCENDS
5480 DATA LIFTS,CREEPS,DWELLS,FLICKERS
5490 REM ++++++++++++++++++
5500 REM PREPOSITIONS
5510 REM ++++++++++++++++++
5520 DATA ON,IN,FROM,UNDER,OVER,NEAR,BENEATH,ATOP,WITH,ACROSS
5530 DATA BESIDE,ASTRIDE,IMMERSED IN,INSIDE,THROUGH
5540 REM ++++++++++++++++++
5550 REM FORMAL STRUCTURES
5560 REM ++++++++++++++++++
5570 DATA 1,2,3,0,1,3,4,5,1,3,0,2,2,3,-1
5580 DATA 3,5,1,3,0,1,2,3,5,1,3,0,2,3,-1
5590 DATA 1,2,3,0,5,1,2,3,0,1,3,4,-1,-1,-1
5600 DATA 1,2,3,4,0,1,2,2,3,0,5,1,2,3,-1
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Grafplot)
130 REM =========================================================
140 DIM X(50),Y(50)
150 SUM = 0
160 TOTAL = 21 '<< num of array elements in X() + Y()
170 C$ = "o" '<< character for graph
180 FOR J = 1 TO TOTAL
190 X(J) = SUM '<< load x-axis array
200 Y(J) = SIN(X(J)) '<< load y-axis array
210 SUM = SUM + .314159
220 NEXT J
230 PRINT "0 <= x <= 2pi : sin(x)"
240 GOSUB 1000 '<< call x-y graph plotting
250 END
1000 REM SS1PL2 =================================================
1010 REM *********************>> XY-PLOT <<**********************
1020 REM ========================================================
1030 REM This subroutine produces an X-Y line graph of
1040 REM two interdependent parameters (e.g., musical waveform
1050 REM cycle over a time period). It performs its own
1060 REM scaling, which means that any set of data, positive
1070 REM negative, of any range, may be graphed without
1080 REM concern for compression or expansion.
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM X(): array holding the x-axis elements
1130 REM Y(): array holding the y-axis elements
1140 REM TOTAL : number of elements in arrays X(),Y()
1150 REM C$ : plotting character
1160 REM Exiting -
1170 REM none (subroutine is procedural)
1180 REM Local -
1190 REM LOWVAL: lowest value in array Y()
1200 REM HIGHVAL: highest value in array Y()
1210 REM SCDISP: scale displacement between LOWVAL,HIGHVAL
1220 REM LEFTDISP: leftmargin displacement for X position
1230 REM K9: loop index, pointer to arrays X(),Y()
1240 REM ========================================================
1250 LOWVAL = Y(1)
1260 HIGHVAL = Y(1)
1270 FOR K9 = 2 TO TOTAL
1280 IF Y(K9) < LOWVAL THEN LOWVAL = Y(K9)
1290 IF Y(K9) < HIGHVAL THEN HIGHVAL = Y(K9)
1300 NEXT K9
1310 SCDISP = HIGHVAL - LOWVAL
1320 IF SCDISP = 0 THEN SCDISP = 1
1330 FOR K9 = 1 TO TOTAL
1340 LEFTDISP = INT(1+(Y(K9)-LOWVAL) / SCDISP * 20+.5)
1350 PRINT X(K9);TAB(15 + LEFTDISP);C$
1360 NEXT K9
1370 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Histo)
130 REM =========================================================
140 DIM X(20)
150 RANGE = 20 '<< set random number range 1-20
160 TOTAL = 400 '<< return 400 values
170 RANDOMIZE
180 GOSUB 1000 '<< generate frequency table
190 GOSUB 2000 '<< call bargraph display
200 END
1000 REM ========================================================
1010 REM *******************>> FREQTABL <<***********************
1020 REM ========================================================
1030 REM This subroutine computes a table of occurrence
1040 REM frequency for each value generated during a run.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM Entering -
1080 REM TOTAL: number of samples to return
1090 REM RANGE: numeric range of samples
1100 REM Exiting -
1110 REM X(): array holding frequency table
1120 REM Local -
1130 REM VALUE: random integer, pointer to array X()
1140 REM K9: loop index
1150 REM ========================================================
1160 FOR K9 = 1 TO TOTAL
1170 VALUE = INT(RND * RANGE)+1 '<< gen random value
1180 X(VALUE)=X(VALUE)+1 '<< record occurrence of value
1190 NEXT K9
1200 RETURN
2000 REM ========================================================
2010 REM *******************>> BARGRAPH <<***********************
2020 REM ========================================================
2030 REM This procedural subroutine prints a simple
2040 REM bargraph. In this case the bargraph represents
2050 REM an occurance frequency table of random integers
2060 REM generated during program execution.
2070 REM ========================================================
2080 REM Variable Descriptions
2090 REM Entering -
2100 REM X(): occurence frequency table,
2110 REM address = random number,
2120 REM contents = frequency of occurance
2130 REM RANGE: range of integer values in table
2140 REM Exiting -
2150 REM none (subroutine is procedural)
2160 REM Local -
2170 REM K9: loop index, pointer to frequency table
2180 REM ========================================================
2190 FOR K9 = 1 TO RANGE
2200 PRINT K9;TAB(10);STRING$(X(K9),">")
2210 NEXT K9
2220 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Hypcosin)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 GOSUB 1000 '<< call hyperbolic cosine distribution
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM ******************>> HYPCOSIN <<************************
1020 REM ========================================================
1030 REM The Hyperbolic Cosine Probability Distribution
1040 REM function produces a symmetrical curve; however,
1050 REM although centered about zero, it has no mean value.
1060 REM ========================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM TOTAL: length of sequence
1100 REM Exiting -
1110 REM X(): array holding Hypercosine distribution
1120 REM Local -
1130 REM R9: uniform random number
1140 REM K9: loop index, pointer to array X()
1150 REM ========================================================
1160 FOR K9 = 1 TO TOTAL
1170 R9 = RND
1180 X(K9) = LOG(TAN(3.14159 * R9 /2))+4
1190 NEXT K9
1200 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (INSORT)
130 REM =========================================================
140 DIM X(50)
150 TOTAL = 50
160 RANDOMIZE
170 PRINT "ARRAY OF RANDOM-ORDER REAL NUMBERS (RANGE 0-1) --"
180 FOR J = 1 TO TOTAL
190 X(J) = RND
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "ARRAY SORTED IN ASCENDING ORDER --"
240 GOSUB 1000 '<< call insertion sort
250 FOR J = 1 TO TOTAL
260 PRINT X(J); '<< list to screen
270 NEXT J
280 END
1000 REM SS2TM2 =================================================
1010 REM ***********************>> INSORT <<*********************
1020 REM ========================================================
1030 REM This algorithm is surprisingly fast, yet simple
1040 REM to code and comprehend. It is also called the
1050 REM card players sort, because during sorting each
1060 REM unsorted element is inserted in its appropriate
1070 REM slot relative to already sorted values.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM X(): array of values to be sorted
1120 REM TOTAL: length of array X()
1130 REM Exiting -
1140 REM X(): array sorted in ascending order
1150 REM Local -
1160 REM K9: loop index, pointer to X()
1170 REM L9: loop index, pointer to X()
1180 REM FIRSTVAL: first value in unsorted list
1190 REM ========================================================
1200 FOR K9=1 TO TOTAL - 1
1210 FIRSTVAL = X(K9+1)
1220 FOR L9=K9 TO 1 STEP -1
1230 IF FIRSTVAL >= X(L9) THEN 1270
1240 X(L9+1) = X(L9)
1250 NEXT L9
1260 L9=0
1270 X(L9+1) = FIRSTVAL
1280 NEXT K9
1290 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM GAMINTS(12),P$(96)
140 RANDOMIZE
150 TOTAL = 5
160 INTOTAL = 6 '<< number of intervals in set
170 GOSUB 2000 '<< call pitch table
180 FOR J = 1 TO INTOTAL
190 GAMINTS(J) = INT(RND * 3)+1 '<< select interval set
200 NEXT J
210 FOR J = 1 TO TOTAL
220 PRINT "CHORD";J
230 ROOT = INT(RND * 12)+1
240 OCTAVE = INT(RND * 3)+1
250 CHORDMEMS = INT(RND * 14)+6
260 GOSUB 1000 '<< call interval gamut generator
270 PRINT
280 NEXT J
290 END
1000 REM ========================================================
1010 REM *******************>> INTGAM <<*************************
1020 REM ========================================================
1030 REM This subroutine generates non octave-repeating
1040 REM chords/gamuts from a set of intervals.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM Entering -
1080 REM P$(): pitch name table
1090 REM GAMINTS(): array of interval sizes
1100 REM ROOT: lowest chord/gamut member
1110 REM OCTAVE: octave register for chord initiation
1120 REM CHORDMEMS: number of tones contained in gamut
1130 REM INTOTAL: number of intervals in GAMINTS()
1140 REM Exiting -
1150 REM none (subroutine is procedural)
1160 REM Local -
1170 REM COUNT: tabulates chordtone generation
1180 REM CHORDTONE: next chord/gamut member
1190 REM K9: loop index
1200 REM L9: loop index, pointer to array GAMINTS()
1210 REM ========================================================
1220 COUNT = 0
1230 CHORDTONE = ROOT + ((OCTAVE - 1) * 12)
1240 FOR K9 = 1 TO 100
1250 FOR L9 = 1 TO INTOTAL
1260 PRINT P$(CHORDTONE);" ";
1270 COUNT = COUNT + 1
1280 IF COUNT = CHORDMEMS THEN RETURN
1290 CHORDTONE = CHORDTONE + GAMINTS(L9)
1300 NEXT L9
1310 NEXT K9
1320 RETURN
2000 REM ========================================================
2010 REM *******************>> PITCHTAB <<***********************
2020 REM ========================================================
2030 REM This subroutine initializes a pitch data table
2040 REM corresponding to integer values 1-n.
2050 REM ========================================================
2070 NOTE$ = " CC# DD# E FF# GG# AA# B"
2080 OCTAVE$ = "1234567"
2090 FOR K9 = 1 TO 7
2100 FOR L9 = 1 TO 12
2110 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
2120 NEXT L9
2130 NEXT K9
2140 RETURN
100 REM ==========================================================
110 REM DRIVER PROGRAM
120 REM (INTLINK)
130 REM ==========================================================
140 DIM PCUM(12),ICUM(12),PCLASS(12)
150 RANDOMIZE(1)
160 TOTAL = 10
170 GOSUB 1000 '<< call interval-linked PC series generator
180 END
1000 REM =========================================================
1010 REM **********************>> INTLINK <<**********************
1020 REM =========================================================
1030 REM This subroutine generates a random-order series,
1040 REM locates the series position at which interval-size
1050 REM redundancy occurs, then links subsequent set
1060 REM permutations by moving remaining values from flag-
1070 REM point in the current series to the beginning of the
1080 REM next series to form its nucleus. Appropriate values
1090 REM are then permutated to complete the (now) current
1100 REM series. Thus, value-group repetitions of various
1110 REM lengths are produced - within an overall serial
1120 REM context - as a method of generating new related
1130 REM sequences for use as pointers to pitch, rhythm,
1140 REM volume, articulation, or other parameter elements.
1150 REM ========================================================
1160 REM Variable Descriptions
1170 REM Entering -
1180 REM TOTAL: number of series to generate & link
1190 REM Exiting -
1200 REM (to ZEROMAT)
1210 REM PCUM: array of pitchclass flags
1220 REM ICUM: array of intervalclass flags
1230 REM (to MATPRINT)
1240 REM PCLASS(): array holding current series
1250 REM REDPT: interval redundancy point marker
1260 REM Local -
1270 REM INTSIZE: interval between consecutive pitchclasses
1280 REM SHIFT: number of places to shift remaining setmems
1290 REM R9: random integer
1300 REM K9: loop index
1310 REM L9: loop index, pointer to PCLASS()
1320 REM ========================================================
1330 REDPT = 1
1340 FOR K9 = 1 TO TOTAL '<< flag carried-over set members
1350 FOR L9 = 1 TO 12
1360 IF PCLASS(L9) > 0 THEN PCUM(PCLASS(L9)) = 1
1370 NEXT L9
1380 FOR L9 = 1 TO 12 '<< gen required new setmembers
1390 IF PCLASS(L9) > 0 THEN 1440
1400 R9 = INT(RND * 12) + 1
1410 IF PCUM(R9) = 1 THEN 1400
1420 PCUM(R9) = 1
1430 PCLASS(L9) = R9
1440 NEXT L9
1450 FOR L9 = 1 TO 11 '<< find intervals btwn setmembers
1460 INTSIZE = PCLASS(L9+1) - PCLASS(L9)
1470 IF INTSIZE < 0 THEN INTSIZE = 12 - ABS(INTSIZE)
1480 IF ICUM(INTSIZE) = 1 THEN 1510'<<mark redundancy
1490 ICUM(INTSIZE) = 1
1500 NEXT L9
1510 REDPT = L9 + 1
1520 PRINT "INTERVAL REDUNDANCY OCCURS";
1530 PRINT " AT POSITION -->";REDPT
1540 GOSUB 2000
1550 GOSUB 3000
1560 SHIFT = 1
1570 FOR L9 = REDPT TO 12 '<< shift set balance forward
1580 PCLASS(SHIFT) = PCLASS(L9)
1590 SHIFT = SHIFT + 1
1600 NEXT L9
1610 FOR L9 = SHIFT TO 12'<< zero remaining array places
1620 PCLASS(L9) = 0
1630 NEXT L9
1640 NEXT K9
1650 RETURN
2000 REM ========================================================
2010 REM *********************>> MATPRINT <<*********************
2020 REM (adapted to program specs)
2030 REM ========================================================
2040 PRINT "PC SET: ";
2050 FOR M9 = 1 TO 12
2060 PRINT PCLASS(M9);
2070 IF M9 = REDPT - 1 THEN PRINT "||";
2080 NEXT M9
2090 PRINT
2100 RETURN
3000 REM ========================================================
3010 REM *********************>> ZEROMAT <<**********************
3020 REM (adapted to program specs)
3030 REM ========================================================
3040 FOR N9 = 1 TO 12
3050 PCUM(N9) = 0 : ICUM(N9) = 0
3060 NEXT N9
3070 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Linear)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 GOSUB 1000 '<< call linear distribution
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM **********************>> LINEAR <<**********************
1020 REM (D)=====================================================
1030 REM The Linear Distribution Function generates
1040 REM continuous,random-order real numbers > 0 & < 1.
1050 REM Results closer to 0 are most likely to occur.
1060 REM The reverse condition may be obtained by altering
1070 REM the algorithm to select the larger rather than
1080 REM the smaller random value in line 1230.
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM TOTAL: length of sequence
1130 REM Exiting -
1140 REM X(): array holding LINEAR real number sequence
1150 REM Local -
1160 REM R8: random number 1
1170 REM R9: random number 2
1180 REM K9: loop index, pointer to array X()
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 R8 = RND
1220 R9 = RND
1230 IF R9 < R8 THEN R8=R9
1240 X(K9) = R8
1250 NEXT K9
1260 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (LINEFIT)
130 REM =========================================================
140 DIM X(100),Y(100)
150 RANDOMIZE(-2438)
160 C$ = "o" '<< character for graph
170 TOTAL = 50
180 PRINT TOTAL;"RANDOM NUMBERS"
190 PRINT
200 FOR J = 1 TO TOTAL
210 X(J)=J '<< data point ordinate
220 Y(J)= INT(RND * 88) + 1 '<< data point coordinate
230 PRINT Y(J), '<< random-order data to screen
240 NEXT J
250 GOSUB 1000 '<< call linear least squares fit
260 PRINT
270 PRINT "STRAIGHT LINE THAT BEST FITS THE DATA:"
280 PRINT
290 PRINT "Y=";SLOPE;"X";
300 IF INTERCEPT < 0 THEN PRINT "-"; ELSE PRINT "+";
310 PRINT ABS(INTERCEPT)
320 FOR K9 = 1 TO TOTAL '<< scale line for graph plotting
330 Y(K9) = SLOPE * K9 + INTERCEPT
340 NEXT K9
350 GOSUB 2000 '<< call x-y graph plot
360 END
1000 REM ========================================================
1010 REM *********************>> LINEFIT <<**********************
1020 REM ========================================================
1030 REM This subroutine calculates the equation of the
1040 REM straight line that best fits a set of data.
1050 REM Its proper name is the Linear Least Squares Fit.
1060 REM When the data is a collection of musical parameter
1070 REM values, this algorithm provides a quick picture of
1080 REM (statistical) direction tendency over the sequence
1090 REM of values.
1100 REM ========================================================
1110 REM Variable Descriptions
1120 REM Entering-
1130 REM X(): array of ordinate increments
1140 REM Y(): array of random integers for coordinate
1150 REM TOTAL: number of data points
1160 REM Exiting -
1170 REM SLOPE: slope of linear least squares fit
1180 REM INTERCEPT: (coordinate) intercept of linear least
1190 REM squares fit line
1200 REM Local -
1210 REM XERR: sum of x errors
1220 REM XSQERR: sum of x-squared errors
1230 REM YERR: sum of y errors
1240 REM XYPRODERR: sum of x-y (cross-product) errors
1250 REM K9: loop index, pointer to X(),Y()
1260 REM ========================================================
1270 XERR = 0
1280 XSQERR = 0
1290 YERR = 0
1300 XYPRODERR = 0
1310 FOR K9 = 1 TO TOTAL
1320 XERR = XERR + X(K9)
1330 XSQERR = XSQERR + X(K9) ^ 2
1340 YERR = YERR + Y(K9)
1350 XYPRODERR = XYPRODERR + X(K9) * Y(K9)
1360 NEXT K9
1370 SLOPE=(TOTAL * XYPRODERR - XERR * YERR) / (TOTAL * XSQERR - XERR ^ 2)
1380 INTERCEPT = (XSQERR * YERR - XERR * XYPRODERR) / (TOTAL * XSQERR - XERR ^ 2)
1390 RETURN
2000 REM ========================================================
2010 REM *********************>> XY-PLOT <<**********************
2020 REM ========================================================
2030 LOWVAL = Y(1)
2040 HIGHVAL = Y(1)
2050 FOR K9 = 2 TO TOTAL
2060 IF Y(K9) < LOWVAL THEN LOWVAL = Y(K9)
2070 IF Y(K9) < HIGHVAL THEN HIGHVAL = Y(K9)
2080 NEXT K9
2090 SCDISP = HIGHVAL - LOWVAL
2100 IF SCDISP = 0 THEN SCDISP = 1
2110 FOR K9 = 1 TO TOTAL
2120 LEFTDISP = INT(1+(Y(K9)-LOWVAL) / SCDISP * 2+.5)
2130 PRINT X(K9);TAB(5+LEFTDISP);C$
2140 NEXT K9
2150 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Logistic)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 PAR1 = 1
180 PAR2 = 5
190 GOSUB 1000 '<< call logistic distribution function
200 FOR J = 1 TO TOTAL
210 PRINT X(J); '<< sequence to screen
220 NEXT J
230 END
1000 REM ========================================================
1010 REM *********************>> LOGISTIC <<*********************
1020 REM ========================================================
1030 REM The Logistic Probability Distribution function is
1040 REM controlled by the variables PAR1 and PAR2.
1050 REM Output takes the form of continuously variable
1060 REM random-order real numbers (negative to positive).
1070 REM The control parameters determine mean and
1080 REM dispersion of the distribution.
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM TOTAL: length of sequence
1130 REM PAR1: control value 1
1140 REM PAR2: control value 2
1150 REM Exiting -
1160 REM X(): array holding Logistic distribution
1170 REM Local -
1180 REM R9: uniform random number
1190 REM K9: loop index, pointer to array X()
1200 REM ========================================================
1210 FOR K9 = 1 TO TOTAL
1220 R9 = RND
1230 X(K9) =(-PAR1 * -LOG(1 / R9 - 1)) / PAR2
1240 NEXT K9
1250 RETURN
100 REM =========================================================
200 REM DRIVER PROGRAM
205 REM =========================================================
220 DIM NUM(20)
230 PERIOD = 2
240 FACTOR = 3
250 STARTNUM = 20
260 NOTES = 20
270 MANY = 10
280 MODE$ = "S"
290 FOR J = 1 TO NOTES
300 NUM(J) = J
310 NEXT J
320 GOSUB 1000 '<< call loop generator (subtractive mode)
330 MODE$ = "A"
340 STARTNUM = 1
350 PRINT:PRINT
360 GOSUB 1000 '<< call loop generator (additive mode)
370 END
1000 REM ========================================================
1010 REM *******************>> LOOPGEN1 <<***********************
1020 REM ========================================================
1030 REM This subroutine is pattern/process oriented.
1040 REM It generates a given number of copies (loops)
1050 REM of an input sequence while processing the
1060 REM sequence in terms of length. The two modes
1070 REM of loop alteration are additive and subtractive.
1080 REM In additive mode, the loop copies grow longer
1090 REM with successive iteration, beginning with a
1100 REM melodic nucleus. In Subtractive mode, loop
1110 REM copies begin with the complete sequence, and
1120 REM grow shorter by a constant factor with each
1130 REM iteration. The loop copies are printed out
1140 REM within the subroutine, rather than being passed
1150 REM back to the main program.
1160 REM ========================================================
1170 REM Variable Descriptions
1180 REM Entering -
1190 REM NUM(): array containing numeric sequence
1200 REM PERIOD: number of cycles between loop change
1210 REM FACTOR: number of values to add/subtr
1220 REM STARTNUM: sequence nucleus in additive mode
1230 REM NOTES: number of values in original sequence
1240 REM MANY: number of loop iterations
1250 REM MODE$: holds flag for additive/subtractive mode
1260 REM
1270 REM Exiting -
1280 REM none
1290 REM
1300 REM Local -
1310 REM ALTER: stores current sequence length
1320 REM SHORT: holds number of values to add/subtract
1330 REM ITER: counts cycles, controls loop growth/trunc.
1340 REM COPIES: loop index
1350 REM ========================================================
1360 SHORT = FACTOR
1370 ITER = PERIOD
1380 IF MODE$ = "A" THEN ALTER = STARTNUM ELSE ALTER = NOTES
1390 IF MODE$ = "S" THEN PRINT "SUBTRACTIVE MODE -" ELSE PRINT "ADDITIVE MODE -"
1400 FOR COPIES = 0 TO MANY-1
1410 IF COPIES < ITER THEN 1440
1420 IF MODE$ = "A" THEN ALTER = STARTNUM + SHORT ELSE ALTER = NOTES - SHORT
1430 IF ALTER > NOTES THEN ALTER = NOTES
1440 FOR DUP = 1 TO ALTER
1450 PRINT NUM(DUP);
1460 NEXT DUP
1470 PRINT "/**/";
1480 IF COPIES = MANY THEN 1530
1490 IF COPIES < ITER THEN 1520
1500 SHORT = SHORT + FACTOR
1510 ITER = ITER + PERIOD
1520 NEXT COPIES
1530 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM X(20),TEMP(20)
140 NUMVALS = 20
150 FACTOR = 6
160 MANY = 6
170 REVERSE$ = "Y"
180 PRINT "ORIGINAL SEQUENCE -"
190 FOR J = 1 TO NUMVALS
200 PRINT J;
210 X(J) = J '<< load array with number sequence
220 NEXT J
230 PRINT
240 PRINT MANY;"COPIES TO BE MADE. DURING EACH CYCLE"
250 PRINT FACTOR;"VALUES WILL BE SHIFTED, REVERSE ORDER -"
260 GOSUB 1000 '<< call loop generator
270 END
1000 REM ========================================================
1010 REM *******************>> LOOPGEN2 <<***********************
1020 REM ========================================================
1030 REM This is a pattern/process oriented subroutine which
1040 REM shifts a specific number of values from the end of
1050 REM a group while generating a given number of loop copies.
1060 REM The shifted values may be placed in reverse order.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM X(): holds original number sequence
1110 REM NUMVALS: total in sequence
1120 REM FACTOR: number of values to shift
1130 REM MANY: number of loops to return
1140 REM REVERSE$: flag to reverse shifted values
1150 REM Exiting -
1160 REM none (original X() array contents are destroyed)
1170 REM
1180 REM Local -
1190 REM TEMP(): stores values to be shifted
1200 REM X(): stores loops, rearranged each cycle
1210 REM COPIES: loop index
1212 REM HOLD: loop index, pointer to array TEMP()
1220 REM GROUP: loop index
1230 REM SHIFT: loop index, pointer to array X()
1240 REM REPLACE: loop index, pointer to array X()
1250 REM CURRLOOP: loop index, pointer to array X()
1260 REM ========================================================
1270 FOR COPIES = 1 TO MANY
1280 REM >>> remove array values to be shifted
1290 FOR HOLD = 0 TO FACTOR - 1
1300 TEMP(HOLD + 1) = X(NUMVALS - HOLD)
1310 NEXT HOLD
1320 REM >>> slide remaining values to end of array
1330 FOR GROUP = 1 TO FACTOR
1340 FOR SHIFT = NUMVALS TO 1 STEP - 1
1350 X(SHIFT) = X(SHIFT - 1)
1360 NEXT SHIFT
1370 NEXT GROUP
1380 REM >>> place values to be moved at head of array
1390 REM >>> if flagged, reverse them
1400 FOR REPLACE = 1 TO FACTOR
1410 IF REVERSE$ = "Y" THEN X(REPLACE) = TEMP(REPLACE) ELSE X(REPLACE) = TEMP(FACTOR + 1 - REPLACE)
1420 NEXT REPLACE
1430 PRINT "/*";
1440 FOR CURRLOOP = 1 TO NUMVALS
1450 PRINT X(CURRLOOP);
1460 NEXT CURRLOOP
1470 PRINT "*/"
1480 NEXT COPIES
1490 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Markov)
130 REM =========================================================
140 DIM CYCLE(5000), SEED(88), FREQ(88)
150 ORDER = 2 '<<nmbr of preceding terms to sum for next term
160 MODULUS = 12 '<< set modulus of residue cycle
170 APPLY$ = "INCLUSIVE" '<< apply to all seeds
180 FOR J = 1 TO 2 '<< generate 2 separate cycles
190 PRINT APPLY$;" ADDITION; SEEDS ARE :";
200 FOR J1 = 1 TO ORDER
210 READ SEED(J1)
220 PRINT SEED(J1); '<< send seeds to screen
230 NEXT J1
240 REM ++++++++++++++++++++
250 DATA 0,1,1,4,5
260 REM ++++++++++++++++++++
270 PRINT
280 GOSUB 1000 '<< call Markovian summation subroutine
290 PRINT
300 PRINT TOTAL; " - MEMBER CYCLE:"
310 PRINT
320 FOR J1 = 1 TO TOTAL
330 PRINT CYCLE(J1), '<< display completed cycle
340 NEXT J1
350 PRINT : PRINT
360 PRINT "FREQUENCY TABLE:"
370 PRINT
380 FOR J1 = 1 TO MODULUS
390 PRINT (J1-1); ":"; FREQ(J1),
400 NEXT J1
410 ORDER = 3 '<< number of preceding terms to sum
420 APPLY$ = "EXCLUSIVE" '<< add outside seed pairs only
430 PRINT
440 PRINT
450 NEXT J
460 END
1000 REM ========================================================
1010 REM MARKOV
1020 REM ========================================================
1030 REM Markovian Integer Summation Residual Cycle Generator
1040 REM ========================================================
1050 REM Variable Descriptions
1060 REM Entering -
1070 REM ORDER: number of immediately preceding terms
1080 REM whose sum determines next term
1090 REM MODULUS: Integer-range modulus; cycle-creating
1100 REM factor to be imposed on each sum
1110 REM SEED(): array of seeds (initial "Order" number
1120 REM of integers to be summed)
1130 REM APPLY$: string to signal inclusive or exclusive
1140 REM addition of series seeds
1150 REM Exiting -
1160 REM CYCLE(): array holding generated integer cycle
1170 REM FREQ(): array of integer occurrence frequencies
1180 REM Local -
1190 REM NXTERM: next term to be computed
1200 REM TOTAL: total number of terms generated
1210 REM K9: loop index
1220 REM L9: loop index
1230 REM ========================================================
1240 FOR K9 = 1 TO ORDER
1250 CYCLE(K9) = SEED(K9) '<< start cycle with seeds
1260 NEXT K9
1270 TOTAL = ORDER
1280 FOR K9 = 1 TO 5000 '<< compute next new term
1290 NXTERM = SEED(ORDER)
1300 FOR L9 = 1 TO (ORDER-1)
1310 NXTERM = NXTERM + SEED(L9)
1320 NEXT L9
1330 IF APPLY$ = "EXCLUSIVE"
THEN NXTERM = SEED(ORDER) + SEED(1)
1340 NXTERM = NXTERM - INT(NXTERM/MODULUS) * MODULUS
1350 CYCLE(K9+ORDER) = NXTERM
1360 FOR L9 = 1 TO (ORDER-1)
1370 SEED(L9) = SEED(L9+1) '<< update seeds
1380 NEXT L9
1390 SEED(ORDER) = NXTERM
1400 TOTAL = TOTAL + 1
1410 FOR L9 = 1 TO ORDER
1420 IF SEED(L9) <> CYCLE(L9) THEN 1470 '<< finished?
1430 NEXT L9
1440 L9 = ORDER
1450 K9 = 5000
1460 TOTAL = TOTAL - ORDER
1470 NEXT K9
1475 GOSUB 2000 ' << call zeromat
1480 FOR K9 = 1 TO MODULUS '<< compute occurrence frequencies
1490 FOR L9 = 1 TO TOTAL
1500 IF CYCLE(L9) + 1 = K9 THEN FREQ(K9) = FREQ(K9) + 1
1510 NEXT L9
1520 NEXT K9
1530 RETURN
2000 REM================================================= CTB1.9
2010 REM *******************>> ZEROMAT <<***********************
2020 REM =======================================================
2030 FOR K9 = 1 TO MODULUS
2040 FREQ(K9) = 0
2050 NEXT K9
2060 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM W(10,10)
140 COUNT = 0
150 TOTAL = 40
160 XLOC = 5 : YLOC = 5 '<< matrix start coordinates
170 ROWS = 10 : COLS = 10
180 PRINT "THE MATRIX FOR THIS RANDOM WALK -"
190 FOR J1 = 1 TO ROWS
200 FOR J2 = 1 TO COLS
210 W(J1,J2)=((J1-1) * COLS) + J2
220 COUNT = COUNT + 1
230 IF (COUNT/COLS) = J1 THEN PRINT W(J1,J2)ELSE PRINT W(J1,J2);
240 IF COUNT < 9 THEN PRINT " ";
250 NEXT J2
260 NEXT J1
270 PRINT "START COORDINATES ARE: ROW ";XLOC;"COLUMN ";YLOC
280 RANDOMIZE
290 GOSUB 1000 '<< call matrix walk
300 END
1000 REM ========================================================
1010 REM *********************>> MATWALK <<**********************
1020 REM ========================================================
1030 REM This subroutine simulates a random walk within the
1040 REM boundaries of a two-dimensional matrix. The walker
1050 REM is free to step up, down, sideways, or diagonally.
1060 REM By shaping the matrix in various proportions, the
1070 REM user can influence the numeric interval sequence.
1080 REM Applied to pitch content, the effect is one of
1090 REM generating melodies with interval class succession
1100 REM which vary with the matrix shape & size.
1110 REM ========================================================
1120 REM Variable Descriptions
1130 REM Entering -
1140 REM W(n,n): random walk matrix
1150 REM TOTAL: number of random steps to be taken
1160 REM XLOC: stores current location on horizontal
1170 REM YLOC: stores current location on vertical
1180 REM ROWS: length of matrix
1190 REM COLS: width of matrix
1200 REM Exiting -
1210 REM none (subroutine is procedural)
1220 REM Local -
1230 REM XSTEP: random number -1, 0, or + 1
1240 REM YSTEP: random number -1. 0, or + 1
1250 REM K9: loop index
1260 REM ========================================================
1270 FOR K9 = 1 TO TOTAL
1280 PRINT W(XLOC,YLOC);" ";
1290 XSTEP = INT(RND * 3) - 1
1300 YSTEP = INT(RND * 3) - 1
1310 XLOC = XLOC + XSTEP
1320 YLOC = YLOC + YSTEP
1330 IF XLOC <= 0 THEN XLOC = 2 ELSE IF XLOC > ROWS THEN XLOC = ROWS - 1
1340 IF YLOC <= 0 THEN YLOC = 2 ELSE IF YLOC > COLS THEN YLOC = COLS - 1
1350 NEXT K9
1360 RETURN
100 REM =========================================================
110 REM PROGRAM DRIVER
120 REM (Meline)
130 REM =========================================================
140 DIM NOTE$(100),P$(84)
150 RANDOMIZE
160 TOTAL = 10 '<< length of sequence
170 SMALL = 1
180 LARGE = 3
190 UP = 80
200 REST = 0
210 START = 48
220 GOSUB 3010 '<< call pitch table
230 FOR J = 1 TO 4
240 NOTE$(1) = P$(START)
250 NOTE = START
260 PRINT "PASS";J
270 PRINT "TOTAL =";TOTAL;";SMALL=";SMALL;";LARGE =";LARGE;";UP =";UP;";REST=";REST;";START =";START
280 PRINT NOTE$(1);" ";
290 FOR J1 = 2 TO TOTAL
300 GOSUB 1000 '<<call rest probability
310 IF FLAG = 0 THEN GOSUB 2000 '<< call interval generator
320 PRINT NOTE$(J1);" "; '<< send array to screen
330 NEXT J1
340 PRINT
350 TOTAL = TOTAL + 10
360 SMALL = SMALL + 1
370 LARGE = LARGE + 2
380 INTVALRANGE = LARGE-SMALL+1
390 UP = UP - 20
400 REST = REST + 10
410 NEXT J
420 END
1000 REM =========================================================
1010 REM ***********************>> REST <<************************
1020 REM =========================================================
1030 REM This subroutine is similar to ADDORN, in that
1040 REM it checks a rest percentage threshold value
1050 REM before deciding whether to insert a rest note
1060 REM =========================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM REST: threshold test value (% of rest)
1100 REM NOTE$(): array to receive rest string (if selected)
1110 REM P$(0): pitchtable array address holding rest string
1120 REM J1: pointer to NOTE$() array
1130 REM Exiting -
1140 REM FLAG: signal to DRIVER not to call pitch generator
1150 REM NOTE$():
1160 REM Local - none
1170 REM =========================================================
1180 FLAG = 0
1190 IF RND * 100 <= REST THEN NOTE$(J1) = P$(0) : FLAG = 1
1200 RETURN
2000 REM =========================================================
2010 REM *********************>> MELINT <<************************
2020 REM =========================================================
2030 REM This subroutine resembles RDINTCHD in concept.
2040 REM However, it generates an interval-contained
2050 REM melodic sequence which is bi-directional
2060 REM as opposed to RDINTCHD's harmonic, unidirectional
2070 REM orientation.
2080 REM =========================================================
2090 REM Variable Descriptions
2100 REM Entering -
2110 REM SMALL: smallest allowable interval-size
2120 REM INTVALRANGE: span of allowable interval-sizes
2130 REM NOTE: most recent note generated
2140 REM UP: probability of upward interval motion
2150 REM NOTE$(): array to be filled with notes/rests
2160 REM P$(): pitch table array
2170 REM J1: pointer to NOTE$() array
2180 REM Exiting -
2190 REM NOTE$():
2200 REM Local -
2210 REM U: range-controlled random integer
2220 REM =======================================================
2230 U = INT(RND * INTVALRANGE) + SMALL
2240 IF RND * 100 <= UP THEN NOTE = NOTE + U ELSE NOTE = NOTE - U
2250 IF NOTE > 84 THEN NOTE = NOTE - 12 ELSE IF NOTE < 1 THEN NOTE = NOTE + 12 '<< in bounds?
2260 NOTE$(J1) = P$(NOTE)
2270 RETURN
3000 REM =========================================================
3010 REM ********************>> PITCHTAB <<***********************
3020 REM =========================================================
3030 NOTE$ = " CC# DD# E FF# GG# AA# B"
3040 OCTAVE$ = "1234567"
3050 P$(0) = " R "
3060 FOR K9 = 1 TO 7
3070 FOR L9 = 1 TO 12
3080 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
3090 NEXT L9
3100 NEXT K9
3110 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Modops)
130 REM =========================================================
140 DIM P$(12)
150 DIM X(12),Y(12)
160 RANDOMIZE
170 TOTAL = 12
180 OP = 5 '<< value for m5 operation
190 GOSUB 1000 '<< call pitch table
200 GOSUB 2000 '<< call random shuffle
210 PRINT
220 PRINT "RANDOM-ORDER 12-TONE SET --"
230 FOR J = 0 TO TOTAL-1
240 PRINT P$(X(J));" "; '<< random 12-tone set to screen
250 NEXT J
260 PRINT : PRINT
270 FOR J = 1 TO 2
280 GOSUB 3000 '<< call m5/m7 permutation
290 PRINT "THE PERMUTATION RESULTING FROM ";"M";OP;" OPERATION"
300 FOR J1 = 0 TO TOTAL-1
310 PRINT P$(Y(J1));" "; '<< send perm to screen
320 NEXT J1
330 PRINT : PRINT
340 OP = 7 '<< value for m7 operation
350 NEXT J
360 END
1000 REM ========================================================
1010 REM *******************>> PITCHTAB <<***********************
1020 REM (modified to load pitch classes only)
1030 REM ========================================================
1040 FOR J = 0 TO TOTAL-1
1050 X(J) = J '<< load set elements
1060 READ P$(J) '<< load pitch class equivalents
1070 NEXT J
1080 REM+++++++++++++++++++++++++++++++++
1090 DATA C,C#,D,D#,E,F,F#,G,G#,A,A#,B
1100 REM+++++++++++++++++++++++++++++++++
1110 RETURN
2000 REM ========================================================
2010 REM ********************>> CONSHUFL <<**********************
2020 REM ========================================================
2030 FOR K9 = 0 TO TOTAL-1
2040 R9 = INT(RND * TOTAL)
2050 S9 = X(K9)
2060 X(K9) = X(R9)
2070 X(R9) = S9
2080 NEXT K9
2090 RETURN
3000 REM ========================================================
3010 REM *********************>> M5SETM7 <<**********************
3020 REM ========================================================
3030 REM This subroutine outputs a permutation of an input
3040 REM set (series) by the "M5" or "M7" operation.
3050 REM ========================================================
3060 REM Variable Descriptions
3070 REM Entering -
3080 REM X(): array holding random 12-tone set
3090 REM OP: value for m5 or m7 operation
3100 REM Exiting -
3110 REM Y(): array holding m5 or m7 permutation
3120 REM Local -
3130 REM K9: loop index, pointer to X(),Y()
3140 REM =======================================================
3150 FOR K9 = 0 TO 11
3160 Y(K9) = (X(K9) * OP) MOD 12
3170 NEXT
3180 RETURN
100 REM ========================================================
110 REM DRIVER PROGRAM
120 REM ========================================================
125 M = 12 '<< set modulus to 12
130 FOR J = 0 TO 83 '<< values to be converted mod M
140 M = 12 '<< set modulus to 12
150 GOSUB 1000 '<< call mod function
160 PRINT R; '<< send remainder to screen
170 IF R = 11 THEN PRINT '<< start newline
180 NEXT J
190 END
1000 REM ========================================================
1010 REM ********************>> MODULO <<************************
1020 REM ========================================================
1030 REM This subroutine is actually a function which
1040 REM receives an integer and returns the value of the
1050 REM integer modulo n. A more practical alternative
1060 REM is to code it as a user-defined funcion:
1070 REM DEF FNM(J,M) = J - INT(J / M) * M
1080 REM ========================================================
1090 REM
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM M: the modulus to be applied
1130 REM J: the integer to be returned mod M
1140 REM Exiting -
1150 REM R: the remainder mod I to be returned
1160 REM Local -
1170 REM none
1180 REM
1190 REM ========================================================
1200 R = J-INT(J/M)*M
1210 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM Motforms
130 REM =========================================================
140 DIM X(15),Y(15),P$(84)
150 RANDOMIZE(967)
160 GOSUB 1000 '<< call pitch table
170 TOTAL = 15
180 PRINT "ORIGINAL PITCH MOTIF --"
190 FOR J = 1 TO TOTAL
200 X(J) = INT(RND * 12) + 1
210 PRINT P$(X(J));" "; '<< random motif to screen
220 NEXT J
230 PRINT
240 GOSUB 3000 '<< call retrograde
250 PRINT "THE RETROGRADE MOTIF --"
260 GOSUB 2000 '<< call table print
270 PRINT
280 GOSUB 4000 '<< call motif inversion
290 PRINT "THE INVERTED MOTIF --"
300 GOSUB 2000 '<< call table print
310 PRINT
320 INTVAL = 1 '<< (set transposition interval
330 PRINT "ORIGINAL MOTIF TRANSPOSITIONS"
340 FOR J = 1 TO 11
350 PRINT "NUMBER ";J
360 GOSUB 5000 '<< call motif transposition
370 GOSUB 2000 '<< call table print
380 PRINT
390 INTVAL = INTVAL + 1
400 NEXT J
410 END
1000 REM =========================================================
1010 REM ********************>> PITCHTAB <<***********************
1020 REM =========================================================
1030 NOTE$ = " CC# DD# E FF# GG# AA# B"
1040 OCTAVE$ = "1234567"
1050 FOR K9 = 1 TO 7
1060 FOR L9 = 1 TO 12
1070 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
1080 NEXT L9
1090 NEXT K9
1100 RETURN
2000 REM ========================================================
2010 REM ********************>> TABLPRNT <<**********************
2020 REM ========================================================
2030 FOR K9 = 1 TO TOTAL
2040 PRINT P$(Y(K9));" ";
2050 NEXT K9
2060 RETURN
3000 REM ========================================================
3010 REM *********************>> MOTRETRO <<*********************
3020 REM ========================================================
3030 REM This subroutine accepts an input pitch sequence
3040 REM and outputs its retrograde form.
3050 REM ========================================================
3060 REM Variable Descriptions
3070 REM Entering -
3080 REM X(): prime motif array
3090 REM TOTAL: motif length
3100 REM Exiting -
3110 REM Y(): retrograde motif array
3120 REM Local -
3130 REM L: pointer to Y()
3140 REM K9; loop index, pointer to X()
3150 REM ========================================================
3160 FOR K9 = 1 TO TOTAL
3170 L = TOTAL-K9+1
3180 Y(L)=X(K9)
3190 NEXT K9
3200 RETURN
4000 REM ========================================================
4010 REM ********************>> MOTINVRT <<**********************
4020 REM ========================================================
4030 REM This subroutine accepts an input pitch sequence
4040 REM and outputs its mirror image form.
4050 REM ========================================================
4060 REM Variable Descriptions
4070 REM Entering -
4080 REM X(): prime motif array
4090 REM TOTAL: motif length
4100 REM Exiting -
4110 REM Y(): inverted motif array
4120 REM Local -
4130 REM K9: loop index, pointer to X(),Y()
4140 REM ========================================================
4150 Y(1)=X(1)
4160 FOR K9 = 2 TO TOTAL
4170 Y(K9) = Y(K9-1)-(X(K9)-X(K9-1))
4180 NEXT K9
4190 RETURN
5000 REM ========================================================
5010 REM ********************>> MOTRNPZ <<***********************
5020 REM ========================================================
5030 REM This subroutine transposes an input motif by
5040 REM a specified number of 1/2 steps. Transposition
5050 REM direction is determined by the sign of the
5060 REM transposition interval.
5070 REM ========================================================
5080 REM Variable Descriptions
5090 REM Entering -
5100 REM X(): array holding random motif
5110 REM TOTAL: motif length
5120 REM INTVAL: interval of transposition in 1/2-steps
5130 REM Exiting -
5140 REM Y(): array holding transposed motif
5150 REM Local -
5160 REM K9: loop index, pointer to Y()
5170 REM ========================================================
5180 FOR K9 = 1 TO TOTAL
5190 Y(K9) = X(K9) + INTVAL
5200 NEXT K9
5210 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Normhist)
130 REM =========================================================
140 DIM X(20)
150 RANGE = 20 '<< set random number range 1-20
160 TOTAL = 1000 '<< return 1000 values
170 RANDOMIZE
180 CLS
190 PRINT "INTEGER VALUE";TAB(20);"NORM. VALUE";TAB(40);"BAR MAP"
200 GOSUB 1000 '<< generate frequency table
210 GOSUB 2000 '<< call data normalization
220 GOSUB 3000 '<< call bargraph display
230 END
1000 REM ========================================================
1010 REM *******************>> FREQTABL <<***********************
1020 REM ========================================================
1030 FOR K9 = 1 TO TOTAL
1040 VALUE = INT(RND * RANGE)+1 '<< gen random value
1050 X(VALUE)=X(VALUE)+1 '<< record occurrence of value
1060 NEXT K9
1070 RETURN
2000 REM SS1ST6 =================================================
2010 REM ********************>> DATANORM <<**********************
2020 REM ========================================================
2030 REM This subroutine compresses wide-range data to
2040 REM fit within the range of 0 to 1. It is especially
2050 REM helpful when printing histograms of huge amounts
2060 REM of data which would otherwise cause the bars to
2070 REM wrap-around the screen.
2080 REM
2090 REM To adequately test probability distribution
2100 REM functions for musical uses, it often is necessary
2110 REM to generate thousands of values to flesh out a
2120 REM curve. When this is the goal, it is important
2130 REM to observe the shape of the distribution, not
2140 REM specific integer frequencies.
2150 REM =======================================================
2160 REM Variable Descriptions
2170 REM Entering -
2180 REM X(): frequency table to be normalized
2190 REM RANGE: range of integers in frequency table
2200 REM Exiting -
2210 REM X(): normalized frequency table
2220 REM Local -
2230 REM SUM: total of values frequency table
2240 REM K9: loop index,pointer to array X()
2250 REM ========================================================
2260 SUM = 0
2270 FOR K9 = 1 TO RANGE
2280 SUM = SUM + X(K9)
2290 NEXT K9
2300 FOR K9=1 TO RANGE
2310 X(K9) = X(K9)/ SUM
2320 NEXT K9
2330 PRINT
2340 RETURN
3000 REM ========================================================
3010 REM *******************>> BARGRAPH <<***********************
3020 REM (adapted to program specs)
3030 REM ========================================================
3040 FOR K9=1 TO RANGE
3050 MAP = INT(100*X(K9)+.5)
3060 PRINT K9;"=";TAB(20);X(K9);TAB(40);STRING$(MAP,">")
3070 NEXT K9
3080 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM GAMINTS(12),P$(96)
140 GAMUTS = 3 '<< number of unique gamuts
150 RANDOMIZE
160 SEGTOTAL = 3 '<< # of scale segments to return per gamut
170 INTOTAL = 6 '<< number of intervals in scale
180 GOSUB 2000 '<< call pitch table
190 FOR J1 = 1 TO GAMUTS
200 PRINT "SCALE GAMUT";J1;"INTERVAL SET ---";
210 HIGHOCTAVE = 7
220 EXCEED = 0
230 REM >>> select an octave-containable (scale) interval set
240 FOR J2 = 1 TO INTOTAL
250 GAMINTS(J2) = INT(RND * 3) + 1
260 EXCEED = EXCEED + GAMINTS(J2)
270 IF EXCEED > 11 THEN 220 '<< within octave?
280 NEXT J2
290 FOR J = 1 TO INTOTAL
300 PRINT GAMINTS(J);
310 NEXT J
320 PRINT
330 GOSUB 1000 '<< call scale generator
340 NEXT J1
350 END
1000 REM ========================================================
1010 REM *******************>> OCTSCALE <<***********************
1020 REM ========================================================
1030 REM This subroutine generates octave-repeating
1040 REM scales from a set of intervals.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM Entering -
1080 REM P$(): pitch name table
1090 REM GAMINTS(): array of interval sizes
1100 REM TONIC: lowest scale/gamut member
1110 REM HIGHOCTAVE: upper register octave limit
1120 REM INTOTAL: number of intervals in GAMINTS()
1130 REM SEGTOTAL: numeric length of scale segment
1140 REM Exiting -
1150 REM none (subroutine is procedural)
1160 REM Local -
1170 REM COUNT: tabulates chordtone generation
1180 REM SCALETONE: next chord/gamut member
1190 REM STARTOCTAVE: scale segment beginning register
1200 REM SCALEMEMS: number of tones in scale segment
1210 REM K9: loop index
1220 REM L9: loop index, pointer to array GAMINTS()
1230 REM M9: loop index, pointer to array P$()
1240 REM ========================================================
1250 FOR K9 = 1 TO SEGTOTAL
1260 TONIC= INT(RND * 12)+1
1270 STARTOCTAVE = INT(RND * 3)+1
1280 SCALEMEMS = INT(RND * 17)+4
1290 PRINT "scale segment";K9;"=";SCALEMEMS;"notes"
1300 COUNT = 0
1310 FOR L9 = STARTOCTAVE TO HIGHOCTAVE
1320 SCALETONE = TONIC
1330 FOR M9 = 1 TO INTOTAL+1
1340 PRINT P$(SCALETONE + ((L9-1) * 12));" ";
1350 COUNT = COUNT + 1
1360 IF COUNT = SCALEMEMS THEN 1410
1370 IF M9 > INTOTAL THEN 1400
1380 SCALETONE = SCALETONE + GAMINTS(M9)
1390 NEXT M9
1400 NEXT L9
1410 PRINT
1420 NEXT K9
1430 PRINT
1440 RETURN
2000 REM ========================================================
2010 REM *******************>> PITCHTAB <<***********************
2020 REM ========================================================
2030 REM This subroutine initializes a pitch data table
2040 REM corresponding to integer values 1-n.
2050 REM ========================================================
2060 NOTE$ = " CC# DD# E FF# GG# AA# B"
2070 OCTAVE$ = "1234567"
2080 FOR K9 = 1 TO 7
2090 FOR L9 = 1 TO 12
2100 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
2110 NEXT L9
2120 NEXT K9
2130 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Ornament)
130 REM =========================================================
140 DIM P$(84),TEMP(200),NOTE$(500)
150 DIM DEC(6),ORN(4),EMBTABLE(4)
160 ORN(1) = 1002 : ORN(2) = 2003
170 ORN(3) = 2004 : ORN(4) = 4006
180 DEC(1) = -1 : DEC(2) = 0 : DEC(3) = -1
190 DEC(4) = 0 : DEC(5) = 1 : DEC(6) = 0
200 DECO = 100 '<< % of sequence notes to decorate
210 RANDOMIZE(-11001)
220 GOSUB 3000 '<< call pitch table
230 MELENGTH = 20
240 PRINT "UNEMBELLISHED PITCH SEQUENCE =";MELENGTH;"NOTES --"
250 FOR J = 1 TO MELENGTH
260 TEMP(J) = INT(RND * 81) + 2
270 PRINT P$(TEMP(J));" "; '<< random sequence to screen
280 NEXT J
290 PRINT : PRINT
300 GOSUB 1000 '<< call ornament selection
310 PRINT "EMBELLISHED PITCH SEQUENCE =";T3;"NOTES ---"
320 FOR J = 0 TO T3
330 PRINT NOTE$(J);" "; '<< embellished seq. to screen
340 NEXT J
350 END
1000 REM ========================================================
1010 REM *******************>> ORNSELEC <<***********************
1020 REM ********* (variation of PROBTABL subroutine) **********
1030 REM ========================================================
1040 REM This subroutine loads a probability table
1050 REM with weights for each of 4 ornament patterns,
1060 REM then calls ADDORN subroutine to interpolate
1070 REM the selected embellishments.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM P$(): pitch table array
1120 REM TEMP(): stores sequence prior to decoration
1130 REM MELENGTH: number of notes in original sequence
1140 REM DECO: percentage of sequence notes to decorate
1150 REM Exiting -
1160 REM NOTE$(): stores final, embellished sequence
1170 REM T3: final number of notes in sequence
1180 REM Local -
1190 REM EMBTABLE(): stores ornament pattern probabilities
1200 REM WSUM: sum of ornament probability weights
1210 REM K9: loop index, pointer to array TEMP()
1220 REM ========================================================
1230 T3 = 0
1240 IF DECO = 0 THEN 1360
1250 PRINT "ORNAMENTS BEING ADDED (PROB. WEIGHTS 4,3,2,1) ---"
1260 PRINT "1) _ - 2) - _ 3) - _ - 4) _ - _"
1270 WSUM = 0
1280 FOR K9 = 1 TO 4
1290 READ EMBTABLE(K9)
1300 EMBTABLE(K9) = EMBTABLE(K9) + WSUM
1310 WSUM = EMBTABLE(K9)
1320 NEXT K9
1330 REM +++++++++++++++++++
1340 DATA 4,3,2,1
1350 REM +++++++++++++++++++
1360 FOR K9 = 1 TO MELENGTH
1370 IF RND * 100 > DECO THEN NOTE$(T3) = P$(TEMP(K9)) ELSE GOSUB 2000
1380 T3 = T3 + 1
1390 NEXT K9
1400 PRINT
1410 RETURN
2000 REM ========================================================
2010 REM *********************>> ADDORN <<***********************
2020 REM ========================================================
2030 REM This subroutine adds selected embellishment
2040 REM patterns to a pre-existant melodic sequence.
2050 REM In the process, the sequence is transferred
2060 REM to a pitch character string array.
2070 REM ========================================================
2080 REM Variable Descriptions
2090 REM Entering -
2100 REM P$(): pitch table array
2110 REM TEMP(): stores sequence prior to decoration
2120 REM EMBTABLE():
2130 REM ORN(): array of ornament patterns
2140 REM DEC(): array of values for pattern reference
2150 REM NOTE$(): stores final, embellished sequence
2160 REM WSUM: sum of ornament probability weights
2170 REM K9: pointer to array TEMP()
2180 REM Exiting -
2190 REM NOTE$(): (above)
2200 REM T3: pointer to array NOTE$()
2210 REM Local -
2220 REM I8: loop index, pointer to array DEC()
2230 REM I9: loop index, pointer to array DEC()
2240 REM M9: loop index, pointer to array ORN()
2250 REM N9: loop index, pointer to array DEC()
2260 REM ========================================================
2270 FOR M9 = 1 TO 4
2280 IF RND * WSUM > EMBTABLE(M9) THEN 2350
2290 I8 = INT(ORN(M9) / 1000) : I9 = CINT((ORN(M9) / 1000 - INT(ORN(M9) / 1000)) * 1000)
2300 FOR N9 = I8 TO I9
2310 NOTE$(T3) = P$(TEMP(K9) + DEC(N9))
2320 T3 = T3 + 1
2330 NEXT N9
2340 RETURN 1390
2350 NEXT M9
2360 RETURN 1390
3000 REM =========================================================
3010 REM ********************>> PITCHTAB <<***********************
3020 REM =========================================================
3030 REM This subroutine initializes a pitch data table
3040 REM corresponding to integer values 1-n.
3050 REM =========================================================
3060 NOTE$ = " CC# DD# E FF# GG# AA# B"
3070 OCTAVE$ = "1234567"
3080 FOR K9 = 1 TO 7
3090 FOR L9 = 1 TO 12
3100 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
3110 NEXT L9
3120 NEXT K9
3130 RETURN
100 REM ========================================================
110 REM DRIVER PROGRAM
120 REM (Partspan)
130 REM ========================================================
140 DIM P$(84),NOTE(48),PART(4),ADJUST(4)
150 CHORDLENGTH = 48 '<< pitchbank
160 VOICES = 4 '<< nmbr of parts
170 MELENGTH = 30 '<< notes in each derived part
180 RANDOMIZE
190 FOR J = 1 TO CHORDLENGTH
200 NOTE(J) = J '<< load pitchbank pointers
210 NEXT J
220 GOSUB 2000 '<< call pitch table
230 PRINT "PITCHBANK UPON WHICH MELODIES WILL BE BASED --"
240 FOR J = 1 TO CHORDLENGTH
250 PRINT P$(J);" "; '<< send pitchbank to screen
260 NEXT J
270 PRINT : PRINT
280 GOSUB 1000 '<< call part range computation
290 FOR J1 = 1 TO 2
300 IF J1 = 2 THEN PRINT "PASS 2, INTERLOCKING -" : D$ = "I" ELSE PRINT "PASS 1, STRATIFIED -" : D$ = "S"
310 FOR J2 = 1 TO VOICES
320 PRINT "VOICE";J2;"MELODY"
330 PRINT "RANGE =";P$(ADJUST(J2));" TO ";
340 PRINT P$(ADJUST(J2) + PART(J2) - 1)
350 FOR J3 = 1 TO MELENGTH
360 R = INT(RND * PART(J2)) + ADJUST(J2)
370 PRINT P$(NOTE(R));" ";
380 NEXT J3
390 PRINT
400 NEXT J2
410 PRINT
420 NEXT J1
430 END
1000 REM =======================================================
1010 REM ********************>> PARTSPAN <<*********************
1020 REM =======================================================
1030 REM This subroutine computes stratified or interlocking
1040 REM instrumental part ranges in reference to a pitch
1050 REM bank which will be used to generate melodic lines.
1060 REM =======================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM VOICES: number of part ranges
1100 REM CHORDLENGTH: number of notes in source pitch bank
1110 REM D$: flag to indicate stratified or interlocking
1120 REM Exiting -
1130 REM ADJUST(): array of part low pitches
1140 REM PART(): array of part ranges
1150 REM Local -
1160 REM SPAN: subdivision of total pitch bank range
1170 REM EXTRA: any remainder from subdivision
1180 REM COMP: compensatory value added to part(s)
1190 REM K9: loop index, pointer to arrays PART(),ADJUST()
1200 REM =======================================================
1210 SPAN = INT(CHORDLENGTH / VOICES)
1220 EXTRA = CHORDLENGTH-(VOICES*SPAN)
1230 FOR K9 = 1 TO VOICES
1240 IF EXTRA <= 0 THEN COMP = 0 ELSE COMP = 1
1250 PART(K9) = SPAN + COMP
1260 EXTRA = EXTRA - 1
1270 ADJUST(1) = 1
1280 IF K9 < VOICES THEN ADJUST(K9+1) = ADJUST(K9) + PART(K9)
1290 NEXT K9
1300 IF D$ = "S" THEN 1350
1310 REM >>> interlock part pitch ranges
1320 FOR K9 = 1 TO VOICES-1
1330 PART(K9) = PART(K9) + INT(PART(K9) * .5)
1340 NEXT K9
1350 RETURN
2000 REM ========================================================
2010 REM ********************>> PITCHTAB <<**********************
2020 REM ========================================================
2030 REM This subroutine initializes a pitch data table
2040 REM corresponding to integer values 1-n.
2050 REM ========================================================
2060 NOTE$ = " CC# DD# E FF# GG# AA# B"
2070 OCTAVE$ = "1234567"
2080 FOR K9 = 1 TO 7
2090 FOR L9 = 1 TO 12
2100 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
2110 NEXT L9
2120 NEXT K9
2130 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Permutot)
130 REM =========================================================
140 ELEMENTS = 1
150 MANY = 1
160 FOR J = 1 TO 10
170 GOSUB 1000 '<< call combinations
180 PRINT "PERMUTATIONS OF";ELEMENTS;"THINGS TAKEN";MANY;"AT A TIME IS";PERMUTS
190 ELEMENTS= ELEMENTS+ 3
200 MANY = MANY + 2
210 NEXT J
220 END
1000 REM SS2ST6 =================================================
1010 REM ********************>> PERMUTS <<***********************
1020 REM ========================================================
1030 REM This subroutine computes the number of possible
1040 REM permutations of n elements taken n at a time.
1050 REM It relies on Stirling's approximation to calculate
1060 REM the requisite factorials.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM ELEMENTS: nunber of items
1110 REM MANY: taken at a time
1120 REM Exiting -
1130 REM PERMUTS : permutation of ELEMENTS, taken MANY at
1140 REM a time
1150 REM Local -
1160 REM NUM:
1170 REM ELEMFACT: log of ELEMENTS factorial
1180 REM MANYFACT: log of MANY factorial
1190 REM ========================================================
1200 NUM = ELEMENTS
1210 GOSUB 2000 '<< call Stirling's approximation
1220 ELEMFACT = APPR
1230 NUM = ELEMENTS - MANY
1240 GOSUB 2000 '<< call Stirling's approximation
1250 MANYFACT = APPR
1260 PERMUTS = INT(EXP(ELEMFACT-MANYFACT)+.5)
1270 RETURN
2000 REM ========================================================
2010 REM ********************>> STIRLING <<**********************
2020 REM ========================================================
2030 APPR = 1
2040 IF NUM <= 0 THEN APPR = 0 : RETURN
2050 FOR K9 = 1 TO 10
2060 APPR = APPR * K9
2070 IF NUM = K9 THEN APPR = LOG(APPR) : RETURN
2080 NEXT K9
2090 APPR = LOG(6.283186)/2+LOG(NUM)*(NUM+.5)-NUM+1/(12*NUM)
2100 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM P$(84) '<< prepare array to hold 7 octaves
140 GOSUB 1000 '<< initialize pitch table
150 FOR J = 1 TO 84
160 PRINT "NUM";J;"="; '<< send a number to screen
170 PRINT P$(J), '<< send corresponding pitch to screen
180 NEXT J
190 END
1000 REM =========================================================
1010 REM ********************>> PITCHTAB <<***********************
1020 REM =========================================================
1030 REM This subroutine initializes a pitch data table
1040 REM corresponding to integer values 1-n.
1050 REM =========================================================
1060 REM Variable Descriptions
1070 REM
1080 REM Entering -
1090 REM none
1100 REM
1110 REM Exiting -
1120 REM P$(): hold pitch element table
1130 REM
1140 REM Local -
1150 REM NOTE$: char string holding pitch class names
1160 REM OCTAVE$: char string holding octave registers
1170 REM K9: loop index, pointer to NOTE$ substring
1180 REM L9: loop index, pointer to OCTAVE$ substring
1190 REM
1200 REM =========================================================
1210 NOTE$ = " CC# DD# E FF# GG# AA# B"
1220 OCTAVE$ = "1234567"
1230 FOR K9 = 1 TO 7
1240 FOR L9 = 1 TO 12
1250 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
1260 NEXT L9
1270 NEXT K9
1280 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Poisson)
130 REM =========================================================
140 DIM X(100)
150 RANDOMIZE
160 TOTAL = 100
165 SPREAD = 5
170 GOSUB 1000 '<< call Poisson distribution function
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM ********************>> POISSON <<***********************
1020 REM ========================================================
1030 REM The Poisson Probability Distribution returns
1040 REM non-negatve, random-order, integers. The control
1050 REM variable, SPREAD, determines the distribution
1060 REM of values.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM TOTAL: length of sequence
1110 REM SPREAD: scaling parameter
1120 REM Exiting -
1130 REM X(): array holding poisson distribution
1140 REM Local -
1150 REM NUM:
1160 REM R9: uniform random number
1170 REM T9: while loop limit
1180 REM K9: loop index, pointer to array X()
1190 REM ========================================================
1200 FOR K9 = 1 TO TOTAL
1210 NUM = 0
1220 R9 = RND
1230 T9 = EXP(-SPREAD)
1240 WHILE R9 > T9
1250 NUM = NUM + 1
1260 R9 = R9 * RND
1270 WEND
1280 X(K9) = NUM
1290 NEXT K9
1300 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Polyrhy)
130 REM =========================================================
140 DIM DUR(100), FRACTION$(100)
150 RANDOMIZE
160 TOTAL = 10
170 M1= 3
180 LEVEL = 1
190 TIMESCALE = 10
200 FOR J = 1 TO 4
210 PRINT "PASS ";J
220 PRINT "LENGTH OF RHYTHM SEQUENCE = ";TOTAL
230 PRINT "MEDIAN =";M1
240 PRINT "TIMESCALE = ";TIMESCALE;"(scale = 1-10)"
250 PRINT "LEVEL = ";LEVEL;
260 PRINT "(from a choice of 1-2-4-8)"
270 GOSUB 1000
280 FOR J1 = 1 TO TOTAL
290 PRINT FRACTION$(J1);
300 NEXT J1
310 PRINT:PRINT
320 LEVEL = LEVEL + LEVEL
330 TOTAL = TOTAL + 10
340 M1 = M1 + 1
350 NEXT J
360 END
1000 REM ========================================================
1010 REM ********************>> POLYRHY <<***********************
1020 REM ========================================================
1030 REM This subroutine computes random-order rhythm
1040 REM duration sequences on 4 selectable levels of
1050 REM complexity. It produces polyrhythmic/metric
1060 REM output layers which occupy identical time frames;
1070 REM That is, as long as the timescale remains
1080 REM constant, all independent output layers will
1090 REM end synchronously, regardless of metrical
1100 REM orientation (3/4,4/4,5/4,7/4,9/4,etc.).
1110 REM =======================================================
1120 REM Variable Descriptions
1130 REM Entering -
1140 REM TOTAL: length of rhythm sequence
1150 REM TIMESCALE: arbitrary time reference
1160 REM M1: basic metrical unit
1170 REM LEVEL: degree of complexity (1-2-4-8)
1180 REM Exiting - (to DRIVER)
1190 REM FRACTION$(): array storing duration fractions
1200 REM Exiting - (to DURRED subroutine)
1210 REM DUR(): array storing fraction numerators
1220 REM NEWMED: reduced fraction denominator
1230 REM K9:loop index, pointer to DUR()
1240 REM Local -
1250 REM ODD: holds flag for odd number of values
1260 REM SUM: total of micropulses in raw sequence
1270 REM BASE: number of micropulses to distribute
1280 REM MEDIAN: metrical base value (3,4,5,7,9,etc)
1290 REM FACTOR: determinant of rnd generator range
1300 REM RANGE: span of rnd generator
1310 REM WEDGE: low bias of rnd generator
1320 REM RCOMP: rnd generator overrun or underrun
1330 REM U,R0,F0: random values for duration numerators
1340 REM K9: loop index, pointer to DUR(), FRACTION$()
1350 REM L9: loop index, pointer to DUR()
1360 REM ========================================================
1370 ODD = 0
1380 SUM = 0
1390 MEDIAN = M1
1400 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1410 REM Lines 1440-1530 reconcile sequence length with
1420 REM metrical base value and timescale.
1430 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1440 BASE = MEDIAN * TIMESCALE
1450 IF TOTAL = 1 THEN DUR(1) = TIMESCALE : GOTO 1840 ELSE IF TIMESCALE - TOTAL > 0 THEN 1490
1460 FOR K9 = 1 TO 30
1470 IF TOTAL > BASE THEN MEDIAN = MEDIAN * 2 : BASE = BASE * 2 ELSE 1580
1480 NEXT K9
1490 IF BASE/2 <> INT(BASE/2)THEN BASE = BASE - 1 : ODD = M1
1500 FOR K9 = 1 TO 100
1510 IF BASE/2 <> INT(BASE/2)OR MEDIAN/2 <> INT(MEDIAN/2) THEN 1580
1520 IF TOTAL <= BASE / 2 THEN MEDIAN = MEDIAN / 2 : BASE = BASE / 2 ELSE 1580
1530 NEXT K9
1540 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1550 REM Lines 1580-1790 compute micropulse (subdivision)
1560 REM level and generate random-order durations.
1570 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1580 BASE = BASE * LEVEL
1590 MEDIAN = MEDIAN * LEVEL
1600 IF LEVEL = 4 THEN FACTOR = 3 ELSE IF LEVEL = 8 THEN FACTOR = 4 ELSE FACTOR = LEVEL
1610 WEDGE = FACTOR
1620 RANGE = (FACTOR + LEVEL) + INT(BASE/TOTAL)
1630 FOR K9 = 1 TO TOTAL
1640 U = INT(RND * RANGE) + WEDGE
1650 DUR(K9) = U
1660 SUM = SUM + U
1670 NEXT K9
1680 RCOMP = BASE - SUM
1690 FOR K9 = 1 TO 10000
1700 FOR L9 = 1 TO TOTAL
1710 IF RCOMP < 0 THEN 1730
1720 IF RCOMP = 0 THEN 1760 ELSE DUR(L9) = DUR(L9) + 1 : RCOMP = RCOMP - 1 : GOTO 1740
1730 IF DUR(L9) < 2 THEN 1740 ELSE DUR(L9) = DUR(L9) - 1 : RCOMP = RCOMP + 1
1740 NEXT L9
1750 NEXT K9
1760 IF ODD < 1 THEN 1840
1770 R0 = INT(RND * TOTAL) + 1
1780 F0 = INT(RND * TOTAL) + 1
1790 IF TOTAL > 1 AND F0 = R0 THEN 1780 ELSE DUR(R0) = DUR(R0) + DUR(F0) : DUR(F0) = -1
1800 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1810 REM Lines 1140-1880 reduce duration fraction and
1820 REM load the sequence into a character string array
1830 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1840 FOR K9 = 1 TO TOTAL
1850 NEWMED = MEDIAN
1860 IF DUR(K9)/2 = INT(DUR(K9)/2)AND NEWMED/2 = INT(NEWMED/2) THEN GOSUB 2000 '<< call fraction reduction
1870 IF DUR(K9) < 0 THEN FRACTION$(K9) = STR$(1)+"/"+MID$(STR$(ODD),2) ELSE FRACTION$(K9) = STR$(DUR(K9)) + "/" + MID$(STR$(NEWMED),2)
1880 NEXT K9
1890 RETURN
2000 REM ========================================================
2010 REM *****************>> DURRED <<***************************
2020 REM (modified form)
2030 REM ========================================================
2040 DUR(K9) = DUR(K9)/2
2050 NEWMED = NEWMED/2
2060 IF DUR(K9)/2 = INT(DUR(K9)/2) AND NEWMED/2 = INT(NEWMED/2)THEN 2040 ELSE RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Primops)
130 REM =========================================================
140 DIM X(100), Y(100)
150 LOW = 500
160 HIGH = 800
170 PRINT "PRIME NUMBERS WITHIN RANGE ";LOW;"TO";HIGH;" --"
180 GOSUB 1000 '<< call prime interval generator
190 FOR J = 1 TO PCNT
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "NUMERIC INTERVALS BETWEEN PRIMES --"
240 FOR J = 1 TO PCNT-1
250 PRINT Y(J);
260 NEXT J
270 END
1000 REM =========================================================
1010 REM ********************>> PRIMINTV <<***********************
1020 REM =========================================================
1030 REM This subroutine invokes the prime number indicator
1040 REM subroutine to locate primes, then creates two
1050 REM array sequences: 1) a list of the primes, and
1060 REM 2) a list of numeric intervals separating primes.
1070 REM The list can be mapped to various musical parameters,
1080 REM and can be modified in scale by addition or
1090 REM subtraction of a numerical constant.
1100 REM =========================================================
1110 REM Variable Descriptions
1120 REM Entering -
1130 REM LOW: smallest integer within test range
1140 REM HIGH: largest integer within test range
1150 REM PRIM: (from SR 2000) prime flag
1160 REM Exiting -
1170 REM NUM: (to SR 2000) current integer to be tested
1180 REM X(): list of prime numbers
1190 REM Y(): list of numeric intervals between primes
1200 REM Local -
1210 REM PCNT: prime number counter, pointer to X(),Y()
1220 REM =========================================================
1230 PCNT = 0
1240 FOR NUM = LOW TO HIGH
1250 GOSUB 2000 '<< call prime number indicator
1260 IF PRIM <> 1 THEN 1300
1270 PCNT = PCNT + 1
1280 X(PCNT) = NUM
1290 IF PCNT >= 2 THEN Y(PCNT-1) = X(PCNT)-X(PCNT-1)
1300 NEXT NUM
1310 RETURN
2000 REM =======================================================
2010 REM *******************>> PRIMENUM <<**********************
2020 REM =======================================================
2030 REM This subroutine locates and returns prime numbers
2040 REM from a stream of consecutive numbers within a
2050 REM specified range. (Prime numbers are integers
2060 REM which have only themselves or the number 1
2070 REM as a factor.)
2080 REM =======================================================
2090 REM Variable Descriptions
2100 REM Entering -
2110 REM NUM: number to be tested for prime
2120 REM Exiting -
2130 REM PRIM: flag indicating a prime number
2140 REM Local -
2150 REM DIVISOR: loop index, divisor for prime test
2160 REM =======================================================
2170 PRIM = 1
2180 IF NUM = 1 THEN PRIM = 0 : RETURN ELSE IF NUM = 2 OR NUM = 3 THEN RETURN
2190 IF NUM = INT(NUM/2) * 2 THEN PRIM = 0 : RETURN
2200 FOR DIVISOR = 3 TO INT(SQR(NUM)) STEP 2
2210 IF NUM = INT(NUM/DIVISOR) * DIVISOR THEN PRIM = 0 : RETURN
2220 NEXT DIVISOR
2230 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Pstnperm)
130 REM =========================================================
140 DIM SET(12),POSIT(12),CUM(12)
150 RANDOMIZE
160 TOTAL = 12
170 LOW = 1
180 HIGH = 12
190 RANGE = HIGH-LOW+1
200 GOSUB 1000 '<< call series generator
210 PRINT "PRIME ORDER SERIES --"
220 FOR J = 1 TO TOTAL
230 PRINT SET(J);" "; '<< send series to screen
240 NEXT J
250 GOSUB 2000 '<< call position permutator
260 PRINT
270 PRINT "SET PERMUTATION RESULTING FROM ";"SWAP OF PC NMBR AND POSITION
280 FOR J = 1 TO TOTAL
290 PRINT POSIT(J);" "; '<< send permutation to screen
300 NEXT J
310 END
1000 REM =======================================================
1010 REM *********************>> SETFLAG <<*********************
1020 REM =======================================================
1030 FOR K9 = 1 TO TOTAL
1040 R9 = INT(RND * RANGE) + LOW
1050 IF CUM(R9) = 1 THEN 1040
1060 CUM(R9) = 1
1070 SET(K9) = R9
1080 NEXT K9
1090 RETURN
2000 REM ========================================================
2010 REM *********************>> PSTNPERM <<*********************
2020 REM ========================================================
2030 REM This subroutine generates a permutation of a
2040 REM prime order series by swapping pitch class numbers
2050 REM with position-in-set numbers. (If the series is
2060 REM the chromatic scale, then, of course, no alteration
2070 REM of the set will take place - the retrograde will
2080 REM be returned.)
2090 REM ========================================================
2100 REM Variable Descriptions
2110 REM Entering -
2120 REM SET(): array containing series, pointer to POSIT()
2130 REM TOTAL: length of series
2140 REM Exiting -
2150 REM POSIT(): array containing set permutation
2160 REM Local -
2170 REM K9: loop index, pointer to SET()
2180 REM ========================================================
2190 FOR K9 = 1 TO TOTAL
2200 POSIT(SET(K9)) = K9
2210 NEXT K9
2220 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Quicksrt)
130 REM =========================================================
140 DIM X(60),STACK(40)
150 TOTAL = 60
160 RANDOMIZE
170 PRINT "ARRAY OF RANDOM-ORDER INTEGERS --"
180 FOR J= 1 TO TOTAL
190 X(J) = INT(RND*60)+1
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "ARRAY SORTED IN ASCENDING ORDER --"
240 GOSUB 1000 '<< call Quicksort algorithm
250 FOR J = 1 TO TOTAL
260 PRINT X(J);
270 NEXT J
280 END
1000 REM SS2TM3 =================================================
1010 REM *********************>> QUICKSRT <<*********************
1020 REM ========================================================
1030 REM This subroutine is one of the fastest sorting
1040 REM algorithms; however, its drawbacks are that it
1050 REM is lengthy, complex, and difficult to decipher.
1060 REM BASIC language does not offer a stack, and this
1070 REM algorithm requires one. Therefore, a stack
1080 REM has been coded within the subroutine. In
1090 REM languages such as C or Pascal the stack code can
1100 REM be eliminated.
1110 REM ========================================================
1120 REM Variable Descriptions
1130 REM Entering -
1140 REM X(): array of values to be sorted
1150 REM STACK(): stack to hold array X() pointers
1160 REM TOTAL: length of array X()
1170 REM Exiting -
1180 REM X(): array sorted in ascending order
1190 REM Local -
1200 REM FIN : indicator. When zero the sort is done
1210 REM PTR: stack pointer. PTR+1 points to the top of the segment, PTR+2 to bottom of segment
1220 REM TOPVAL: value at top of segment
1230 REM BOTTOMVAL: value at bottom of segment
1240 REM SEGTOP: pointer to top of segment
1250 REM SEGBOTTOM: pointer to bottom of segment
1260 REM COMPVAL: value being compared against current X()
1270 REM ========================================================
1280 FIN = 1
1290 PTR = 0
1300 STACK(PTR+1)=1
1310 STACK(PTR+2)=TOTAL
1320 WHILE FIN <> 0
1330 FIN=FIN-1
1340 PTR=FIN+FIN
1350 TOPVAL=STACK(PTR+1)
1360 BOTTOMVAL=STACK(PTR+2)
1370 COMPVAL=X(TOPVAL)
1380 SEGTOP=TOPVAL
1390 SEGBOTTOM=BOTTOMVAL+1
1400 WHILE SEGBOTTOM-1 <> SEGTOP
1410 SEGBOTTOM=SEGBOTTOM-1
1420 IF COMPVAL <=X(SEGBOTTOM)THEN 1450 ELSE X(SEGTOP) = X(SEGBOTTOM)
1430 SEGTOP=SEGTOP+1
1440 IF SEGBOTTOM = SEGTOP
THEN 1460
ELSE IF COMPVAL >= X(SEGTOP)
THEN 1430
ELSE X(SEGBOTTOM) = X(SEGTOP)
1450 WEND
1460 X(SEGTOP)=COMPVAL
1470 IF BOTTOMVAL-SEGTOP < 2 THEN 1520
1480 PTR=FIN+FIN
1490 STACK(PTR+1)=SEGTOP+1
1500 STACK(PTR+2)=BOTTOMVAL
1510 FIN=FIN+1
1520 IF SEGBOTTOM - TOPVAL < 2 THEN 1570
1530 PTR=FIN+FIN
1540 STACK(PTR+1)=TOPVAL
1550 STACK(PTR+2)=SEGBOTTOM-1
1560 FIN=FIN+1
1570 WEND
1580 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 RANDOMIZE
140 LASTLOC = 7
150 PRINT "START POSITION = ";LASTLOC
160 FOR J = 1 TO 40
170 GOSUB 1000 '<< call random walk
180 PRINT CURRLOC;
190 LASTLOC = CURRLOC
200 NEXT J
210 END
1000 REM ========================================================
1010 REM ********************>> RANDWALK <<**********************
1020 REM ========================================================
1030 REM This subroutine simulates a simple, bi-directional
1040 REM random walk which is restricted at both ends.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM
1080 REM Entering -
1090 REM LASTLOC: previous location of walker
1100 REM Exiting -
1110 REM CURRLOC: present location of walker
1120 REM Local -
1130 REM D: step direction storage
1140 REM U: random number determining step direction
1150 REM S: next step value after computation
1160 REM
1170 REM ========================================================
1180 D=1
1190 U=RND
1200 IF U < .5 THEN D = -1
1210 S = LASTLOC + D
1220 IF S > 15 THEN S = 14 '<< upper boundary test & reset
1230 IF S < 1 THEN S = 2 '<< lower boundary test & reset
1240 CURRLOC = S
1250 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM P$(96)
140 RANDOMIZE
150 TOTAL = 5 '<< number of discrete chords
160 GOSUB 2000 '<< call pitch table
170 FOR J = 1 TO TOTAL
180 PRINT "CHORD";J
190 ROOT = INT(RND * 12)+1 '<< chord start pitch (C-B)
200 OCTAVE = INT(RND * 3)+1 '<< chord start octave (1-3)
210 CHORDMEMS = INT(RND * 7)+3 '<< number of chordtones
220 SMALL = INT(RND * 5)+1 '<< smallest rnd interval
230 LARGE = INT(RND * 8)+5 '<< largest rnd interval
240 INTVALRANGE = LARGE - SMALL + 1
250 GOSUB 1000 '<< call random-interval chord generator
260 PRINT
270 NEXT J
280 END
1000 REM ========================================================
1010 REM *********************>> RDINTCHD <<*********************
1020 REM ========================================================
1030 REM This subroutine generates constrained
1040 REM random-interval chords.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM Entering -
1080 REM ROOT: lowest chordmember
1090 REM OCTAVE: octave register for chord initiation
1100 REM CHORDMEMS: number of tones contained in chord
1110 REM SMALL: smallest interval size selected
1120 REM INTVALRANGE: overall range for interval choice
1130 REM Exiting -
1140 REM none (subroutine is procedural)
1150 REM Local -
1160 REM INTVAL: selected interval size for next chordmem
1170 REM CHORDTONE: next chordmember
1180 REM K9: loop index
1190 REM ========================================================
1200 CHORDTONE = ROOT
1210 FOR K9 = 1 TO CHORDMEMS
1220 PRINT P$(CHORDTONE + ((OCTAVE-1) * 12));" ";
1230 INTVAL = INT(RND * (INTVALRANGE))+SMALL
1240 CHORDTONE = CHORDTONE + INTVAL
1250 NEXT K9
1260 PRINT
1270 RETURN
2000 REM =========================================================
2010 REM ********************>> PITCHTAB <<***********************
2020 REM =========================================================
2030 REM This subroutine initializes a pitch data table
2040 REM corresponding to integer values 1-n.
2050 REM =========================================================
2060 NOTE$ = " CC# DD# E FF# GG# AA# B"
2070 OCTAVE$ = "1234567"
2080 FOR K9 = 1 TO 7
2090 FOR L9 = 1 TO 12
2100 P$(L9+(K9-1)*12) = MID$(NOTE$,(L9*2-1),2)+MID$(OCTAVE$,K9,1)
2110 NEXT L9
2120 NEXT K9
2130 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Rhyprops)
130 REM =========================================================
140 CLS
150 PRINT "THIS PROGRAM CONVERTS RHYTHMIC INFORMATION"
160 PRINT " - EXPRESSED AS NUMERIC PROPORTIONS - "
170 PRINT "INTO TIME DURATIONS."
180 PRINT
190 PRINT "THE PROPORTION(S) WILL BE REALIZED ";"AS A FRACTION"
200 PRINT "OR SEQUENCE OF FRACTIONS OF A WHOLE NOTE."
210 PRINT "FOR EXAMPLE, 4/1 MEANS A DURATION EQUAL ";"TO 4 WHOLE NOTES;"
220 PRINT "1/4 MEANS A DURATION EQUAL TO ONE QUARTER NOTE."
230 PRINT
240 PRINT "- PRESS ANY KEY TO CONTINUE -"
250 A$=INKEY$
260 IF A$ = "" THEN 250
270 PRINT
280 PRINT "----------- A NOTE ABOUT PROPORTIONS -----------"
290 PRINT
300 PRINT "WHEN VALUE 1 > VALUE 2 (E.G., 9:8),"
310 PRINT "VALUE 2 SHOULD CONFORM TO ONE OF THE FOLLOWING"
320 PRINT "NUMBERS - 1,2,4,8,16 ."
330 PRINT
340 PRINT
350 PRINT "WHEN VALUE 2 > VALUE 1 (E.G.,4:9), VALUE 1"
360 PRINT "SHOULD CONFORM TO ONE OF THE ABOVE NUMBERS."
370 PRINT
380 PRINT
390 PRINT "ON THE OTHER HAND, ANY PROPORTION CAN BE INPUT."
400 PRINT "THE COMPUTATION WILL BE MADE,"
410 PRINT "BUT THE RESULT MAY BE TOO COMPLEX TO USE."
420 PRINT
430 PRINT "FOR EXAMPLE, IF THE PROPORTION 10,9,4 ";"(MEANING 10 NOTES"
440 PRINT "IN THE TIME OCCUPIED BY NINE ";"QUARTER NOTES) IS INPUT,"
450 PRINT "ORIGINAL FORM OUTPUT WILL BE ";"TEN IDENTICAL FRACTIONS -"
460 PRINT " 524288/2330169
470 PRINT
480 PRINT " - PRESS ANY KEY TO CONTINUE - "
490 A$ = INKEY$
500 IF A$ = "" THEN 490
510 CLS
520 TOTAL = 3
530 GOSUB 1010 '<< call multiple value storage
540 E = 0: I = 1: F = TOTAL: G = 1
550 PRINT "ORIGINAL FORM --"
560 GOSUB 2000 '<< call value extraction
570 PRINT
580 PRINT"RETROGRADE FORM -- "
590 E = 0: I = TOTAL: F = 1: G = -1
600 GOSUB 2000 '<< call value extraction
610 PRINT
620 PRINT "INVERTED FORM -- "
630 E = 1: I = 1: F = TOTAL: G = 1
640 GOSUB 2000 '<< call value extraction
650 PRINT
660 PRINT "RETROGRADE INVERSION FORM -- "
670 E= 1: I = TOTAL: F = 1: G = -1
680 GOSUB 2000 '<< call value extraction
690 PRINT
700 END
1000 REM ========================================================
1010 REM **********************>> SEQSTORE <<********************
1020 REM (adapted to program specs)
1030 REM ========================================================
1040 PRINT "+++++++ VALUE 1, VALUE 2, METRICAL BASE ++++++ "
1050 FOR K9 = 1 TO TOTAL
1060 R1# = K9 * K9
1070 R2# = K9 + 3
1080 B# = 8
1090 PRINT "SELECTED PROPORTION";K9;"-->";R1#;":";R2#;", ";"BASE";B#
1100 R1#= R1# * 1000000!
1110 R2#=R2# * 1000
1120 C#(K9) = R1#+ R2#+ B#
1130 NEXT K9
1140 RETURN
2000 REM =======================================================
2010 REM *******************>> SEQXTRCT <<**********************
2020 REM (adapted to program specs)
2030 REM =======================================================
2040 FOR K9 = I TO F STEP G
2050 D# = C#(K9)
2060 D# = D#/1000000!
2070 R1 = INT(D#)
2080 R2 = INT((D# - INT(D#)) * 1000)
2090 D# = D# * 1000
2100 B = INT((D# - INT(D#)) * 1000+.5)
2110 GOSUB 3000 '<< call proportion/rhythm conversion
2120 NEXT K9
2130 RETURN
3000 REM =======================================================
3010 REM ******************>> RHYPROPS <<***********************
3020 REM =======================================================
3030 REM This subroutine converts numeric proportions
3040 REM into rhythm duration values.
3050 REM =======================================================
3060 REM Variable Descriptions
3070 REM Entering -
3080 REM R1: proportion value #1
3090 REM R2: proportion value #2
3100 REM B: rhythm median value
3110 REM E: flag to invert proportion
3120 REM Exiting -
3130 REM none (subroutine is procedural)
3140 REM Local -
3150 REM CUM: converted duration numerator
3160 REM DUR: converted duration denominator
3170 REM L9: loop index
3180 REM =======================================================
3190 IF E = 1 THEN SWAP R1,R2
3200 IF R1 < R2 THEN 3280
3210 CUM = 1
3220 DUR = R1 * B / R2
3230 IF DUR <> INT(DUR)THEN CUM = CUM * 2 : DUR = DUR * 2 : GOTO 3230
3240 FOR L9 = 1 TO R1
3250 PRINT CUM;"/";DUR;
3260 NEXT L9
3270 RETURN
3280 DUR = R2/R1
3290 IF INT(DUR) <> DUR THEN DUR = DUR * 2 : B = B * 2 : GOTO 3290
3300 FOR L9 = 1 TO R1
3310 PRINT DUR;"/";B;
3320 NEXT L9
3330 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Rnd-Rnd)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
161 LOW = 1
162 HIGH = 12
163 RANGE = HIGH - LOW + 1
170 GOSUB 1000 '<< call recursive random distribution
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM *********************>> RND-RND <<**********************
1020 REM ========================================================
1021 REM The RND-RND probability distribution generates
1022 REM a range of integers whose occurrence frequency
1023 REM falls off with magnitude. It's distribution
1024 REM curve is similar to the exponential curve.
1029 REM ========================================================
1030 REM Variable Descriptions
1040 REM Entering -
1050 REM TOTAL:
1060 REM RANGE:
1070 REM LOW:
1080 REM Exiting -
1090 REM X():
1100 REM Local -
1110 REM K9: loop index, pointer to array X()
1111 REM ========================================================
1120 FOR K9 = 1 TO TOTAL
1130 X(K9) = INT(RND * RND * (RANGE)) + LOW
1140 NEXT K9
1150 RETURN
100 REM ========================================================
110 REM DRIVER PROGRAM
120 REM (Rotation)
130 REM ========================================================
140 REM This set of subroutines performs rotation and
150 REM transposition operations on a 12-element set
160 REM of values. This program deals with number sets
170 REM to point out applications to parameters other
180 REM than pitch; however, the values may be printed
190 REM as pitch classes simply by adding a pitch
200 REM conversion subroutine.
210 REM ========================================================
220 DIM CUM(12),SET(12),MAT1(12,12),MAT2(12,12),MAT3(12,12)
230 RANDOMIZE
240 SET = 12
250 PRINT "A RANDOM-ORDER SET -->"
260 GOSUB 1000 '<< call set generator
270 FOR J = 0 TO SET-1
280 PRINT SET(J);" ";
290 NEXT J
300 PRINT
310 PRINT
320 ROTEGROUP = 4
330 PRINT "UNPARTITIONED ARRAY, ELEMENT/GROUP ROTATION -->"
340 PRINT "(";ROTEGROUP;"SET MEMBERS PER CYCLE ROTATED )"
350 GOSUB 5000 '<< call Euclid's Algorithm
360 PRINT "TOTAL NUMBER OF UNIQUE CYCLES =";CYCLES
370 GOSUB 2000 '<< call unpartitioned set group rotation
380 FOR J1 = 0 TO CYCLES-1
390 FOR J2 = 0 TO SET-1
400 PRINT MAT1(J1,J2);
410 NEXT J2
420 PRINT
430 PRINT
440 NEXT J1
450 PRINT "'0' START POINT TRANSPOSITION -->"
460 GOSUB 3000 '<< call set transposition
470 FOR J1 = 0 TO CYCLES-1
480 FOR J2 = 0 TO SET-1
490 PRINT MAT2(J1,J2);
500 NEXT J2
510 PRINT
520 PRINT
530 NEXT J1
540 NUMSEGS = 4
550 SEGMEMS = SET/NUMSEGS
560 PRINT "PARTITIONED ARRAY, ROTATION WITHIN SEGMENT -->"
570 PRINT "(DIVIDED INTO";NUMSEGS;"EQUAL SEGMENTS)"
580 GOSUB 4000 '<< call set segment member rotation
590 FOR J1 = 0 TO SEGMEMS - 1
600 PRINT "|";
610 FOR J2 = 0 TO SET - 1
620 PRINT MAT3(J1,J2);
630 IF (J2+1) MOD SEGMEMS = 0 THEN PRINT "|";
640 NEXT J2
650 PRINT
660 PRINT
670 NEXT J1
680 END
1000 REM ========================================================
1010 REM **********************>> SETFLAG <<*********************
1020 REM ========================================================
1030 FOR K9 = 0 TO SET - 1
1040 R9 = INT(RND * SET)
1050 IF CUM(R9) = 1 THEN 1040
1060 CUM(R9) = 1
1070 SET(K9) = R9
1080 NEXT K9
1090 RETURN
2000 REM ========================================================
2010 REM *********************>> SETROTAT <<*********************
2020 REM ========================================================
2030 REM This subroutine rotates set members by moving a
2040 REM specified group of notes from the beginning to the
2050 REM end of the series.
2060 REM ========================================================
2070 REM Variable Descriptions
2080 REM Entering -
2090 REM SET: length of series
2100 REM ROTEGROUP: # of contiguous set members to rotate
2110 REM Exiting -
2120 REM MAT1: matrix of rotated sets
2130 REM Local -
2140 REM R9: rotation factor marker
2150 REM S9: counter, pointer to MAT1(n,n)
2160 REM T9: pointer to SET()
2170 REM K9: loop index
2180 REM L9: loop index, pointer to MAT(n,n)
2190 REM ========================================================
2200 ROTEGROUP = ROTEGROUP - 1
2210 R9 = 0
2220 S9 = 0
2230 FOR K9 = ROTEGROUP TO SET-1 + ROTEGROUP
2240 FOR L9 = 1 TO SET
2250 T9 = (K9+L9+R9) MOD SET
2260 MAT1(S9,L9-1) = SET(T9)
2270 NEXT L9
2280 R9 = R9 + ROTEGROUP
2290 S9 = S9 + 1
2295 IF S9 = CYCLES THEN RETURN
2300 NEXT K9
2310 RETURN
3000 REM ========================================================
3010 REM *******************>> ZEROTRNP <<***********************
3020 REM ========================================================
3030 REM This subroutine transposes a collection of sets
3040 REM sets to '0' start point.
3050 REM ========================================================
3060 REM Variable Descriptions
3070 REM Entering -
3080 REM MAT1(n,n): matrix of rotated sets
3090 REM SET: length of series
3100 REM Exiting -
3110 REM MAT2(n,n): matrix of transposed sets
3120 REM Local -
3130 REM INTVAL: interval of transposition
3140 REM S9: set member after transposition
3150 REM K9: loop index, pointer to MAT1(n,n) & MAT2(n,n)
3160 REM L9: loop index, pointer to MAT1(n,n) & MAT2(n,n)
3170 REM ========================================================
3180 FOR K9 = 0 TO CYCLES-1
3190 INTVAL = MAT1(K9,0)
3200 FOR L9 = 0 TO SET-1
3210 S9 = MAT1(K9,L9)-INTVAL
3220 IF S9 < 0 THEN S9 = S9 + 12
3230 MAT2(K9,L9) = S9
3240 NEXT L9
3250 NEXT K9
3260 RETURN
4000 REM ========================================================
4010 REM **********************>> SEGROTAT <<********************
4020 REM ========================================================
4030 REM This subroutine rotates partitioned-set segment
4040 REM members.
4050 REM ========================================================
4060 REM Variable Descriptions
4070 REM Entering -
4080 REM SET(): prime set
4090 REM SET: length of series
4100 REM NUMSEGS: symmetrical set partitioning
4110 REM Exiting -
4120 REM MAT3(n,n): matrix of sets after internal rotation
4130 REM Local -
4140 REM SEGMEMS: number of members in each segment
4150 REM S9: counter, pointer to MAT(n,n)
4160 REM T9: counter, pointer to MAT(n,n)
4170 REM K9: loop index
4180 REM L9: loop index, pointer to SET()
4190 REM M9: loop index, pointer to SET()
4200 REM ========================================================
4210 S9 = 0
4220 SEGMEMS = SET/NUMSEGS
4230 FOR K9 = 1 TO SEGMEMS
4240 T9 = 0
4250 FOR L9 = 0 TO SET-1 STEP SEGMEMS
4260 FOR M9 = S9 + 1 TO SEGMEMS + S9
4270 MAT3(S9,T9) = SET(M9 MOD SEGMEMS + L9)
4280 T9 = T9 + 1
4290 NEXT M9
4300 NEXT L9
4310 S9 = S9 + 1
4320 NEXT K9
4330 RETURN
5000 REM ========================================================
5010 REM ********************>> EUCREDUC <<**********************
5020 REM (modified to meet program specs)
5030 REM ========================================================
5040 A9 = SET
5050 B9 = ROTEGROUP
5060 IF A9 > B9 THEN SWAP A9,B9
5070 WHILE A9 > 0
5080 C9 = INT(B9/A9)
5090 D9 = B9-A9*C9
5100 B9 = A9
5110 A9 = D9
5120 WEND
5130 CYCLES = SET/B9
5140 RETURN100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Rowforms)
130 REM =========================================================
140 REM This set of subroutines produces commonly found
150 REM 12-tone row forms - original, retrograde, inversion,
160 REM and transpositions. Because the processes are well
170 REM known and simple, variable descriptions have been
180 REM dispensed with.
190 REM =========================================================
200 DIM P$(12)
210 DIM X(12),Y(12)
220 INTVAL = 4
230 RANDOMIZE
240 GOSUB 1000 '<< load element tables
250 GOSUB 2000 '<< call random shuffle
260 PRINT
270 PRINT "RANDOM-ORDER 12-TONE ROW --"
280 FOR J = 0 TO 11
290 PRINT P$(X(J));" "; '<< random 12-tone row to screen
300 NEXT J
310 PRINT : PRINT
320 FOR J = 1 TO 3
330 ON J GOSUB 3000,4000,5000 '<< call retro,invrt,trnpz
340 FOR J1 = 0 TO 11
350 PRINT P$(Y(J1));" "; '<< row forms to screen
360 NEXT J1
370 PRINT : PRINT
380 NEXT J
390 END
1000 REM ========================================================
1010 REM *********************<< PITCHTAB <<*********************
1020 REM (modified to program specs)
1030 REM ========================================================
1040 FOR J = 0 TO 11
1050 X(J) = J '<< load row elements
1060 READ P$(J) '<< load pitch class equivalents
1070 NEXT J
1080 REM+++++++++++++++++++++++++++++++++
1090 DATA C,C#,D,D#,E,F,F#,G,G#,A,A#,B
1100 REM+++++++++++++++++++++++++++++++++
1110 RETURN
2000 REM ========================================================
2010 REM ********************>> CONSHUFL <<**********************
2020 REM ========================================================
2030 FOR K9 = 0 TO 11
2040 R9 = INT(RND * 12)
2050 S9 = X(K9)
2060 X(K9) = X(R9)
2070 X(R9) = S9
2080 NEXT K9
2090 RETURN
3000 REM ========================================================
3010 REM **********************>> ROWRETRO <<********************
3020 REM =======================================================
3030 REM This subroutine outputs retrograde form.
3040 REM =======================================================
3050 PRINT "RETROGRADE ORDER --"
3060 FOR K9 = 0 TO 11
3070 L = (11 - K9) MOD 12
3080 Y(L) = X(K9)
3090 NEXT K9
3100 RETURN
4000 REM ========================================================
4010 REM ********************>> ROWINVRT <<**********************
4020 REM ========================================================
4030 REM This subroutine outputs inverted form.
4040 REM ========================================================
4050 PRINT "INVERTED ORDER --"
4060 FOR K9 = 0 TO 11
4070 Y(K9) = (12 - X(K9)) MOD 12
4080 NEXT K9
4090 RETURN
5000 REM =======================================================
5010 REM ********************>> ROWTRNPZ <<*********************
5020 REM =======================================================
5030 REM This subroutine outputs row form transpositions.
5040 REM =======================================================
5050 PRINT "TRANSPOSED (UP MAJOR 3RD) ORIGINAL FORM --"
5060 FOR K9 = 0 TO 11
5070 Y(K9) = (X(K9) + INTVAL) MOD 12
5080 NEXT K9
5090 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Rowsquar)
130 REM =========================================================
140 DIM P$(12),CUM(12),X(12),Y(12)
150 RANDOMIZE
160 GOSUB 1000 '<< call pitch table
170 GOSUB 2000 '<< call set generator
180 GOSUB 3000 '<< call composite row form printout
190 END
1000 REM ========================================================
1010 REM *********************>> PITCHTAB <<*********************
1020 REM (modified to load pitch classes only)
1030 REM ========================================================
1040 FOR J = 0 TO 11
1050 READ P$(J) '<< load pitch table
1060 NEXT J
1070 REM++++++++++++++++++++++++++++++++++++++++
1080 DATA "C ","C# ","D ","D# ","E ","F "
1090 DATA "F# ","G ","G# ","A ","A# ","B "
1100 REM++++++++++++++++++++++++++++++++++++++++
1110 RETURN
2000 REM ========================================================
2010 REM *********************>> SETFLAG <<**********************
2020 REM (modified to program specs)
2030 REM ========================================================
2040 FOR K9 = 0 TO 11
2050 F = INT(RND*12)
2060 IF CUM(F) = 1 THEN 2050
2070 CUM(F) = 1
2080 IF K9 = 0 THEN TRANS = F
2090 IF F-TRANS < 0 THEN X(K9) = F-TRANS+ 12 ELSE X(K9) = F-TRANS
2100 Y(K9) = (12-X(K9)) MOD 12
2110 NEXT K9
2120 RETURN
3000 REM ========================================================
3010 REM *********************>> ROWSQUAR <<*********************
3020 REM ========================================================
3030 REM This subroutine prints a square matrix containing
3040 REM composite 12-tone row forms: Original (Prime),
3050 REM Retrograde, Inversion, and Retrograde-Inversion.
3060 REM ========================================================
3070 REM Variable Descriptions
3080 REM Entering -
3090 REM X(): original order set array
3100 REM Y(): inverted order set array
3110 REM P$(): pitch table array
3120 REM Exiting -
3130 REM none (subroutine is procedural)
3140 REM Local -
3150 REM INTVAL: transposition interval
3160 REM K9: loop index, pointer to Y()
3170 REM L9: loop index, pointer to X()
3180 REM =======================================================
3190 CLS
3200 PRINT " MATRIX OF TRANSPOSITIONS YIELDING O,RO,I,RI "
3210 PRINT "++++++++++++++++++++++++++++++++++++++++++++++++++"
3220 PRINT "+ ORIGINAL ----> +"
3230 PRINT "+ | INVERSION +"
3240 PRINT "+ V +"
3250 FOR K9= 0 TO 11
3260 PRINT "+";TAB(8);
3270 INTVAL = Y(K9)
3280 FOR L9= 0 TO 11
3290 PRINT P$((X(L9) + INTVAL) MOD 12);
3300 NEXT L9
3310 PRINT TAB(50);"+"
3320 NEXT K9
3330 PRINT "+ ^ +"
3340 PRINT "+ | RETROGRADE INVERSION +"
3350 PRINT "+ <--- RETROGRADE +"
3360 PRINT "++++++++++++++++++++++++++++++++++++++++++++++++++"
3370 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Samplset)
130 REM =========================================================
140 DIM SET(100),A(100),B(100)
150 PERMUT = 5
160 TOTAL = 12
170 PRINT "A SEQUENTIAL SET -"
180 FOR J = 1 TO TOTAL
190 SET(J) = J : PRINT SET(J);
200 NEXT J
210 PRINT
220 FACTOR = 2
230 FOR CYCLE = 1 TO PERMUT
240 PRINT "PERMUTATION ";CYCLE
250 TARGET = 1
260 PRINT "SET START POSITION = ";TARGET;"; ""SET TARGET FACTOR= ";FACTOR
270 GOSUB 1000 '<< call sampling
280 FACTOR = FACTOR + 2
290 NEXT CYCLE
300 END
1000 REM =========================================================
1010 REM *******************>> SAMPLSET <<************************
1020 REM =========================================================
1030 REM This subroutine produces numeric series permutations
1040 REM by cyclical set sampling at a selected interval.
1050 REM (start at set member n and remove every nth element,
1060 REM looping back through the series until reordered.)
1070 REM The algorithm is derived from the classic 'Josephus'
1080 REM Problem', which is expressed below in pseudo-code:
1090 REM
1100 REM Arrange a group of men in a circle;
1110 REM move around the circle;
1120 REM shoot and remove every nth man;
1130 REM repeat until none remains.
1140 REM
1150 REM ========================================================
1160 REM Variable Descriptions
1170 REM Entering -
1180 REM SET(): initial value series
1190 REM TOTAL: series length
1200 REM TARGET: current set sample
1210 REM FACTOR: sampling interval
1220 REM Exiting -
1230 REM none: (subroutine is procedural)
1240 REM Local -
1250 REM SETL: current set length (shrinks every iteration)
1270 REM A(): bounce array 1
1280 REM B(): bounce array 2
1290 REM ACNT: pointer to A()
1300 REM BCNT: pointer to B()
1310 REM K9: loop index, pointer to A(),B()
1320 REM ========================================================
1330 SETL = TOTAL
1340 FOR K9 = 1 TO SETL
1350 A(K9)=SET(K9)
1360 NEXT K9
1370 BCNT = 0
1380 FOR K9 = 1 TO SETL
1390 IF K9 = TARGET THEN PRINT A(K9); : TARGET = TARGET + FACTOR ELSE BCNT = BCNT + 1 : B(BCNT) = A(K9)
1400 NEXT K9
1410 IF BCNT < 1 THEN 1530
1420 TARGET = TARGET - SETL
1430 ACNT = 0
1440 IF TARGET MOD BCNT <> 0 THEN TARGET = TARGET MOD BCNT ELSE TARGET = BCNT
1450 FOR K9 = 1 TO BCNT
1460 IF K9 = TARGET THEN PRINT B(K9); : TARGET = TARGET + FACTOR ELSE ACNT = ACNT + 1 : A(ACNT) = B(K9)
1470 NEXT K9
1480 IF ACNT < 1 THEN 1530
1490 SETL = ACNT
1500 TARGET = TARGET - BCNT
1510 IF TARGET MOD SETL <> 0 THEN TARGET = TARGET MOD SETL ELSE TARGET = SETL
1520 GOTO 1370
1530 PRINT
1540 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Scorform)
130 REM =========================================================
140 PRINT "FIFTY RANDOM VALUES FROM 1-50 ARE BEING PUT IN"
150 PRINT "PITCH, RHYTHM, ARTICULATION, AND VOLUME FILES"
160 PRINT "NAMED 'P1.DAT','R1.DAT','A1.DAT','V1.DAT' -----"
170 FOR J1 = 1 TO 4
180 IF J1 = 1
THEN OPEN "O",#1,"P1.DAT"
ELSE
IF J1 = 2
THEN OPEN "O",#2,"R1.DAT"
ELSE
IF J1 = 3
THEN OPEN "O",#3,"A1.DAT"
ELSE OPEN "O",#4,"V1.DAT"
190 FOR J2 = 1 TO 50
200 NUM = INT(RND * 50)+1
210 PRINT #J1,NUM; '<< put 50 values in each file
220 IF J2 MOD 15 = 0 THEN PRINT #J1, '<< 10 per line
230 NEXT J2
240 CLOSE #J1
250 NEXT J1
260 PRINT
270 PRINT "NOW THE 4 SEPARATE PARAMETER FILES ARE BEING"
280 PRINT "PLACED IN FINAL SCORE FILE NAMED 'SCORE.DAT' ---"
290 PRINT
300 GOSUB 1000 '<< call score formatting
310 END
1000 REM ========================================================
1010 REM *******************>> SCORFORM <<***********************
1020 REM ========================================================
1030 REM Formatted-Score-Filing Subroutine
1040 REM ========================================================
1050 X$ = "+"
1060 Z$ = "SCORE.DAT"
1070 OPEN "I",#1,"P1.DAT"
1080 OPEN "I",#2,"R1.DAT"
1090 OPEN "I",#3,"A1.DAT"
1100 OPEN "I",#4,"V1.DAT"
1110 OPEN "O",#5,Z$
1120 PRINT #5,"NOTELIST:"
1130 WHILE NOT EOF(1)
1140 LINE INPUT #1,A$
1150 PRINT #5,"P ";A$
1160 LINE INPUT #2,B$
1170 PRINT #5,"R ";B$
1180 LINE INPUT #3,C$
1190 PRINT #5,"A ";C$
1200 LINE INPUT #4,D$
1210 PRINT #5,"V ";D$
1220 PRINT #5,"/*";STRING$(55,X$);"*/"
1230 WEND
1240 CLOSE #1,#2,#3,#4,#5
1250 PRINT "HERE IS FINAL SCORE --"
1260 OPEN "I",#5,Z$
1270 WHILE NOT EOF(5)
1280 LINE INPUT #5,A$
1290 PRINT A$
1300 WEND
1310 CLOSE #5
1320 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Seqfile)
130 REM =========================================================
140 DIM X(200)
150 SEQTOTAL = 5
160 OPEN "O",#1,"SEQ.DAT" '<< prepare file for writing
170 PRINT "FILE LOOKS LIKE THIS ---"
180 GOSUB 1000 '<< call sequence filing routine
190 CLOSE #1
200 OPEN "I",#1,"SEQ.DAT" '<< prepare file for reading
210 PRINT "EXTRACTED SEQUENCES LOOK LIKE THIS --"
220 GOSUB 2000 '<< call sequence extraction routine
230 CLOSE #1
240 END
1000 REM ========================================================
1010 REM ********************>> SEQSTORE <<**********************
1020 REM ========================================================
1030 REM Discrete Sequence Store and File Subroutine
1040 REM ========================================================
1050 REM Variable Descriptions
1060 REM Entering -
1070 REM SEQTOTAL: number of sequences to store
1080 REM Exiting -
1090 REM X(): array containing sequence and keys
1100 REM Local -
1110 REM SEQLEN: random-length number sequence
1120 REM FILEVAL: integer for array storage & filing
1130 REM K9: loop index
1140 REM L9: loop index, pointer to array X()
1150 REM T8: counter, pointer to array X()
1160 REM ========================================================
1170 FOR K9 = 1 TO SEQTOTAL
1180 SEQLEN = INT(RND * 20)+5
1190 FOR L9 = 1 TO SEQLEN
1200 FILEVAL = L9 * K9
1210 IF L9 = 1 THEN X(L9+T8) = FILEVAL * 1000 + SEQLEN ELSE X(L9+T8) = FILEVAL
1220 PRINT X(L9+T8);:PRINT #1,X(L9+T8);
1230 NEXT L9
1240 T8 = T8 + SEQLEN
1250 NEXT K9
1260 PRINT
1270 RETURN
2000 REM ========================================================
2010 REM ********************>> SEQXTRCT <<**********************
2020 REM ========================================================
2030 REM Discrete Sequence Retrieval Subroutine
2040 REM ========================================================
2050 REM Variable Descriptions
2060 REM Entering -
2070 REM X(): array containing sequence & keys
2080 REM Exiting -
2090 REM none (subroutine is procedural)
2100 REM Local -
2110 REM S8: sequence counter
2120 REM K9: loop index, pointer to array X()
2130 REM ========================================================
2140 S8 = 0
2150 FOR K9= 1 TO 10000
2160 IF EOF(1) THEN 2190 ELSE INPUT #1,X(K9)
2170 IF X(K9) < 1000 THEN PRINT X(K9); ELSE PRINT : S8 = S8 + 1 :PRINT "SEQUENCE";S8 : PRINT INT(X(K9)/1000);
2180 NEXT K9
2190 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 DIM SET(12),CUM(12)
140 RANDOMIZE
150 TOTAL = 12
160 LOW = 1
170 HIGH = 12
180 RANGE = HIGH-LOW+1
190 GOSUB 1000
200 FOR J = 1 TO TOTAL
210 PRINT SET(J);" "; '<< send series to screen
220 NEXT J
230 END
1000 REM =======================================================
1010 REM *********************>> SETFLAG <<*********************
1020 REM =======================================================
1030 REM This subroutine generates random-order series by
1040 REM the array flag method. That is, when a random
1050 REM integer is generated, the subroutine checks the
1060 REM content of the CUM() address pointed to by the
1070 REM random number to determine whether a flag (1)
1080 REM is present. If the address is empty, it receives
1090 REM the flag, and the random number is placed in SET()
1100 REM as a series member. If the address has the flag,
1110 REM the number is discarded and another generated.
1120 REM =======================================================
1130 REM Variable Descriptions
1140 REM Entering -
1150 REM TOTAL: length of set
1160 REM LOW: lowest value
1170 REM RANGE: set value range
1180 REM Exiting -
1190 REM SET(): final set of values
1200 REM Local -
1210 REM CUM(): array holding occurrence flags
1220 REM R9: random value to be tested for occurrence
1230 REM K9: loop index, pointer to array SET()
1240 REM =======================================================
1250 FOR K9 = 1 TO TOTAL
1260 R9 = INT(RND * RANGE) + LOW
1270 IF CUM(R9) = 1 THEN 1260
1280 CUM(R9) = 1
1290 SET(K9) = R9
1300 NEXT K9
1310 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Shellsrt)
130 REM =========================================================
140 DIM X(50)
150 TOTAL = 50
160 RANDOMIZE
170 PRINT "ARRAY OF RANDOM-ORDER REAL NUMBERS (RANGE 0-1) --"
180 FOR J = 1 TO TOTAL
190 X(J) = RND
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "ARRAY SORTED IN ASCENDING ORDER --"
240 GOSUB 1000 '<< call Shell sort algorithm
250 FOR J = 1 TO TOTAL
260 PRINT X(J); '<< list to screen
270 NEXT J
280 END
1000 REM SS1TM2 =================================================
1010 REM *********************>> SHELLSRT <<*********************
1020 REM ========================================================
1030 REM This in-place binary sorting subroutine is fast,
1040 REM compact, and easy to understand. The algorithm
1050 REM works by successively splitting the list into
1060 REM smaller halves, rearranging contents along the way.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM X(): array of values to be sorted
1110 REM TOTAL: length of list
1120 REM Exiting -
1130 REM X(): array sorted in ascending order
1140 REM Local -
1150 REM SUBDIV: list subdivision size
1160 REM REMAINDER: original list size less SUBDIV
1170 REM FLAG: 0 or 1 condition indicates switch or no
1180 REM switch has occurred
1190 REM TEMP: temporary storage
1200 REM K9: loop index, first sublist pointer
1210 REM COMPTR: second sublist pointer for comparison
1220 REM and switch
1230 REM ========================================================
1240 SUBDIV = TOTAL
1241 SUBDIV = INT(SUBDIV / 2)
1250 WHILE SUBDIV > 0
1270 REMAINDER = TOTAL - SUBDIV
1280 FLAG = 0
1290 FOR K9=1 TO REMAINDER
1300 COMPTR = K9+SUBDIV
1310 IF X(K9) <= X(COMPTR)THEN 1360
1320 TEMP = X(K9)
1330 X(K9) = X(COMPTR)
1340 X(COMPTR) = TEMP
1350 FLAG = 1
1360 NEXT K9
1370 IF FLAG > 0 THEN 1280
1371 SUBDIV = INT(SUBDIV / 2)
1372 WEND
1373 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (S-MSORT)
130 REM =========================================================
140 DIM X(50)
150 TOTAL = 50
160 RANDOMIZE
170 PRINT "ARRAY OF RANDOM-ORDER REAL NUMBERS (RANGE 0-1) --"
180 FOR J = 1 TO TOTAL
190 X(J) = RND
200 PRINT X(J);
210 NEXT J
220 PRINT
230 PRINT "ARRAY SORTED IN ASCENDING ORDER --"
240 GOSUB 1010 '<< call Shell-Metzner sort
250 FOR J = 1 TO TOTAL
260 PRINT X(J); '<< list to screen
270 NEXT J
280 END
1000 REM SS1TM3 =================================================
1010 REM ********************>> S-MSORT << **********************
1020 REM ========================================================
1030 REM The shell-Metzner sorting algorithm is a variation
1040 REM on the Shell sort. It rearranges an array of values
1050 REM into ascending order. It is a binary sort, very
1060 REM fast, and does the sorting in place. It does not
1070 REM require a stack, as does the Quicksort algorithm.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM X(): array of values to be sorted
1120 REM TOTAL: length of array X()
1130 REM Exiting -
1140 REM X(): array sorted in ascending order
1150 REM Local -
1160 REM SUBDIV: list subdivision size
1170 REM REMAINDER: original list size minus SUBDIV
1180 REM PTR1: loop index, first sublist pointer
1190 REM COMPTR: second sublist pointer for comparison
1200 REM and switch
1210 REM K9: loop index
1220 REM TEMP: temporary storage
1230 REM ========================================================
1240 SUBDIV = TOTAL
1250 SUBDIV = INT(SUBDIV / 2)
1260 WHILE SUBDIV > 0
1270 REMAINDER =TOTAL - SUBDIV
1280 FOR K9 = 1 TO REMAINDER
1290 PTR1 = K9
1300 COMPTR = PTR1 + SUBDIV
1310 IF X(PTR1) <= X(COMPTR) THEN 1350
1320 TEMP = X(PTR1)
1321 X(PTR1) = X(COMPTR)
1330 X(COMPTR) = TEMP
1331 PTR1 = PTR1 - SUBDIV
1340 IF PTR1 >= 1 THEN 1300
1350 NEXT K9
1360 SUBDIV = INT(SUBDIV / 2)
1370 WEND
1380 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (SNDTEXT)
130 REM =========================================================
140 DIM X(51),Y(100)
150 TOTAL = 50
160 RANGE = 26 '<< letters of alphabet
170 BLANKS = 10 '<< additional codes to be filtered as blanks
180 X(0) = TOTAL
190 RANDOMIZE
200 PRINT "RANDOM INTEGERS TO INTERPRET AS ASCII CODES --"
210 FOR J = 1 TO TOTAL
220 X(J) = INT(RND * (RANGE+BLANKS)) + 97
230 PRINT X(J);
240 NEXT J
250 PRINT
260 PRINT "THE NUMBER-TO-CHARACTER CONVERTED TEXT --"
270 GOSUB 1000 '<< call numeric-to-character conversion
280 PRINT TEXT$ '<< text-converted sequence to screen
290 PRINT "THE TEXT CONVERTED BACK TO INTEGERS ";
300 PRINT "WITH NON ALPHABET-RANGE VALUES AS BLANKS --"
310 GOSUB 2000
320 FOR J = 1 TO TOTAL
330 PRINT Y(J);
340 NEXT J
350 END
1000 REM SS1WP3 ==================================================
1010 REM *********************>> SNDTEXT1 <<**********************
1020 REM =========================================================
1030 REM This subroutine converts integers to their
1040 REM corresponding character representation using
1050 REM the CHR$ function. It also adds blanks randomly
1060 REM to simulate the appearance of normal text. It may
1070 REM be adapted to a number of applications which
1080 REM correlate text and musical parameters in some
1090 REM fashion. For example, a sequence of pitch values,
1100 REM transposed to the approprate ASCII code range, can
1110 REM be converted to alphabetic characters whose codes
1120 REM represent the mapping of pitch onto text. The result,
1130 REM however, will probably not conform to any known
1140 REM language because of the absence of syntactical rules.
1150 REM ========================================================
1160 REM Variable Descriptions
1170 REM Entering -
1180 REM X(): sequence of integer values, to be interpreted
1190 REM as ASCII codes
1200 REM TOTAL: length of array X()
1210 REM Exiting -
1220 REM TEXT$: string of alphabet characters representing
1230 REM mapping of numbers to text
1240 REM Local -
1250 REM K9: loop index, pointer to array X()
1260 REM ========================================================
1270 TEXT$ = ""
1280 FOR K9 = 1 TO X(0)
1290 IF X(K9) > 122 THEN TEXT$ = TEXT$ + " " ELSE TEXT$ = TEXT$ + CHR$(X(K9))
1300 NEXT K9
1310 RETURN
2000 REM SS1WP2=================================================
2010 REM *********************>> SNDTEXT2 <<********************
2020 REM =======================================================
2030 REM This subroutine is the converse of SNDTEXT1 - a
2040 REM character-to-number conversion algorithm. Text
2050 REM strings may be input and translated to integers,
2060 REM which in turn may be assigned to pitch, rhythm,
2070 REM volume, or any musical parameter.
2080 REM =======================================================
2090 REM Variable Descriptions
2100 REM Entering -
2110 REM TEXT$: character string
2120 REM Exiting -
2130 REM Y(): array holding integer-converted sequence
2140 REM Local -
2150 REM K9: loop index, pointer to array Y()
2160 REM =======================================================
2170 Y(0) = LEN(TEXT$)
2180 FOR K9 = 1 TO Y(0)
2190 Y(K9) = ASC(MID$(TEXT$,K9,1))
2200 NEXT K9
2210 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Stats)
130 REM =========================================================
140 DIM X(200),Y(15)'<< sequence array, frequency table array
150 RANGE = 15 '<< set random number range 1-15
160 TOTAL = 200 '<< return 200 values
170 RANDOMIZE
180 GOSUB 1000 '<< generate sequence array & frequency table
190 GOSUB 2000 '<< call bargraph display
200 GOSUB 3000 '<< call statistical mode (maxval)
210 GOSUB 4000 '<< call least frequent (minval)
220 GOSUB 5000 '<< call arithmetic mean
230 GOSUB 6000 '<< call statistical variance
240 GOSUB 7000 '<< call standard deviation
250 END
1000 REM ========================================================
1010 REM *******************>> FREQTABL <<***********************
1020 REM ========================================================
1030 FOR K9 = 1 TO TOTAL
1040 VALUE = INT(RND * RANGE)+1 '<< gen random value
1050 X(K9) = VALUE '<< load sequence array
1060 Y(VALUE)=Y(VALUE)+1 '<< record occurrence of value
1070 NEXT K9
1080 RETURN
2000 REM ========================================================
2010 REM *******************>> BARGRAPH <<***********************
2020 REM ========================================================
2030 FOR K9 = 1 TO RANGE
2040 PRINT K9;TAB(10);STRING$(Y(K9),">")
2050 NEXT K9
2060 RETURN
3000 REM ========================================================
3010 REM *********************>> MAXVAL <<***********************
3020 REM ========================================================
3030 REM This subroutine finds the statistical mode of
3040 REM a collection of values. It scans the integer
3050 REM frequency table, then records the address and
3060 REM number of occurrence of the most frequent value(s).
3070 REM ========================================================
3080 REM Variable Descriptions
3090 REM Entering -
3100 REM Y(): occurrence frequency table
3110 REM RANGE: range of integer values in table
3120 REM Exiting -
3130 REM none (subroutine is procedural)
3140 REM Local -
3150 REM MAX: statistical mode
3160 REM K9: loop index, pointer to frequency table
3170 REM ========================================================
3180 MAX = Y(1)
3190 FOR K9 = 2 TO RANGE
3200 IF MAX < Y(K9) THEN MAX = Y(K9)
3210 NEXT K9
3220 FOR K9 = 1 TO RANGE
3230 IF Y(K9) = MAX THEN PRINT "THE INTEGER";K9;"= MODE;";" FREQ =";MAX
3240 NEXT K9
3250 RETURN
4000 REM ========================================================
4010 REM ********************>> MINVAL <<************************
4020 REM ========================================================
4030 REM This subroutine scans the occurrence frequency
4040 REM table, then records the address and number of
4050 REM occurrences of the least frequent value.
4060 REM ========================================================
4070 REM Variable Descriptions
4080 REM Entering -
4090 REM Y(): occurrence frequency table
4100 REM RANGE: range of integer values in table
4110 REM Exiting -
4120 REM none (subroutine is procedural)
4130 REM Local -
4140 REM MIN: least frequent integer
4150 REM K9: loop index, pointer to array Y()
4160 REM ========================================================
4170 MIN = Y(1)
4180 FOR K9 = 2 TO RANGE
4190 IF MIN > Y(K9) THEN MIN = Y(K9)
4200 NEXT K9
4210 FOR K9 = 1 TO RANGE
4220 IF Y(K9) = MIN THEN PRINT "THE INTEGER";K9;" = LEAST FREQUENT;";" FREQ =";MIN
4230 NEXT K9
4240 RETURN
5000 REM ========================================================
5010 REM **********************>> MEAN <<************************
5020 REM ========================================================
5030 REM This subroutine finds the arithmetic mean of
5040 REM a sample collection.
5050 REM ========================================================
5060 REM Variable Descriptions
5070 REM Entering -
5080 REM TOTAL: length of sequence
5090 REM Exiting -
5100 REM none (subroutine is procedural)
5110 REM Local -
5120 REM SUM: sum of sequence values
5130 REM MEAN: arithmetic mean of values
5140 REM K9: loop index, pointer to sequence array X()
5150 REM ========================================================
5160 SUM = 0
5170 FOR K9 = 1 TO TOTAL
5180 SUM = SUM + X(K9)
5190 NEXT K9
5200 MEAN = SUM / TOTAL
5210 PRINT "MEAN =";MEAN;" ";
5220 RETURN
6000 REM ========================================================
6010 REM *******************>> VARIANCE <<***********************
6020 REM ========================================================
6030 REM This subroutine computes statistical variance of
6040 REM a collection of samples.
6050 REM ========================================================
6060 REM Variable Descriptions
6070 REM Entering -
6080 REM TOTAL: length of sequence
6090 REM MEAN: arithmetic mean of sequence values
6100 REM Exiting -
6110 REM none (subroutine is procedural)
6120 REM Local -
6130 REM VARIANCE: statistical variance
6140 REM TEMP: temporary storage of computation
6150 REM K9: loop index, pointer to sequence array X()
6160 REM ========================================================
6170 VARIANCE = 0
6180 FOR K9 = 1 TO TOTAL
6190 TEMP = (X(K9) - MEAN) ^ 2
6200 VARIANCE = VARIANCE + TEMP
6210 NEXT K9
6220 VARIANCE = VARIANCE / (TOTAL - 1)
6230 PRINT "VARIANCE = ";VARIANCE
6240 RETURN
7000 REM ========================================================
7010 REM ********************>> STDEV <<*************************
7020 REM ========================================================
7030 REM This subroutine computes standard deviation and
7040 REM standard error of the mean.
7050 REM ========================================================
7060 REM Variable Descriptions
7070 REM Entering -
7080 REM VARIANCE: statistical variance
7090 REM Exiting -
7100 REM none (subroutine is procedural)
7110 REM Local -
7120 REM DEV: standard deviation
7130 REM STDERR: standard error of the mean
7140 REM ========================================================
7150 DEV = SQR(VARIANCE)
7160 STDERR = DEV / SQR(TOTAL)
7170 PRINT "STANDARD DEVIATION = ";DEV
7180 PRINT "STANDARD ERROR OF THE MEAN = ";STDERR
7190 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Stirling)
130 REM =========================================================
140 FOR J = 9 TO 12
150 NUM = J
160 PRINT "INTEGER FOR WHICH FACTORIAL ";"WILL BE COMPUTED IS";NUM
170 GOSUB 1000 '<< call stirling's approximation
180 PRINT "LOG OF FACTORIAL IS APPROXIMATELY";APPR
190 IF NUM < 34 THEN PRINT "FACTORIAL IS APPROXIMATELY";INT(EXP(APPR)+.5)
200 PRINT
210 NEXT J
220 END
1000 REM ========================================================
1010 REM ********************>> STIRLING <<**********************
1020 REM ========================================================
1030 REM Stirling's approximation is useful in applications
1040 REM which require calculation of porbabilities, combin-
1050 REM ations, and permutations. The subroutine returns
1060 REM the exact log of N factorial for values <= 10, and
1070 REM returns the approximation of the log of n factorial
1080 REM for values larger than 10.
1090 REM Stirling's approximation is useful in applications
1100 REM ========================================================
1110 REM Variable Descriptions
1120 REM Entering -
1130 REM NUM: integer for which factorial is to be computed
1140 REM Exiting -
1150 REM APPR: Stirling's approximation of log of NUM
1160 REM Local -
1170 REM K9: loop index for factorial up to 10
1180 REM ========================================================
1190 APPR = 1
1200 IF NUM <= 0 THEN APPR = 0 : RETURN
1210 FOR K9 = 1 TO 10
1220 APPR = APPR * K9
1230 IF NUM = K9 THEN APPR = LOG(APPR) : RETURN
1240 NEXT K9
1250 APPR = LOG(6.283186)/2+LOG(NUM)*(NUM+.5)-NUM+1/(12*NUM)
1260 RETURN
100 REM ========================================================
110 REM DRIVER PROGRAM
111 REM ========================================================
120 REM This subroutine is a set of subroutines which
130 REM produce systematic(as opposed to random-order)
140 REM permutations of a series of values.
150 REM If program structure appears strange to you,
160 REM it is because the algorithm was directly adapted
170 REM from the original, written in Pascal language.
180 REM ========================================================
190 DIM A(12), S(500),T(500)
220 PRINT "ENTER NUMBER OF SET MEMBERS TO BE PERMUTATED:"
230 INPUT N
240 PRINT "HOW MANY PERMUTATIONS TO BE RETURNED?"
250 INPUT T
260 K = N
270 FOR I = 1 TO N
280 A(I) = I
290 NEXT I
300 GOSUB 1030 '<< call permute
310 END
1000 REM =======================================================
1010 REM ******************>> SYSTPERM <<***********************
1020 REM =======================================================
1030 IF K = 1 THEN 4010 '<< call print
1040 GOSUB 2010 '<< call stack push
1050 K = K - 1
1060 GOSUB 1030 '<< call permute
1070 I = 1
1080 IF I = K THEN 1200
1090 X = A(I)
1100 A(I) = A(K)
1110 A(K) = X
1120 GOSUB 2010 '<< call stack push
1130 K = K - 1
1140 GOSUB 1030 '<< call permute
1150 X = A(I)
1160 A(I) = A(K)
1170 A(K) = X
1180 I = I + 1
1190 GOTO 1080
1200 GOSUB 3010 '<< call stack pop
1210 RETURN
1220 REM:
2000 REM =======================================================
2010 REM ***********************>> PUSH <<**********************
2020 REM =======================================================
2030 P = P + 1
2040 S(P) = K
2050 T(P) = I
2060 RETURN
3000 REM ========================================================
3010 REM ***********************>> POP <<***********************
3020 REM ========================================================
3030 K = S(P)
3040 I = T(P)
3050 P = P - 1
3060 RETURN
4000 REM ========================================================
4010 REM ********************>> PRINT <<**************************
4020 REM ========================================================
4030 FOR J = 1 TO N
4040 PRINT A(J);
4050 NEXT J
4060 PRINT
4070 Z = Z + 1
4080 IF Z = T THEN END ELSE 1200
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Timpoint)
130 REM =========================================================
140 DIM SET(12),CUM(12)
150 DIM P$(12),FRACTION$(12)
160 RANDOMIZE
170 MEDIAN = 16
180 GOSUB 1000 '<< call pitch class table
190 FOR J = 1 TO 4
200 GOSUB 2000 '<< call set generator
210 PRINT "RANDOM-ORDER 12-TONE ROW #";J;"MOD";MDLS;"--"
220 FOR J1 = 0 TO 11
230 PRINT P$(SET(J1));" "; '<< series to screen
240 NEXT J1
250 PRINT
260 PRINT "THE NUMERIC EQUIVALENT --"
270 FOR J1 = 0 TO 11
280 PRINT SET(J1);
290 NEXT J1
300 PRINT
310 PRINT "DURATIONS REPRESENTING THE DISTANCE";" BETWEEN TIME POINTS --"
320 PRINT "(USING A 16TH-NOTE PULSE BASE ";"AND A MEASURE OF ";MDLS;"-16THS)"
330 GOSUB 3000 '<< call timepoint generator
340 FOR J1 = 0 TO 11
350 PRINT FRACTION$(J1); '<< timepoints to screen
360 NEXT J1
370 PRINT "TOTAL OF DURATIONS =";TALLY;
380 PRINT
390 PRINT
400 NEXT J
410 END
1000 REM ========================================================
1010 REM ********************>> PITCHTAB <<**********************
1020 REM (modified to load pitch classes only)
1030 REM ========================================================
1040 FOR J = 0 TO 11
1050 READ P$(J) '<< load pitch classes
1060 NEXT J
1070 REM+++++++++++++++++++++++++++++++++
1080 DATA C,C#,D,D#,E,F,F#,G,G#,A,A#,B
1090 REM+++++++++++++++++++++++++++++++++
1100 RETURN
2000 REM ========================================================
2010 REM ********************>> SETFLAG <<***********************
2020 REM (modified to generate modulus-converted
2030 REM series and reset flag array)
2040 REM ========================================================
2050 MDLS = 12/J '<< change modulus for each new series
2060 FOR K9 = 0 TO 11
2070 R9 = INT(RND * 12)
2080 IF CUM(R9) = 1 THEN 2070
2090 CUM(R9) = 1
2100 SET(K9) = R9 MOD MDLS
2110 NEXT K9
2120 FOR K9 = 0 TO 12
2130 CUM(K9) = 0 '<< zero flags prior to next call
2140 NEXT K9
2150 RETURN
3000 REM ========================================================
3010 REM *********************>> TIMPOINT <<*********************
3020 REM ========================================================
3030 REM This subroutine produces rhythm duration values
3040 REM using the serial 'timepoint system'. That is,
3050 REM a sequence of time durations,mod n,is derived
3060 REM from the distance between consecutive set
3070 REM members. The modulus determines the number of
3080 REM metrical pulses contained within one measure.
3090 REM ========================================================
3100 REM Variable Descriptions
3110 REM Entering -
3120 REM SET(): array of series values
3130 REM MDLS: modulus for computation
3140 REM MEDIAN: basic pulse unit
3150 REM Exiting -
3160 REM FRACTION$(): character array of time durations
3170 REM TALLY: total of time durations
3180 REM Local -
3190 REM DUR: fraction numerator
3200 REM K9: loop index, pointer to SET()
3210 REM =======================================================
3220 TALLY = 0
3230 FOR K9 = 0 TO 10
3240 IF SET(K9+1) <= SET(K9) THEN DUR = MDLS - SET(K9) + SET(K9+1)ELSE DUR = SET(K9+1) - SET(K9)
3250 TALLY = TALLY + DUR
3260 FRACTION$(K9) = STR$(DUR) + "/" + STR$(MEDIAN)
3270 NEXT K9
3280 DUR = MDLS - SET(K9)
3290 TALLY = TALLY + DUR
3300 FRACTION$(11) = STR$(DUR) + "/" + STR$(MEDIAN)
3310 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM =========================================================
130 REM To change the probabilities in this program, edit
140 REM the DATA statements which are read into the table.
150 REM =========================================================
160 DIM P(4,4),P$(4)
170 REM >> load pitch character set
180 P$(1)="C"
190 P$(2)="F"
200 P$(3)="G"
210 P$(4)="B"
220 TOTAL = 25
230 LASTPITCH = 3
240 PRINT
250 PRINT "CURRENT PROBABILITY TABLE --"
260 FOR J1 = 1 TO 4
270 FOR J2 = 1 TO 4
280 READ P(J1,J2) '<< load probability table
290 PRINT P(J1,J2), '<< send to screen
300 NEXT J2
310 PRINT
320 NEXT J1
330 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
340 DATA .0,.5,.1,.0
350 DATA .1,.2,.5,.1
360 DATA .6,.3,.1,.5
370 DATA .3,.0,.3,.4
380 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
390 RANDOMIZE
400 PRINT P$(LASTPITCH);" ";
410 FOR J = 1 TO TOTAL-1
420 GOSUB 1000 '<< call transition probability
430 PRINT P$(NEXTPITCH);" "; '<< send choice to screen
440 LASTPITCH = NEXTPITCH
450 NEXT J
460 END
1000 REM ========================================================
1010 REM *********************>> TRANTABL <<*********************
1020 REM ========================================================
1030 REM This subroutine incorporates a first-order
1040 REM transitional probability table to determine
1050 REM melodic pitch class sequence.
1060 REM
1070 REM A 2-dimensional matrix holds occurence frequency
1080 REM probabilities which make the current note choice
1090 REM conditional on the previous choice.
1100 REM The appropriate probabilities are entered in the
1110 REM matrix P(), either as program DATA statements,
1120 REM or via user INPUT statements.
1130 REM
1140 REM For output data to be accurate, it is important
1150 REM that the sum of each column be 1.0. Moreover,
1160 REM the data table should be well thought out to
1170 REM prevent situations with no exit. For instance,
1180 REM if, in the following table, the probability that C
1190 REM follows F is changed to 0.0, the probability that
1200 REM F follows F is changed to 1.0, and the probability
1210 REM that G follows F is changed to 0.0, nothing but the
1220 REM pitch F will be generated once F is selected.
1230 REM
1240 REM ================== example of concept ==================
1250 REM
1260 REM L A S T P I T C H
1270 REM C F G B
1280 REM |--------|--------|--------|---------|
1290 REM C | 0.0 | 0.5 | 0.1 | 0.0 |
1300 REM NEXT |--------|--------|--------|---------|
1310 REM F | 0.1 | 0.2 | 0.5 | 0.1 |
1320 REM PITCH |--------|--------|--------|---------|
1330 REM G | 0.6 | 0.3 | 0.1 | 0.5 |
1340 REM |--------|--------|--------|---------|
1350 REM B | 0.3 | 0.0 | 0.3 | 0.4 |
1360 REM |--------|--------|--------|---------|
1370 REM
1380 REM Read the columns for last pitch, rows for next pitch.
1390 REM For instance, if the last pitch returned was B
1400 REM (col 4), then the probability of the next pitch being
1410 REM B (row 4) is 0.1. This principle can be extended to
1420 REM three, four, or more dimensions, but quickly becomes
1430 REM difficult to comprehend.
1440 REM ========================================================
1450 REM Variable Descriptions
1460 REM Entering -
1470 REM LASTPITCH: holds last note choice
1480 REM Exiting -
1490 REM NEXTPITCH: holds the current note choice
1500 REM Local -
1510 REM U: uniform random number
1520 REM T9: threshold test value
1530 REM K9: loop index, pointer to data table
1540 REM =======================================================
1550 U = RND
1560 T9 = 0
1570 FOR K9 = 1 TO 4
1580 T9 = P(K9,LASTPITCH) + T9
1590 IF U <= T9 THEN 1610
1600 NEXT K9
1610 NEXTPITCH = K9
1620 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Triangle)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 GOSUB 1000 '<< call triangular distribution function
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM ********************>> TRIANGLE <<**********************
1020 REM ========================================================
1030 REM The Triangular Distribution Function generates
1040 REM continuous, random-order real numbers > 0 & < 1.
1050 REM Middle-valued results are most likely to occur.
1060 REM ========================================================
1070 REM Variable Descriptions
1080 REM Entering -
1090 REM TOTAL: length of sequence
1100 REM Exiting -
1110 REM X(): array holding triangular distribution
1120 REM Local -
1130 REM R8: random number 1
1140 REM
1150 REM R9: random number 2
1160 REM ========================================================
1170 FOR K9 = 1 TO TOTAL
1180 R8 = RND
1190 R9 = RND
1200 X(K9) = .5 * (R8+R9)
1210 NEXT K9
1220 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (TSEARCH1)
130 REM =========================================================
140 DIM X(200)
150 TOTAL = 200
160 LOW = 1
170 HIGH = 60
180 RANGE = HIGH - LOW + 1
190 RANDOMIZE
200 PRINT "ARRAY OF RANDOM-ORDER NUMBERS (RANGE 1-";RANGE;")"
210 FOR J = 1 TO TOTAL
220 X(J) = INT(RND * RANGE)+1
230 PRINT X(J);
240 NEXT J
250 PRINT
260 PRINT
270 TABLKEY = LOW
280 PRINT "LOWEST VALUE -";LOW
290 GOSUB 1000 '<< call linear unsorted table search
300 TABLKEY = HIGH
310 PRINT "HIGHEST VALUE -";HIGH
320 GOSUB 1000 '<< call linear unsorted table search
330 END
1000 REM SS2TL1 =================================================
1010 REM *********************>> TSEARCH1 <<*********************
1020 REM ========================================================
1030 REM This linear unsorted table search subroutine
1040 REM scans a value sequence (list) for occurrences of
1050 REM keyed values. In this implementation, the search
1060 REM is for array positions where the low and high
1070 REM boundaries of the random generator range are stored.
1080 REM If the values are not found to be present at all,
1090 REM a message to that effect is printed. Although not
1100 REM strictly a part of the searching algorithm, an
1110 REM value occurrence counter (ITEMCOUNT) has been
1120 REM included .
1130 REM
1140 REM If TSEARCH is to be applied to pitch, then the
1150 REM indicated key positions would be used to reference
1160 REM the appropriate addresses in the pitch character
1170 REM string array (table).
1180 REM ========================================================
1190 REM Variable Descriptions
1200 REM Entering -
1210 REM X(): array of bounded random integers
1220 REM TOTAL: length of sequence
1230 REM TABLKEY: search argument (key to search for)
1240 REM Exiting -
1250 REM none (subroutine is procedural)
1260 REM Local -
1270 REM ITEMCOUNT: occurrence frequency tabulator
1280 REM K9: loop index, pointer to X(),
1290 REM key position indicator
1300 REM =======================================================
1310 ITEMCOUNT = 0
1320 FOR K9 = 1 TO TOTAL
1330 IF TABLKEY = X(K9)THEN PRINT "FOUND AT POSITION ";K9 ELSE 1350
1340 ITEMCOUNT = ITEMCOUNT + 1
1350 NEXT K9
1360 PRINT "KEY ITEM OCCURRED";ITEMCOUNT;"TIME(S)"
1370 PRINT
1380 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (TSEARCH2)
130 REM =========================================================
140 DIM X(50)
150 TOTAL = 50
160 PRINT "A SORTED ARRAY OF INTEGERS (RANGE 1-100) --"
170 FOR J = 1 TO TOTAL
180 X(J) = J * 2
190 PRINT X(J);
200 NEXT J
210 PRINT
220 PRINT
230 ARG = 58
240 PRINT "THE INTEGER";ARG; "WILL BE THE ITEM TO SEARCH FOR"
250 GOSUB 1000
260 IF KPOS = 0 THEN PRINT "NOT FOUND" ELSE PRINT "KEY ";ARG;"= POS"KPOS;
270 END
1000 REM SS1TL2 ================================================
1010 REM *******************>> TSEARCH2 <<**********************
1020 REM =======================================================
1030 REM This binary search subroutine requires a sorted
1040 REM table with unique entry keys. It is the fastest
1050 REM algorithm in common use, and have a variety of
1060 REM compositional application - from simple boundary
1070 REM searches to test condition retrieval.
1080 REM =======================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM X() array of sorted items (keys)
1120 REM TOTAL: length of array X()
1130 REM ARG: search argument (item to look for)
1140 REM Exiting -
1150 REM KPOS: location (address) of item if found,
1160 REM 0 if not found
1170 REM Local -
1180 REM LL: lower limit for current search portion
1190 REM UL: upper limit for current search portion
1200 REM KVAL: computed value of key
1210 REM MP: computed halfway point
1220 REM ========================================================
1230 LL=0
1240 UL=TOTAL+1
1250 KPOS=0
1260 IF ARG < X(1) OR ARG > X(TOTAL)THEN RETURN
1270 IF UL >=LL
THEN MP=INT((UL+LL)/2) : KV=X(MP) :
IF KV <> ARG
THEN IF KV >= ARG
THEN UL=MP-1 : GOTO 1270
ELSE LL=MP+1 : GOTO 1270
ELSE KPOS=MP
ELSE KPOS=UL
1280 IF ARG <> X(KPOS)
THEN KPOS = 0
1290 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (TSEARCH3)
130 REM =========================================================
140 DIM X(52)
150 TOTAL = 50
160 PRINT "A SORTED ARRAY OF INTEGERS (RANGE 1-100) --"
170 FOR J = 1 TO TOTAL
180 X(J) = J * 2
190 PRINT X(J);
200 NEXT J
210 PRINT
220 PRINT
230 ARG = 96
240 PRINT "THE INTEGER";ARG; "WILL BE THE ITEM TO SEARCH FOR"
250 GOSUB 1000 '<< call interpolation search
260 IF KPOS = 0 THEN PRINT "NOT FOUND" ELSE PRINT "KEY ";ARG;"= POS";KPOS;
270 END
1000 REM SS2TL2 =================================================
1010 REM *********************>> TSEARCH3 <<*********************
1020 REM ========================================================
1030 REM This Interpolation Search subroutine requires a
1040 REM sorted list of unique keys (elements). It is
1050 REM faster than the Binary Search in some cases,
1060 REM particularly when the distribution of items is
1070 REM highly skewed. It uses the key's value as an
1080 REM indicator of where to begin the search. which is
1090 REM similar to the method most people use to index
1100 REM an element in a sorted list. Musical applications
1110 REM range from analysis of random-order data to
1120 REM retrieval of stored condition in rule-based
1130 REM compositional procedures.
1140 REM ========================================================
1150 REM Variable Descriptions
1160 REM Entering -
1170 REM X(): array of sorted items (keys)
1180 REM TOTAL: length of array X()
1190 REM Exiting -
1200 REM KPOS: location (address) of item if found,
1210 REM 0 if not found
1220 REM Local -
1230 REM LL: lower search boundary
1240 REM UL: upper search boundary
1250 REM LOKEY: key at lower boundary
1260 REM UPKEY: key at upper boundary
1270 REM INTPOS: interpolated position in array for
1280 REM next comparison
1290 REM INTKEY: key at interpolated position
1300 REM ========================================================
1310 LL = 0
1320 UL = TOTAL + 1
1330 X(LL) = X(1) - 1
1340 X(UL) = X(TOTAL) + 1
1350 LOKEY = X(1)
1360 UPKEY = X(TOTAL)
1370 KPOS = 0
1380 IF ARG < LOKEY OR ARG > UPKEY THEN RETURN
1390 IF UL < LL THEN RETURN
1400 INTPOS = LL + INT((UL - LL) * (ARG - LOKEY) / (UPKEY - LOKEY))
1410 INTKEY = X(INTPOS)
1420 IF INTKEY <> ARG
THEN IF INTKEY >= ARG
THEN UL = INTPOS - 1: UPKEY = INTKEY: GOTO 1390
ELSE LL = INTPOS + 1: LOKEY = INTKEY: GOTO 1390
ELSE KPOS = INTPOS
1430 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (TSEARCH4)
130 REM =========================================================
140 DIM X(52)
150 TOTAL = 50
160 PRINT "A SORTED ARRAY OF INTEGERS (RANGE 1-100) --"
170 FOR J = 1 TO TOTAL
180 X(J) = J * 2
190 PRINT X(J);
200 NEXT J
210 PRINT
220 PRINT
230 ARG = 42
240 SWIDTH = 5
250 PRINT "THE INTEGER";ARG;"WILL BE THE ITEM TO SEARCH FOR"
260 GOSUB 1000 '<< call interpolation search
270 FOR J =LLL TO LUL
280 PRINT X(J) '<< send returned segment to screen
290 NEXT J
300 END
1000 REM SS1TL3 =================================================
1010 REM *********************>> TSEARCH4 <<*********************
1020 REM ========================================================
1030 REM This Proximity Search subroutine requires a
1040 REM sorted list of unique keys (elements). It is
1050 REM more powerful than the Binary Search in that
1060 REM it returns a subset of the array on either side
1070 REM of the key (even if the requested item is missing
1080 REM from the list. This method may be preferable for
1090 REM compositional applications which require searching
1100 REM of rule-groups for prioritized solutions to compos-
1110 REM itional problems, an approach gaining popularity
1120 REM as an alternative to the Monte Carlo method of
1130 REM random number parameter generation.
1140 REM ========================================================
1150 REM Variable Descriptions
1160 REM Entering -
1170 REM X(): array of sorted items (keys)
1180 REM TOTAL: length of array X()
1190 REM ARG: search argument (item to look for)
1200 REM SWIDTH: width of search below & above item
1210 REM Exiting -
1220 REM LUL: upper limit of list of items returned
1230 REM LLL: lower limit of list of items returned
1240 REM Local -
1250 REM K9: loop index, pointer to array X()
1260 REM ========================================================
1270 FOR K9=1 TO TOTAL
1280 IF ARG <= X(K9) THEN 1310
1290 NEXT K9
1300 K9=TOTAL+1
1310 IF ARG=X(K9) THEN LUL=K9+SWIDTH ELSE LUL=K9+SWIDTH-1
1320 LLL=K9-SWIDTH
1330 IF LUL > TOTAL THEN LUL=TOTAL
1340 IF LLL < 1 THEN LLL=1
1350 RETURN
100 REM =========================================================
110 REM ==================== DRIVER PROGRAM =====================
120 REM =========================================================
130 DIM TONE(84)
140 NUMTONES = 84
150 OCTDIV = 19 '<< specify a 19-tone per octave scale
160 FREQ1 = 61.735
170 GOSUB 1000 '<< call tuning compiler
180 FOR J= 1 TO NUMTONES
190 PRINT TONE(J), '<< send scale frequencies to screen
200 NEXT J
210 END
1000 REM ========================================================
1010 REM ********************>> TUNINGS <<***********************
1020 REM ========================================================
1030 REM This subroutine compiles a data table containing
1040 REM equal-tempered, octave-repeating tunings.
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM
1080 REM Entering -
1090 REM FREQ1: frequency in Herz (cps) of scale tonic
1100 REM NUMTONES: number of pitches to compute
1110 REM OCTDIV: number of equalsize steps within octave
1120 REM Exiting -
1130 REM TONE(): array of computed scale frequencies
1140 REM Local -
1150 REM COEFF: coefficient for specified octave division
1160 REM K9: loop index, pointer to array TONE()
1170 REM
1180 REM ========================================================
1190 COEFF = 2^(1/OCTDIV)
1200 TONE(1) = INT(FREQ1+.5)
1210 FOR K9= 2 TO NUMTONES
1220 TONE(K9) = INT(TONE(K9-1)*COEFF+.5)
1230 NEXT K9
1240 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
115 REM (Valratio)
120 REM =========================================================
130 DIM P(12),X(100)
140 RANDOMIZE(-29312)
150 TOTAL = 100
160 RANGE = 12
170 WINDO = 4
180 GOSUB 1000 '<< call value ratio control
185 PRINT "SIZE OF VALUE WINDOW IS ";WINDO
190 FOR J = 1 TO 100
200 PRINT X(J),
210 NEXT J
220 END
1000 REM ========================================================
1010 REM ******************>> REPRATIO <<***********************
1020 REM ========================================================
1030 REM This algorithm prevents repetition of values which
1040 REM fall within a specified 'window' of predetermined
1050 REM size. For instance, if 100 values are to be
1060 REM returned, a window of 9 is specified, and a
1070 REM random number value range of 1-10 is entered,
1080 REM then the sequence which is generated will be a
1090 REM non-repeating series (set). However, if a smaller
1100 REM window is entered, then only the values falling
1110 REM within the sliding 'window' will be prevented
1120 REM from containing repetitions.
1130 REM ========================================================
1140 REM Variable Descriptions
1150 REM
1160 REM Entering -
1170 REM TOTAL: number of values to be returned
1180 REM RANGE: 1-n inclusive limits for random numbers
1190 REM WINDO: size of window for repetition prevention
1200 REM Exiting -
1210 REM X(): array holding sequence of values
1220 REM Local -
1230 REM U: random number, pointer to array P()
1240 REM P(): array which records value occurence
1250 REM K9: loop index, pointer to array X()
1260 REM
1270 REM ========================================================
1280 FOR K9 = 1 TO TOTAL
1290 U = INT(RND * RANGE)+1
1300 IF P(U) = 1 THEN 1290
1310 P(U) = 1
1320 X(K9) = U
1330 IF K9 <= WINDO THEN 1350
1340 P(X(K9-WINDO)) = 0
1350 NEXT K9
1360 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
115 REM (Valuprobs)
120 REM =========================================================
130 DIM WTABLE(5), X(40)
140 RANDOMIZE
150 PROBS = 5
160 TOTAL = 40
170 GOSUB 1000 '<< call probability table subr.
180 GOSUB 2000 '<< call table look-up & test
190 FOR J = 1 TO TOTAL
200 PRINT X(J), '<< send choices to screen
210 NEXT J
220 END
1000 REM ========================================================
1010 REM *******************>> PROBTABL <<**********************
1020 REM ========================================================
1030 REM This subroutine reads relative weights into a
1040 REM cumulative probability table (array).
1050 REM ========================================================
1060 REM Variable Descriptions
1070 REM Entering -
1080 REM PROBS: number of relative probability weights
1090 REM Exiting -
1100 REM WTABLE(): data table containing relative weights
1110 REM Local -
1120 REM WSUM: holds current sum of probability weights
1130 REM K9: loop index, pointer to array WTABLE()
1140 REM ========================================================
1150 WSUM = 0
1160 FOR K9 = 1 TO PROBS
1170 READ WTABLE(K9)
1180 WTABLE(K9)=WTABLE(K9)+WSUM
1190 WSUM=WTABLE(K9)
1200 NEXT K9
1210 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1220 DATA 1,2,3,4,5
1230 REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1240 RETURN
2000 REM ========================================================
2010 REM *******************>> PROBCALC <<***********************
2020 REM ========================================================
2030 REM This subroutine generates the numbers 1-n over a
2040 REM run of n values in relative proportion to the
2050 REM probability weights contained in WTABLE().
2060 REM The numbers may be used directly, or they may
2070 REM serve as pointers to pitch class characters,
2080 REM rhythmic duration, volume, or articulation
2090 REM arrays.
2100 REM ========================================================
2110 REM Variable Descriptions
2120 REM Entering -
2130 REM TOTAL: number of values to be returned
2140 REM WTABLE(): array containing relative weights
2150 REM PROBS: number of relative probability weights
2160 REM WSUM: holds current sum of probability weights
2170 REM Exiting -
2180 REM X(): array containing selected values
2190 REM Local -
2200 REM WSUM: stores current sum of probability weights
2210 REM R: random number, scaled to sum of weights
2220 REM L9: loop index, pointer to WTABLE()
2230 REM K9: loop index, pointer to array X()
2240 REM ========================================================
2250 FOR K9 = 1 TO TOTAL
2260 R = RND * WSUM
2270 FOR L9 = 1 TO PROBS
2280 IF R <= WTABLE(L9) THEN 2300
2290 NEXT L9
2300 X(K9) = L9
2310 NEXT K9
2320 RETURN
100 REM =========================================================
110 REM VECTORS
120 REM =========================================================
130 REM The subroutine VECTSTOR creates 'event vectors'
140 REM by storing pitch, rhythm and volume data for a
150 REM single musical event in one double precision number.
170 REM The subroutine PARXTRCT extracts the event attributes
180 REM from the composite value.
200 REM =========================================================
210 REM =========================================================
220 REM Variable Descriptions
230 REM
240 REM P: holds value of event vector pitch parameter
250 REM R: holds value of event vector rhythm parameter
260 REM V: holds value of event vector volume parameter
270 REM COMP#(): double precision vector (values P,R,V)
280 REM K9: loop index, pointer to array COMP#()
290 REM
300 REM =========================================================
310 REM =================== DRIVER PROGRAM ======================
320 REM =========================================================
330 DIM COMP#(10)
340 GOSUB 1000 '<< call event vector storage
350 PRINT
360 GOSUB 2000 '<< call event vector extract
370 END
1000 REM ========================================================
1010 REM ******************>> VECTSTOR <<************************
1020 REM ========================================================
1030 PRINT "STORE EVENT PARAMETERS IN DBL PRECIS. NUMBER --
1040 FOR K9= 1 TO 10
1050 P = K9 '<< assign pitch value
1060 R = K9 * 5 '<< assign rhythm duration value
1070 V = K9 * 10 '<< assign volume level value
1080 PRINT "PITCH = ";P,"RHYTHM = ";R, "VOLUME =";V,
1090 COMP#(K9) = (P * 1000000!) + (R * 1000) + V
1100 PRINT "COMPOSITE NUMBER IS ";COMP#(K9)
1110 NEXT K9
1120 RETURN
2000 REM ========================================================
2010 REM *******************>> PARXTRCT <<***********************
2020 REM ========================================================
2030 PRINT "EXTRACT EVENT PARAMETERS FROM COMPOSITE NUMBER--"
2040 FOR K9 = 1 TO 10
2050 COMP#(K9) = COMP#(K9)/1000000!
2060 P = INT(COMP#(K9))
2070 PRINT "P=";P ,
2080 R = INT((COMP#(K9) - INT(COMP#(K9))) * 1000)
2090 PRINT "R=";R ,
2100 COMP#(K9) = COMP#(K9) * 1000
2110 V = INT((COMP#(K9) - INT(COMP#(K9))) * 1000+.5)
2120 PRINT "V=";V
2130 NEXT K9
2140 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Voss)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
170 LAST = 24
180 GOSUB 1000 '<< call one-over-f distribution function
190 FOR J = 1 TO TOTAL
200 PRINT X(J); '<< sequence to screen
210 NEXT J
220 END
1000 REM ========================================================
1010 REM ********************>> VOSS <<**************************
1020 REM ========================================================
1030 REM This subroutine generates 1/f fractional noise
1040 REM patterns for use in any musical parameter. Each
1050 REM subsequent value is conditional on the last value
1060 REM generated, and all generated values correlate
1070 REM logarithmically with the past, resulting in a
1080 REM process which has longe-range memory.
1090 REM ========================================================
1100 REM Variable Descriptions
1110 REM Entering -
1120 REM TOTAL: length of sequence
1130 REM LAST: last value generated
1140 REM Exiting -
1150 REM X(): array holding one-over-f distribution
1160 REM Local -
1170 REM FRACT: current one-over-f value
1180 REM HALFVALS: 1/2 the number of possible values
1190 REM PROB: 1 / number of possible values
1200 REM R9: uniform random number
1210 REM S9: stores in-progress computation
1220 REM K9: loop index, pointer to array X()
1230 REM ========================================================
1240 REM
1250 REM
1260 FOR K9 = 1 TO TOTAL
1270 FRACT = 0
1280 HALFVALS = 16 ' = 1/2 number of poss values
1290 PROB = .03125 ' = 1/num poss values
1300 WHILE HALFVALS > = 1
1310 S9 = INT(LAST/HALFVALS)
1320 IF S9 = 1 THEN LAST = LAST-HALFVALS
1330 R9 = RND
1340 IF R9 < PROB THEN S9 = 1-S9
1350 FRACT= FRACT + S9 * HALFVALS
1360 HALFVALS = HALFVALS/2
1370 PROB = PROB * 2
1380 WEND
1390 X(K9) = FRACT
1400 LAST = FRACT
1410 NEXT K9
1420 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Weibull)
130 REM =========================================================
140 DIM X(50)
150 RANDOMIZE
160 TOTAL = 50
161 SPREAD = 20
162 DENSHAPE = 1
170 GOSUB 1000 '<< call Weibull distribution function
180 FOR J = 1 TO TOTAL
190 PRINT X(J); '<< sequence to screen
200 NEXT J
210 END
990 REM =========================================================
1000 REM **********************>> WEIBULL <<*********************
1010 REM ========================================================
1020 REM The Weibull Probability Distribution function
1030 REM generates random-order real numbers greater than
1040 REM zero. Its curve can assume a variety of shapes in
1050 REM accordance with the value of its input parameter,
1060 REM DENSHAPE. The SPREAD parameter controls only the
1070 REM horizontal scale.
1080 REM ========================================================
1090 REM Variable Descriptions
1100 REM Entering -
1110 REM TOTAL: length of sequence
1120 REM SPREAD: horizontal scaling parameter
1130 REM DENSHAPE : curve shaping parameter
1140 REM Exiting -
1150 REM X(): array holding Weibull distribution
1160 REM Local -
1170 REM R9: uniform random number
1180 REM K9: loop index, pointer to array X()
1189 REM ========================================================
1190 FOR K9 = 1 TO TOTAL
1200 R9 = RND
1210 R9=1/(1-R9)
1220 X(K9) = SPREAD * LOG(R9)^(1/DENSHAPE)
1230 NEXT K9
1240 RETURN
100 REM =========================================================
110 REM DRIVER PROGRAM
120 REM (Wordplay)
130 REM =========================================================
140 DIM WORD$(200),TEXT$(13)
150 DIM TXTLN(12),TXTWD(200),X(20),WTABL(20)
160 FOR J = 1 TO 20
170 X(J) = J
180 NEXT J
190 READ TOTAL
200 PRINT "THE ORIGINAL TEXT --"
210 FOR J = 1 TO TOTAL
220 READ TEXT$(J)
230 PRINT TEXT$(J)
240 NEXT J
250 PRINT
260 RANDOMIZE
270 PRINT "A RANDOM ORDERING OF THE TEXT LINES --"
280 GOSUB 1000
290 TEXT$(TOTAL) = TEXT$(TOTAL) + " #"
300 PRINT "WORDS IN TEXT" : PRINT
310 CHARSET$ =" abcdefghijklmnopqrstuvwxyz0123456789"
320 CHARSET$ = CHARSET$ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
330 ENDFLAG = 0 : PHRPTR = 1 : POSIT = 1 : COUNT = 0
340 WHILE ENDFLAG <> 1
350 GOSUB 2000 '<< call next word
360 CLNWORD$ = NXTWORD$
370 GOSUB 3000 '<< call string clean-up & compress
380 WRDCNT = WRDCNT + 1
390 NXTWORD$ = CLNWORD$
400 PRINT NXTWORD$,
410 WORD$(WRDCNT) = NXTWORD$
420 SIZE = LEN(NXTWORD$)
430 WTABL(SIZE) = WTABL(SIZE) + 1
440 WEND
450 PRINT
460 P$=" ## ### ## ###"
470 PRINT "length frequency length frequency"
480 FOR J = 1 TO 20 STEP 2
490 PRINT USING P$;J,WTABL(J),J+1,WTABL(J+1)
500 NEXT J
510 GOSUB 4000 '<< call weighted average
520 PRINT
530 PRINT "AVERAGE WORD LENGTH = ";AVERAGE
540 PRINT "A RANDOM ORDERING OF THE TEXT WORDS --"
550 GOSUB 5000 '<< call random word-walk
560 PRINT
570 END
580 REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
590 DATA 12
600 DATA "At morn -at noon -at twilight dim-"
610 DATA "Maria! thou hast heard my hymn!"
620 DATA "In joy and woe -in good and ill-"
630 DATA "Mother of God, be with me still!"
640 DATA "When the hours flew brightly by,"
650 DATA "And not a cloud obscured the sky,"
660 DATA "My soul, lest it should truant be,"
670 DATA "Thy grace did guide to thine and thee;"
680 DATA "Now, when storms of Fate o'rcast"
690 DATA "Darkly my Present and my Past,"
700 DATA "Let my Future radiant shine"
710 DATA "With sweet hopes of thee and thine!"
720 REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1000 REM ========================================================
1010 REM ********************>> RANDLINE <<**********************
1020 REM ========================================================
1030 REM This subroutine is an adaptation of the sampling-
1040 REM without-replacement algorithm. It simply uses the
1050 REM ARRAYFLAG method of serializing the lines, then
1060 REM returns one copy of each line in random-order.
1070 REM ========================================================
1080 REM Variable Descriptions
1090 REM Entering -
1100 REM TEXT$(): array holding lines of text
1110 REM TOTAL: number of lines in TEXT$()
1120 REM Exiting -
1130 REM none (subroutine is procedural)
1140 REM Local -
1150 REM LINSTEP: random number
1160 REM TXTLN(): array to store occurrence flags
1170 REM K9: loop index
1180 REM ========================================================
1190 FOR K9 = 1 TO TOTAL
1200 LINSTEP = INT(RND * TOTAL)+1
1210 IF TXTLN(LINSTEP)= 1 THEN 1200
1220 PRINT TEXT$(LINSTEP)
1230 TXTLN(LINSTEP) = 1
1240 NEXT K9
1250 RETURN
2000 REM ========================================================
2010 REM ********************>> NEXTWORD <<**********************
2020 REM ========================================================
2030 REM This subroutine extracts the next word in line
2040 REM from the list of phrases supplied by the DRIVER
2050 REM PROGRAM, which also passes several flags to
2060 REM signal the processing status. End-of-word is
2070 REM indicated by (" "), end-of-phrase by ("_#").
2080 REM ========================================================
2090 REM Variable Descriptions
2100 REM Entering -
2110 REM TEXT$(): list of phrases to be broken into words
2120 REM PHRPTR: phrase pointer
2130 REM POSIT: position in phrase being analyzed
2140 REM Exiting -
2150 REM ENDFLAG: signal for end of processing (if = 1)
2160 REM NXTWORD$: next word (extracted)
2170 REM Local -
2180 REM SCANCHAR$: character being scanned
2190 REM K9: phrase loop index
2200 REM L9: word loop index
2210 REM ========================================================
2220 NXTWORD$ = ""
2230 FOR K9 = POSIT TO LEN(TEXT$(PHRPTR))
2240 SCANCHAR$ = MID$(TEXT$(PHRPTR),K9,1)
2250 IF SCANCHAR$ = "#" THEN ENDFLAG = 1 : RETURN
2260 IF SCANCHAR$ <> " " THEN 2300
2270 NEXT K9
2280 PHRPTR = PHRPTR + 1 : POSIT = 1
2290 IF NXTWORD$ = "" THEN 2230 ELSE ENDFLAG = 0 : RETURN
2300 NXTWORD$ = NXTWORD$ + SCANCHAR$
2310 IF K9 = LEN(TEXT$(PHRPTR)) THEN PHRPTR = PHRPTR + 1 : POSIT = 1 :ENDFLAG = 0 : RETURN
2320 FOR L9 = K9 + 1 TO LEN(TEXT$(PHRPTR))
2330 SCANCHAR$ = MID$(TEXT$(PHRPTR),L9,1)
2340 IF SCANCHAR$ = " " THEN POSIT = L9 : GOTO 2380
2350 NXTWORD$ = NXTWORD$ + SCANCHAR$
2360 NEXT L9
2370 PHRPTR = PHRPTR + 1 : POSIT = 1
2380 ENDFLAG = 0
2390 RETURN
3000 REM ========================================================
3010 REM **********************>> STRCLEAN <<********************
3020 REM ========================================================
3030 REM This subroutine strips all special characters from
3040 REM a string, then compresses it.
3050 REM ========================================================
3060 REM Variable Descriptions
3070 REM Entering -
3080 REM CLNWORD$: string to be cleaned
3090 REM CHARSET$: string of legal characters to be kept
3100 REM Exiting -
3110 REM CLNWORD$: cleaned string
3120 REM Local -
3130 REM TBUFF$: temporary string buffer
3140 REM K9: loop index, pointer to CLNWORD$ characters
3150 REM ========================================================
3160 TBUFF$ = ""
3170 FOR K9 = 1 TO LEN(CLNWORD$)
3180 IF INSTR(CHARSET$,MID$(CLNWORD$,K9,1)) <> 0 THEN TBUFF$ = TBUFF$+MID$(CLNWORD$,K9,1)
3190 NEXT K9
3200 CLNWORD$ = TBUFF$
3210 RETURN
4000 REM ========================================================
4010 REM **********************>> AVERAGE <<*********************
4020 REM ========================================================
4030 REM This subroutine computes the weighted average length
4040 REM of all words contained in the text.
4050 REM ========================================================
4060 REM Variable Descriptions
4070 REM Entering -
4080 REM X(): array of values to be averaged
4090 REM WTABL(): array of weights corresponding to each X()
4100 REM TOTAL: number of values in X() and WTABL()
4110 REM Exiting -
4120 REM AVERAGE: weighted average length of words
4130 REM Local -
4140 REM PRODSUM: sum of products of value and weight
4150 REM WEIGHTSUM: sum of weights
4160 REM K9: loop index, pointer to WTABLE()
4170 REM ========================================================
4180 PRODSUM = 0 : WEIGHTSUM = 0
4190 FOR K9 = 1 TO TOTAL
4200 PRODSUM = PRODSUM + WTABL(K9) * X(K9)
4210 WEIGHTSUM = WEIGHTSUM + WTABL(K9)
4220 NEXT K9
4230 AVERAGE = PRODSUM / WEIGHTSUM
4240 RETURN
5000 REM ========================================================
5010 REM *********************>> RANDWORD <<*********************
5020 REM ========================================================
5030 REM This subroutine is identical in function to
5040 REM RANDLINE, except that it randomizes word order.
5050 REM ========================================================
5060 REM Variable Descriptions
5070 REM Entering -
5080 REM WORD$(): array holding words of text
5090 REM WRDCNT: number of words in array WORD$()
5100 REM Exiting -
5110 REM none (subroutine is procedural)
5120 REM Local -
5130 REM TXTWD(): array to store occurrence flags
5140 REM WRDSTEP: random number
5150 REM K9: loop index
5160 REM ========================================================
5170 FOR K9 = 1 TO WRDCNT
5180 WRDSTEP = INT(RND * WRDCNT)+1
5190 IF TXTWD(WRDSTEP) = 1 THEN 5180
5200 PRINT WORD$(WRDSTEP);" ";
5210 TXTWD(WRDSTEP) = 1
5220 IF K9 MOD 10 = 0 THEN PRINT
5230 NEXT K9
5240 RETURN
Back
