SlideShare a Scribd company logo
1 of 13
Introduction to Writing Algorithms.
                                            (In MINC)

                                         Christopher Bailey

               Hi!! I'm Sammy the Serialist, and I'm going to show you, through an example, the basic
               steps in creating a CMIX (MINC) algorithm. Along the way, we're going to use "Chris
               Bailey's 8-Step Method for Creating Algorithms"

What are algorithms: Basically, the word "algorithm" usually refers simply to a way or
method of doing a task, with the task usually being of a repetitive nature, or being something that
can be described easily in an "overall" way. In computer music, examples of such tasks might be
"play a chromatic scale" or "play 200 random notes" or "make a very cloudy tremolating sound."
As a tool for composers, in other words, algorithms are most often used to generate textures.

Generally speaking, in computer music, algorithms do two things:

    1. make your life easier: you can use them to do some of the "thinking" for you (but
       remember, you have to teach the machine "how to think"), creating textures where the
       details don't matter as much as the overall effect; this is the most common kind of
       algorithmic composition: using algorithms to create clouds, lines, or whatever: soundfiles
       that you will insert into a larger piece.
    2. For the exploration of things like style modeling, genetics, games, physical laws (gas
       particles dancing around, et al), artificial intelligence, etc. This gets into "deeper" aspects
       of algorithmic composition, which we won't get into here (Brad Garton's advanced class
       begins to explore this wonderful world. . .)

What we want to look at here is how to use algorithms to create simple textures and other sound
materials for use in your music. The idea/example illustrated here is rather assinine, but it does
cover all the concepts you will need to know for basic algorithmic design.

To make this process easier, I came up with simple way of thinking things through before and
while writing code to accomplish a given musical task.

Here it is:

                     Chris Bailey's Basic 8-Step Process
               1) Think of and explore your idea, draw pictures, diagrams, and etc. to
               figure out what's happening in the different musical parameters. How is
               pitch changing? How is start-time happening? How is duration working?
               Remember that you don't necessarily have to write all of the notes in their
               temporal order: some algorithms may splatter notes in time randomly (not
               in time-order); others may write notes (or other sounds) in rhythm, from
first-to-last, time-wise. All sorts of possibilities can happen, so try to open
               your mind to different ways of solving whatever musical problem you have.

               2) Divide job into loops. (Sometimes the task you have can be
               accomplished with one loop that writes all of the sound involved, other
               times you may want to have a number of loops write the sounds for
               different sections of a segment of music, for example.)

               3) Basic set-up stuff: Here is where you write statements at the top of the
               score for things that won't be changing during the algorithmic process.
               Thus commands like rtsetparams() , opening input and output files with
               rtinput() and rtoutput() , certain makegen()s, (if they're not going to be
               changing throughout the score), and so on.

       Repeat 4-7 for each loop

               4) Outline each loop. Type your while or for statements, and then add
               brackets below, into which you will eventually insert your loop(s).

               5) Action Statements. Write out the statements that actually make the
               sound. (typically the instrument name(s), as in WAVETABLE or the like.)
               Then fill in their parameters with variables.

               6) Work outwards from the Action Statements, figuring out how each
               parameter will be determined each time the loop goes around---
               pitch,duration,start, etc.

               7) Initialize all variables before each loop starts.

               8) Run it, test it, fix it, modify it, love it.

OK, now I describe these steps in more detail:

       Step 1) Think of your idea. Draw a picture. Figure out
       what's happening in terms of pitch, rhythm (start-times),
       durations, articulations (amplitude envelopes), loudness,
       stereo placement, and whatever other factors are involved
       in the instrument(s) you're using.

       Sammy the Serialist Example, cont.’: Let's see. . . I have an Evil 12 Tone Row, and I want to make
       a nice leapy melody, with the pitch-classes cycling through my Evil Row. Of course, they must
       always come in different octaves. The rhythm--well, I'm an evil serialist, so of course I want it to
       be based on my row. The duration of any note will be simply to sound until the next note. I want
       the articulations to be either an Sfp attack, or else a hairpin (<>) kind of articulation. Loudness--
       well, of course, it, too must be based on the row! HaHa! And stereo placement too!! Ha ha ha!!
So, now you've thought of how your musical excerpt is going to work. Now, go on to the next
step--

       step 2) Divide your job into as many separate simple-as-
       possible loops as you can. In general, a single loop should
       create either a single line, or a uniform or uniformly
       changing texture.

              Sammy Example, cont.: I think I will only need one loop, since I am creating one line of
              pitches. Later on, for counterpoint, I can use more loops.

       step 3) Begin by defining basic stuff, like your output
       file, your input files, any makegens that stay the same for
       the entire thing, etc.

              Sammy Example, cont.:

                      rtsetparams(44100, 2)
                      rtoutput("evil.rows.aiff")
                      makegen(1, 10,1000, 1, .2, .2, .2, .1)

              These are the basic setup items for our script. "Timbre" stays the same--(which, for
              WAVETABLE is makegen slot 1). But articulation, (i.e.--amplitude envelope, which for
              WAVETABLE is makegen slot 2, (and usually type 24)) changes, so that will be "in" the
              loop--we’ll get to it later on.

       step 4)Write the outlines of your loop(s). This means,
       basically, control (while or for) statements, plus (if
       necessary) a statement at the end of the loop that
       increments your counter.

              while: As long as the expression in () is True, then the stuff below, the statements in {} will
              execute. After the stuff in {} is done executing, the () expression is tested again, if still
              True, then the statements in {} are executed again, and so on, until the () expression is
              False, then the {} stuff is skipped and the program goes on.

              Example:

                      while (x<100)

                               {

                                        statements, commands, 'n' stuff

                                        x=x+1

                               }
