| Author |
Message |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Mon Jun 02, 2008 2:12 pm Post subject:
Collecting Envelope Generators Subject description: let's build and share Envelopes |
 |
|
Let's design some Envelope Generators ^_^
- - -
I'll start with the simplest thing I've always been using.
A simple exponential decay! ..
(encapsulated into a ready-to-use class)
| Code: | class kjzExpDecay01
{
/* kijjaz's simple exponential decay version 0.1
Copyright (C) 2008 Kijjasak Triyanond (kijjaz@yahoo.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
// set up a gain, feedback into itself, and output the signal
Gain g => Gain g_fb => g => Gain output;
// this impulse add to the envelope
Impulse i => g;
0 => g_fb.gain; // default: no feedback
fun void add(float x)
{
x => i.next;
}
fun void set(float x)
{
x - g.last() => i.next;
}
fun void decayRate(float x)
{
1.0 - x::samp/second => g_fb.gain;
}
fun void decayTime(dur x)
{
1.0 - samp/x => g_fb.gain;
}
} |
test code (with example decay time control):
| Code: | kjzExpDecay01 A;
Noise s => Gain s_g => dac;
A.output => s_g;
3 => s_g.op;
int i;
while(true)
{
if (i == 0)
{
50::ms => A.decayTime;
A.set(1.0);
}
else
{
20::ms => A.decayTime;
A.set(.25);
}
250::ms => now;
i++;
if (i == 8) 0 => i;
} |
Last edited by kijjaz on Mon Jun 02, 2008 4:11 pm; edited 1 time in total |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Mon Jun 02, 2008 3:42 pm Post subject:
|
 |
|
There is another envelope I've just think up now,
the shape is like this kind of function:
f(x) = 4 * (a^x-1)/(a^(2x))
which is.. hmm looks cute ^_^
please let me know if there is a nice way to call it.
for now i'll call it the ... -_-
I can't even think of a name for it -_-" ..
ok.. exponential hill generator -_-"
| Code: | class kjzExpHill01
{
// kijjaz's exponential hill generator version 0.1
Gain g => Gain g_fb => g;
// envelope trigger
Impulse i => g;
Step one; 1 => one.next; // constant signal 1.0
one => Gain OneMinusG;
g => OneMinusG;
2 => OneMinusG.op; // calculate 1-g
g => Gain product => Gain output;
OneMinusG => product;
3 => product.op; // calculue g*(1-g)
// normally, if g is around 0-1, maximum product is .25
// (because maximum of x*(1-x) is .25)
// so we'll adjust by multiplying the result with 4
// to make maximum 1
4 => product.gain;
0 => g_fb.gain; // default: no feedback
fun void add(float x)
{
x => i.next;
}
fun void set(float x) // default set value is 1
{
x - g.last() => i.next;
}
fun void decayRate(float x)
{
1.0 - x::samp/second => g_fb.gain;
}
fun void decayTime(dur x)
{
1.0 - samp/x => g_fb.gain;
}
fun void noteOn()
{
1 => set;
}
} |
test code:
| Code: |
kjzExpHill01 A;
A.output => Gain s1Freq => TriOsc s1 => Gain s1AmpEnv => dac;
A.output => s1AmpEnv;
3 => s1AmpEnv.op;
500 => s1Freq.gain;
while(true)
{
Std.rand2f(1, 50)::ms => A.decayTime;
A.noteOn();
250::ms => now;
} |
|
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Mon Jun 02, 2008 4:10 pm Post subject:
|
 |
|
Now this one is a mass-movement design in the same set
| Code: | class kjzMassMovement01
{
// kijjaz's mass and movement envelope generator version 0.1
Gain p, v, a, F; // position, velocity, acceleration, Force (F=ma)
Step mass; // object mass
1 => mass.next; // default mass value = 1 unit
p => Gain p_fb => p; // update position
v => Gain v2p => p_fb; // velocity adds to position
samp/second => v2p.gain;
v => Gain v_fb => v; // update velocity
a => Gain a2v => v_fb; // acceleration adds to velocity
samp/second => a2v.gain;
a => Gain a_fb => a; // update acceleration
Gain input => Gain FdivM; // outside force applied to this mass
4 => FdivM.op;
mass => FdivM; // calculate delta F = m * delta a
FdivM => a; // add outside force to the system
// these add values to p, v, a
Impulse p_add => p;
Impulse v_add => v;
Impulse a_add => a;
fun void addP(float x)
{
x => p_add.next;
}
fun void addV(float x)
{
x => v_add.next;
}
fun void addA(float x)
{
x => a_add.next;
}
fun void setP(float x)
{
x - p.last() => p_add.next;
}
fun void setV(float x)
{
x - v.last() => v_add.next;
}
fun void setA(float x)
{
x - a.last() => a_add.next;
}
fun void pDecayRate(float x)
{
1.0 - x::samp/second => p_fb.gain;
}
fun void pDecayTime(dur x)
{
1.0 - samp/x => p_fb.gain;
}
fun void vDecayRate(float x)
{
1.0 - x::samp/second => v_fb.gain;
}
fun void vDecayTime(dur x)
{
1.0 - samp/x => v_fb.gain;
}
fun void aDecayRate(float x)
{
1.0 - x::samp/second => a_fb.gain;
}
fun void aDecayTime(dur x)
{
1.0 - samp/x => a_fb.gain;
}
} |
test code:
| Code: | kjzMassMovement01 A;
A.p => SinOsc s => dac;
220 => A.setP;
2::second => now;
110 => A.setV;
2::second => now;
-220 => A.setA;
2::second => now;
1760 => A.setA;
2::second => now; |
|
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 255 Location: Finland
Audio files: 9
|
Posted: Mon Jun 02, 2008 4:14 pm Post subject:
|
 |
|
It's more efficient to use filters to generate the envelopes.
Here's a simple exponential decay:
| Code: | //Exponential decay from 1.0 to 'decayFactor' in 'decayTime'
//Controls:
0.1 => float decayFactor;
100::ms => dur decayTime;
Impulse impulse => OnePole exp => Gain AM => dac;
1.0 => exp.b0;
-Math.pow(decayFactor,samp/decayTime) => exp.a1;
//Fire!
1.0 => impulse.next;
//Apply:
3 => AM.op;
SinOsc sin => AM;
//Play:
week => now; |
_________________ To boldly go where no man has bothered to go before. |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Mon Jun 02, 2008 4:18 pm Post subject:
|
 |
|
Oh.. OnePole, thanks. that's more simple and looks nice also ^_^.
- - -
I've been testing kjzExpHill01 by trying to use it as a grain envelope shaper,
it turns out to sound quite smooth and easy to use.
this is one test code. very Birdie again hahhahh.
| Code: | Gain master => dac;
.05 => master.gain;
kjzExpHill01 A[10];
DelayL d[10];
Gain g[10];
Noise s1 => LPF s1_f => SinOsc s2;
40000 => s1.gain;
s1_f.set(5, 1);
for(int i; i < 10; i++)
{
s2 => d[i] => g[i] => master;
A[i].output => g[i];
3 => d[i].op => g[i].op;
second => d[i].max;
}
while(true)
{
for(int i; i < 10; i++)
{
Std.rand2f(0, 400)::ms=> d[i].delay;
A[i].noteOn();
Std.rand2f(1, 500)::ms => A[i].decayTime;
Std.rand2f(1, 300)::ms => now;
}
} |
|
|
|
Back to top
|
|
 |
Inventor
Stream Operator

Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Tue Jun 03, 2008 11:24 am Post subject:
|
 |
|
Whoah, slow down and back up a sec. I know I should know this by now, but exactly how does an envelope generator work? I presume it tracks the envelope of a signal so that you can do something with it? If that is the case then I've had good luck with thiis:
| Code: | | adc => FullRect fwr => LPF lpf => blackhole; |
Then you set the lpf frequency so that it tracks the signal envelope. But that is much simpler than your code, so I must be missing something. Can you educate me on what I do not understand? Thanks! _________________ "Let's make noise for peace." - Kijjaz |
|
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Tue Jun 03, 2008 11:35 am Post subject:
|
 |
|
No, an envelope is a slower-moving curve usually controlling the amplitude of a signal - ADSR is probably the most common type in synthesis though it has its limits. http://en.wikipedia.org/wiki/ADSR_envelope
One of the things I like in software synthesis is the ability to make arbitrary envelopes. Hardware synths often put pretty severe limits on the kind of enveloping you can do.
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Jun 03, 2008 2:55 pm Post subject:
|
 |
|
kijjaz to Inventor: Oh, that you talking about is definitely an Envelope Follower.
Basically, it's a device that tries to follow the envelope of the input signal.
An Envelope is.. i see it's like a.. a.....
a letter envelope -_-"
for example, if you have a SinOsc letter,
but you want to fit it in a shape,
you put in an envelope and it'd look like the shape of the envelope from outside hahaha -_-
so basically, the way we usually 'envelope' a signal is by multiplying it with a signal created from an Envelope Generator.
http://www.soundonsound.com/sos/nov99/articles/synthsecrets.htm
This place introduce Envelopes well. |
|
|
Back to top
|
|
 |
Inventor
Stream Operator

Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Tue Jun 03, 2008 3:04 pm Post subject:
|
 |
|
I see now, thanks for the clarification, guys. Interesting stuff. _________________ "Let's make noise for peace." - Kijjaz |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Jun 03, 2008 3:34 pm Post subject:
|
 |
|
| dewdrop_world wrote: |
One of the things I like in software synthesis is the ability to make arbitrary envelopes. Hardware synths often put pretty severe limits on the kind of enveloping you can do.
|
I agree. Envelopes, particularly beyond simple stuff are a big issue on hardware synths... but I find that's partially because in hardware envelopes are linked to the polyphony architecture in a rather hard and non-flexible way.
I feel this is a huge issue and will/should be a big part of coming to terms with interfaces for electronic music in general in the next years/decades.
More practically speaking in the here&now; Curvetable (see /examples/special/ ) will get you a "envelope" with a arbitrary number of points and versatile ways of defining the curves between them. If that won't do you likely need some higher level behaviour that'll probably be very context dependant.
---
aargh! I thought I had submitted this some hours ago but now see I didn't. Oops. _________________ Kassen |
|
|
Back to top
|
|
 |
elektro80
Site Admin

Joined: Mar 25, 2003 Posts: 21959 Location: Norway
Audio files: 14
|
Posted: Tue Jun 03, 2008 4:40 pm Post subject:
|
 |
|
| Kassen wrote: | | dewdrop_world wrote: |
One of the things I like in software synthesis is the ability to make arbitrary envelopes. Hardware synths often put pretty severe limits on the kind of enveloping you can do.
|
I agree. Envelopes, particularly beyond simple stuff are a big issue on hardware synths... but I find that's partially because in hardware envelopes are linked to the polyphony architecture in a rather hard and non-flexible way. |
Excellent points.
I´m kinda expecting someone to come up with some digital hybrid envelope module designs soon. More complex envelopes would be cool, more control points and why not implement envelope tables?
Gate outs at the control/ step points in a complex voltage controlled envelope?
I can imagine some pretty cool patches here.
It´s time for more and  _________________ A Charity Pantomime in aid of Paranoid Schizophrenics descended into chaos yesterday when someone shouted, "He's behind you!"
MySpace
SoundCloud
Flickr |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Jun 04, 2008 3:49 am Post subject:
|
 |
|
| elektro80 wrote: | More complex envelopes would be cool, more control points and why not implement envelope tables?
Gate outs at the control/ step points in a complex voltage controlled envelope?
|
That's basically what Curvetable is; a series of points with values, relative time offsets and a indication of the type of curve. Currently it takes up to 100 coefficients so that should get you 33 indexed points, I think. That should probably do. _________________ Kassen |
|
|
Back to top
|
|
 |
rogan

Joined: Dec 16, 2007 Posts: 83 Location: Urbana, IL
Audio files: 5
|
Posted: Fri Jun 06, 2008 2:26 am Post subject:
|
 |
|
Hi all,
It's been a while since I've written anything in CSound, but I remember it being extremely easy to use exponential curves in ftables. I was kind of surprised that ADSR envelopes in chuck could only do linear interpolation. Is there any thought of implementing exponential envelopes (ftables)? It's all fine and good to code exponential envelopes as a sample by sample basis, but I feel like it makes more sense to have an envelope generator to do it automatically. |
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 255 Location: Finland
Audio files: 9
|
Posted: Fri Jun 06, 2008 4:06 am Post subject:
|
 |
|
You can always lowpass an ADSR envelope to get rid of the sharp edges. I actually use a Step that is doubly lowpassed with two OnePoles doing leaky integration. (Two OnePoles instead of one TwoPole to avoid floating point errors with long envelopes.)
But I agree that there should be a native implementation for smooth envelopes in ChucK. _________________ To boldly go where no man has bothered to go before. |
|
|
Back to top
|
|
 |
elektro80
Site Admin

Joined: Mar 25, 2003 Posts: 21959 Location: Norway
Audio files: 14
|
Posted: Fri Jun 06, 2008 8:16 am Post subject:
|
 |
|
| Kassen wrote: | | elektro80 wrote: | More complex envelopes would be cool, more control points and why not implement envelope tables?
Gate outs at the control/ step points in a complex voltage controlled envelope?
|
That's basically what Curvetable is; a series of points with values, relative time offsets and a indication of the type of curve. Currently it takes up to 100 coefficients so that should get you 33 indexed points, I think. That should probably do. |
Oh yes, but we want modules doing this in our dotcom systems, don´t we?
 _________________ A Charity Pantomime in aid of Paranoid Schizophrenics descended into chaos yesterday when someone shouted, "He's behind you!"
MySpace
SoundCloud
Flickr |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sat Jun 07, 2008 4:32 am Post subject:
|
 |
|
| elektro80 wrote: |
Oh yes, but we want modules doing this in our dotcom systems, don´t we?
 |
I think 100 coefficients would mean a 100 pots and/or a 100 jacks. that would be one expensive module...
You could mount up a Mac Mini or MiniITX-based board? _________________ Kassen |
|
|
Back to top
|
|
 |
|