From: ihnp4!tektronix!amadeus.LA.TEK.COM!jrb
Subject: ravel info
Date: 20 Mar 88 18:46:29 PST (Sun)

.Ravel is a C like midi programming language.
It is interpreted and combines C like prog. language
features with midi facilities built-in to the language.
There is special support for certain Yamaha synths
like the dx7 and fb01 (and the archaic sixtrak). Other
synths can be used with no problem. The system is
aimed at algorithmic composition. There is a set
of built-in functions that aid aleatory (random-based)
composition. Certain motif based functions are also
available. 

.Machines:

	1. ibm-pc/mpu-401 only.
	Distribution disks are 9 sector 48tpi dsdd.

	2. Atari ST.  
	Distribution disks are single sided of course.

.Price. Introductory price is $30. This includes
a loose leaf programming manual of about 300 pages
and software on two disks. One music disk and one binary
disk. If a user pays $50, the user becomes registered.
This means that I will assume you are interested in
Ravel 3.0, any shared music or programs, bugs, and
whatever comes up. One may choose to pay $30 to take
a look and then throw in $20 to become registered.

.Available from
		Jim Binkley
		5814 SW Taylor
		Portland, Or. 97221


===== a copy of older Ravel 1.0 programs ======

#
# GAMELOT (sorry...)
#
# "gamelan like"  melody. 
#
# Dedicated to the Java Cafe, and Herr Van Gulik's origins.
#
# Taken from "Music of the Whole Earth", David Reck.
#

#
# This program requires a Yamaha fb01,
# to take advantage of cents tuning capability.
#
# four modes, 3 slendo and 1 pelog.
# piece switches states between 3 slendo modes and 1 pelog
# scale, that is not really setup for any particular mode.
#
# This should not be taken as a slight on Indonesian music
# OR a serious attempt to duplicate gamelan.
#

MAXNOTE = 18
SLENDRONOTES = 16
PELOGNOTES = 18

uchar snotes[MAXNOTE]
uchar scents[MAXNOTE]

uchar mode			# current mode
uchar melnote		# global melody note
uchar meltime		# global melody time
uchar counter
uchar nonotes

# set up 5 tone slendro scale
# slendro 5 tones are 263,223,253,236,225  cents apart in one octave
# sets up a slendo scale, assuming 5 notes with correct cents
# not used, but shows basic notes and cents. Key of C.
#
riff initSlendro()
	snotes[0] = C
	scents[0] = 0
	snotes[1] = D
	scents[1] = 63
	snotes[2] = E
	scents[2] = 86
	snotes[3] = G
	scents[3] = 39
	snotes[4] = A
	scents[4] = 75
end

# 7 tone pelog scale
# mode is lima
#
# C,C#,E,F,F#,A,B with appropriate cents
#
# 5 F
# 4 B
# 3 E
#
# 2 C
# 2 A
#  
# 1 C#
# 1 F#
# 18 notes needed
riff initPelog()
	snotes[0] = C
	scents[0] = 0
	snotes[7] = HC
	scents[7] = 0

	snotes[1] = C#
	scents[1] = 67

	snotes[2] = E
	scents[2] = 12
	snotes[8] = HE  
	scents[8] = 12
	snotes[9] = HE
	scents[9] = 12

	snotes[10] = HF
	scents[10] = 37
	snotes[3] = F
	scents[3] = 37
	snotes[17] = F
	scents[17] = 37
	snotes[16] = F
	scents[16] = 37
	snotes[15] = LF
	scents[15] = 37

	snotes[4] = F#
	scents[4] = 83

	snotes[5] = A
	scents[5] = 35
	snotes[12] = HA
	scents[12] = 35

	snotes[14] = LB 
	scents[14] = 0
	snotes[6] = B 
	scents[6] = 0
	snotes[11] = HB
	scents[11] = 0 
	snotes[13] = B
	scents[13] = 0 

end


