Synthesis ToolKit instruments - Now it gets really interesting - Programming for Musicians and Digital Artists: Creating music with ChucK (2015)

Programming for Musicians and Digital Artists: Creating music with ChucK (2015)

Part 2. Now it gets really interesting!

Chapter 7. Synthesis ToolKit instruments

This chapter covers

· New physical modeling instrument unit generators, such as

o Wind instruments, including clarinet, brass, and flute

o Better stringed instruments, including mandolin and sitar

o Rigid objects, including metal/wood bars and glass

o Particle models, like maracas, tambourines, and wind chimes

o Voice acoustics and vocal models in ChucK

o UGens for classic analog and digital synthesizer sounds

In this chapter you’ll expand your arsenal of unit generators, covering many self-contained instrument UGens. We say instrument because these UGens make sound in response to frequency, noteOn, noteOff, messages, and other parameters, depending on the type of model implemented. By the end of this chapter, you’ll be able to build a band to play Indian classical music automatically.

You’ll learn to use and make sound with models as diverse as clarinet, brass, flute, mandolin, sitar, marimba, maraca (shakers), and voice. We’ll touch on the physics of those instruments and what differentiates individual members within a particular instrument family. We’ll also look at the acoustics of the human voice and how to model that using ChucK UGens. We’ll also cover UGens that can be used to make sounds reminiscent of classic analog and digital synthesizers, organs, and more. It’s especially cool to be able to make these classic analog sounds in ChucK, because you can exploit the power of computer programming to control and compose with them.

In the previous chapter, we introduced the idea of synthesis by physical modeling (PM), looking at the plucked string, and also explored using delays to model room acoustics and some other physical phenomena such as the Doppler pitch shift. Many of the new UGens you’ll see in this chapter are physical models as well. The exciting thing about PM synthesis is that the simulated instruments respond to many of the same controls that actual players use to control the real physical instruments. Bowing pressure and position, blowing pressure, lip tension, the stiffness of a reed, and the number of beans in a maraca or other shaker all are available control parameters in the ChucK PM instrument UGens.

Synthesis history: the Synthesis ToolKit in C++

Many of the UGens in ChucK came from the Synthesis ToolKit in C++, created beginning in 1995 by Perry R. Cook when he was at the Stanford Center for Computer Research in Music and Acoustics. He was trying to unify all of the instruments he had created in lots of different computer languages and bring them into a common, open source, publicly available code collection that others could use easily. Most of the STK is included in ChucK.

At this point, we can note again that the clarinets (and violins) you’ve built so far don’t sound very realistic, even though you keep improving them by adding vibrato, ADSR envelopes, and so on. The lesson of the plucked string is that perhaps you can do better by looking at the actual physics involved in instruments like the clarinet, flute, and trombone. And that’s what you’re going to do in this chapter, which introduces many instruments and some of the parameters you can use to control them. We won’t belabor the physics too much, nor will we dive deeply into all of the available parameters. The goal here is to give you a sampler of the many things ChucK and STK provide to make new sounds and more interesting music.

7.1. STK wind instruments

ChucK has many built-in UGens that model the physics of various instruments and sound-producing objects. You’ll look first at the clarinet, which uses a delay line to model the tube (waveguide) along which sound waves travel up and down, a filter to model the wave reflections and transmissions at the bell (open end), and a nonlinear spring simulation to model the reed. The clarinet model block diagram of figure 7.1 looks pretty close to what you built for your plucked string model in the previous chapter: a delay line, a filter, a bit of noise, and so on. The differences here are that instead of waves traveling up and down a string, you’re using the delay line to model sound waves traveling up and down the clarinet bore (tube). There’s an envelope generator to model the player’s blowing pressure, and you add noise to that to model the rush of air through the reed. The biggest difference in this model from your plucked string is that it has an additional box that models the springiness of the reed, responding to the player’s blowing pressure (the ADSR) and the pressure inside the bore (coming back from the delay line, through the low-pass bore filter).

Figure 7.1. The clarinet model contains excitation (ADSR + Noise for blowing pressure), a delay line to model the bore, a filter in the loop, and a nonlinear reed/spring model.

