Table Of Contents
Open Table Of Contents
Composition using this project:
GUI-less DAW
A DAW(digital audio workstation) do not have a graphical user interface, yet includes essential features for music production:
- a mixer: Master,Bus,Fx Send etc.
- basic music modules: Note, Scale, Chord
- instruments: drum machine, bass ,guitar etc.
- effects : FeedBackDelay etc.
- algorithm composition modules
- algorithm sequence generator
- implemented: Fibonacci, Euclid
- TODO: cellular automata, Markov chain etc
- spectral composition
- risset appregio, resset beat
- FibonacciPad
- grain synthesis
All these features are implemented using ChucK language, a real-time audio programming language. This project is hosted on github: https://github.com/lmaxwell/chuckComposition
code structure
├── lib
│ ├── basic
│ │ ├── BPM.ck
│ │ ├── Chord.ck
│ │ └── Scale.ck
│ ├── effect
│ │ ├── FbDelay.ck
│ │ └── RtGrain.ck
│ ├── instrument
│ │ ├── FibonacciArp.ck
│ │ ├── LFO.ck
│ │ ├── MandolinBass.ck
│ │ ├── MandoPlayer.ck
│ │ ├── RissetBeat.ck
│ │ ├── RissetChordBeat.ck
│ │ └── RissetNoteBeat.ck
│ ├── mixer
│ │ └── Mixer.ck
│ └── seq
│ ├── EuclidSeq.ck
│ └── FibonacciSeq.ck
├── pop
│ ├── 07.ck
│ └── 27.ck
├── README.md
├── run.ck
├── autogen.sh
How to run
The following command runs pop/27.ck
chuck run.ck:pop/27.ck
run.ck helps to preload all the modules in “lib” directory
Machine.add("lib/basic/BPM.ck");
Machine.add("lib/basic/Chord.ck");
Machine.add("lib/basic/Scale.ck");
Machine.add("lib/effect/FbDelay.ck");
Machine.add("lib/effect/RtGrain.ck");
Machine.add("lib/instrument/FibonacciArp.ck");
Machine.add("lib/instrument/LFO.ck");
Machine.add("lib/instrument/MandoPlayer.ck");
Machine.add("lib/instrument/MandolinBass.ck");
Machine.add("lib/instrument/RissetBeat.ck");
Machine.add("lib/instrument/RissetChordBeat.ck");
Machine.add("lib/instrument/RissetNoteBeat.ck");
Machine.add("lib/mixer/Mixer.ck");
Machine.add("lib/seq/EuclidSeq.ck");
Machine.add("lib/seq/FibonacciSeq.ck");
for(0=>int i;i<me.args();i++)
Machine.add(me.arg(i));
run.ck can be updated by autogen.sh when new modules are added into “lib” directory.
bash autogen.sh
pop/27.ck
pop/27.ck is a song composed with 280 lines of code based this library. This is what it sounds like:
Mixer.master.set();
0.3=>Mixer.master.gain;
Scale scale;
scale.set(70,"aeolian");
Chord chord;
RissetChordBeat rcb => Mixer.bus[0];
0.6=>Mixer.bus[0].gain;
0.5=>Mixer.bus[0].send[0].gain;
//-0.5=>Mixer.bus[0].pan;
BPM bpm;
bpm.set(120);
FbDelay fbd;
fbd.setTime(bpm.quarterNote*3.0/4.0);
fbd.setFeedBack(0.6);
fbd.setMix(1);
//rcb=>fbd=>Mixer.bus[1];
bpm.quarterNote-now%bpm.quarterNote => now;
//Machine.add("util/rec-auto-stereo.ck");
Impulse i => Moe moe => Mixer.bus[2];
Dinky dk => moe;
0.5=>dk.gain;
i=>Larry larry => Mixer.bus[2];
dk =>larry;
0.8=>Mixer.bus[2].gain;
-0.9=>Mixer.bus[2].pan;
0.9=>Mixer.fxdelay.pan;
0.5=>Mixer.bus[2].send[0].gain;
0.0=>Mixer.bus[2].send[1].gain;
Mixer.fxdelay.fbdelay.setTime(bpm.quarterNote*3.0/4.0);
//Mixer.fxdelay.fbdelay.setFeedBack(0.8);
spork ~moe.run();
spork ~larry.run();
RissetNoteBeat rnb=> Mixer.bus[1];
0.4=>Mixer.bus[1].send[0].gain;
0.7=>Mixer.bus[1].gain;
0.5=>Mixer.bus[1].pan;
RissetNoteBeat rnb_low => Mixer.bus[3];
0.4=>Mixer.bus[3].send[0].gain;
0.8=>Mixer.bus[3].gain;
EuclidSeq impulseseq;
EuclidSeq dkseq;
dkseq.set(16,9,0);
int measure;
LFO lfo_rcb;
120=>lfo_rcb.sync;
//spork ~lfo_rcb.am(rcb,2,8,1::samp,10::samp);
LFO lfo_wave;
while(true)
{
/*
Wave wave => Mixer.bus[4];
0.05=>Mixer.bus[4].gain;
0.6=>Mixer.bus[4].send[0].gain;
1000=>wave.freq;
-0.2=>Mixer.bus[4].pan;
spork ~wave.run(bpm.quarterNote*4*16);
spork ~lfo_wave.am(wave,2,10,10::ms,15::ms);
*/
section1();
section2();
section3();
section4();
section5();
section6();
/*
wave.stop();
*/
}
fun void section6()
{
//section 3
0=> measure;
while(measure<16)
{
Math.random2(10,30)=>int num;
<<<num>>>;
rnb.set(num);
Math.random2(4,10)=> num;
rnb_low.set(num);
<<<num>>>;
Math.random2(10,30)=>num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
spork ~dinky(chord,8*BPM.quarterNote,-1,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+24),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
spork ~dinky(chord,8*BPM.quarterNote,-2,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+24),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void section5()
{
//section 3
0=> measure;
while(measure<16)
{
Math.random2(10,30)=>int num;
<<<num>>>;
rnb.set(num);
Math.random2(4,10)=> num;
rnb_low.set(num);
<<<num>>>;
Math.random2(10,30)=>num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
spork ~dinky(chord,8*BPM.quarterNote,-1,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+24),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
spork ~dinky(chord,8*BPM.quarterNote,-2,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+24),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void section4()
{
//section 3
0=> measure;
while(measure<16)
{
Math.random2(10,30)=>int num;
<<<num>>>;
rnb.set(num);
Math.random2(4,10)=> num;
rnb_low.set(num);
<<<num>>>;
Math.random2(10,30)=>num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
spork ~dinky(chord,8*BPM.quarterNote,-1,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
spork ~dinky(chord,8*BPM.quarterNote,-2,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-24),bpm.quarterNote*6);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void section3()
{
//section 3
impulseseq.setRotation(2);
0=> measure;
while(measure<16)
{
Math.random2(10,30)=>int num;
<<<num>>>;
rnb.set(num);
Math.random2(4,10)=> num;
rnb_low.set(num);
<<<num>>>;
Math.random2(10,30)=>num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
spork ~dinky(chord,8*BPM.quarterNote,-1,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-12),bpm.quarterNote*3);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
spork ~dinky(chord,8*BPM.quarterNote,-2,2);
spork ~rnb_low.play(Std.mtof(chord.sample()-12),bpm.quarterNote*3);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void section2()
{
impulseseq.setRotation(1);
//section 2
0=> measure;
while(measure<16)
{
Math.random2(10,30)=>int num;
<<<num>>>;
rnb.set(num);
<<<num>>>;
Math.random2(10,30)=>num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
spork ~dinky(chord,8*BPM.quarterNote,-1,0);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
spork ~dinky(chord,8*BPM.quarterNote,-1,1);
spork ~rnb.play(Std.mtof(chord.sample()+12),bpm.quarterNote*3);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void section1()
{
//section 1
0=> measure;
while(measure<32)
{
if (measure == 4)
spork ~impulse();
if (measure ==8)
1.0=>Mixer.bus[2].send[1].gain;
Math.random2(5,15)=>int num;
rcb.set(num);
<<<num>>>;
chord.set(scale.get(1),"minor7");
if (measure >16)
spork ~dinky(chord,8*BPM.quarterNote,-1,0);
rcb.play(chord,8*BPM.quarterNote);
chord.set(scale.get(7)-12,"dom7");
if (measure >16)
spork ~dinky(chord,8*BPM.quarterNote,-1,0);
rcb.play(chord,8*BPM.quarterNote);
measure+4=>measure;
}
}
fun void dinky(Chord chord ,dur _dur, int low,int high)
{
now + _dur=>time mark;
dkseq.setRotation(Math.random2(0,16));
while(now<mark)
{
if (dkseq.genNext())
dk.play(Std.mtof(chord.sample()+Math.random2(low,high)*12),bpm.sixteenthNote);
else
bpm.sixteenthNote=>now;
}
}
fun void impulse()
{
impulseseq.set(16,11,1);
while(true)
{
if(impulseseq.genNext())
{
1.0=>i.next;
0.5=>i.gain;
}
bpm.sixteenthNote=>now;
}
}