# nem mode
# C,E,A emphasized, others are auxilliary
# we span two octaves
# 5 c
# 4 e
# 3 a
# 2 d, 2 g
riff initNem()
	snotes[0] = C
	scents[0] = 0
	snotes[5] = HC
	scents[5] = 0
	snotes[6] = C
	scents[6] = 0
	snotes[7] = HC
	scents[7] = 0
	snotes[12] = LC
	scents[12] = 0

	snotes[1] = D
	scents[1] = 63
	snotes[14] = HD
	scents[14] = 63

	snotes[2] = E
	scents[2] = 86
	snotes[8] = HE
	scents[8] = 86
	snotes[9] = E
	scents[9] = 86
	snotes[10] = HE
	scents[10] = 86

	snotes[3] = G
	scents[3] = 39
	snotes[15] = HG
	scents[15] = 39

	snotes[4] = A
	scents[4] = 75
	snotes[11] = HA
	scents[11] = 75
	snotes[13] = HA
	scents[13] = 75

end

# sanga mode
#
# 5 e 
# 4 a
# 3 d 
# 2 c
# 2 g
# 
riff initSanga()
	snotes[0] = C
	scents[0] = 0
	snotes[14] = HC
	scents[14] = 0

	snotes[1] = D
	scents[1] = 63
	snotes[5] = HD
	scents[5] = 63
	snotes[6] = D
	scents[6] = 63

	snotes[7] = LE
	scents[7] = 86
	snotes[2] = E
	scents[2] = 86
	snotes[8] = HE
	scents[8] = 86
	snotes[9] = E
	scents[9] = 86
	snotes[10] = HE
	scents[10] = 86

	snotes[3] = G
	scents[3] = 39
	snotes[15] = HG
	scents[15] = 39

	snotes[4] = A
	scents[4] = 75
	snotes[11] = HA 
	scents[11] = 75
	snotes[12] = A
	scents[12] = 75
	snotes[13] = HA
	scents[13] = 75

end

# 
# slendro scale, manjura mode
#
#	5 g
#	4 c
#	3 e
#	2 d
#	2 a
#
riff initManjura()
	snotes[0] = C
	scents[0] = 0
	snotes[5] = HC
	scents[5] = 0
	snotes[6] = C
	scents[6] = 0
	snotes[7] = HC
	scents[7] = 0

	snotes[1] = D
	scents[1] = 63
	snotes[14] = HD
	scents[14] = 63
	
	snotes[2] = E
	scents[2] = 86
	snotes[8] = HE
	scents[8] = 86
	snotes[9] = E
	scents[9] = 86

	snotes[10] = LG
	scents[10] = 39
	snotes[3] = G
	scents[3] = 39
	snotes[11] = HG
	scents[11] = 39
	snotes[12] = G
	scents[12] = 39
	snotes[13] = HG
	scents[13] = 39

	snotes[4] = A
	scents[4] = 75
	snotes[15] = HA
	scents[15] = 75
end

riff nextMode()
	if ( mode == 0 )
		nonotes = SLENDRONOTES
		void initNem()
		counter = 90
		metro 85
	else
		if ( mode == 1 )
			nonotes = SLENDRONOTES
			void initSanga()
			counter = 125
			metro 145
		else
			if ( mode == 2)
				nonotes = SLENDRONOTES
				void initManjura()
				counter = 140
				metro 160
			else
				nonotes = PELOGNOTES
				void initPelog()
				counter = 175
				metro 175
			end
		end
	end
	void printf(mode)
	mode++
	if ( mode == 4)
		mode = 0
	end
end

vco	s1
	uchar sectcount

	counter = 0
	mode = 0

	sectcount = 0

	for(;;)
		# choose mode
		if ( counter == 0 )
			void nextMode()
			sectcount++
		end
		counter--
		#
		# play note
		#
		melnote = mrandrange(0,nonotes)
		if ( mrand() % 2 )
			meltime = q
		else
			meltime = e
		end
		# note time velocity cents
		snotes[melnote] meltime	mrandrange(100,127)	scents[melnote]

	end
