| Author |
Message |
Slinky

Joined: Jan 09, 2009 Posts: 15 Location: Sweden
|
Posted: Sun Jan 11, 2009 1:53 pm Post subject:
Can I attach an UGen to control variables? |
 |
|
How to attach a UGen output to control variables?
Something like: UGen => Filter but instead of doing that for data flow I'd like to do a similar thing for control flow (such that the UGen output feeds to a control parameter inside another UGen).
What I'm trying to build is an envelope-modulated filter. The filter cutoff frequency would be modulated by an envelope (simple decay from max to 0). When the UGen triggers, this thing would run also, modifying the filter cutoff parameter.
Is there some built-in simple and elegant way how to achieve this? _________________ "Mortal immortals, immortal mortals, living their death and dying their life."
--Heraclitus, Fragment 62, Hippolytus Ref. Ix, 10,6 |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Jan 11, 2009 2:20 pm Post subject:
Acidic demo |
 |
|
| Code: | BlitSaw b => LPF f => ADSR env => JCRev rev => dac;
8 => f.Q;
.125::second => env.decayTime;
100::ms => env.attackTime;
.08 => rev.mix;
Envelope mod => blackhole;
.25::second => mod.duration;
fun void modulate()
{
while(1)
{
mod.value() => f.freq;
ms => now;
}
}
spork ~modulate();
while(1)
{
Std.mtof(30 + (Std.rand2(0,6) * 3)) => b.freq;
10000 => mod.value;
200 => mod.target;
1 => env.keyOn;
.25::second => now;
1 => env.keyOff;
.125::second => now;
} |
_________________ Kassen |
|
|
Back to top
|
|
 |
Slinky

Joined: Jan 09, 2009 Posts: 15 Location: Sweden
|
Posted: Sun Jan 11, 2009 2:43 pm Post subject:
Re: Acidic demo |
 |
|
Thank you!
How did you know I needed it to make some 303-like sounds  _________________ "Mortal immortals, immortal mortals, living their death and dying their life."
--Heraclitus, Fragment 62, Hippolytus Ref. Ix, 10,6 |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Jan 11, 2009 2:55 pm Post subject:
|
 |
|
I just felt like doing something a bit acidic. I like the blit-based UGens a lot for acid sounds, don't forget to try to modulate the .harmonics() function on those, you may like the result :¬). _________________ Kassen |
|
|
Back to top
|
|
 |
radarsat1

Joined: Mar 14, 2008 Posts: 85 Location: Montreal
|
Posted: Sun Jan 11, 2009 4:12 pm Post subject:
|
 |
|
The only problem with this approach (and its currently the only way) is that it leads to zipper noise. Every change to the parameter will be immediate instead of enveloped, so you need to step at very small increments to avoid too much noise (in this case, 1::ms), but then this is quite CPU hungry.
It would be cool if there was a way to chuck a ugen at a parameter. I was thinking that perhaps if parameters were actually UGens it might be possible. For example, dac has "parameters" called dac.left and dac.right, which are actually sub-dac UGens. It would be cool if LPF had a sub-ugen called LPF.cutoff. Or if there was some UGen that could take any parameter and UGenify it, like:
| Code: | LPF.cutoff => dac;
SinOsc s => Modulate m(f.cutoff) => blackhole; |
For now this is impossible but maybe something like it could be developed. |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Jan 11, 2009 4:36 pm Post subject:
|
 |
|
In some cases that would have clear and unambiguous benefits but in this case that will mean calculating new filter coefficients every sample, I'm not sure how expensive that would be.
I do agree that that would be a very natural step to take in the future, maybe after block processing and clearly in some cases like Pan2.pan() we could have that style of modulation nearly for free. _________________ Kassen |
|
|
Back to top
|
|
 |
rogan

Joined: Dec 16, 2007 Posts: 83 Location: Urbana, IL
Audio files: 5
|
Posted: Sun Jan 11, 2009 4:37 pm Post subject:
|
 |
