Marotte
Joined: Dec 03, 2007 Posts: 2 Location: Tibet
|
Posted: Mon Dec 03, 2007 1:11 pm Post subject:
Presentation & My first chuck program Subject description: Hi Everybody. Request for comments |
 |
|
Hi,
I read a lot of your posts since some weeks and I told myself I have to write something...
I use to make sounds with computer using some more "user-friendly" softwares like LMMS and ZynAddSubFX, and, appart of that I'm a computer scientist with nothing to code right now. I told myself it's should be a good thing to me to learn a programing language I do not know... But, what to program ? And then, I discovered chuck so I can learn a language and make sounds in the same time :)
I always found difficult to produce a kick drum line in the softwares I tried, and most of the time you must write a sequence from 0 to the end, without some repeating functionalities.
Let's see the code, I hope it should work on a maximum of plateform.
| Code: |
// First attempt of a kick drum generator by Marotte
//
minute / samp / 60 => float samplerate;
class Kicker
{
// Polyphony
16 => int voicemax;
// Timing utilities
140. => float tempo;
minute / tempo => dur b;
4 * b => dur t;
// The patch
SinOsc voice[voicemax];
ADSR env[voicemax];
.4 => float gain;
380. => float startfreq; // Default startfreq is 200 Hz
60. => float endfreq; // Default endfreq is 60 Hz
b/4 => dur decay; // Default decay is a quarter of beat
1. => float dropdown; // Coef for exponential frequency dropdown
.06 => float gainran; // gain randomness
5 => float sfreqran; // startfreq randomness (Hz)
5 => float efreqran; // endfreq randomness (Hz)
10. => float decayran; // Decay randomness (ms)
5::ms => dur attackTime;
5::ms => dur releaseTime;
Dyno limiter; limiter.limit ();
fun void init ()
{
for (0 => int i; i < voicemax; i++)
{
startfreq => voice[i].freq;
voice[i] => env[i] => limiter => dac;
attackTime => env[i].attackTime;
releaseTime => env[i].releaseTime;
// Let's start with all ADSR at "done" state as we will use "ADSR.state()==4" to select a free voice.
voice[i].gain (0.); env[i].keyOn (); env[i].keyOff (); releaseTime => now;
gain => voice[i].gain;
}
<<< "Patch ready" >>>;
}
init ();
fun int freevoice()
{
for (0=> int i; i < voicemax; i++)
{
if (env[i].state() == 4) return i; // Cool, we find one.
}
// No free voice, look for a voice in "release" state
for (0 => int i; i < voicemax; i++)
{
if (env[i].state() == 3) return i;
}
// No voice in "release" state !
<<< "No voice available !" >>>;
return Math.rand2(0,voicemax); // Better solution ?
}
fun void play ()
{
freevoice() => int cur;
0. => voice[cur].phase;
startfreq => voice[cur].freq;
Math.rand2f (-sfreqran, sfreqran) => float sfreqoffset;
startfreq + sfreqoffset => voice[cur].freq;
gain => voice[cur].gain;
Math.rand2f (-gainran, gainran) => float gainoffset;
voice[cur].gain() + gainoffset => voice[cur].gain;
if (voice[cur].gain() < 0.0001) voice[cur].gain() + .001 => voice[cur].gain;
Math.rand2f (-decayran, decayran) => float decayoffset;
now + decay + decayoffset::ms => time end;
Math.rand2f (-efreqran,efreqran) => float efreqoffset;
env[cur].keyOn ();
<<< "Voice ",cur, " GAIN: ", voice[cur].gain(), " START F: ",startfreq + sfreqoffset, " END F: ", endfreq + efreqoffset, " DECAY: ", 1000 * (decay + decayoffset::ms) / samplerate, " ms" >>>;
while (now < end)
{
if (endfreq <= startfreq)
{
if (voice[cur].freq() >= endfreq + efreqoffset)
{
voice[cur].freq() - dropdown * Math.exp (1 / voice[cur].freq()) => voice[cur].freq;
}
samp => now;
}
else
{
//<<< voice[cur].freq () >>>;
if (voice[cur].freq() < endfreq - efreqoffset)
{
voice[cur].freq() + dropdown * Math.exp (1 / voice[cur].freq()) => voice[cur].freq;
}
samp => now;
}
}
env[cur].keyOff (); //<<< cur, " OFF|", " Now : ", (now / samp) / samplerate, " second" >>>;
}
fun void loop (float periode, float playtime, float holdtime, float length)
{
periode * t => dur per;
playtime * t => dur pt;
holdtime * t => dur ht;
length * t => dur len;
now + len => time endloop;
while (now < endloop)
{
now + pt => time stop;
while (now < stop)
{
spork ~ play ();
per => now;
}
ht => now;
}
decay => now; // Let the last sporked play () to finish and do the last keyOff ()
}
}
Kicker k;
150. => k.tempo;
40. => k.decayran;
.5 => k.gain;
.3 => k.dropdown;
k.b/3 => k.decay;
30. => k.sfreqran;
210. => k.startfreq;
k.init (); // Don't forget to init () after you set some Kicker's values
// Not used in this exemple, but "inversed kick" (with startfreq < end freq) should work...
//Kicker pouet;
//.00001 => pouet.gainran;
//150. => pouet.tempo;
//.3 => pouet.dropdown; // In this case, down = up :)
//.009 => pouet.gain;
//pouet.t/8 => pouet.decay;
//60. => pouet.startfreq;
//1800. => pouet.endfreq;
//150. => pouet.efreqran;
//pouet.init();
2*second => now; // Mmmmh...
while (1)
{
spork ~ k.loop (.25,5,0,64);
spork ~ k.loop (.1,.25,3.75,60);
spork ~ k.loop (.03,.1,5.9,60);
hour => now;
<<< "RESTART" >>>;
}
|
Please let me know what do you think about it.
Edit by your friendly editor Kassen; I switched on BBCode for this post as this made the "code" tag stop working which in turn gots rid of the tabs. BBCode==good, HTML==bad (at least for posting code here). Cheers |
|
kijjaz

Joined: Sep 20, 2004 Posts: 452 Location: bangkok, thailand
Audio files: 2
|
Posted: Mon Dec 03, 2007 2:49 pm Post subject:
|
 |
|
Wow this is a nice poly synth and the groove is good.
It sounds quite variable, and interesting.
Cool. I'll look forward to your new experiments and patches ^_^
or let's share some new ideas. |
|
Inventor

Joined: Oct 13, 2007 Posts: 1143 Location: Florida, USA
Audio files: 50
|
Posted: Wed Dec 05, 2007 12:38 pm Post subject:
|
 |
|
| Haha, you posted to the right place. Kijjaz is the drum master, he makes all the groovy sounds! The two of you should have a blast with this. I'd join in, but I'm hot and heavy on another project right now. Good luck and welcome! |
|