end


# one every 2 (may have double beat)
vco low
	uchar rval
	for (;;)
		rval = mrand() % 3
		if (rval == 0)
			snotes[melnote]-12	h mrandrange(100,127) scents[melnote]
		else
			snotes[melnote]-12	q mrandrange(100,127) scents[melnote]
			snotes[melnote]-12	q mrandrange(100,127) scents[melnote]
		end
	end
end

# one every 4
vco lower
	uchar note
	for (;;)
		snotes[melnote]-24	q	mrandrange(100,127) scents[melnote]
		rest	q
		rest	q
		rest	q
	end
end


# once every 16
vco whole
	uchar note
	for (;;)
		if ( {mrand() % 3} == 1)
			snotes[melnote]-36	w 127 scents[melnote]
		else
			rest	w
		end
		rest	w
		rest	w
		rest	w
	end
end

 
====================== program #2 ============================================


#
# compufunk
#
# setup:
# 3 voicelists
# vco 1: bass voice
#	Determines overall harmonic structure. Current chord note
#	is stored in a global. Melody uses this to improvise off of.
#	There are two base forms. Both consist of various bass riffs
#	stored as procedural data (coded up). The first form has
#	very little improv. The second pieces its riffs together
#	in a random fashion.
# vco 2: keyboard reader, maps a key to various changes
#        should be plugged into melody player channel at MIDI level
#	 since various keys may change the melody patches.
# vco 3: melody player, there are a number of melody forms. See
#	the key description. The melody follows the bass voice.
# vco 4: optional double of melody code.
#
# various keys cause various transformations.
#
# Idea is to play bass and jam against it with solo instrument.
# melody can be switched in and out, can play duet with it.

#
# harmonic structure:
#
# Two parts
#	1. 8 bar melody lead. Melody plays horns in fifths and
#	uses fairly staid melody form.
#	2. 12 bar blues form. 
#	Harmonic structure is
#	E E E E A A E E C D E E
#	all minor 7th chords. Suggest using polytonality by
#	playing chord notes of minor 7th that is a fifth higher.
#

# key transformations
#
# a key: - force one round of "theme" 8 bar melody lead.
# c key: - melody form 1. dorian/blues pentatonic random melody
# d key: - turn melody generation OFF
# e key: - melody form 2. pentatonic chords
# f key: - melody form 3. "wave" melody, ascending arpeggios
# g key: - melody form 4. fractal melody
# h key: - melody form 5. dorian/polytonal melody (add a 7th sometimes)
# p key: - enable random switches between patches for melody voice.
# o key: - enable random switches between melody forms.
# m key: - make random change on patch for melody - use melody patch set.
# r key: - make random change on patch for melody - use rhythm patch set.
# s key: - turn second melody on (toggle)


#############################################
#
# constants
#
NOMODES = 4
OCTAVE = 12
FIFTH  = 7
PENTA  = 5
JAZZMINOR = 7
MAXRHYTHM = 5              # random rhythmic patches to choose from
MAXMEL    = 15             # random melody patches to choose from

# definitely need character constants!!!
#
ACHAR = 0x61
BCHAR = 0x62
CCHAR = 0x63
DCHAR = 0x64
ECHAR = 0x65
FCHAR = 0x66
GCHAR = 0x67
HCHAR = 0x68
ICHAR = 0x69
JCHAR = 0x6a
KCHAR = 0x6b 
LCHAR = 0x6c
MCHAR = 0x6d
NCHAR = 0x6e
OCHAR = 0x6f
PCHAR = 0x70
QCHAR = 0x71        # don't use      
RCHAR = 0x72
SCHAR = 0x73


#############################################
# global vars

uchar mode             # melody mode
uchar chordbase        # fundamental of current chord
uchar pentascale[5]
uchar minorscale[7]
uchar solocount
uchar basemode         # bass harmonic/tempo mode
uchar pkey             # set if patch change desired
uchar okey             # set if mode changes should be automatic
uchar lastnote
uchar solo2on
uchar solopatch