The best news is that even though you could build a clarinet by making these individual UGens and hooking them all together, you don’t have to because the Clarinet UGen has all of these things built in! And, because it’s a physical model, you can play the STK Clarinet by just declaring one and “blowing” it, as shown in the following listing.

Listing 7.1. Playing the ChucK STK Clarinet physical model unit generator

Running this code, you’ll hear that the Clarinet doesn’t start making musical sound until you blow it hard enough. This is sometimes called the speaking threshold. After that point, every new note played around the loop, each time with increasing pressure, has a different quality, just like a real clarinet. That’s the power of physical models.

The Clarinet has other parameters you can change and control, such as .reed (stiffness), .noiseGain, .vibratoGain, and .vibratoFreq (internal sine wave modulation of breath pressure). Because it’s an instrument, you can also blow it using .noteOn (identical to .startBlowing) and turn it off with .noteOff.

7.1.1. The STK brass instrument physical model UGen

Once you’ve made a wind instrument, you can make others by adding extra physics and controls. By giving the reed/spring some mass, it becomes more like the lip of a brass player. The tube remains basically the same, and if you want to play just a note, you can use the .freq method, as shown in the next listing, which plays a little trumpet exercise on the STK Brass UGen, which is a self-contained UGen that models a brass instrument.

Listing 7.2. Playing the ChucK STK Brass PM UGen

// Playing a PM UG trumpet in a nice space

Brass trump => NRev rev => dac;

0.1 => rev.mix;

// notes for our "exercise"

[82,84,86,84,82,84,86,84,82,77,86,86,89] @=> int notes[];

// play through the exercise, except for the last note

0 => int i;

while (i < notes.cap()-1)

{

0.8 => trump.startBlowing;

Std.mtof(notes[i]) => trump.freq;

0.1 :: second => now;

1 => trump.stopBlowing;

0.05 :: second => now;

i++;

}

// add a little breath vibrato for last note

0.4 => trump.vibratoGain;

0.8 => trump.startBlowing;

Std.mtof(notes[i]) => trump.freq;

second => now;

1 => trump.stopBlowing;

second => now;

The Brass UGen also gives you even more control via the independent controls via the .lip and .slide methods.

7.1.2. The STK Flute physical model UGen

A flute is just a waveguide tube too, so if you change the properties of the reed, you can use a similar model to mimic the air jet of flute-like instruments. The STK Flute UGen does that, providing extra access to the properties of the flute jet via the .jetDelay method. This parameter controls the speed of the air across the blowing hole of the flute and can be used to make the flute overblow to other harmonics, as is typical of flute-like instruments when blown really hard. There are other parameters as well, which you can look up in the ChucK UGen reference (appendix C).Listing 7.3 sets the .jetDelay method randomly to show the flexibility and realism of this physical model. If you want to play notes to sound like a regular flute, use the .freq method as with most other sound-producing UGens.

Listing 7.3. Noodling around with the STK Flute PM UGen

// Noodling around with the STK Flute UGen

Flute pipe => dac;

while (true)

{

// pick a random MIDI note to play

Std.mtof(Math.random2(60,80)) => pipe.freq;

1 => pipe.noteOn;

0.8 :: second => now;

// then randomly mess around with the jetDelay

for (0 => int i; i < 4; i++) {

Math.random2f(0.0,1.0) => pipe.jetDelay;

0.2 :: second => now;

}

1 => pipe.noteOff;

0.1 :: second => now;

}

Other STK wind instruments include:

· BlowHole models a clarinet with one tone hole (via .tonehole) and one register hole (via .vent).

· BlowBotl models a simple pop-bottle-like instrument.

· Saxofony models a variety of reed instruments (including sax) mostly by accessing the .blowPosition method.

Try this

Try playing a scale using the Flute, BlowBotl, or Saxofony instruments. Make one of these instruments and hook it to the dac. Put your notes in an array, and using a for loop, set the frequency using Std.mtof and play notes in that loop using .noteOn and .noteOff. Remember to advance time for both the note-on and note-off segments!

After looking at quite a few STK wind instruments and exploring their parameters, it should be pretty clear that there’s quite a bit of expressiveness in these instruments. You can play notes on them fairly easily by using the .freq and .noteOn methods, but you can go much deeper if you actually control the parameters.

