Since the examples I showed you in class were . . er,
somewhat less than gratifying, I present here some "drum-loop"
material I used in the piece of mine that you heard the first day of
class. This example is similar to what I was attempting to demonstrate
in class, but has a slightly different
decision-making process involved in it's algorithms.
We begin with a similar, though simpler, algorithm than that used by the
Burundi drums; it simply writes out a steady beat:
for a "drum-loop" of sixteen beats. In the loop itself, we make a decision
for each beat: "are we going to place a hit here or not?" We do that
by using the sampfunc statement to get a value from the "drum-pattern"
makegen we just created. Then we test that value using an if formulation. As follows:
Thus, we have to have two loops now: the "inner" one pulls us through an
individual measure of sixteen beats, the "outer" loop pulls us
through however many "measures" we want to go through. Hence the
following set-up will occur (this one assumes [arbitrarily] we want
to write 6 measures):
To calculate the start-time for a given beat in the whole
output, we need to know what measure it's in and what beat
it's on, and apply those to the following equation:
Thus
Unless our tune is exactly at a tempo of MM60, however, we have to
factor in an additional tempo modifier, which we multiply by that final
"beat" value we just got, to get the final start-time:
So, with the calculations for start-time under our belt, we can
look at the whole darn thang so far:
Here is a typical military-drum pattern:
I decided to divide the music into "measures" of a quarter-note's
duration. Within each quarter, patterns of sixteenths will appear. There
are really only a few patterns of four sixteenths that will appear in
this style of drumming, most of them not involving syncopation.
(Ya gotta keep the troops marching, not shakin' their booties).
Here are the ones I used:
I translated these into a series of makegen commands:
Now, notice that some of these patterns are repeated. Eventually, I'm
going to have sampfunc() choose randomly from
So, now, in addition to cycling through the beats as before:
We make that "2" into a variable, let's call it
We embed that in a larger loop, which will write us 100 "quarter-notes"
worth of sound, and the whole thing looks like this:
Now try listening to the sound examples. First, and least interesting
is the source for the snare sounds.
Second, is the snare patterns made with the above algorithm.
Finally, you can hear this in the context of the whole piece. Note that here,
the above-created "snare"-drum pattern gets panned way off to one channel of
the stereo mix, and another, (much simpler--
(it consists of simple alternation between bass
and cymbal)) to the other channel.
Try it, and see [hear].
rtsetparams(44100, 2)
rtinput("source.aiff")
rtoutput("beats.aiff")
/* STEREO parameters:
* p0 = outsk; p1 = insk; p2 = dur (normal) OR if - , endtime;
* p3 = amp; p4-n = channel mix matrix
* "we're stashing the setline info in gen table 1"
* read: makegen slot 1 is used for amplitude envelope
*/
makegen(1, 24, 10000, 0,1, 9,1, 10,0)
/* that envelope makegen will start each note off full force,
* amplitudinally speaking, and then smooth out to 0
* at the end. */
/* temporal locations of start-times of sounds within input file */
makegen(2, 2, 6, 0)
0.594, 1.970, 3.781, 5.162, 6.469, 7.733
/* tempo will be defined by time-distance between attacks */
tempo=.17
/* initialize other variables*/
start=0
insk=0
x=0
/*the main loop */
for (hit=0; hit<16; hit=hit+1)
{
/* choose which "drum" to hit this time */
x=random()*6+1
insk=sampfunc(2, x)
/* set parameters*/
STEREO(start, insk, .1, amp, 1, 1)
start=start+tempo
}
makegen(3, 2, 16, 0)
1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 1
/* somewhere in the loop . . . . . */
if (sampfunc(2, beat)==1)
{
/* in here we'll put statements to write the drumbeat */
}
Also, we now begin to define our music in terms of cycles or,
traditionally speaking, measures; that is, each time we go through
the pattern, we fill a "measure" of sixteen beats.
for (measure=0; measure<6; measure=measure+1)
{
for (beat=0; beat<16; beat=beat+1)
{
/*stuff for each beat */
}
}
start=(measure*16)+beat
measure
start=((measure*16)+beat)*tempo
rtsetparams(44100, 2)
rtinput("source.aiff")
rtoutput("beats.aiff")
/* STEREO parameters:
p0 = outsk; p1 = insk; p2 = dur (normal) OR if - , endtime;
p3 = amp; p4-n = channel mix matrix
"we're stashing the setline info in gen table 1"
read: makegen slot 1 is used for amplitude envelope
*/
makegen(1, 24, 10000, 0,1, 9,1, 10,0)
/* that envelope makegen will start each note off full force,
amplitudinally speaking, and then smooth out to 0
at the end. */
/* temporal locations of start-times of sounds within input file */
makegen(2, 2, 6, 0)
0.594, 1.970, 3.781, 5.162, 6.469, 7.733
makegen(3, 2, 16, 0)
1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 1
/* tempo will be defined by distance between attacks */
tempo=.17
/* initialize other variables*/
start=0
insk=0
x=0
beat=0
measure=0
/*the main loop */
for (measure=0; measure<6; measure=measure+1)
{
for (beat=0; beat<16; beat=beat+1)
{
if (sampfunc(2, beat)=1)
{
/* choose which "drum" to hit this time */
x=random()*6+1
insk=sampfunc(2, x)
/* set parameters*/
start=((measure*16)+beat)*tempo
STEREO(start, insk, .1, amp, 1, 1)
}
}
makegen(10, 2, 4, 0)
1 0 1 1
makegen(11, 2, 4, 0)
1 1 1 1
makegen(12, 2, 4, 0)
1 0 0 1
makegen(13, 2, 4, 0)
1 0 0 1
makegen(14, 2, 4, 0)
1 0 1 1
makegen(15, 2, 4, 0)
1 1 1 1
makegen(16, 2, 4, 0)
1 1 1 1
makegen(17, 2, 4, 0)
1 1 1 1
makegen(18, 2, 4, 0)
1 1 0 1
makegen(19, 2, 4, 0)
1 0 1 0
makegen(20, 2, 4, 0)
1 0 1 0
makegen(21, 2, 4, 0)
1 0 1 0
makegen(22, 2, 4, 0)
1 0 1 0
makegen(23, 2, 4, 0)
1 0 0 0
makegen(24, 2, 4, 0)
1 0 0 0
makegen(25, 2, 4, 0)
1 0 1 1
makegen
s
10 thru 25, to choose which pattern to use for a given quarter-note
"measure." By repeating some of the patterns (for example, "1 1 1 1"
occurs a whole bunch of times), I can get a "weighting" of the decision
of what pattern to use: "1 1 1 1" is going to appear more than "1 1 0 1".
for (beat=0; beat<16; beat=beat+1)
{
if (sampfunc(2, beat)=1)
whichpattern
,
and then the following writes a "quarter-note"'s worth of "sixteenth-notes"
of sound:
whichpattern=(random()*16)+10
/* picks a pattern (i.e.--one of the makegens
*defined above) from 10 - 25 */
for (sixteenth=0; sixteenth<4; sixteenth=sixteenth+1)
{
if (sampfunc(whichpattern, beat)==1)
{
insk=sampfunc(9, random()*6)
/* this chooses a different "hit" to use,
* as in the Burundi drumming */
start=
STEREO(start, insk, .5, .9, 0, 1)
}
}
rtsetparams(44100, 2)
rtoutput("loops.snares.aiff")
/* this contains the inskip times of the drum samples.
* Note: I carefully went through the
* source file and placed every sound at 1-second intervals, exactly.
* I guess I just . . . . don't like writing decimal numbers.*/
makegen(9, 2, 6, 0)
0 1 2 3 4 5
srand(3827436)
/* reseed the guy */
/* now for the patterns makegens as above */
makegen(10, 2, 4, 0)
1 1 1 0
makegen(11, 2, 4, 0)
1 0 1 0
makegen(12, 2, 4, 0)
1 1 1 1
makegen(13, 2, 4, 0)
1 1 1 1
makegen(14, 2, 4, 0)
1 1 1 1
makegen(15, 2, 4, 0)
1 1 1 1
makegen(16, 2, 4, 0)
1 1 1 0
makegen(17, 2, 4, 0)
1 1 1 0
makegen(18, 2, 4, 0)
1 0 1 0
makegen(19, 2, 4, 0)
1 1 1 0
makegen(20, 2, 4, 0)
1 1 1 0
makegen(21, 2, 4, 0)
1 1 1 1
makegen(22, 2, 4, 0)
1 0 1 0
makegen(23, 2, 4, 0)
1 0 0 0
makegen(24, 2, 4, 0)
1 1 1 1
makegen(25, 2, 4, 0)
1 1 1 1
makegen(1, 24, 3000, 0,1,5,1,10,0)
/*amplitude envelope */
t=0.19475
/* again, defining the tempo as attack-distance */
rtinput("DRUMSAMPS/snares.source.aiff")
/* open the file with the drum hit sounds */
for (quarter_note=0; quarter_note<100; quarter_note=quarter_note+1)
{
whichpattern=(random()*16)+10
/* picks a pattern from 10 - 25 */
for (sixteenth=0; sixteenth<4; sixteenth=sixteenth+1)
{
if (sampfunc(whichpattern, sixteenth)==1)
{
insk=sampfunc(9, random()*6)
/* this chooses a different "hit" to use,
* as in the Burundi drumming */
start=((quarter_note*4)+sixteenth)*t
/*as in the above examples, except we're using
*"quarter_note" as "measure", and "sixteenth" as
*"beat".*/
STEREO(start, insk, .5, .9, 0, 1)
}
}
}