# store the basic chord prog in terms of basenote here
uchar chordProg[12]

# fb01 patch groups
#
uchar fbrhythm[MAXRHYTHM]
uchar fbmelody[MAXMEL]

#############################################
# functions

# setup fb01 patches to randomly choose from
# all are bank 1
#
riff initpatch()
	fbrhythm[0] = 31       # steeldrum
	fbrhythm[1] = 32       # timpani
	fbrhythm[2] = 22       # xylo
	fbrhythm[3] = 43       # snare
	fbrhythm[4] = 45       # tomtom

	fbmelody[0] = 33
	fbmelody[1] = 34
	fbmelody[2] = 37
	fbmelody[3] = 38
	fbmelody[4] = 40
	fbmelody[5] = 41
	fbmelody[6] = 42
	fbmelody[7] = 2
	
	fbmelody[8] = 8
	fbmelody[9] = 9
	fbmelody[10] = 16
	
	fbmelody[11] = 18
	fbmelody[12] = 20
	fbmelody[13] = 7
	fbmelody[14] = 11

end

riff initHarmony()
	chordProg[0] = LE
	chordProg[1] = LE
	chordProg[2] = LE
	chordProg[3] = LE
	chordProg[4] = LA
	chordProg[5] = LA
	chordProg[6] = LE
	chordProg[7] = LE
	chordProg[8] = LC
	chordProg[9] = LD
	chordProg[10] = LE
	chordProg[11] = LE
end

riff init()
	pentascale[0] = 3
	pentascale[1] = 5
	pentascale[2] = 7
	pentascale[3] = 10
	pentascale[4] = 12

	minorscale[0] = 2
	minorscale[1] = 3
	minorscale[2] = 5
	minorscale[3] = 7
	minorscale[4] = 9
	minorscale[5] = 10
	minorscale[6] = 12
end

riff choosetwo(t1,t2)
	if ( mrand() < 127 )
		return(t1)
	else
		return(t2)
	end
end

########################################
# base melody fragments
#

# helper function for below b1, simple variation
riff subb1()
	LE  tq  105
	LE  te  90
	E   tq  choosetwo(105,100)
	LE  te  90
	D   tq  choosetwo(105,100)
	LE  te  90
	E   tq  choosetwo(105,100)
	LB  te  94
# m2
	LE	tq	choosetwo(110,105)
	LE	te
	E	q       choosetwo(105,95)
	LD	tq      choosetwo(100,90)
 	LB	te      90
    	if ( mrand() < 120 )
		LD	tq      100
		LB	te      90
	else
		LA	tq      100
		LG	te      90
	end
end

# 2 measures
riff b1(base)
	chordbase = base
	if ( base == LE && mrand() < 50 )
		void subb1()
		return(1)
	end
	if ( mrand() < 50 )
		base	q   mrandrange(115,121)
	else
		base tq mrandrange(115,117)
		base te  90
	end
	base+12 q   100
	base+10 h   mrandrange(90,100)
# m2
	base	q   mrandrange(110,117)
	base+12 q   100
#
	base+10 tq  mrandrange(90,110)
	base+7  te  100
# m2, b4
	base+5  tq  100
	if ( mrand() < 100 )
		base+3  te  100
	else
		base+3  te  90
	end
end


# similar to b1, but only a measure long
riff b5(base)
	chordbase = base
	base	q   120
	base+12 q   100
	if ( mrand() < 100 )
		base+10 h   100
	else
		base+10 tq  mrandrange(115,100)  
		base+10 te  90
		base+7  q
	end
end

# second measure of b1
riff b6(base)
	chordbase = base		
	base	q   115
	base+12 q   100
	base+10 tq  105
	base+7  te  100
	base+5  tq  100
	base+3  te  100
end

