12 : Creating Rhythmic Noise

Over a year ago, when I first tried the OLPC/Sugar software, I was fascinated by the TamTam activities. Had such activities been available in my time, I may even have liked school.

The TamTam activity builds on top of the Csound framework to allow children to explore sounds and music. As I explored the Csound tutorial by Michel Gogins, I came across his comment, “Of all the languages I have used, both in my career as a programmer and in my career as an algorithmic composer, Python have been by far the easiest and most productive language to learn and to use.”

Gogins also writes, “Csound must be considered as one of the most powerful musical instruments ever created.”

Hence, the motivation for this article. We will explore how to create noise and, we hope, you will go on to compose music :) In the current state of the world, we need even more music.

To know a bit about the people behind the code , see http://www.csounds.com/journal/2006spring/meetTheCsound5Developers.html.

Getting Started

You will need to install the following packages:

csound

csound-python

Csound requires an xml-like configuration file with 3 sections. Create a minimal file, tutorial.csd:

<CsoundSynthesizer>

<CsOptions>

</CsOptions>

<CsInstruments>

</CsInstruments>

<CsScore>

</CsScore>

</CsoundSynthesizer>

We will be satisfied with the default options. The instruments section is where we define the 'orchestra', that is all the instruments which will be used to create our musical masterpiece. These are the same as the contents of myfile.orc in the beginners articles in http://www.csounds.com/journal/articleIndex.html.

The score section will contain a list of instructions for the instruments in our orchestra. These are same as the contents of myfile.sco mentioned in the above articles.

Create the same simple instrument as in the beginners' introduction - http://www.csounds.com/ezine/winter1999/beginner/index.html

<CsInstruments>

sr=44100 ; Sample Rate

kr=22050 ; Control Rate

ksmps=2 ; sr/kr As far as I know this is always the case

nchnls=2 ; 1=mono, 2=stereo, 4=quad

instr 1 ; Instrument 1 begins here

aout oscil 10000, 440, 1 ; An oscillator

outs aout, aout ; Output the results to a stereo sound file

endin ; Instrument 1 ends here

</CsInstruments>

The first four lines are the header information which controls the output format. The remaining lines are the definition of the instrument, which is a simple oscillator operating at a frequency of 440Hz and a volume of 10000, about a third of the maximum. (Volume is represented as a 16bit integer.) The third parameter to the oscil command/opcode identifies the waveform table to be used in the score given below. The oscillator is given a variable name aout. The same sound is passed to both the channels.

Now, add the score:

<CsScore>

f 1 0 16384 10 1 ; table #, start time, the size, generator, parameter

i 1 0 1 ; instrument #, start time, duration

</CsScore>

f is the waveform table which is available at the start of performance with 16384 samples. The generator value 10 with parameter 1 corresponds to a sine wave in Csound.

The i line is an instrument event with the instrument number, the start time and duration in seconds as the parameters.

You can run this script, get a wave file and play it.

$ csound -Wo tutorial.wav tutorial.cs

$ aplay tutorial.wav

Controlling Csound using Python

Write the following code in tutorial.py. This is pretty useless as all it does is replace the command line for executing csound. But have patience.

# Import the Csound API extension module.

import csnd

# Create an instance of Csound.

csound = csnd.CppSound()

# Enable Csound to print console messages

csound.setPythonMessageCallback()

# Load the tutorial piece created earlier.

csound.load('tutorial.csd')

# Set the Csound command for off-line rendering.

csound.setCommand('csound -Wo tutorial.wav temp.orc temp.sco')

# Export the .orc and .sco file for performance

csound.exportForPerformance()

# Actually run the performance.

csound.perform()

We will now add code to generate the score algorithmically. However, our current instrument is pretty hopeless. So, you will need to refine the instrument in tutorial.csd as follows:

instr 1

iamp = p4

ifqc = p5

itabl1 = p6

aout oscil iamp, ifqc, itabl1