|
radarsat1
| Quote: | | It would be cool if there was a way to chuck a ugen at a parameter. |
This would be nice, but because of the way UGens calculate (every sample), this would be a huge CPU rate. This would be interesting if UGens had a control rate parameter, but that would take a massive rewrite of the ChucK code. :(
Edit: I just noticed Kassen said basically the same thing at the same time.... |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Mon Jan 12, 2009 7:58 pm Post subject:
|
 |
|
I think we have a problem here on a conceptual level.
I think a lot of ChucK's syntax comes from this desire to trade efficiently between sound quality and CPU usage; we already have very powerful means of setting the modulation rate (exactly as in my example above), yet it seems that many people don't find this convenient to write.
Basically; what ChucK does do very well here (the variable control-rate) on a functional level isn't experienced as enough by some people in some contexts. I wonder if this is a lack of clear documentation or whether we need some sort of syntactic sugar. _________________ Kassen |
|
|
Back to top
|
|
 |
rogan

Joined: Dec 16, 2007 Posts: 83 Location: Urbana, IL
Audio files: 5
|
Posted: Mon Jan 12, 2009 8:43 pm Post subject:
|
 |
|
Kassen said:
| Quote: | | I wonder if this is a lack of clear documentation or whether we need some sort of syntactic sugar. |
I think I had this problem at first. ChucK connects UGens so easily, that I think people expect it to be able to link variables just as easily. Only when you start having to think about how ChucK works internally does it make sense that you can't do it.
I think more clear documentation would be a good idea. The actual code isn't that hack-y to write as it is (at least, in my opinion). |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Mon Jan 12, 2009 9:07 pm Post subject:
|
 |
|
Yeah, I think people simply look at ChucK itself without considering something like CSound as a context. Compared to inter-UGen connections the type of structure I illustrated above makes little sense, compared to CSound it's (potentially) quite powerful and sensible indeed.
I'm hesitant about this. Sugar is nice but I'm not sacrificing tricks like making sure modulations occur only occasionally (on a DSP scale) but always at zero-crossings, for example.
I also think that in some cases optimisations in C could mean UGens could have audio-rate modulation inputs that are way faster, without punishment, then CK code could (currently) hope to be. This would -however- lead to inconsistencies that might be in themselves confusing to some; Pan2.pan() is quite different from LPF.freq() if we want to call it every samp; the first is a mere float, the other is a full-blown calculation of Hard Stuff. Another issue is that some UGens, like the various osc's and Gain already do have UGen rate modulation inputs, but without a syntax for extending that beyond the very simple level. _________________ Kassen |
|
|
Back to top
|
|
 |
radarsat1

Joined: Mar 14, 2008 Posts: 85 Location: Montreal
|
Posted: Tue Jan 13, 2009 10:31 am Post subject:
|
 |
|
| Quote: | | I think a lot of ChucK's syntax comes from this desire to trade efficiently between sound quality and CPU usage; we already have very powerful means of setting the modulation rate (exactly as in my example above), yet it seems that many people don't find this convenient to write. |
it's not just about CPU usage or syntactic convenience though, but of course that's a big factor. but I also mentioned "zipper noise". if you change a parameter every 10 ms, it immediately jumps to the new value, and this can create audible artifacts. instead, you want to use an envelope to smoothly slide a parameter to a new value. but you can't chuck an envelope at a parameter, so you have to do it manually with single-sample steps.
this isn't efficient and also doesn't allow to take advantage of the nice facilities available in the Envelope object. basically you have to re-implement Envelope in ChucK code. |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Jan 13, 2009 1:23 pm Post subject:
|
 |
|
This would depend on the function being called though. For functions like Envelope.target() or LiSa.playPos() you wouldn't typically want a gradual slide (though in some cases you might, of course). I don't think automatically sliding in all cases would be a good idea.
Right now I'm inclined to wait for block processing before we make definitive choices here. The only real issues right now are syntactic sugar and CPU usage, it's not like we are unable to do anything we might like to do. I'd like to see how much of a issue there would still be if we'd take a lot of that CPU usage away using block processing. _________________ Kassen |
|
|
Back to top
|
|
 |
|