# 1 measure
riff b3(base)
	chordbase = base
	base	tq  mrandrange(90,115)
	base	te  mrandrange(80,95)
	base+12 tq  mrandrange(90,105)
	base+12 te  85
	base+10 te  105 
	base+12 te  90
	base+10 te
	base+5  te  105
	base+7  te
	base+10 te
end 

#1 measures
riff b4(base)
	chordbase = base
	base+12  tq  110
	base+12  te  100
	base+3   tq  105
	base+3   te  100
	base+5   tq  110
	base+5   te  100
	base+7   tq  110
	base+7   te  100
end

riff b7(base)
	chordbase = base
	base	tq	110 
	base    te       90
	base+3  tq      105
	base+3  te       90
	base+5  tq      100
	base+5  te      107
	base+7  tq      mrandrange(110,115)
	base+7  te      100
end

riff specialB()
	chordbase = LC
	LC	q   110
	LC+12   q   100
	LC+10   h   95
	chordbase = LD
	LD	q   110
	LD+12	q   90
	LD+10 tq  105
	LD+7  te  100 	
	LD+5  tq  100 	
	LD+3  te  100 
end

# end of bass melody fragments
#

riff solotime()
	if ( {mrand()%2} == 0 )
		return(tq) 
	else
		return(te)
	end
end


riff choosethree(t1,t2,t3)
	uchar rno
	rno = mrand()
	if ( rno < 85 )
		return(t1)
	end
	if ( rno < 170 )
		return(t2)
	end
	return(t3)
end

#
# choose a note out of one of the two scales
# add an octave to base to get note up into middle range
#
riff solonote()
	uchar index
	
	if ( {solocount % 4} < 2) 
		return(pentascale[mrand()%PENTA]+ OCTAVE + chordbase)
	else
		return(minorscale[mrand()%JAZZMINOR] + OCTAVE + chordbase)
	end
end

#
# play so many measures of solo melody
#
riff dosolo()
	uchar mcount
	uchar time
	uchar solocount
	uchar tcount
	uchar note
	uchar vel

	solocount++
	if ( mode == 5 )
		solopatch = 0
		patch 0
	end
	for ( mcount = 0; mcount < 6; mcount++)
		# check to see if random mode changes are
		# desired
		if ( mcount == 3 && okey )
			mode = {mrand() % NOMODES} + 1
		end
		for ( tcount = 0; tcount < w; )
			time = solotime()
			if ( mode == 1 )
				solonote() time  mrandrange(90,115)
			else 
			if ( mode == 2 )
				vel = mrandrange(90,120)
				note = solonote() 
				if ( mrand() < 150 )
					chord note,note+12,note+24 end time + 12
				else
					chord note,note+7,note+12,note+14,note+24 end time + 12
				end
				time = time + 12
			else # mode is 3
			if ( mode == 3 )
				note = 	solonote()
				vel = mrandrange(80,110)
				note 		s   vel  				
				note + 2	t   vel + 2
 				note + 5        s   vel + 4
				note + 7        t   vel + 6
				note + 12       s   vel + 8
				note + 17       t   vel + 10
				note + 19       s   vel + 12
				note + 24       t   vel + 14
			else # mode is 4, fractal melody 
			if ( mode == 4 )
				lastnote = mfractal1(lastnote)
				vel++
				if ( vel > 115 )
					vel = 85
				end
				chordbase+pentascale[lastnote%PENTA]+24 choosethree(s,e,h) vel
			else # mode is 5, basemode special melody
			if ( mode == 5 )
				if ( solopatch != 0 )
					patch 0
					solopatch = 0
				end
				note = solonote()
				time = solotime()
				vel = mrandrange(100,120)
				chord note,note+7 end time vel
			# mode 6, venture into polytonal up a 5th
			else
				if ( mrand() < 190 )
					note = solonote() + 7
				else
					note = solonote() 
				end
				note solotime() mrandrange(90,120)
			end
			end
			end
			end
			end
			tcount = tcount + time
		end
	end
	# if pkey set however random changes 1..33
	if ( pkey ) 
		solopatch = {mrand() % 32} + 1
		patch solopatch
	end