7.2. Better stringed instruments

When you built your plucked string model in the previous chapter, it made a string-like sound but didn’t particularly sound like a guitar, banjo, or other stringed instrument. Aspects that separate certain stringed instruments from others include the overall length (mostly affects pitch range), the shape and size (and materials) of the body, and the type and number of strings. Classical guitars have nylon strings, where folk and electric guitars have steel strings. The steel strings sound brighter, because they’re stiffer than the nylon ones. Smith and Jaffe described how to modify the Karplus-Strong model to mimic the effects of string stiffness, which serves to stretch the higher harmonics upward. This shifting upward of the upper harmonics gives the characteristic brighter sound of steel. You can model this by adding allpass filters in the string loop (special filters that change delay differently for different frequencies). The ChucK STK StifKarp UGen shown in the following listing does just that, with access to the amount of stiffness and spectral stretching via the .stretch method .

Listing 7.4. Playing strings of different stiffness using the StifKarp UGen

7.2.1. The STK Sitar physical model UGen

The Indian sitar, shown in figure 7.2, is characterized by a nonlinear string/bridge interaction (the bridge is where the strings connect to the resonating body). The shape of the bridge causes the strings to chatter when they vibrate, giving a characteristically bright, buzzy quality to the sitar. The STK Sitar UGen models this nonlinear buzz and mimics the pitch bends that sitar players perform on nearly every note. Listing 7.5 shows how to play a raga, or rag, (Indian scale, rhymes with frog) on the Sitar UGen .

Figure 7.2. Nonlinear buzzing bridge (left) of the Indian sitar stringed instrument (right)

Listing 7.5. STK Sitar UGen modeling nonlinear bridge and pitch bends

7.2.2. The STK Mandolin physical model UGen

The STK Mandolin UGen instrument in listing 7.6 adds many improvements over all of your string models so far, including a body model (which can be made virtually larger or smaller via the .bodySize method), .pluckPos , .stringDamping, and .stringDetune . The code in the listing experiments with this instrument, randomly setting body size, damping, and the other parameters to different values between 0.0 and 1.0.

Listing 7.6. STK Mandolin UGen includes a body model and performance controls

Try this

Write a program to play a scale on the Mandolin UGen, like the many scales you’ve played before, using an array and a for loop. Before the for loop, set one of the parameters of .bodySize, .stringDetune, or .pluckPosition to a value between 0.1 and 0.9. Play the scale, add shred, and then change this parameter and play the scale again. Can you hear the difference? Do this for all of these parameters, one at a time. Experiment!

7.2.3. The STK bowed string instrument UGen

Bowed strings are a little trickier than plucked strings, but science and digital signal processing (DSP) have provided efficient techniques for modeling them using waveguide techniques. Shown in the following listing, the built-in ChucK Bowed UGen can be used easily. You can tell it to play notes by setting the frequency and sending it .noteOn messages . You also add a little flourish at the end, as you did with the Brass example, by increasing the vibrato on the last note .

Listing 7.7. Playing a scale on the STK Bowed string model

You might recognize the code of listing 7.7 as similar to our first SawOsc-based violin patch (listing 6.5), but it’s much shorter and simpler. If you play this a few times, you’ll hear that each note sounds a little different each time. This again is one of the benefits of PMs. The Bowed PM UGen lets you control meaningful things like .bowPressure , .bowPosition , rate of bowing, and so on, as shown in listing 7.8. But if you fiddle with those, don’t be surprised if the instrument doesn’t make sound at all or sounds odd. With the benefits of PMs come some of the real-world side effects: they’re hard to play by varying all the parameters by hand. A good rule is to make small changes, maybe in a loop (or two), to see how each parameter changes the behavior, as shown in the following listing. Note the variety of sounds available from this instrument.

Listing 7.8. Fiddling around with the STK Bowed UGen

Now you know that there are many stringed instrument physical models built into ChucK as unit generators. Each models a particular physical attribute, like stiffness or nonlinear buzzing, and/or models a specific instrument like the sitar or mandolin. The available parameters give you a lot of expression to play with and use in your compositions. But are there more instrument families you can synthesize using PM? Yep!

