// Listing 7.18 Ragajam Indian music in ChucK
Sitar sitar => Gain master => dac; // (1) Sitar instrument, master mixer Gain
sitar => Delay delay => Gain sitarFeedback => delay; // (2) Delay line to give Sitar an echo
delay => master; // (3) Connects delay line to output mixer
// drone "singers" to accompany
VoicForm singerDrones[4]; // (4) Uses four "singers" as low drones.
NRev droneRev => master; // (5) Drones get their own reverb...
for( 0 => int i; i < singerDrones.cap(); i++)
{
singerDrones[i] => droneRev; // (6) ...connect the singers...
(.5/singerDrones.cap()) => singerDrones[i].gain; // (7) ...and set their gains appropriately.
}
// singer parameters (drone)
[26,38,45,50] @=> int drones[]; // (8) Pitches for low drone singers.
.5 => droneRev.mix;
for( 0 => int i; i < singerDrones.cap(); i++)
{
.02 => singerDrones[i].vibratoGain; // (9) Gives droners a little vibrato.
"lll" => singerDrones[i].phoneme; // (10) Sets the "word" they're singing.
Std.mtof(drones[i]) => singerDrones[i].freq; // (11) Sets their pitches
}
// Shaker percussion, and control function
Shakers shaker => master; // (12) Shaker percussionist, connects to output mixer
fun void shake()
{ // (13) Function to cause the shaker to play a "note"
// drum control
Math.random2(1,2) => shaker.preset;
Math.random2f(60.0,128.0) => shaker.objects;
Math.random2f(.8,1.0) => shaker.decay;
shaker.noteOn(Math.random2f(0.0, 4.0));
}
// global raga scale
[62,63,65,67,69,70,72,74] @=> int raga[];
// global timing/tempo parameter
.2 => float beattime;
// sitar echo parameters
beattime::second => delay.max;
beattime::second => delay.delay;
.5 => sitarFeedback.gain;
// master volume parameter
.7 => master.gain;
// MAIN PROGRAM, ragajam.ck // warm up with a drone solo
5::second => now; // // (14) Drones begin the piece
// main loop, add Sitar and Shaker
while (true) {
Math.random2(1,3) => float factor; // (15) Random timing for each new "measure"
// loop
for( 0 => int i; i < raga.cap(); i++ )
{
// sitar control, // (17) Random note from raga array
Std.mtof(raga[Math.random2(0,raga.cap()-1)]) => sitar.freq;
sitar.noteOn(Math.randomf()); // (16) Sitar player
// play a percussion sound
shake(); // (18) Tells the shaker to play on beat...
// advance time by 1/2 our basic beat
(0.5*beattime)::second*factor => now;
// an occasional half-time percussion hit for flavor
if (Math.random2(1,3) == 1) // (19) ...and lets him play on off-beat every so often.
{
shake();
}
// advance time by the other 1/2 beat
(0.5*beattime)::second*factor => now;
}
}