Just playing around with ChucK, a “strongly-timed music programming language,” in 2009. This piece contains:
- An arp using a StifKarp.
- A random melody.
- A kick drum made with a sweeping sine wave.
- A bassline track made with a sine wave.
- Some feedback delay lines.
Try on Patchieshttps://patchies.app/?id=6wjvo38hcycyou6
// Master BPM
float bpm;
(140) => bpm;
// Each step
int step;
dur each;
((60 / bpm) / 48)::second => each;
// Master Track
Gain master;
master => dac;
(0.5) => master.gain;
// Synth Track
Gain synth;
Delay synth_d;
Gain synth_g;
synth => master;
synth => synth_d;
synth_d => synth_g;
synth_g => synth_d;
synth_g => master;
(each * 36) => synth_d.max;
(each * 36) => synth_d.delay;
(0.5) => synth_g.gain;
// Bass Track
Gain bass;
bass => master;
(0.6) => bass.gain;
// Random Melody
Gain melody;
Delay melody_d;
Gain melody_g;
melody => master;
melody => melody_d;
melody_d => melody_g;
melody_g => melody_d;
melody_g => master;
(0.5) => melody_g.gain;
(each * 60) => melody_d.max;
(each * 60) => melody_d.delay;
// Percussion
Gain percussion;
percussion => master;
// Instrument Class
class Trig {
(1) => int freq;
(0) => int left;
(0) => int num;
fun void next() {
(left - 1) => left;
if (left <= 0) {
(freq) => left;
() => trigger;
(num + 1) => num;
}
}
fun void setFreq(int newFreq) {
int del;
(newFreq - freq) => del;
(freq + del) => freq;
(left + del) => left;
}
fun void trigger() {
}
}
// Channel Arp
StifKarp arp;
arp => synth;
class Pattern1 extends Trig {
[
9, 4, 4, 9, 4, 4, 9, 4,
9, 4, 4, 9, 4, 4, 9, 4,
11, 4, 4, 11, 4, 4, 11, 4,
12, 4, 4, 12, 4, 4, 14, 16,
9, 4, 4, 9, 4, 4, 9, 4,
9, 4, 4, 9, 4, 4, 9, 4,
11, 4, 4, 11, 4, 4, 11, 4,
12, 4, 4, 12, 4, 4, 14, 16,
9, 5, 5, 9, 5, 5, 9, 5,
9, 5, 5, 9, 5, 5, 9, 5,
11, 5, 5, 11, 5, 5, 11, 5,
12, 5, 5, 12, 5, 5, 14, 16,
9, 2, 2, 9, 2, 2, 9, 2,
11, 2, 2, 11, 2, 2, 11, 2,
12, 2, 2, 12, 2, 2, 12, 2,
14, 2, 2, 14, 2, 2, 16, 17
] @=> int noteNum[];
fun void trigger() {
(noteNum[num % 128] + 60) $ float => Std.mtof => arp.freq;
(1) => arp.noteOn;
}
}
Pattern1 arp_t;
(12) => arp_t.freq;
// Channel Bass
SinOsc basssynth => bass;
class Pattern2 extends Trig {
[9, 9, 6, 6, 2, 2, 7, 8] @=> int noteNum[];
fun void trigger() {
(noteNum[num % 8] + 36) $ float => Std.mtof => basssynth.freq;
}
}
Pattern2 basssynth_t;
(192) => basssynth_t.freq;
// Channel Melody
Mandolin mel => melody;
class Pattern3 extends Trig {
[
[0, 4, 9, 11, 12],
[4, 9, 11, 12, 16],
[0, 4, 6, 9, 12, 16],
[4, 6, 9, 12, 16, 18],
[2, 4, 5, 9, 11, 12],
[4, 5, 9, 11, 12, 17],
[2, 7, 11, 14, 17, 19],
[2, 4, 8, 11, 14, 16, 19]
] @=> int notes[][];
int last;
fun void trigger() {
int cur;
int l[];
if (step % 768 >= 720) {
setFreq (12);
} else {
setFreq (24 - 12 * (num % 2));
}
(notes[(step / 192) % notes.cap()]) @=> l;
do {
(Std.rand2(0, l.cap() - 1)) => cur;
} while (last == cur);
cur => last;
(l[cur] + 48) => Std.mtof => mel.freq;
(1) => mel.noteOn;
}
}
Pattern3 mel_t;
(24) => mel_t.freq;
// Bass Drum
SinOsc bd => ADSR bd_c => percussion;
(1::ms, 0::ms, 1, 20::ms) => bd_c.set;
800 => bd.freq;
fun void bd_s() {
(step % 48) => int cst;
400 * Math.pow(1 - ((cst $ float) / 48), 20) => bd.freq;
if (cst == 0) {
bd_c.keyOn ();
}
if (cst == 20) {
bd_c.keyOff ();
}
}
(0.5) => synth.gain;
// Main Loop
(0) => step;
() => arp_t.next;
() => basssynth_t.next;
while (1) {
() => arp_t.next;
() => basssynth_t.next;
() => mel_t.next;
() => bd_s;
(1 + step) => step;
(each) => now;
}