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