Here the {} stuff will execute over and over until x=99. Then the {} stuff will execute one
    more time, then x=x+1=100, and "x<100" will now be a False statement, so the the
    program will skip the {} stuff and go on.

    For : Similar to while, but here, in the initial statement, you tell it the initial value of a
    counter variable, followed by a semicolon, followed by an expression that has to be True
    for the {} stuff to be executed (usually that the counter is less than some upper limit, as
    with while ), followed by another semicolon, followed by a command (usually a change
    in the counter variable) that you execute each time you go through the loop.

            for (x=0; x<9; x=x+1)

                        {

                              commands & stuff

                        }

    if: This is another control statement which you may want to use at some point. If the
    expression is True then the {} stuff will be executed. There can also be an optional else part.
    If the expression following the if is False then the {} stuff following the else will be
    executed. If there is no else part, then the program just goes on, skipping the {} stuff after
    the if statement.

            if (x<.5)

                        {

                              commands & stuff

                        }

            else

                        {

                              commands & stuff

                        }

    Example, cont.:Hi, Sammy here again. . . . I’m going to use While type loops in my
    example.

step 5) Now begin to write the loop. Remember, you DON'T,
repeat, DON'T start at the beginning and work your way
down. You start at the middle, and work your way back to
the beginning. More precisely, you start at the Action
Statement(s), and work backwards. The Action Statement(s)
is/are usually your instrument statement(s), such as
WAVETABLE, or COMBIT, or whatever, or maybe a makegen for
envelope (articulation), timbre, etc. the Action Statements
usually take a set of Parameters, like pitch, duration,
etc., which change each time you go through the loop.

     Example, cont.: We are going to have two Action Statements. One, of course, makes the
     notes:

            WAVETABLE(start, dur, amp, pitch, stereo)

     The other makes the "articulation" with the appropriate amplitude envelope:

            makegen(2, 24, 2000, bla bla bla (we'll fill this in eventually))

     So, now our basic loop looks like yay:

            while (x<100)

                    {

                             WAVETABLE(start, dur, amp, pitch, stereo)
                             makegen(2, 24, 2000, bla bla bla bla)

                             x=x+1


                    }

step 6)Now, work backwards from your Action Statement(s),
considering each Parameter in turn, and figuring out how it
is calculated. Generally, there are three types of
Parameters:

     CONSTANT: This means that the parameter is the same
     for every note created by the loop. Constants are
     easy: you just fill them in with the appropriate
     number. If the loudness is always the same in a loop,
     for example, you would just fill in the third slot of
     the WAVETABLE command with the constant loudness. For
     example:

            WAVETABLE(start, dur, 1000, pitch, stereo)

     NON-DEPENDENT:This means that every time the loop goes
     around, the parameter is calculated afresh. If in a
     loop, the statement dur=random()*2, this means that
     every time the loop goes around, dur is recalculated,
regardless (i.e.in- or non-dependent) of its previous
value.

     random()= May as well introduce this here: the
     random() function produces a random value from 0
     to 1. Hence x=random() will assign to the
     variable x, a random number from 0 to 1.

DEPENDENT:This is when a variable's value depends on
the value it had last time. A typical standard example
is when the start time of the next note you're going
to create equals the current start time plus the dur
of the current note. (In other words, "start the next
note when this one ends.")

As a rule of thumb, dependent statements, like our
example (start=start+dur) usually go after the Action
Statements. Non-dependent values go before the Action
Statements. In other words, you, or rather, the loop,
calculates the non-dependent values, then, writes the
note, then calculate the Dependent values (for the
next note), and then goes back to the beginning of the
loop (to do the same for the next note.)

About choosing values for things: There are, in general, 3
ways of choosing values for things. Let's call them RANGE,
SELECT and CYCLIC:
RANGE: This is just if you want any random value
between x and y, then you just write random()*(y-x)+x,
where x < y. Remember that equation--you’ll learn to
love it. It gives you floating-point numbers, (i.e.--
with a decimal point and lots of stuff after it); if
you need integers, you can use the trunc() function,
which just removes the decimal stuff. (trunc(x.y)=x)
(It doesn’t round, it just removes the nastiness
beyond the decimal point.) Because of the truncation,
you have to add 1 in the equation to get your range of
numbers, so it becomes: trunc(random()*(y-x+1)+x)
(Remember, this one is for integers from x to y .)

SELECT: but let's say you want to select from 5
specific values, such as 1, 3, 4, 5, and 6. It would
be nice to have these in a table, and then be able to
say, "choose a random value from the table." Well, we
can do this with sampfunc, and the data , or type 2,
makegen. First, we make our table of values that we
will select from. Here’s an example:

     makegen(a, 2, n, 0)
     1, 3, 4, 5, 6

a is the ["slot"] number of the table: this is the
same in all makegens. If you use more than one table,
they should obviously be numbered differently. Also,
you shouldn't use the numbers 1, 2, 3, or even 4,
because these are often used already by your CMIX
instrument; (remember, for example, that WAVETABLE
uses slots 1 and 2 for timbre and amplitude envelope ,
respectively.)

n is the number of values you are going to store.

2 specifies that this is a "data" type makegen (as
opposed to a "make a harmonic wave" type (10) or a
"make an envelope" (24) type, or any of the other
types available (see Luke's makegen page.))

The second line contains the actual table, with values
separated by commas.

     Sammy example, cont.: Let's make a table for our Evil 12-Tone Row. Heh, heh.

             makegen(-3, 2, 12, 0)
             0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1

     OK, now, how do we later choose a random value from this table? The answer
     is:

             sampfunc(t, i)

     where t is the table# (referring to the first of the the makegen parameters) and i
     is the # of the piece of data. (However, note that the data gets numbered from
     0, not 1, so the last value in our table is #11, not #12.)

     Let's pretend we made that table above, and now, what will happen when we
     call sampfunc ?

             sampfunc(3, 1)=2

             sampfunc(3, 0)=0

             sampfunc(3, 6)=3
sampfunc(4, 6)=error, because we didn't make a table numbered 4 yet.

            sampfunc(3, random()*12 ) choose a random number between 0 and
            11.99999, and select that # value. Thus if (random()*11) gave us 4.42533,
            (automatically truncated to 4) then the sampfunc would give us 10
            (item#4=10).

            sampfunc(3, random()*n ) The range of random numbers we select is
            between 0, and n , the number of items. (Note that if you are selecting
            from, say, 6 items, they are numbered 0-1-2-3-4-5, but you type
            random()*6 because the highest possible number, 5.99999, would be
            truncated automatically (by the sampfunc command) to give you 5.
            Thus you will never get an actual "6" as a result of the randomizing.)

CYCLIC: OK, but let's say we don't want to select
randomly from our table, but to cycle through it as we
cycle through our loop. If our table had, say, six
elements, we could use a counter variable, say c, and
each time we went through the loop, at the end, we
would say: c=c+1; except we would have to check if c >
number-of-elements in the table, and if it was, we
would reset it to 0, and the cycling would begin
again.

    Our example, cont.: So, we are going to want to cycle through the row, over
    and over, as we go through our loop. So we need a counter, c. Every time we're
    going to need a row pitch, (or pitch-class, since we'll determine the octave
    later), we say

            pitchclass=sampfunc(3, c)

    Later, we say

            c=c+1
            if (c>11) c=0

    That makes sure c keeps : climbing to 11, skipping back to 0, then climbing to
    11, skipping back to 0, then climbing to 11, skipping back to 0 . . . . etc.

    So now let's go ahead and consider each parameter of our Action Statements,
    one by one, gradually filling in our algorithm.

    First, let's look at what we have so far:

            while (x<100)

                     {

                             makegen(2, 24, bla bla bla)
                             WAVETABLE(start, dur, amp, pitch, stereo)
x=x+1

                 }

We’ll start with the first thingy, the envelope makegen. Remember, we wanted
to have two choices for envelope, either Sfp, or a <> articulation (a hairpin).
These can be chosen randomly. (I.e.--this is a non-dependent decision--what
was decided the last time we went through the loop doesn't matter to us.) We
can generate a random number 'twixt 0 and 1, and if the number is <= (less
than or equal to) .5, then do an Sfp, if it's >.5, then do a <> articulation. In other
words:

        q=random()
        if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0)
        else makegen(2, 24, 2000, 0,0,1,1,2,0)

The first, if you inspect it, is an Sfp envelope, the second, a <> envelope.

Oh-kee, now for start-time. Start-time is dependent. It depends on the value
that start-time had the last time we went through the loop, and the last
duration used. In other words, the start-time of the current note depends on
when and how long the last note was. Since it's dependent, we put it after the
Action Statement(s). In our case, it's simply going to equal start+dur. So here's
our growing algorithm now:

        while (x<1000)

                 {
                         q=random()
                         if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0)
                         if (q>.5) makegen(2, 24, 2000,0,0,1,1,2,0)
                         WAVETABLE(start, dur, amp, pitch,stereo)
                         start=start+dur
                         x=x+1
                 }

Now we consider dur. This baby is non-dependent , it doesn't care what the last
dur was, but it is CYCLIC. We want to cycle through the row to get durations.
So here's where we use our counter, c. To reiterate what we developed a while
back, the statements

        c=c+1
        if (c>11) c=0

will keep our counter going round and round as we go round the loop.

Then, before our Action Statements, we put an equation giving us the value of
dur:

        dur = (sampfunc(3, c) + 2) / 20
Remember, what this says is: get the value from our row table (table #3) that c
points to. Then, add 2, so we don't get any 0 durations (we could have added
any positive number), then, divide by 20 (again, that's arbitrary) to make the
durations shorter (turning up the tempo (I like things fast (I do live in New
York, after all.)))

OK, let's check where we are now:

         rtsetparams(44100, 2)
         rtoutput("evil.rows.aiff")
         makegen(1, 10 , 2000, 1, .2, .2, .2)
         makegen(3, 2, 12, 0)
         0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1
         while (x<1000)

                  {
                           q=random()
                           if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0)
                           if (q>.5) makegen(2, 24, 2000, 0,0,1,1,2,0)
                           dur=(sampfunc(3, c)+2)/20
                           WAVETABLE(start, dur, amp, pitch, stereo)
                           start=start+dur
                           c=c+1
                           if (c>11) c=0
                           x=x+1
                  }

Amp and stereo follow similar procedures. For amp, we have to add a number
(12 again, I guess) so we don't get an amp of 0 once every 12 notes, (which
would be pointless (but then again, this whole example is rather pointless)),
then multiply it all by 1000 to bring the amplitude values into an audible
range (remember, RTcmix amplitudes run from 0 to 32768); for stereo, which as
you remember, must be from 0 to 1 (left to right), we must "shrink" the range
from 0 - 11 to 0 - 1, by dividing by 11.

Hence:

         amp=(sampfunc(3,c)+12)*1000
         stereo=sampfunc(3,c) / 11

Pitch is not too much more complicated. Remember that octave-pitch-class
notation has 2 parts, an octave argument, followed by a . , then a pitch-class , or
pc argument. So, we will generate a random octave, and then look up our
pitch-class from the table as we discussed earlier, but divide it by 100, so that
it will come after a decimal point. (4 divided by one hundred will be .04, or
10/100 will be .10) Then, we just add them, and taadaa!! instant pitch. (In
other words, pc 2 will become .02, if we add that to octave 8, we get 8.02,
middle d.)

Hence:
oct=trunc(random()*5)+6

            gives us a random octave between 6 and 11.

            (since random() gives us numbers with lots of decimal stuff, and we just want
            integers for the octave, no decimal stuff, we use trunc(). So if random()*7 gives
            us 6.632453645, then trunc(6.632453645) gives us 6)

            The following statement gives us our complete pitch argument:

                     pitch=oct + (sampfunc(3, c)/100)

step 7) Initialize all variables. Write all the variables
you've used, at the top of your score, and set them equal
to 0 (or another initial value, if necessary).

     Let's check the whole example out now:

            rtsetparams(44100,2)
            rtoutput("evil.rows.aiff")
            makegen(1, 10 , 2000, 1, .2, .2, .2)
            makegen(3, 2, 12, 0)
            0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1
            x=0
            q=0
            dur=0
            c=0
            amp=0
            stereo=0
            oct=0
            pitch=0
            start=0
            while (x<100)
                       {
                                 /* choose articulation (envelope) */
                                 q=random()
                                 if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0)
                                 if (q>.5) makegen(2, 24, 2000, 0,0,1,1,2,0)
                                 /* choose duration */
                                 dur=(sampfunc(3, c)+2)/20
                                 /*choose amplitude and stereo position */
                                 amp=(sampfunc(3,c)+12)*1000
                                 stereo=sampfunc(3,c)/11
                                 /*choose pitch*/
                                 oct=trunc(random()*5)+6
                                 pitch=oct + (sampfunc(3, c)/100)
                                 /*Action Statement */
                                 WAVETABLE(start, dur, amp, pitch, stereo)
                                 /* update dependent variables*/
                                 start=start+dur
                                 /* update the cycling counter */
                                 c=c+1
if (c>11) c=0
                                      /* update the main loop control counter*/
                                      x=x+1
                              }

       step 8) Run it, test it, fix it, love it!!!

              This baby should work now, but it's musical usefulness is currently highly
              questionable. I'll leave it to you, gentle reader , to modify it into something someone
              might want to listen to. I chose this example, because it demonstrated all the different
              kinds of variables and their uses. Most simple, texture-generating algorithms won't
              use all of the types of variables and variable-uses discussed here. But, now that you've
              been through this monstrosity, building your own algorithms will be, (hopefully) a
              much easier task.

       Whelp, that's about it.

       (fun with fonts)
       Let's just review the 8 steps:

                      1) Explore your idea, what's happening in
                      the different musical parameters . .

                      2) Divide job into loops

                      3) Basic stuff: rtsetparams, output files,
                      input files, makegens, etc.,

                      repeat 4-7 for each loop:

                      4) Outlines of loop (while or for
                      statements, counters, etc.)

                      5) Action Statements

                      6) Work outwards from Action Statements ,
                      figuring out each parameter.

                      7) Initialize variables.

                      8) Run it, test it, etc.