7.3. Bars and other rigid things

John Chowning discovered that modulating one sine wave with another could yield complex sounds, including bell-like tones, which he noted have “inharmonic spectra.” Inharmonic means that the sounds are composed of sine waves, but the frequencies of those sines are not related by simple integer ratios like the frequencies 100, 200, and 300, are. Also recall that stiff strings have stretched harmonics, because high frequencies travel up and down the string faster than low frequencies. Smith and Jaffe showed how to use allpass filters to model that in the Karplus-Strong plucked string.

For really stiff structures like rigid bars, even though waves travel up and down just like in the string, using allpass filters to model the stiffness might not be very efficient because you have to use really big filters to get enough stretching of the spectrum. Also, stiff structures such as metal plates and glass objects don’t have clear waveguide paths up and down. But all of these, as well as objects such as drumheads, exhibit sine wave modes of oscillation, just not usually harmonic or in a regular spectral pattern.

Fear not, because there’s a synthesis method called modal synthesis that uses resonant filters like the ones you used in section 6.6 to model the individual resonant modes of the sounds of objects. ChucK’s ModalBar UGen was created to model the sounds of bars but can be used to model a variety of modal sounds. It has a number of built-in settings for vibraphone, marimba, woodblock, agogo bell, and other bar-like sounds, as shown in the following listing.

Listing 7.9. Trying out the many presets of the ModalBar UGen

// Demo of modal bar presets

ModalBar bar => dac;

while (true) {

// pick a random object type

Math.random2(0,8) => bar.preset;

// and random frequency

Math.random2f(200.0,1000.0) => bar.freq;

// Then whack it!!

1 => bar.noteOn;

0.4 :: second => now;

}

This example shows the sounds you can get from just one model, changing the filter settings to more closely match metal bars, wood bars, and other rigid things.

If you want to make a new model, you can also use the ModalBar UGen but explicitly set the modal frequencies and amount of resonance (Q) for the four modes built into ModalBar. If you look at the spectrum in figure 7.3 of the sound of whacking a water glass with a wooden pencil, you can see four clear modes that dominate. The modal frequencies are marked as 1206, 2240, 3919, and 5965 Hz, and their amplitudes are roughly 0, -7, -3, and -8 dB.

Figure 7.3. Spectrum of sound produced by striking a water glass clearly shows four dominant modes.

With just a little bit of code, you can reprogram the modes of ModalBar to match those shown in figure 7.3 exactly in frequency and amplitude, and with more work, you can figure out what the resonance parameters should be to match the decay times of each mode (listing 7.10). Modal frequencies are set as ratios (.modeRatio ), relative to the first (0th) mode. Each .modeGain is set using the convenient ChucK built-in Std.dbtorms() function, which converts dB gain to linear amplitude. The .modeRadius parameter is a little tricky, but 1.0 means that the mode would never decay (essentially making that filter into a sine wave oscillator, like setting the Q to infinity); 0.9999 causes the mode to die away over a period of about 2 seconds; 0.999 dies in about 1/8 second. Smaller numbers decay more rapidly. The next listing shows how to makeModalBar match our struck water glass quite closely.

Listing 7.10. Spectral modeling using the ModalBar UGen: a struck glass sound

ChucK has another type of physical model for rigid/stiff objects called BandedWG, which models each mode as a waveguide (a delay line; you should remember this from our plucked string explorations) with a band-pass filter (a filter that allows only part of a signal, within a specified frequency range, or band, to pass through) for each mode, to match other properties. The inclusion of delay gives more physical control than just modeling the sinusoidal modes with resonant filters, as ModalBar does. You can actually bow the BandedWG model, in this case to match the characteristics of a Tibetan prayer bowl, as demonstrated in the following listing.

Listing 7.11. Bowing a rigid bar using the BandedWG UGen

// Test some Banded WaveGuide parameters

BandedWG bwg => dac;

// set to model Tibetan prayer bowl

3 => bwg.preset;

// whack the "bowl" to get it started

1 => bwg.noteOn;

// bring the bow to the surface

