Author |
Message |
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Fri Oct 26, 2007 4:05 am Post subject:
Collecting ChucK drum sound designs |
|
|
from this thread: Rockin' with ChucK
http://electro-music.com/forum/topic-21179.html
I came up with the idea of collecting more example of drum sound design in ChucK
especially one that's ready to use by other users.
I hope this can be one place to talk more about different methods for drum sound design
and implementation in ChucK, especially for live use (CPU-efficient enough)
I've got three working codes around here I'd like to share with you all
(below the drum class, there is also an example on how to trigger and set some example parameters)
Code: | // easy white noise snare
class kjzSnare101 {
// note: connect output to external sources to connect
Noise s => Gain s_env => LPF s_f => Gain output; // white noise source
Impulse i => Gain g => Gain g_fb => g => LPF g_f => s_env;
3 => s_env.op; // make s envelope a multiplier
s_f.set(3000, 4); // set default drum filter
g_fb.gain(1.0 - 1.0/3000); // set default drum decay
g_f.set(200, 1); // set default drum attack
fun void setFilter(float f, float Q)
{
s_f.set(f, Q);
}
fun void setDecay(float decay)
{
g_fb.gain(1.0 - 1.0 / decay); // decay unit: samples!
}
fun void setAttack(float attack)
{
g_f.freq(attack); // attack unit: Hz!
}
fun void hit(float velocity)
{
velocity => i.next;
}
}
kjzSnare101 A;
A.output => dac;
A.hit(0.8);
2::second => now;
A.setDecay(10000);
A.setFilter(5000, 5);
A.hit(0.8);
2::second => now; |
Code: | // with some approvements from 101: snare ringing in the body
class kjzSnare102 {
// note: connect output to external sources to connect
Noise s => Gain s_env => LPF s_f => Gain output; // white noise source
Impulse i => Gain g => Gain g_fb => g => LPF g_f => s_env;
s_env => DelayA ringing => Gain ringing_fb => ringing => LPF ringing_f => output;
3 => s_env.op; // make s envelope a multiplier
s_f.set(3000, 4); // set default drum filter
g_fb.gain(1.0 - 1.0/3000); // set default drum decay
g_f.set(200, 1); // set default drum attack
ringing.max(second);
ringing.delay((1.0 / 440) :: second); // set default: base ringing frequency = 440Hz
ringing_fb.gain(0.35); // set default ringing feedback
ringing_f.set(1500, 1); // set default ringing LPF
ringing_f.gain(0.6); // set default ringing vol
fun void setFilter(float f, float Q)
{
s_f.set(f, Q);
}
fun void setDecay(float decay)
{
g_fb.gain(1.0 - 1.0 / decay); // decay unit: samples!
}
fun void setAttack(float attack)
{
g_f.freq(attack); // attack unit: Hz!
}
fun void hit(float velocity)
{
velocity => i.next;
}
fun void setRingingGain(float g)
{
g => ringing_f.gain;
}
fun void setRingingFreq(float f)
{
(1.0 / f)::second => ringing.delay;
}
fun void setRingingFeedback(float g)
{
g => ringing_fb.gain;
}
fun void setRingingFilter(float f, float Q)
{
ringing_f.set(f, Q);
}
}
kjzSnare102 A;
A.output => dac;
A.hit(0.8);
1::second => now;
A.setRingingFeedback(.995);
A.setRingingFilter(500, 1);
A.hit(0.8);
3::second => now; |
and this one is another model i just developed.
i use this method many times, but it's good to see it incapsulated into a class:
Code: | // simple analog-sounding bass drum with pitch and amp decay and sine overdrive
class kjzBD101
{
Impulse i; // the attack
i => Gain g1 => Gain g1_fb => g1 => LPF g1_f => Gain BDFreq; // BD pitch envelope
i => Gain g2 => Gain g2_fb => g2 => LPF g2_f; // BD amp envelope
// drum sound oscillator to amp envelope to overdrive to LPF to output
BDFreq => SinOsc s => Gain ampenv => SinOsc s_ws => LPF s_f => Gain output;
g2_f => ampenv; // amp envelope of the drum sound
3 => ampenv.op; // set ampenv a multiplier
1 => s_ws.sync; // prepare the SinOsc to be used as a waveshaper for overdrive
// set default
80.0 => BDFreq.gain; // BD initial pitch: 80 hz
1.0 - 1.0 / 2000 => g1_fb.gain; // BD pitch decay
g1_f.set(100, 1); // set BD pitch attack
1.0 - 1.0 / 4000 => g2_fb.gain; // BD amp decay
g2_f.set(50, 1); // set BD amp attack
.75 => ampenv.gain; // overdrive gain
s_f.set(600, 1); // set BD lowpass filter
fun void hit(float v)
{
v => i.next;
}
fun void setFreq(float f)
{
f => BDFreq.gain;
}
fun void setPitchDecay(float f)
{
f => g1_fb.gain;
}
fun void setPitchAttack(float f)
{
f => g1_f.freq;
}
fun void setDecay(float f)
{
f => g2_fb.gain;
}
fun void setAttack(float f)
{
f => g2_f.freq;
}
fun void setDriveGain(float g)
{
g => ampenv.gain;
}
fun void setFilter(float f)
{
f => s_f.freq;
}
}
kjzBD101 A;
A.output => dac;
for(int i; i < 8; i++)
{ A.hit(.5 + i * .1); .5::second => now; } |
|
|
Back to top
|
|
|
Nalaregeork
Joined: Oct 26, 2003 Posts: 17 Location: South East New York
|
Posted: Fri Oct 26, 2007 9:59 am Post subject:
|
|
|
Nice stuff |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Sat Oct 27, 2007 12:15 am Post subject:
|
|
|
WooHoo! just what I needed to complete drum_lab.ck, thanks kijjaz! I'm going to check these files out immediately! |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Sat Oct 27, 2007 10:14 pm Post subject:
|
|
|
Here's the tom-tom modified from the BD101
This can also be used well as a bass drum because we can set "base frequency" of the drum.
Code: | // simple analog-sounding tom-tom with pitch and amp decay and sine overdrive
class kjzTT101
{
Impulse i; // the attack
i => Gain g1 => Gain g1_fb => g1 => LPF g1_f => Gain TomFallFreq; // tom decay pitch envelope
i => Gain g2 => Gain g2_fb => g2 => LPF g2_f; // tom amp envelope
// drum sound oscillator to amp envelope to overdrive to LPF to output
TomFallFreq => SinOsc s => Gain ampenv => SinOsc s_ws => LPF s_f => Gain output;
Step BaseFreq => s; // base Tom pitch
g2_f => ampenv; // amp envelope of the drum sound
3 => ampenv.op; // set ampenv a multiplier
1 => s_ws.sync; // prepare the SinOsc to be used as a waveshaper for overdrive
// set default
100.0 => BaseFreq.next;
50.0 => TomFallFreq.gain; // tom initial pitch: 80 hz
1.0 - 1.0 / 4000 => g1_fb.gain; // tom pitch decay
g1_f.set(100, 1); // set tom pitch attack
1.0 - 1.0 / 4000 => g2_fb.gain; // tom amp decay
g2_f.set(50, 1); // set tomD amp attack
.5 => ampenv.gain; // overdrive gain
s_f.set(1000, 1); // set tom lowpass filter
fun void hit(float v)
{
v => i.next;
}
fun void setBaseFreq(float f)
{
f => BaseFreq.next;
}
fun void setFreq(float f)
{
f => TomFallFreq.gain;
}
fun void setPitchDecay(float f)
{
f => g1_fb.gain;
}
fun void setPitchAttack(float f)
{
f => g1_f.freq;
}
fun void setDecay(float f)
{
f => g2_fb.gain;
}
fun void setAttack(float f)
{
f => g2_f.freq;
}
fun void setDriveGain(float g)
{
g => ampenv.gain;
}
fun void setFilter(float f)
{
f => s_f.freq;
}
}
kjzTT101 A;
A.output => dac;
for(int i; i < 8; i++)
{ A.setBaseFreq(60 + i*20); A.hit(.5 + i * .1); .8::second => now; } |
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Sun Oct 28, 2007 7:22 am Post subject:
|
|
|
Inventor: Wow! That's an exciting tom tom drumming pattern. cool! |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Sun Oct 28, 2007 1:32 pm Post subject:
|
|
|
I'm testing this prototype "RimShot 101"
please give me some comment on the sound character.
i'll add more features very soon after i'm satisfied with the result.
this one uses quite many UGens, but it surely sounds more complex.
Code: | // easy rim shot: (Testing)
class kjzRim101_testing
{
Impulse i => LPF f1 => DelayA body => Gain ampenv => SinOsc drive => Gain output;
body => Gain body_fb => body;
i => Gain g1 => Gain g1_fb => g1 => ampenv;
Noise n => LPF n_f => Gain n_ampenv => output;
i => Gain g2 => Gain g2_fb => g2 => LPF g2_f => n_ampenv;
3 => ampenv.op => n_ampenv.op;
1 => drive.sync;
f1.set(1000, 1);
second => body.max;
second / 600 => body.delay;
.9 => body_fb.gain;
1.0 - 1.0/800 => g1_fb.gain;
1.2 => ampenv.gain;
0.3 => n_ampenv.gain;
n_f.set(5000, 1.5);
1.0 - 1.0/1000 => g2_fb.gain;
g2_f.set(50, 1);
fun void hit(float v)
{
v => i.next;
}
}
kjzRim101_testing A;
A.output => dac;
.8 => A.output.gain;
A.hit(1);
2::second => now; |
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Mon Oct 29, 2007 4:48 am Post subject:
|
|
|
kijjaz wrote: | I'm testing this prototype "RimShot 101"
please give me some comment on the sound character.
i'll add more features very soon after i'm satisfied with the result.
this one uses quite many UGens, but it surely sounds more complex.
|
I tried it out, and it sounds a bit short in duration, can we make it sustain a little more? |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Fri Feb 29, 2008 5:41 pm Post subject:
|
|
|
I still haven't slept (and it's 7 A.M. now hahahhha)..
before I go out of town for 10 days..
i planned this for a very long time but never started the project:
I want to make a very very simple delayline implementation of a snare drum.
I try to connect things as directly as possible..
and with filtered white noise ringmodulating the bottom of the snare drum to simulate the buzz in the snare.
i wasn't expected to hear something exactly like a real snare..
just a good electric snare drum sound is enough..
but this time, I was shocked. !! ..
(its parameter is still in testing stage..
but they're quite easy to understand and we can hear some different after tuning them right away)
so hear it out yourself, brothers and sisters!
This time i'm proud of this, for real. ... and proud that it's much simple than I planned to. it's a happy prototype! ..
Code: | // Simple Delayline Snare 01 version 0.1 testing
// by kijjaz
// simple delaylines snare drum design: still a testing prototype
// licence: Attribution-Share Alike 3.0
// You are free:
// * to Share — to copy, distribute and transmit the work
// * to Remix — to adapt the work
// Under the following conditions:
// * Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
// * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license.
290.0 => float SnareHeadFreq;
600.0 => float SnareBodyFreq;
630.0 => float SnareBottomFreq;
.4 => float SnareHeadDecay;
.3 => float SnareBottomDecay;
.5 => float SnareBodyDecay;
7000.0 => float SnareBuzzFreq;
.7 => float SnareBuzzQ;
4.0 => float SnareBuzzGain;
180.0 => float StickFreq;
6.0 => float StickQ;
.8 => float HeadMicGain;
.4 => float BottomMicGain;
DelayA drumHead1 => DelayA drumBody1 => DelayA drumHead2 =>
Gain drumHead2_mod => DelayA drumBody2 =>
drumHead1;
drumHead1 => Gain drumHead1_mic => SinOsc drumHead1_drive => Dyno limiter => dac;
drumHead2 => Gain drumHead2_mic => limiter;
drumHead1_mic.gain(HeadMicGain / 2);
drumHead1_drive.sync(1);
drumHead2_mic.gain(BottomMicGain);
limiter.limit();
limiter.gain(.9);
drumHead2_mod.op(3);
Noise snareBuzz => LPF snareBuzz_f => drumHead2_mod;
snareBuzz_f.set(SnareBuzzFreq, SnareBuzzQ);
snareBuzz.gain(SnareBuzzGain);
drumHead1 => Gain drumHead1_fb => drumHead1;
drumHead2 => Gain drumHead2_fb => drumHead2;
Impulse stickImp => LPF stickImp_f => drumHead1;
stickImp_f.set(StickFreq, StickQ);
second => drumHead1.max => drumHead2.max => drumBody1.max => drumBody2.max;
second / SnareHeadFreq => drumHead1.delay;
second / SnareBodyFreq => drumBody1.delay => drumBody2.delay;
second / SnareBottomFreq => drumHead2.delay;
SnareHeadDecay => drumHead1_fb.gain;
SnareBottomDecay => drumHead2_fb.gain;
SnareBodyDecay => drumBody1.gain => drumBody2.gain;
// - - - start hitting
int i;
while(true)
{
if (i % 8 < 3) stickImp.next(40); else stickImp.next(2 + i%2 * 3);
if ((i * 7) % 12 > 1) 300::ms => now;
else
for(int j; j < 6; j++)
{
stickImp.next(j + j%2);
50::ms => now;
}
i++;
} |
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Fri Feb 29, 2008 7:14 pm Post subject:
|
|
|
Excellent sound, brother! The example sounds like a military cadence drumming, close to the real thing. Don't you just love it when your explorations yield fruit? Once you tidy that thing up and put it in a class and all that stuff, I'm thinking it belongs in Guitar Lab for sure! Great work kijjaz. |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Fri Feb 29, 2008 7:17 pm Post subject:
|
|
|
p.s. I added your nick to the copyright button on the front panel of Guitar Lab, kijjaz, since you had so much stuff in it. When you click on it you get an arcade shooting sound made with your earlier drum class. |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Wed Mar 05, 2008 2:28 am Post subject:
|
|
|
Sounds just like the real thing to me. I like how you documented the class so well. I'm plugging it into Guitar Lab right now, let you know when I am done. |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Mar 05, 2008 5:24 am Post subject:
|
|
|
Stupid simple techno kick I just made. Not so advanced but simple&cheap and there are lots of numbers to tweak. :¬).
The one interesting bit is perhaps the use of "step" to scale a Envelope so it can be used as a modulation signal.
Code: | SinOsc s => ADSR env => dac;
Step c => Envelope mod => s;
SinOsc t => s;
80 => t.gain;
30 => t.freq;
300 => c.next;
80 => s.freq;
2 => s.sync;
.7 => env.sustainLevel;
50::ms => env.decayTime;
.1::second => env.releaseTime;
.05::second => mod.duration;
while(1)
{
1 => mod.value;
1 => mod.keyOff;
1 => env.keyOn;
.1::second => now;
1 => env.keyOff;
.4::second => now;
} |
_________________ Kassen |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Wed Mar 05, 2008 6:20 am Post subject:
|
|
|
kijjaz to Kassen: oh yes. that's one of my favourites hahahah ^_^
i also love putting that result to an overdrive.
Sometimes i force the phase to start at 0 everytime we do the 'note on'
- - -
I'll try to improve the snare drum sound.
maybe i'll try to add a filter or something as an option to shape the delayed sound.
now it really depends on the comb filtering and some overdrive to shape its actual sound.
I might try to make one with a different model also..
but right now i'm so satisfied with this cutie ^_^
especially its ease-of-use. |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Mar 05, 2008 6:55 am Post subject:
|
|
|
kijjaz wrote: | Sometimes i force the phase to start at 0 everytime we do the 'note on'
- - -
|
Yeah, but then it's the same every time and you might as well use a sample, I like the slight liveliness, makes it a bit more organic and if anything needs that it's techno kicks.
:¬) _________________ Kassen |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Wed Mar 05, 2008 12:04 pm Post subject:
|
|
|
kijjaz to Kassen: Yes. I like that also. ^_^ so basically i use both way, or in the middle (for example, average the phase with 0.0)
I still don't have enough free time to design more cymbals -_-"
I'm still not fully satisfied with what I have tried for a cymbal. |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Mar 05, 2008 12:50 pm Post subject:
|
|
|
Yeah, and morphing. I like to morph sounds over the course of a loop and samples won't quite do that, in that way.
Cymbals are just very hard to synthesise and except for jazz brushed hits I don't even like them that much. Plenty of stuff left; cowbell, rim-shot, clap.... BTW, the Shakers has some good tuned percussion hidden in between the coins and pebbles. Bamboo chimes can be cool for percussion, both for "mysterious moods" and Tom Waits style freaked drums.... and those are basically free thanks to Perry. Ermmm.... Woodblock? Steel-drum (for dub?).... _________________ Kassen |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Fri Mar 07, 2008 3:40 am Post subject:
|
|
|
Here comes a prototype of the sound of..
Digital-Electro rimshot.. !
Digitally Noisy! ..
Code: | // kijjaz's Table Rimshot 01 - version 0.1 testing
550.0 => float freq;
.3 => float randomRange;
.9 => float decay;
(second / samp / freq) $ int => int samples;
float table[samples];
Step s => Dyno compressor => dac;
s.gain(.5);
compressor.compress();
compressor.thresh(.1);
int j;
while(true)
{
// reset
if (now % second == 0::ms) for(int i; i < samples; i++) Std.rand2f(-1, 1) => table[i];
Std.rand2(0, (samples * randomRange) $ int) => int i;
table[(j + i) % samples] => s.next;
decay *=> table[(j + i) % samples];
samp => now;
j++;
} |
And this same one with randomwalk patch..
(sounds like a snare drum with the loose snare problem.)
Code: | // kijjaz's Table Rimshot 01 - version 0.1 testing with Ramdomwalk patch
440.0 => float freq;
.5 => float randomRange;
.95 => float decay;
(second / samp / freq) $ int => int samples;
float table[samples];
Step s => Dyno compressor => dac;
s.gain(.5);
compressor.compress();
compressor.thresh(.1);
int j, k;
1 => k;
while(true)
{
// reset
if (now % second == 0::ms) for(int i; i < samples; i++) Std.rand2f(-1, 1) => table[i];
Std.rand2(0, (samples * randomRange) $ int) => int i;
table[(j + i) % samples] => s.next;
decay *=> table[(j + i) % samples];
samp => now;
if (maybe) -1 *=> k;
k +=> j;
if (j < 0) samples +=> j;
} |
and this one produce a more consistent tone
(by initializing the table with a sine wave <-- this should be optimized later)
Code: | // kijjaz's Table Rimshot 01 - version 0.1 testing, with Sine - initialization
550.0 => float freq;
.7 => float randomRange;
.9 => float decay;
(second / samp / freq) $ int => int samples;
float table[samples];
Step s => Dyno compressor => dac;
s.gain(.5);
compressor.compress();
compressor.thresh(.1);
int j;
while(true)
{
// reset
if (now % second == 0::ms) for(int i; i < samples; i++) Math.sin(i $ float / samples * 3.14159) => table[i];
Std.rand2(0, (samples * randomRange) $ int) => int i;
table[(j + i) % samples] => s.next;
decay *=> table[(j + i) % samples];
samp => now;
j++;
} |
|
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Tue Feb 17, 2009 4:26 am Post subject:
|
|
|
Sweet, kijjaz! These drums are super-simple so they won't overburden the cpu at all. I've been having trouble with too much cpu usage in my KNoW Wave generator so I can make use of them for sure. Plus the variability makes them excellent candidates.
It sounds though that you are going to put them in classes so I'll wait for that, no need to do extra work. Kijjaz: you make the instruments and I'll make the applications. Then we'll all make noise for peace! _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
telstarmagikistferrari
Joined: Jun 16, 2008 Posts: 280 Location: Indianapolis, Indiana
Audio files: 43
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Thu Feb 19, 2009 12:29 am Post subject:
|
|
|
Nice use of the drum models, it sounded like a marching band. Well done! K for kijjaz! _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
|