home *** CD-ROM | disk | FTP | other *** search
- #
- # bendlib.ma - (dx7) pitch bend library of Ravel routines
- #
- # Implementation Assumptions:
- #
- # 1. Setup for dx7 type instrument.
- # might work elsewhere as is but may take some changes.
- #
- # 2. check SEMITONEUNITS; i.e., no of pitch bend
- # units per semitone. We set poff to 1.
- #
- # 3. Assume that
- # dx7 is setup as follows:
- # range 12 (an octave span for the bend)
- # step 0 - continuous bend (not semitones)
- #
- #########################################
- # Functions supported:
- ##############################################################
- # 1. riff vibratto(note, bendTime, totalTime, vibrattoStep, velocity)
- # vibrato on specified note. note issued here.
- #
- # 2. riff vnonote(firstNote, curbend, totalTime, vibrattoStep, velocity)
- # vibratto on note already issued.
- #
- # 3. riff bendUp(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
- # pitch bend up of interval of 1-12 semitones
- #
- # 4. riff bendDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
- # pitch bend down of interval of 1-12 semitones
- #
- # 5. riff bendUpDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
- # pitch bend up then down. Jan Hammer would like it.
- #
- # There are also some test routines at the bottom with a test vco
- # driver.
- #
- # They can function as examples of how to use the above riffs.
- # You might want to comment them out to reduce code size.
-
- export
- vibratto, # riff
- vnonote, # riff
- bendUp, # riff
- bendDown, # riff
- bendUpDown # riff
- end
-
- # bend units per semi-tone
- SEMITONEUNITS = 680
- # bend units per whole-tone
- WHOLETONEUNITS = 1360
- # bend units at pitchbend center
- BENDCENTER = 8192
-
- #
- # vibratto - play vibratto around requested tone.
- #
- # time is broken up into two parts, bendTime and remainder.
- # bendTime comes first. This permits vibratto followed by
- # normal non-vibratto tone.
- #
- # vibrattoStep - range of bend around center tone.
- # 10 - minimum
- # 60 - medium
- # 100 - heavy
- #
- riff vibratto(firstNote, bendTime, totalTime, vibrattoStep, velocity)
- # interval - number of semitones to bend up
- int events
- int bendIncrement
- int curincrement
- int bendvalue
- int elapsedTime
- int remainingTime
-
- # make sure pitch bend offset is set at 1 so
- # that we use the true MIDI numbers in decimal
- # Remember this is a compiler pseudo-op.
- poff 1
-
- bendIncrement = vibrattoStep
-
- # play note with 0 eventime
- # the note lasts "totalTime" time before a noteoff
- # is issued
- note firstNote 0,totalTime velocity
-
- bendvalue = BENDCENTER
- # start off with pitch bend wheel centered
- # take no time to do this
- bend 0 BENDCENTER
-
- # loop through pitch bend up
- elapsedTime = 0
- for ( events = 0; events < bendTime; events++)
- # alternate up/down around pitch
- if ({events % 2} == 0)
- bend 1 BENDCENTER+bendIncrement
- else
- bend 1 BENDCENTER-bendIncrement
- end
- elapsedTime++
- end
- # issue another pitch bend to make sure we
- # arrived where we want because for loop
- # above may not have arrived precisely
- bend 0 BENDCENTER
- # use bend constant to return pitchbend wheel to center
- poff 1
- # deterime amount of eventtime remaining
- # we may have some slop if the amount of time
- # spent playing bends did not equal the bendTime
- if (elapsedTime == bendTime)
- remainingTime = totalTime - bendTime
- else
- remainingTime = {bendTime - elapsedTime} + {totalTime - bendTime}
- end
- # tie note for remaining time
- tie remainingTime
- # void printf("bend %d \n",BENDCENTER)
- # issue rest to make sure noteoff in effect. this
- # is paranoia most likely
- rest 0
- # put pitchbend wheel at center
- bend 0 BENDCENTER
- # void dumptime()
- end
-
- #
- # vnonote - play vibratto around requested tone. Used
- # by other bend routines. Does not issue initial note.
- # Also assumes that we do pitch bend for entire totalTime.
- # I.e., not broken up into pitch bend, no pitch bend step.
- #
- # vibrattoStep - range of bend around center tone.
- # 10 - minimum
- # 60 - medium
- # 100 - heavy
- #
- riff vnonote(firstNote, curbend, totalTime, vibrattoStep, velocity)
- # interval - number of semitones to bend up
- int events
- int bendvalue
- int bendIncrement
- int elapsedTime
- int remainingTime
-
- # make sure pitch bend offset is set at 1 so
- # that we use the true MIDI numbers in decimal
- poff 1
-
- bendIncrement = vibrattoStep
-
- bendvalue = curbend
-
- # loop through pitch bend up
- for ( events = 0; events < totalTime; events++)
- # alternate up/down around pitch
- if ({events % 2} == 0)
- bend 1 bendvalue+bendIncrement
- else
- bend 1 bendvalue-bendIncrement
- end
- end
- # issue another pitch bend to make sure we
- # arrived where we want because for loop
- # above may not have arrived precisely
- bend 0 bendvalue
- # issue rest to make sure noteoff in effect. this
- # is paranoia most likely
- rest 0
- # void dumptime()
- bend 0 BENDCENTER
- end
-
- #
- # bendUp according to specified interval.
- #
- # Eventtime is broken up according to following scheme.
- #
- # 1. issue note for firstTime events
- # 2. bend for bendTime events
- # 3. tie for remaining time (totalTime - (firstTime + bendTime)
- # Latter non-bend time may have vibratto attached.
- #
- # e.g.,
- # C, e, e, q, 2, 100, 0, 0
- #
- # would mean play C for e events, then bend to D for e events,
- # and quit with no vibratto at end.
- #
- # firstnote - starting note
- # firstTime - time devoted to first note before bend
- # bendTime - period of time for bends
- # totalTime - total elapsed time for note to note. If totalTime
- # is larger than bendTime, we do the pitch bend first
- # and spend the remaining amount of time on the note.
- # interval - 1..12 semitones.
- # velocity - desired velocity.
- # vibratto - flag, 1 for TRUE, 0 for FALSE, if specified
- # then we use vibratto for last totalTime-bendTime period.
- # This permits more guitar-like effects.
- # vibrattoStep - how much pitch bend for vibratto
- #
- # bendUp(C, 0, h, w, 12, 100, 0, 0)
- # would execute a linear bend from C to HC for the first 'h'
- # of time, and then execute the HC for the 2nd 'h' with
- # total elapsed time of 'w'.
- #
- # Algorithm needs work but this gets the job done.
- #
-
- riff bendUp(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
- # interval - number of semitones to bend up
- int events
- int bendIncrement
- int totalBendUnits
- int pertimeClick
- int curincrement
- int bendvalue
- int elapsedTime
- int remainingTime
-
- # make sure pitch bend offset is set at 1 so
- # that we use the true MIDI numbers in decimal
- poff 1
-
- # don't set interval to 0
- if (interval == 0)
- void printf("bendUp: invalid 0 interval\n")
- final
- end
- # total number of bend units to cover interval
- totalBendUnits = interval * SEMITONEUNITS
-
- # determine per bend event time and how much
- # to bend per bend call
- # if more time than total bend units according
- # to the interval, then divide the time
- # by the number of bend units to get the per
- # bend call time, otherwise time is 1
- if (bendTime > totalBendUnits)
- pertimeClick = bendTime / totalBendUnits
- bendIncrement = totalBendUnits / pertimeClick
- else
- bendIncrement = totalBendUnits / bendTime
- pertimeClick = 1
- end
-
- # void printf("bendIncrement %d\n",bendIncrement)
- # void printf("pertimeClick %d\n",pertimeClick)
- # void printf("totalBendUnits %d\n",totalBendUnits)
-
- # play note with 0 eventime
- # the note lasts "totalTime" time before a noteoff
- # is issued
- note firstNote firstTime,totalTime velocity
- # void dumptime()
- bendvalue = BENDCENTER
- # start off with pitch bend wheel centered
- # take no time to do this
- poff 1
- bend 0 BENDCENTER
- curincrement = bendIncrement
- # loop through pitch bend up
- elapsedTime = 0
- for ( events = 0; events < bendTime; events++)
- bend pertimeClick BENDCENTER+curincrement
- # void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
- curincrement = curincrement + bendIncrement
- elapsedTime = elapsedTime + pertimeClick
- end
- # issue another pitch bend to make sure we
- # arrived where we want because for loop
- # above may not have arrived precisely
- bend 0 BENDCENTER + totalBendUnits
-
-
- # use bend constant to return pitchbend wheel to center
- poff 1
- # deterime amount of eventtime remaining
- # we may have some slop if the amount of time
- # spent playing bends did not equal the bendTime
- if (elapsedTime == bendTime)
- remainingTime = totalTime - {firstTime + bendTime}
- else
- remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
- end
- # do vibratto for last half
- # use special vibratto routine that does not issue note
- # just bends
- if (vflag)
- void vnonote(firstNote, BENDCENTER+totalBendUnits, remainingTime, vsteps, velocity)
- return(0)
- end
- # tie note for remaining time
- tie remainingTime
- # void printf("bend %d \n",BENDCENTER)
- # issue rest to make sure noteoff in effect. this
- # is paranoia most likely
- rest 0
- # put pitchbend wheel at center
- bend 0 BENDCENTER
- # void dumptime()
- end
-
- #
- # bend Down requested interval
- #
- # interval 0..12: max range an octave
- riff bendDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
- # interval - number of semitones to bend up
- int events
- int bendIncrement
- int totalBendUnits
- int pertimeClick
- int curincrement
- int bendvalue
- int elapsedTime
- int remainingTime
-
- # make sure pitch bend offset is set at 1 so
- # that we use the true MIDI numbers in decimal
- poff 1
-
- # don't set interval to 0
- if (interval == 0)
- void printf("bendUp: invalid 0 interval\n")
- final
- end
- # total number of bend units to cover interval
- totalBendUnits = interval * SEMITONEUNITS
-
- # determine per bend event time and how much
- # to bend per bend call
- # if more time than total bend units according
- # to the interval, then divide the time
- # by the number of bend units to get the per
- # bend call time, otherwise time is 1
- if (bendTime > totalBendUnits)
- pertimeClick = bendTime / totalBendUnits
- bendIncrement = totalBendUnits / pertimeClick
- else
- bendIncrement = totalBendUnits / bendTime
- pertimeClick = 1
- end
-
- # void printf("bendIncrement %d\n",bendIncrement)
- # void printf("pertimeClick %d\n",pertimeClick)
- # void printf("totalBendUnits %d\n",totalBendUnits)
-
- # play note with 0 eventime
- # the note lasts "totalTime" time before a noteoff
- # is issued
- note firstNote firstTime, totalTime velocity
- # void dumptime()
- bendvalue = BENDCENTER
- # start off with pitch bend wheel centered
- # take no time to do this
- poff 1
- bend 0 BENDCENTER
- curincrement = bendIncrement
- # loop through pitch bend up
- elapsedTime = 0
- for ( events = 0; events < bendTime; events++)
- bend pertimeClick BENDCENTER-curincrement
- # void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
- curincrement = curincrement + bendIncrement
- elapsedTime = elapsedTime + pertimeClick
- end
- # issue another pitch bend to make sure we
- # arrived where we want because for loop
- # above may not have arrived precisely
- bend 0 BENDCENTER - totalBendUnits
- # void printf("%d \n",BENDCENTER+totalBendUnits)
- # use bend constant to return pitchbend wheel to center
- poff 1
- # deterime amount of eventtime remaining
- # we may have some slop if the amount of time
- # spent playing bends did not equal the bendTime
- if (elapsedTime == bendTime)
- remainingTime = totalTime - {firstTime + bendTime}
- else
- remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
- end
- # do vibratto for last half
- # use special vibratto routine that does not issue note
- # just bends
- if (vflag)
- void vnonote(firstNote, BENDCENTER-totalBendUnits, remainingTime, vsteps, velocity)
- return(0)
- end
- # tie note for remaining time
- tie remainingTime
- # void printf("bend %d \n",BENDCENTER)
- # issue rest to make sure noteoff in effect. this
- # is paranoia most likely
- rest 0
- # put pitchbend wheel at center
- bend 0 BENDCENTER
- # void dumptime()
- end
-
- #
- # bendUpDown
- #
- # bend up interval requested
- # then bend down
- #
- riff bendUpDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
- # interval - number of semitones to bend up
- int events
- int bendIncrement
- int totalBendUnits
- int pertimeClick
- int curincrement
- int bendvalue
- int elapsedTime
- int remainingTime
- int firstHalf # first half of time delta
- int secondHalf # second half of time delta
-
- # make sure pitch bend offset is set at 1 so
- # that we use the true MIDI numbers in decimal
- poff 1
-
- # don't set interval to 0
- if (interval == 0)
- void printf("bendUp: invalid 0 interval\n")
- final
- end
-
- # split bend timedelta into first half and second
- # half and make sure all events are accounted for
- # in time
- firstHalf = bendTime >> 1
- if ({bendTime % 2} != 0)
- secondHalf = firstHalf + 1
- else
- secondHalf = firstHalf
- end
-
- # total number of bend units to cover interval
- totalBendUnits = interval * SEMITONEUNITS
-
- # determine per bend event time and how much
- # to bend per bend call
- # if more time than total bend units according
- # to the interval, then divide the time
- # by the number of bend units to get the per
- # bend call time, otherwise time is 1
- if (firstHalf > totalBendUnits)
- pertimeClick = firstHalf / totalBendUnits
- bendIncrement = totalBendUnits / pertimeClick
- else
- bendIncrement = totalBendUnits / firstHalf
- pertimeClick = 1
- end
-
- # void printf("bendIncrement %d\n",bendIncrement)
- # void printf("pertimeClick %d\n",pertimeClick)
- # void printf("totalBendUnits %d\n",totalBendUnits)
-
- # play note with 0 eventime
- # the note lasts "totalTime" time before a noteoff
- # is issued
- note firstNote firstTime,totalTime velocity
- # void dumptime()
- bendvalue = BENDCENTER
- # start off with pitch bend wheel centered
- # take no time to do this
- poff 1
- bend 0 BENDCENTER
- curincrement = bendIncrement
- # loop through pitch bend up
- elapsedTime = 0
- for ( events = 0; events < firstHalf; events++)
- bend pertimeClick BENDCENTER+curincrement
- # void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
- curincrement = curincrement + bendIncrement
- elapsedTime = elapsedTime + pertimeClick
- end
-
- # make sure we got to top
- bend 0 BENDCENTER + totalBendUnits
- curincrement = totalBendUnits
-
- # now loop down, keep running totals
- for ( events = 0; events < secondHalf; events++)
- bend pertimeClick BENDCENTER+curincrement
- # void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
- curincrement = curincrement - bendIncrement
- elapsedTime = elapsedTime + pertimeClick
- end
-
- # issue another pitch bend to make sure we
- # arrived where we want because for loop
- # above may not have arrived precisely
- bend 0 BENDCENTER
-
- # void printf("%d \n",BENDCENTER+totalBendUnits)
- # use bend constant to return pitchbend wheel to center
- poff 1
- # deterime amount of eventtime remaining
- # we may have some slop if the amount of time
- # spent playing bends did not equal the bendTime
- if (elapsedTime == bendTime)
- remainingTime = totalTime - {firstTime + bendTime}
- else
- remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
- end
- if (vflag)
- void vnonote(firstNote, BENDCENTER, remainingTime, vsteps, velocity)
- return(0)
- end
-
- # tie note for remaining time
- tie remainingTime
- # void printf("bend %d \n",BENDCENTER)
- # issue rest to make sure noteoff in effect. this
- # is paranoia most likely
- rest 0
- # put pitchbend wheel at center
- bend 0 BENDCENTER
- # void dumptime()
- end
-
-
- # should start with 4 note chord from LLC to LC range
- # LLC, LE, LG, LC to LC, E, G, HC octave bend. Fun.
- # then play major scale via bends twice.
- # finish off with normal C to HC for contrast
- #
- riff testBendUp()
- int i
- void printf("C chord bend up\n")
- LG 0,w
- LE 0,w
- LLC 0,w
- void bendUp(LC, 0, h, w, 12, 100, 0, 0)
- void printf("C scale down twice\n")
- for ( i = 0; i < 2; i++)
- C q
- # up to D
- void bendUp(C, 0, e, q, 2, 100, 0, 0)
- # up to E
- void bendUp(D, 0, e, q, 2, 100, 0, 0)
- # up to F
- void bendUp(E, 0, e, q, 1, 100, 0, 0)
- void bendUp(F, 0, e, q, 2, 100, 0, 0)
- void bendUp(G, 0, e, q, 2, 100, 0, 0)
- void bendUp(A, 0, e, q, 2, 100, 0, 0)
- void bendUp(B, 0, e, q, 1, 100, 0, 0)
- end
- void printf("C HC reference tones\n")
- C q
- HC q
-
- end
-
- riff testBendDown()
- void printf("bend down: C scale down to G\n")
- # C
- note C q 127
- # C to LB
- void bendDown(C, 0, e, q, 1, 127, 0, 0)
- # LB to LA
- void bendDown(LB, 0, e, q, 2, 127, 0, 0)
- # LA to LG
- void printf("bend down: LG scale down to LC\n")
- void bendDown(LA, 0, e, q, 2, 127, 0, 0)
- # LG to LC
- void bendDown(LG, 0, e, q, 7, 127, 0, 0)
-
-
- void printf("C then C to LC\n")
- C q
- void bendDown(C, 0, q, w, 12, 127, 0, 0)
- #
- void printf("reference tones LC C \n")
- LC q
- C q
- end
-
- riff testVibratto()
- int vsteps
- int i
- vsteps = 0
- for ( i = 0 ; i < 20; i++)
- void printf("vsteps %d\n",vsteps)
- void vibratto(C, q*3, w, vsteps, 100)
- vsteps = vsteps + 10
- end
- end
-
- riff testguitarRiff()
- void bendUp(LG, 2, e+2, q, 2, 110, 1, 70)
-
- void vibratto(LA, q,q, 80, 100)
- void vibratto(E, q,q, 60, 100)
- void bendUpDown(D, 3, q+e-3, q+e, 2, 110, 0, 0)
- void vibratto(C, e, e, 50, 100)
- void vibratto(LA, 3*q,3*q, 110, 100)
- rest e
- void bendUp(LG, 0, e, q+e, 2, 110, 1, 110)
- end
-
- vco testBendLib()
- void testguitarRiff()
- void testBendUp()
- void testBendDown()
- void testVibratto()
- end
-
-
-