1 => bwg.startBowing;

// then bow it with increasing pressure

for (0 => int i; i <= 7; i++)

{

<<< "bowPressure=", i*0.1 => bwg.bowPressure >>>;

second => now;

}

// then bow it with decreasing pressure

for (6 => int i; i > 0; i--)

{

<<< "bowPressure=", i*0.1 => bwg.bowPressure >>>;

second => now;

}

You’ve learned about the acoustics and synthesis of the sounds of rigid objects like bars of metal and wood. You’ve also learned that you can tweak the parameters of the ModalBar and BandedWG models to simulate a large variety of such objects. Next, we’ll move on to a completely different family of sound-making things: shakers, scrapers, crunchers, and other particle-based systems.

7.4. Particle models

There are other types of physical systems of musical interest, specifically ones that make sound by the interactions of lots of small particles or objects. Examples include maracas, tambourines, sleigh bells, wind chimes, things crunching beneath our feet (leaves, snow, sand, gravel), and general scraping and scratching sounds. The Shakers UGen in STK covers these and more with an algorithm called Physically Informed Stochastic Event Modeling (PhISM), which is fancy talk for using one or more resonant filters (like the ResonZ resonant filter you’ve used before), but exciting the filters at random times (stochastic) with impulses and tiny noise bursts. You can control the damping (how quickly the sound dies away after you “shake” the model), resonance (general center frequency of the resonances, roughly correlates with total object size), and how many objects are inside the virtual shaker. You can also just use the 22 presets. The following listing is a program that runs through all of the presets.

Listing 7.12. Testing all the presets for the Shakers UG Listing

// Fun with particles, the Shakers instrument

Shakers shak => dac;

// Run through all the presets in order

for (0 => int i; i < 23; i++){

i => shak.preset;

1 => shak.noteOn;

1.0 :: second => now;

}

The next listing is another program that picks one Shakers preset, the Quarters in a Coffee Mug instrument , and randomly fiddles with the parameters, including the number of quarters in the mug and the damping (or decay time) of the whole system .

Listing 7.13. Experimenting with the parameters of one particular shaker preset

A large number of sounds can be made with the Shakers UGen, and you can tweak the parameters (objects, decay, freq) to endless variety. Next, you’ll leave the realm of the physical and enter the world of classic electronic sounds.

7.5. Synth soundz

In the last 60 years—or more—the music world has seen the introduction of many new sounds based on electronic circuits, ranging from electronic organs, through electric guitars and their amplifiers, to synthesizers, and of course computers. In this section, we’ll look at some of ChucK’s more electronic-sounding unit generators.

Many classic analog synthesizers combine oscillators with filters. One of the most popular synthesizers of all time was the Moog (pronounced like vogue, not like Google), named after synthesizer pioneer Bob Moog (1934–2005). The Minimoog, first produced in 1970 by R.A. Moog Inc., had three oscillators (each switchable to generate sine, triangle, sawtooth, square, or pulse) with an ADSR envelope generator, with the oscillators fed through a sweepable (time-varying resonance) filter, also driven by an ADSR. ChucK pays homage to the Moog synthesizers with the Moog UGen, which has an oscillator through a resonant filter that sweeps with each .noteOn, as shown in the next listing.

Listing 7.14. ChucK’s shout-out to the Minimoog, the Moog UGen

// Homage to a classic analog synth sound

Moog mog => dac;

// table of pitches to use

[77,72,69,75,70,67,74,70,65,72] @=> int cars[];

// play first note;

play(cars[0],0.25);

// then play most of the rest

for (1 => int i; i < cars.cap()-1; i++)

{

if (i % 3 == 0) play(cars[i],0.5);

else play(cars[i],0.25);

}

// push up "mod wheel" for last note

0.25 => mog.vibratoGain;

play(cars[cars.cap()-1], 1.0);

// function to play notes on/off

fun void play(int note, float howLong)

{

Std.mtof(note) => mog.freq;

1 => mog.noteOn;

(howLong - 0.05) :: second => now;

1 => mog.noteOff;

0.05 :: second => now;

}

There are some additional Moog parameters available, such as .filterSweepRate, .filterQ, and .vibratoFreq.