Note: This tutorial was just to get you started using algorithmic compositional tools. There
are an infinite number of approaches to algorithmic composition, and we encourage
anyone to strike out in different directions. Every new approach will bring new musical
results, and ways of thinking about music, and that’s always exciting. . . .

More Related Content

What's hot

Algorithms and flowcharts1
Algorithms and flowcharts1Algorithms and flowcharts1
Algorithms and flowcharts1Lincoln School
 
2.3 Apply the different types of algorithm to solve problem
2.3 Apply the different types of algorithm to solve problem2.3 Apply the different types of algorithm to solve problem
2.3 Apply the different types of algorithm to solve problemFrankie Jones
 
Best Techniques To Design Programs - Program Designing Techniques
Best Techniques To Design Programs - Program Designing TechniquesBest Techniques To Design Programs - Program Designing Techniques
Best Techniques To Design Programs - Program Designing TechniquesTech
 
1153 algorithms%20and%20flowcharts
1153 algorithms%20and%20flowcharts1153 algorithms%20and%20flowcharts
1153 algorithms%20and%20flowchartsDani Garnida
 
Basic Flowcharting
Basic FlowchartingBasic Flowcharting
Basic Flowchartingsebrown
 
Algorithmsandflowcharts1
Algorithmsandflowcharts1Algorithmsandflowcharts1
Algorithmsandflowcharts1rajnidhiman
 