outs aout, aout

endin

The new oscillator uses the amplitude, frequency and waveform table reference as parameters. The variables in Csound have a strict format reminiscent of Fortran. Local variables start with the letters "i", "k" or "a". Variables starting with the letter "i" are initialized to a value when the instrument is started and do not usually change. The letter "a" indicates an audio rate variable and the letter "k" indicates a control rate variable.

There are also some special "p" variables or parameters which send values from the score to the orchestra – p1, p2 and p3 are the instrument's number, start time and the duration. The variables p4, p5, p6, etc. are flexible. They are used above for amplitude, frequency and the waveform table.

Now, add a call to add_score the tutorial.py as follows:

csound.setCommand('csound -Wo tutorial.wav temp.orc temp.sco')

add_score(csound)

# Export the .orc and .sco file for performance

Now, code an add_score method:

def add_score(csound):

sarega = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]

for time in range(8):

csound.addNote(1, time, 1, 8000 , sarega[time], 1)

Your instrument will play the notes. Let us improve the instrument and put an envelope in each event. Modify the instrument definition in tutorial.csd as follows:

instr 1

iamp = p4

ifqc = p5

itabl1 = p6

kamp linseg 0, .2, 1, .2, .8, p3-.5, .8, .2, 0

aout oscil iamp, ifqc, itabl1

outs aout*kamp, aout*kamp

endin

You can define an envelop using the opcode linseg, which represents the starting amplitude followed by pairs of time interval and the amplitude at the end of the interval. The control variable kamp starts with 0, rises to 1 in .2 sec, then drop to .8 in next .2 sec, and retains that value until .2 sec before the end. In the last .2 sec, the value drops from .8 to 0. As you can imagine, an instrument can be programmed to generate pretty complex sounds for each event. You can get an idea of the programming possibilities by playing two frequencies close to each other. Replace the add_score method in tutorial.py with:

def add_score(csound):

sarega = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]

for time in range(8):

csound.addNote(1, time, 1, 8000 , sarega[time], 1)

csound.addNote(1, time, 1, 8000 , sarega[time] + 5, 1)

Not surprisingly, you should hear beats.

Musicians do not work with frequencies. They work with octaves. So, let us define another instrument which uses a converter opcode to convert a number into a frequency. The whole number represents the octave and the decimal part the semitone. So, to the instruments section in tutorial.csd add the following:

instr 2

iamp = p4

ifqc = cpspch(p5)

itabl1 = p6

kamp linseg 0, .2, 1, .2, .8, p3-.5, .8, .2, 0

asigl oscil iamp, ifqc*.999, itabl1

asigr oscil iamp, ifqc*1.001, itabl1

outs asigl*kamp, asigr*kamp

endin

Notice, that the definition has a different oscillator definition for the right and left channels. In the score section, include a second waveform table

f2 0 16384 10 1 .5 .3333

This table is also a sine wave but includes the 1st and 2nd harmonics with amplitudes a half and a third of the primary wave.

Now, modify the add_score method in tutorial.py to use both instruments:

def add_score(csound):

sarega = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]

pitch = [8.00, 8.02, 8.04, 8.05, 8.07, 8.08, 8.11, 9.00]

for time in range(8):

csound.addNote(1, time, 1, 8000 , sarega[time], 1)

csound.addNote(2, time, 2, 8000, pitch[time], 1)

The second instrument plays the same tones but at an octave higher. It also uses the second waveform table. You can explore various programming possibilities – like varying amplitudes, varying durations and varying the relative start time of instruments.

As you would have noticed, there is no constraints on the size of the orchestra you can single handedly create. You can find some simple drum instruments at http://www.csounds.com/ezine/autumn1999/synthesis/index.html. So, go ahead, try them and, may be, create a synthetic tabla!

Next month, we will explore playing with sounds using Soundfonts and Csound.



<Prev>  <Next>

Comments