Try this

Write new code to test these out! Maybe something like this:

// Trying out the Moog parameters

Moog mog => dac;

200.0 => mog.freq;

while (1) {

Math.random2f(1.0,1.0) => mog.filterQ;

Math.random2f(0.01,1.0) => mog.filterSweepRate;

1 => mog.noteOn;

if (Math.random2(0,10) == 0) {

Math.random2f(1.0,20.0) => mog.vibratoFreq;

0.5 => mog.vibratoGain;

second => now;

}

else {

0.01 => mog.vibratoGain;

0.125 :: second => now;

}

1 => mog.noteOff;

0.125 :: second => now;

}

We also talked about FM synthesis in the previous chapter, which can be quite nice for making synthesizer-type sounds. For example, the PercFlut models a percussive flute sound, but it can sound pretty synthetic because it’s FM. BeeThree pays tribute to the sound of the classic Hammond B3 organ, but again it can sound synthetic because it models an electronic organ. The HevyMetl FM UGen is modeled somewhat after the characteristics of a distortion guitar but definitely has the sound of classic oscillator-based synthesizers. Try the example in the following listing of using HevyMetlto play a song associated with a particularly famous electric guitar player (Jimi Hendrix playing the “Star Spangled Banner” at Woodstock, 1969).

Listing 7.15. Using the HevyMetl FM UGen to synthesize an electric guitar

The code uses both a PRCRev and a Delay for echo to give it all a stadium sound. The array named banner contains elements specifying MIDI note number, duration, and modulation amount. You also use a function to play the individual notes , and after you’ve played through all the notes in your array using a while loop , you go a little crazy on the last note, sweeping the pitch downward (a digital whammy bar) using another while loop .

7.6. Voices

If you look at the spectrum (figure 7.4) of our “eee” sound from “see” from chapter 1, you’ll note that the spectrum is harmonic, with regularly spaced sine spikes, but you also might note that some of the sines have higher amplitudes than others. The way the voice works is that the vocal folds oscillate periodically for pitched sounds (vowels, ell, em, and so on), and the vocal tract consisting of a person’s throat, mouth, tongue, and nasal passages serves to filter that sound and shape the spectrum. Depending on the shape of the vocal tract, some frequencies are emphasized (resonances) and others are deemphasized. The resonant peaks are called speech formants, and their locations determine whether you hear an “eee,” an “ahh,” or another sound from the variety you can make, all on the same pitch. The formants in the “eee” spectrum are-shown in figure 7.4.

Figure 7.4. Spectrum of “eee” sound shows harmonics and resonant speech formants.

Because ChucK has both oscillators and resonant filter UGens, it’s pretty easy to build a model that sounds like a human voice. The code of listing 7.16 uses a SawOsc UGen to model the vocal folds through three resonant filters (one for each of three formant resonances of the vocal tract) to make a pretty good singer model. You also add a SinOsc to modulate the SawOsc for vibrato. Once it’s hooked up, the resonances are calibrated , and you drop into an infinite loop to sing random vowels and pitches .

Listing 7.16. Building a simple formant (resonant filter) voice model

ChucK also has a built-in VoicForm (voice modeled with formant filters) UGen instrument, which includes a vocal fold oscillator (with vibrato), a noise source (whispering an “eee” means not letting the vocal folds make a pitch but pressing them together just enough to make noise), four formant filters, and presets for common vowels and consonants. As shown in listing 7.17, you can select the phonemes (individual speech sounds) by number or by name as a string.

Note that the transitions between vowels and pitches are smoothed, not making pops and clicks between new settings like your simple voice model of listing 7.15. That’s because VoicForm has built-in smoothing envelopes that make the transitions gradual when moving to new oscillator and filter frequencies.

Listing 7.17. Using ChucK’s VoicForm formant voice UGen

The VoicForm UG also gives you control of the mix of pitched voiced versus unvoiced noise sources to be filtered via the .voiceMix method, so you can whisper or make breathy voices. You can also control the vibrato amount via .vibratoGain, the vibrato rate via .vibratoRate, and the rate at which the oscillator moves from pitch to pitch via .pitchSweepRate.