Pseudocode-Flowchart
Pseudocode-FlowchartPseudocode-Flowchart
Pseudocode-Flowchartlotlot
 
8.1 alogorithm & prolem solving
8.1 alogorithm & prolem solving8.1 alogorithm & prolem solving
8.1 alogorithm & prolem solvingKhan Yousafzai
 
Programming fundamentals lecture 2 of c
Programming fundamentals lecture 2 of cProgramming fundamentals lecture 2 of c
Programming fundamentals lecture 2 of cRaja Hamid
 
Introduction to flowchart
Introduction to flowchartIntroduction to flowchart
Introduction to flowchartJordan Delacruz
 
Pseudocode algorithim flowchart
Pseudocode algorithim flowchartPseudocode algorithim flowchart
Pseudocode algorithim flowchartfika sweety
 
Flowcharts and algorithms
Flowcharts and algorithmsFlowcharts and algorithms
Flowcharts and algorithmsStudent
 
Chapter 6 algorithms and flow charts
Chapter 6  algorithms and flow chartsChapter 6  algorithms and flow charts
Chapter 6 algorithms and flow chartsPraveen M Jigajinni
 

What's hot (20)

Algorithms and flowcharts1
Algorithms and flowcharts1Algorithms and flowcharts1
Algorithms and flowcharts1
 
Algorithm and psuedocode
Algorithm and psuedocodeAlgorithm and psuedocode
Algorithm and psuedocode
 
2.3 Apply the different types of algorithm to solve problem
2.3 Apply the different types of algorithm to solve problem2.3 Apply the different types of algorithm to solve problem
2.3 Apply the different types of algorithm to solve problem
 
Best Techniques To Design Programs - Program Designing Techniques
Best Techniques To Design Programs - Program Designing TechniquesBest Techniques To Design Programs - Program Designing Techniques
Best Techniques To Design Programs - Program Designing Techniques
 
1153 algorithms%20and%20flowcharts
1153 algorithms%20and%20flowcharts1153 algorithms%20and%20flowcharts
1153 algorithms%20and%20flowcharts
 
Algorithm itabq
Algorithm itabqAlgorithm itabq
Algorithm itabq
 
Problem solving and design
Problem solving and designProblem solving and design
Problem solving and design
 
Flow chart
Flow chartFlow chart
Flow chart
 
3 algorithm-and-flowchart
3 algorithm-and-flowchart3 algorithm-and-flowchart
3 algorithm-and-flowchart
 
Basic Flowcharting
Basic FlowchartingBasic Flowcharting
Basic Flowcharting
 
Algorithmsandflowcharts1
Algorithmsandflowcharts1Algorithmsandflowcharts1
Algorithmsandflowcharts1
 
Introduction to algorithms
Introduction to algorithmsIntroduction to algorithms
Introduction to algorithms
 
Pseudocode-Flowchart
Pseudocode-FlowchartPseudocode-Flowchart
Pseudocode-Flowchart
 
8.1 alogorithm & prolem solving
8.1 alogorithm & prolem solving8.1 alogorithm & prolem solving
8.1 alogorithm & prolem solving
 
Savitch ch 03
Savitch ch 03Savitch ch 03
Savitch ch 03
 
Programming fundamentals lecture 2 of c
Programming fundamentals lecture 2 of cProgramming fundamentals lecture 2 of c
Programming fundamentals lecture 2 of c
 
Introduction to flowchart
Introduction to flowchartIntroduction to flowchart
Introduction to flowchart
 
