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