There are more ways to synthesize voices. John Chowning figured out early in his experiments with FM that if he set the frequencies of a number of sine wave carrier oscillators near each formant frequency and modulated all of them with a sine wave at the fundamental pitch, he could generate voice-like sounds. The ChucK FMVoices instrument UGen does just this.

There are more UGens that we haven’t talked about yet. You can read about those in appendix C and try them out for your music making.

7.7. Example: Indian music

For a final example, called ragajam, you’re going to make a band to play Indian music. In all of the code that follows, you’ll use a sitar as your primary solo instrument. You’ll have other instruments, so, as shown in listing 7.18, you’ll make a Gain called master for mixing before the dac . For a little echo, you’ll connect the sitar to a Delay UGen , connect the Delay to itself (through a feedback gain), and connect the whole thing to the master mixer . You’ll then set the parameters for the sitar echo, including setting the feedback gain so the echo decays.

Note

All of the code from here until the end of the chapter is a continuation of listing 7.18. So it all goes into one .ck file before you run it.

Listing 7.18. Ragajam Indian music in ChucK

You need accompaniment for your sitar player, so you use some very low singers as drones. First, you declare an array of four singers (VoicForm UGens) and an NRev reverberator for them to sing through. Using a for loop, you connect them all to their reverb and set their gains . Then you set the parameters for each drone singer: vibrato , the vowel they will sing , and their pitches (from an array ).

You’d like some percussion as well, so for that you can use the Shakers UGen . You’ll also define a shake function to control the sitar player’s pretty random playing. That way you can tell him to shake (call the function), and he’ll set up parameters randomly and do his own .noteOnto make sound.

As is traditional in many kinds of music, you need to pick a musical scale, called a raga in Indian music:

// global raga scale

[62,63,65,67,69,70,72,74] @=> int raga[];

and you need to pick a tempo, called a lay (or laya).

// global timing/tempo parameter

.2 => float beattime;

Now that you’ve set the tempo, you can set the Sitar delay parameters to help reinforce the rhythm:

// sitar echo parameters

beattime::second => delay.max;

beattime::second => delay.delay;

.5 => sitarFeedback.gain;

Finally, before you teach this band to play, you need to realize that you have six instruments playing (four drones, a sitar, and a shaker), so you might want to scale down your master gain:

// master volume parameter

.7 => master.gain;

Time to play! You let the drones start it all off for a few seconds ; then the sitar and shaker join in, playing at random multiples of the basic tempo. The sitar player selects random notes from the raga[] array, and the shaker plays along (randomly too ). The result is pretty magical, all thanks to ChucK:

7.8. Summary

In this chapter we introduced a lot more unit generators, specifically ones that are self-contained instruments, meaning that they respond to messages like .freq, .noteOn, and .noteOff to make sound. You learned about a lot of physical (and physically inspired) models, specifically:

· Stiff and nonlinear strings, and the Sitar and Mandolin

· Wind instruments such as the Clarinet and Flute

· Rigid bars and hard objects like glass and metal via ModalBar and BandedWG

· Particle models to make the sounds of Shakers, scrapers, wind chimes, and the like

· The human voice, synthesis from scratch using filters, and the VoicForm UGen

You also learned about STK UGens that implement other synthesis models and how to use them:

· FMVoices and other FM algorithms

· Electronic and synthesizer sounds, via the Moog, Wurley, and other UGens

You learned that almost all of these instrument UGens have control parameters that are similar to those of the real instruments. You now know a lot of new ways to make sounds and music and can use these UGens in your compositions. In our final Indian music example of this chapter, you built a band made up of vocal drones, a shaker percussionist, and a solo sitar player.

In the next chapter, you’ll learn how to make your bands more flexible, break up the individual players into separate ChucK files, and run them individually, in parallel, from a master conductor program. This is called concurrency, and it will make your programs and music-making even more powerful.

For further reading

To learn more about PM synthesis and the STK and how all of the instrument models work, check out Real Sound Synthesis for Interactive Applications, by Perry R. Cook (CRC Press, 2003). And see Julius O. Smith’s excellent web resources on PM: https://ccrma.stanford.edu/~jos/pasp/.