Pseudocode algorithim flowchart
Pseudocode algorithim flowchartPseudocode algorithim flowchart
Pseudocode algorithim flowchart
 
Flowcharts and algorithms
Flowcharts and algorithmsFlowcharts and algorithms
Flowcharts and algorithms
 
Chapter 6 algorithms and flow charts
Chapter 6  algorithms and flow chartsChapter 6  algorithms and flow charts
Chapter 6 algorithms and flow charts
 

Similar to Introduction to writing algorithms

ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docx
ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docxISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docx
ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docxpriestmanmable
 
Notes2
Notes2Notes2
Notes2hccit
 
Cite References.Classification in Discriminant Analysis Discussi.docx
Cite References.Classification in Discriminant Analysis Discussi.docxCite References.Classification in Discriminant Analysis Discussi.docx
Cite References.Classification in Discriminant Analysis Discussi.docxclarebernice
 
Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Bryan O'Sullivan
 
Intro to OpenMP
Intro to OpenMPIntro to OpenMP
Intro to OpenMPjbp4444
 
Gráficas en python
Gráficas en python Gráficas en python
Gráficas en python Jhon Valle
 
Coding in Disaster Relief - Worksheet (Advanced)
Coding in Disaster Relief - Worksheet (Advanced)Coding in Disaster Relief - Worksheet (Advanced)
Coding in Disaster Relief - Worksheet (Advanced)Charling Li
 
from media import #useful functions to manipulate sounds#Chan.docx
from media import #useful functions to manipulate sounds#Chan.docxfrom media import #useful functions to manipulate sounds#Chan.docx
from media import #useful functions to manipulate sounds#Chan.docxhanneloremccaffery
 
Digital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and PythonDigital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and PythonMel Chua
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospectivechenge2k
 
Introduction to programming - class 11
Introduction to programming - class 11Introduction to programming - class 11
Introduction to programming - class 11Paul Brebner
 
DA lecture 3.pptx
DA lecture 3.pptxDA lecture 3.pptx
DA lecture 3.pptxSayanSen36
 
constructing_generic_algorithms__ben_deane__cppcon_2020.pdf
constructing_generic_algorithms__ben_deane__cppcon_2020.pdfconstructing_generic_algorithms__ben_deane__cppcon_2020.pdf
constructing_generic_algorithms__ben_deane__cppcon_2020.pdfSayanSamanta39
 

Similar to Introduction to writing algorithms (20)

ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docx
ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docxISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docx
ISTA 130 Lab 21 Turtle ReviewHere are all of the turt.docx
 
Notes2
Notes2Notes2
Notes2
 
Loops_in_Rv1.2b
Loops_in_Rv1.2bLoops_in_Rv1.2b
Loops_in_Rv1.2b
 
Cracking for beginners - copy (2)
Cracking for beginners - copy (2)Cracking for beginners - copy (2)
Cracking for beginners - copy (2)
 
Cite References.Classification in Discriminant Analysis Discussi.docx
Cite References.Classification in Discriminant Analysis Discussi.docxCite References.Classification in Discriminant Analysis Discussi.docx
Cite References.Classification in Discriminant Analysis Discussi.docx
 
Template Haskell
Template HaskellTemplate Haskell
Template Haskell
 
Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Real World Haskell: Lecture 1
Real World Haskell: Lecture 1
 
Intro to OpenMP
Intro to OpenMPIntro to OpenMP
Intro to OpenMP
 
Gráficas en python
Gráficas en python Gráficas en python
Gráficas en python
 
Coding in Disaster Relief - Worksheet (Advanced)
Coding in Disaster Relief - Worksheet (Advanced)Coding in Disaster Relief - Worksheet (Advanced)
Coding in Disaster Relief - Worksheet (Advanced)
 
Logo tutorial
Logo tutorialLogo tutorial
Logo tutorial
 
from media import #useful functions to manipulate sounds#Chan.docx
from media import #useful functions to manipulate sounds#Chan.docxfrom media import #useful functions to manipulate sounds#Chan.docx
from media import #useful functions to manipulate sounds#Chan.docx
 
Digital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and PythonDigital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and Python
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospective
 
Python Math Concepts Book
Python Math Concepts BookPython Math Concepts Book
Python Math Concepts Book
 
Introduction to programming - class 11
Introduction to programming - class 11Introduction to programming - class 11
Introduction to programming - class 11
 
DA lecture 3.pptx
DA lecture 3.pptxDA lecture 3.pptx
DA lecture 3.pptx
 
More Pointers and Arrays
More Pointers and ArraysMore Pointers and Arrays
More Pointers and Arrays
 
constructing_generic_algorithms__ben_deane__cppcon_2020.pdf
constructing_generic_algorithms__ben_deane__cppcon_2020.pdfconstructing_generic_algorithms__ben_deane__cppcon_2020.pdf
constructing_generic_algorithms__ben_deane__cppcon_2020.pdf
 
Beginning Python
Beginning PythonBeginning Python
Beginning Python
 

More from Krishna Chaytaniah

More from Krishna Chaytaniah (9)

Sortsearch
SortsearchSortsearch
Sortsearch
 
Linear sorting
Linear sortingLinear sorting
Linear sorting
 
Istqb ctfl syll 2011
Istqb ctfl syll 2011Istqb ctfl syll 2011
Istqb ctfl syll 2011
 
Design and analysis of computer algorithms (dave mount, 1999)
Design and analysis of computer algorithms (dave mount, 1999)Design and analysis of computer algorithms (dave mount, 1999)
Design and analysis of computer algorithms (dave mount, 1999)
 
Design and analysis of computer algorithms
Design and analysis of computer algorithmsDesign and analysis of computer algorithms
Design and analysis of computer algorithms
 
Node js
Node jsNode js
Node js
 
Oracle apps
Oracle appsOracle apps
Oracle apps
 
Salesforce content best_practices_rollout_webinar_deck
Salesforce content best_practices_rollout_webinar_deckSalesforce content best_practices_rollout_webinar_deck
Salesforce content best_practices_rollout_webinar_deck
 
Clojure 1a
Clojure 1aClojure 1a
Clojure 1a
 