end

# first baseform
# not much variation in riffs
#
riff baseform1() 	
	void b1(LE)
	void b1(LE)
	void b1(LA)
	void b1(LE)
	if ( mrand() < 200 )
		void specialB() 
	else
		void b1(LB)
	end
	void b1(LE)
end

# in charge of varying the bass melody
#
riff baseform2()
	uchar rval
	uchar chordindex
	uchar lastval

	lastval = 1
	for ( chordindex = 0; chordindex < 12; chordindex++)
		rval = mrand() % 5
		# try again if riff number matches, should reduce
		# frequency of repeats
		if (lastval == rval)
			rval = mrand() % 5
		end

		if ( rval == 1 )
			void b3(chordProg[chordindex])
		else
		if ( rval == 2 )
			void b4(chordProg[chordindex])
		else
		if ( rval == 3 )
			void b5(chordProg[chordindex])
	 	else
		if ( rval == 4 )
			void b6(chordProg[chordindex])
		else
		 	void b7(chordProg[chordindex])
		end
		end
		end
		end
		lastval = rval
	end # for
end

###################################################### 
# VOICELISTS
###################
#
# bass is first voice.
#
# determines harmonic structure.
# The base tone of the current chord is saved by any routines
# called by the "bass" voicelist. Melody generation uses this
# to generate melodic fragments.
#
vco bass
	uchar index
	uchar firstcall

	okey = 0
	pkey = 0
	mode = 0        # solo starts off
	basemode = 1
	solocount = 0
	lastnote = LE
	void init()
	void initHarmony()
	void initpatch()
	firstcall = 1

	# now start to play bass variations unless n key is
	# typed. 
	# 'n' means normal form again
	for (;;)
		# if basemode is set then play 8 bar "line"
		
		if ( basemode )
			mode = 5
			void b1(LE)
			void b1(LG)
			void b1(LA)
			void b1(LE)
			void b1(LE)
			void b1(LC)
			void b1(LD)
			void b1(LE)
			mode = 4
			basemode = 0
		# else normal improv section
		else
			if ( firstcall )
				firstcall = 0
				void baseform1()
			else
			# small percent of normal base playing
				if ( mrand() < 10 )
					void baseform1()
				else
			# great deal of improv base playing
					void baseform2()
				end
			end
		end
	end
end

#
# check the keyboard
# if a char is received turn on the solo channel
# or turnoff the solo  if it is playing
#
vco readKey

	uchar input
	uchar patchVal

	#
	# check every quarter note
	for(;;)
		if (misch()) 
			input = mgetch()
			if ( input == ACHAR )
				basemode = 1
				okey = 0
				pkey = 0
			end
			if ( input == CCHAR )
				mode = 1
			end
			if ( input == DCHAR )
				mode = 0
			end
			if ( input == ECHAR )
				mode = 2
			end
			if ( input == FCHAR )
				mode = 3
			end
			if ( input == GCHAR )
				mode = 4
			end
			if ( input == HCHAR )
				mode = 6
			end
			if ( input == PCHAR )
				pkey = ~pkey    # toggle
			end
			if ( input == OCHAR )
				okey = ~okey    # toggle
			end
			# random change of melody patch
			if ( input == MCHAR )
				solopatch = fbmelody[mrand()%MAXMEL]-1
				patch solopatch
			end
			# random change to rhythm patch
			if ( input == RCHAR )
				solopatch = fbrhythm[mrand()%MAXRHYTHM]-1
				patch solopatch
			end
			if ( input == SCHAR )
				solo2on = ~solo2on
			end
		else
			REST	q
		end
	end
end

#
# play a solo when mode is non-zero
#
vco solo
	for(;;)
		if ( mode )
			void dosolo()
		else
			REST 	w
		end
	end
end

# optional double of solo voice
#
vco solo2
	solo2on = 0
	
	for(;;)
		if ( solo2on )
			void dosolo()
		else
			REST 	w
		end
	end
end