Introduction to writing algorithms

  • 1. Introduction to Writing Algorithms. (In MINC) Christopher Bailey Hi!! I'm Sammy the Serialist, and I'm going to show you, through an example, the basic steps in creating a CMIX (MINC) algorithm. Along the way, we're going to use "Chris Bailey's 8-Step Method for Creating Algorithms" What are algorithms: Basically, the word "algorithm" usually refers simply to a way or method of doing a task, with the task usually being of a repetitive nature, or being something that can be described easily in an "overall" way. In computer music, examples of such tasks might be "play a chromatic scale" or "play 200 random notes" or "make a very cloudy tremolating sound." As a tool for composers, in other words, algorithms are most often used to generate textures. Generally speaking, in computer music, algorithms do two things: 1. make your life easier: you can use them to do some of the "thinking" for you (but remember, you have to teach the machine "how to think"), creating textures where the details don't matter as much as the overall effect; this is the most common kind of algorithmic composition: using algorithms to create clouds, lines, or whatever: soundfiles that you will insert into a larger piece. 2. For the exploration of things like style modeling, genetics, games, physical laws (gas particles dancing around, et al), artificial intelligence, etc. This gets into "deeper" aspects of algorithmic composition, which we won't get into here (Brad Garton's advanced class begins to explore this wonderful world. . .) What we want to look at here is how to use algorithms to create simple textures and other sound materials for use in your music. The idea/example illustrated here is rather assinine, but it does cover all the concepts you will need to know for basic algorithmic design. To make this process easier, I came up with simple way of thinking things through before and while writing code to accomplish a given musical task. Here it is: Chris Bailey's Basic 8-Step Process 1) Think of and explore your idea, draw pictures, diagrams, and etc. to figure out what's happening in the different musical parameters. How is pitch changing? How is start-time happening? How is duration working? Remember that you don't necessarily have to write all of the notes in their temporal order: some algorithms may splatter notes in time randomly (not in time-order); others may write notes (or other sounds) in rhythm, from
  • 2. first-to-last, time-wise. All sorts of possibilities can happen, so try to open your mind to different ways of solving whatever musical problem you have. 2) Divide job into loops. (Sometimes the task you have can be accomplished with one loop that writes all of the sound involved, other times you may want to have a number of loops write the sounds for different sections of a segment of music, for example.) 3) Basic set-up stuff: Here is where you write statements at the top of the score for things that won't be changing during the algorithmic process. Thus commands like rtsetparams() , opening input and output files with rtinput() and rtoutput() , certain makegen()s, (if they're not going to be changing throughout the score), and so on. Repeat 4-7 for each loop 4) Outline each loop. Type your while or for statements, and then add brackets below, into which you will eventually insert your loop(s). 5) Action Statements. Write out the statements that actually make the sound. (typically the instrument name(s), as in WAVETABLE or the like.) Then fill in their parameters with variables. 6) Work outwards from the Action Statements, figuring out how each parameter will be determined each time the loop goes around--- pitch,duration,start, etc. 7) Initialize all variables before each loop starts. 8) Run it, test it, fix it, modify it, love it. OK, now I describe these steps in more detail: Step 1) Think of your idea. Draw a picture. Figure out what's happening in terms of pitch, rhythm (start-times), durations, articulations (amplitude envelopes), loudness, stereo placement, and whatever other factors are involved in the instrument(s) you're using. Sammy the Serialist Example, cont.’: Let's see. . . I have an Evil 12 Tone Row, and I want to make a nice leapy melody, with the pitch-classes cycling through my Evil Row. Of course, they must always come in different octaves. The rhythm--well, I'm an evil serialist, so of course I want it to be based on my row. The duration of any note will be simply to sound until the next note. I want the articulations to be either an Sfp attack, or else a hairpin (<>) kind of articulation. Loudness-- well, of course, it, too must be based on the row! HaHa! And stereo placement too!! Ha ha ha!!
  • 3. So, now you've thought of how your musical excerpt is going to work. Now, go on to the next step-- step 2) Divide your job into as many separate simple-as- possible loops as you can. In general, a single loop should create either a single line, or a uniform or uniformly changing texture. Sammy Example, cont.: I think I will only need one loop, since I am creating one line of pitches. Later on, for counterpoint, I can use more loops. step 3) Begin by defining basic stuff, like your output file, your input files, any makegens that stay the same for the entire thing, etc. Sammy Example, cont.: rtsetparams(44100, 2) rtoutput("evil.rows.aiff") makegen(1, 10,1000, 1, .2, .2, .2, .1) These are the basic setup items for our script. "Timbre" stays the same--(which, for WAVETABLE is makegen slot 1). But articulation, (i.e.--amplitude envelope, which for WAVETABLE is makegen slot 2, (and usually type 24)) changes, so that will be "in" the loop--we’ll get to it later on. step 4)Write the outlines of your loop(s). This means, basically, control (while or for) statements, plus (if necessary) a statement at the end of the loop that increments your counter. while: As long as the expression in () is True, then the stuff below, the statements in {} will execute. After the stuff in {} is done executing, the () expression is tested again, if still True, then the statements in {} are executed again, and so on, until the () expression is False, then the {} stuff is skipped and the program goes on. Example: while (x<100) { statements, commands, 'n' stuff x=x+1 }
  • 4. Here the {} stuff will execute over and over until x=99. Then the {} stuff will execute one more time, then x=x+1=100, and "x<100" will now be a False statement, so the the program will skip the {} stuff and go on. For : Similar to while, but here, in the initial statement, you tell it the initial value of a counter variable, followed by a semicolon, followed by an expression that has to be True for the {} stuff to be executed (usually that the counter is less than some upper limit, as with while ), followed by another semicolon, followed by a command (usually a change in the counter variable) that you execute each time you go through the loop. for (x=0; x<9; x=x+1) { commands & stuff } if: This is another control statement which you may want to use at some point. If the expression is True then the {} stuff will be executed. There can also be an optional else part. If the expression following the if is False then the {} stuff following the else will be executed. If there is no else part, then the program just goes on, skipping the {} stuff after the if statement. if (x<.5) { commands & stuff } else { commands & stuff } Example, cont.:Hi, Sammy here again. . . . I’m going to use While type loops in my example. step 5) Now begin to write the loop. Remember, you DON'T, repeat, DON'T start at the beginning and work your way down. You start at the middle, and work your way back to the beginning. More precisely, you start at the Action Statement(s), and work backwards. The Action Statement(s) is/are usually your instrument statement(s), such as
  • 5. WAVETABLE, or COMBIT, or whatever, or maybe a makegen for envelope (articulation), timbre, etc. the Action Statements usually take a set of Parameters, like pitch, duration, etc., which change each time you go through the loop. Example, cont.: We are going to have two Action Statements. One, of course, makes the notes: WAVETABLE(start, dur, amp, pitch, stereo) The other makes the "articulation" with the appropriate amplitude envelope: makegen(2, 24, 2000, bla bla bla (we'll fill this in eventually)) So, now our basic loop looks like yay: while (x<100) { WAVETABLE(start, dur, amp, pitch, stereo) makegen(2, 24, 2000, bla bla bla bla) x=x+1 } step 6)Now, work backwards from your Action Statement(s), considering each Parameter in turn, and figuring out how it is calculated. Generally, there are three types of Parameters: CONSTANT: This means that the parameter is the same for every note created by the loop. Constants are easy: you just fill them in with the appropriate number. If the loudness is always the same in a loop, for example, you would just fill in the third slot of the WAVETABLE command with the constant loudness. For example: WAVETABLE(start, dur, 1000, pitch, stereo) NON-DEPENDENT:This means that every time the loop goes around, the parameter is calculated afresh. If in a loop, the statement dur=random()*2, this means that every time the loop goes around, dur is recalculated,
  • 6. regardless (i.e.in- or non-dependent) of its previous value. random()= May as well introduce this here: the random() function produces a random value from 0 to 1. Hence x=random() will assign to the variable x, a random number from 0 to 1. DEPENDENT:This is when a variable's value depends on the value it had last time. A typical standard example is when the start time of the next note you're going to create equals the current start time plus the dur of the current note. (In other words, "start the next note when this one ends.") As a rule of thumb, dependent statements, like our example (start=start+dur) usually go after the Action Statements. Non-dependent values go before the Action Statements. In other words, you, or rather, the loop, calculates the non-dependent values, then, writes the note, then calculate the Dependent values (for the next note), and then goes back to the beginning of the loop (to do the same for the next note.) About choosing values for things: There are, in general, 3 ways of choosing values for things. Let's call them RANGE, SELECT and CYCLIC: RANGE: This is just if you want any random value between x and y, then you just write random()*(y-x)+x, where x < y. Remember that equation--you’ll learn to love it. It gives you floating-point numbers, (i.e.-- with a decimal point and lots of stuff after it); if you need integers, you can use the trunc() function, which just removes the decimal stuff. (trunc(x.y)=x) (It doesn’t round, it just removes the nastiness beyond the decimal point.) Because of the truncation, you have to add 1 in the equation to get your range of numbers, so it becomes: trunc(random()*(y-x+1)+x) (Remember, this one is for integers from x to y .) SELECT: but let's say you want to select from 5 specific values, such as 1, 3, 4, 5, and 6. It would be nice to have these in a table, and then be able to say, "choose a random value from the table." Well, we can do this with sampfunc, and the data , or type 2,
  • 7. makegen. First, we make our table of values that we will select from. Here’s an example: makegen(a, 2, n, 0) 1, 3, 4, 5, 6 a is the ["slot"] number of the table: this is the same in all makegens. If you use more than one table, they should obviously be numbered differently. Also, you shouldn't use the numbers 1, 2, 3, or even 4, because these are often used already by your CMIX instrument; (remember, for example, that WAVETABLE uses slots 1 and 2 for timbre and amplitude envelope , respectively.) n is the number of values you are going to store. 2 specifies that this is a "data" type makegen (as opposed to a "make a harmonic wave" type (10) or a "make an envelope" (24) type, or any of the other types available (see Luke's makegen page.)) The second line contains the actual table, with values separated by commas. Sammy example, cont.: Let's make a table for our Evil 12-Tone Row. Heh, heh. makegen(-3, 2, 12, 0) 0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1 OK, now, how do we later choose a random value from this table? The answer is: sampfunc(t, i) where t is the table# (referring to the first of the the makegen parameters) and i is the # of the piece of data. (However, note that the data gets numbered from 0, not 1, so the last value in our table is #11, not #12.) Let's pretend we made that table above, and now, what will happen when we call sampfunc ? sampfunc(3, 1)=2 sampfunc(3, 0)=0 sampfunc(3, 6)=3
  • 8. sampfunc(4, 6)=error, because we didn't make a table numbered 4 yet. sampfunc(3, random()*12 ) choose a random number between 0 and 11.99999, and select that # value. Thus if (random()*11) gave us 4.42533, (automatically truncated to 4) then the sampfunc would give us 10 (item#4=10). sampfunc(3, random()*n ) The range of random numbers we select is between 0, and n , the number of items. (Note that if you are selecting from, say, 6 items, they are numbered 0-1-2-3-4-5, but you type random()*6 because the highest possible number, 5.99999, would be truncated automatically (by the sampfunc command) to give you 5. Thus you will never get an actual "6" as a result of the randomizing.) CYCLIC: OK, but let's say we don't want to select randomly from our table, but to cycle through it as we cycle through our loop. If our table had, say, six elements, we could use a counter variable, say c, and each time we went through the loop, at the end, we would say: c=c+1; except we would have to check if c > number-of-elements in the table, and if it was, we would reset it to 0, and the cycling would begin again. Our example, cont.: So, we are going to want to cycle through the row, over and over, as we go through our loop. So we need a counter, c. Every time we're going to need a row pitch, (or pitch-class, since we'll determine the octave later), we say pitchclass=sampfunc(3, c) Later, we say c=c+1 if (c>11) c=0 That makes sure c keeps : climbing to 11, skipping back to 0, then climbing to 11, skipping back to 0, then climbing to 11, skipping back to 0 . . . . etc. So now let's go ahead and consider each parameter of our Action Statements, one by one, gradually filling in our algorithm. First, let's look at what we have so far: while (x<100) { makegen(2, 24, bla bla bla) WAVETABLE(start, dur, amp, pitch, stereo)
  • 9. x=x+1 } We’ll start with the first thingy, the envelope makegen. Remember, we wanted to have two choices for envelope, either Sfp, or a <> articulation (a hairpin). These can be chosen randomly. (I.e.--this is a non-dependent decision--what was decided the last time we went through the loop doesn't matter to us.) We can generate a random number 'twixt 0 and 1, and if the number is <= (less than or equal to) .5, then do an Sfp, if it's >.5, then do a <> articulation. In other words: q=random() if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0) else makegen(2, 24, 2000, 0,0,1,1,2,0) The first, if you inspect it, is an Sfp envelope, the second, a <> envelope. Oh-kee, now for start-time. Start-time is dependent. It depends on the value that start-time had the last time we went through the loop, and the last duration used. In other words, the start-time of the current note depends on when and how long the last note was. Since it's dependent, we put it after the Action Statement(s). In our case, it's simply going to equal start+dur. So here's our growing algorithm now: while (x<1000) { q=random() if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0) if (q>.5) makegen(2, 24, 2000,0,0,1,1,2,0) WAVETABLE(start, dur, amp, pitch,stereo) start=start+dur x=x+1 } Now we consider dur. This baby is non-dependent , it doesn't care what the last dur was, but it is CYCLIC. We want to cycle through the row to get durations. So here's where we use our counter, c. To reiterate what we developed a while back, the statements c=c+1 if (c>11) c=0 will keep our counter going round and round as we go round the loop. Then, before our Action Statements, we put an equation giving us the value of dur: dur = (sampfunc(3, c) + 2) / 20
  • 10. Remember, what this says is: get the value from our row table (table #3) that c points to. Then, add 2, so we don't get any 0 durations (we could have added any positive number), then, divide by 20 (again, that's arbitrary) to make the durations shorter (turning up the tempo (I like things fast (I do live in New York, after all.))) OK, let's check where we are now: rtsetparams(44100, 2) rtoutput("evil.rows.aiff") makegen(1, 10 , 2000, 1, .2, .2, .2) makegen(3, 2, 12, 0) 0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1 while (x<1000) { q=random() if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0) if (q>.5) makegen(2, 24, 2000, 0,0,1,1,2,0) dur=(sampfunc(3, c)+2)/20 WAVETABLE(start, dur, amp, pitch, stereo) start=start+dur c=c+1 if (c>11) c=0 x=x+1 } Amp and stereo follow similar procedures. For amp, we have to add a number (12 again, I guess) so we don't get an amp of 0 once every 12 notes, (which would be pointless (but then again, this whole example is rather pointless)), then multiply it all by 1000 to bring the amplitude values into an audible range (remember, RTcmix amplitudes run from 0 to 32768); for stereo, which as you remember, must be from 0 to 1 (left to right), we must "shrink" the range from 0 - 11 to 0 - 1, by dividing by 11. Hence: amp=(sampfunc(3,c)+12)*1000 stereo=sampfunc(3,c) / 11 Pitch is not too much more complicated. Remember that octave-pitch-class notation has 2 parts, an octave argument, followed by a . , then a pitch-class , or pc argument. So, we will generate a random octave, and then look up our pitch-class from the table as we discussed earlier, but divide it by 100, so that it will come after a decimal point. (4 divided by one hundred will be .04, or 10/100 will be .10) Then, we just add them, and taadaa!! instant pitch. (In other words, pc 2 will become .02, if we add that to octave 8, we get 8.02, middle d.) Hence:
  • 11. oct=trunc(random()*5)+6 gives us a random octave between 6 and 11. (since random() gives us numbers with lots of decimal stuff, and we just want integers for the octave, no decimal stuff, we use trunc(). So if random()*7 gives us 6.632453645, then trunc(6.632453645) gives us 6) The following statement gives us our complete pitch argument: pitch=oct + (sampfunc(3, c)/100) step 7) Initialize all variables. Write all the variables you've used, at the top of your score, and set them equal to 0 (or another initial value, if necessary). Let's check the whole example out now: rtsetparams(44100,2) rtoutput("evil.rows.aiff") makegen(1, 10 , 2000, 1, .2, .2, .2) makegen(3, 2, 12, 0) 0, 2, 8 , 11, 10, 6, 3, 4, 7, 9, 5, 1 x=0 q=0 dur=0 c=0 amp=0 stereo=0 oct=0 pitch=0 start=0 while (x<100) { /* choose articulation (envelope) */ q=random() if (q<=.5) makegen(2, 24, 2000, 0,0,1,1,2,.5,19,.5,30,0) if (q>.5) makegen(2, 24, 2000, 0,0,1,1,2,0) /* choose duration */ dur=(sampfunc(3, c)+2)/20 /*choose amplitude and stereo position */ amp=(sampfunc(3,c)+12)*1000 stereo=sampfunc(3,c)/11 /*choose pitch*/ oct=trunc(random()*5)+6 pitch=oct + (sampfunc(3, c)/100) /*Action Statement */ WAVETABLE(start, dur, amp, pitch, stereo) /* update dependent variables*/ start=start+dur /* update the cycling counter */ c=c+1
  • 12. if (c>11) c=0 /* update the main loop control counter*/ x=x+1 } step 8) Run it, test it, fix it, love it!!! This baby should work now, but it's musical usefulness is currently highly questionable. I'll leave it to you, gentle reader , to modify it into something someone might want to listen to. I chose this example, because it demonstrated all the different kinds of variables and their uses. Most simple, texture-generating algorithms won't use all of the types of variables and variable-uses discussed here. But, now that you've been through this monstrosity, building your own algorithms will be, (hopefully) a much easier task. Whelp, that's about it. (fun with fonts) Let's just review the 8 steps: 1) Explore your idea, what's happening in the different musical parameters . . 2) Divide job into loops 3) Basic stuff: rtsetparams, output files, input files, makegens, etc., repeat 4-7 for each loop: 4) Outlines of loop (while or for statements, counters, etc.) 5) Action Statements 6) Work outwards from Action Statements , figuring out each parameter. 7) Initialize variables. 8) Run it, test it, etc. Note: This tutorial was just to get you started using algorithmic compositional tools. There are an infinite number of approaches to algorithmic composition, and we encourage
  • 13. anyone to strike out in different directions. Every new approach will bring new musical results, and ways of thinking about music, and that’s always exciting. . . .