Modulation of parameters "by hand"? Does ChucK have a function reference data type?
I'm trying to create a generic "modulation" function where I can give it some parameters to set up the modulation and a property to modulate. My current way of thinking would require passing a function object into the shred so that the parameter to be modulated can be chosen at the time of the function calling... Now I know already that I can't do something like the following: --code-- // A failed attempt at tremolo SinOsc osc1 => Gain master => dac; 440 => osc1.freq; SinOsc lfo => master.gain; 5 => lfo.freq; .3 => lfo.gain; --/code-- So thus I set up this function: --code-- fun void tremolo(Gain noteGain) { SinOsc lfo => blackhole; 5.75 => lfo.freq; .3 => lfo.gain; while (true) { 1-lfo.last() => noteGain.gain; // Assume "resolution" is a dur such as 10::ms, it is the resolution of our modulation resolution => now; } } --/code-- And spork it with a gain object to modify... That works great, but I'll need to code a separate function for every single possible parameter that I'd want to modulate, so is there a way of specifying the specific parameter on the function call instead of the whole object, for instance, the prototype could be: --code-- fun void modulate(FunctionObject param) --/code-- And then the updated values would (in theory) be ChucK'ed directly to that "param" instead of object.parameter? I tried setting it up this way but I don't seem to know the object type for passing a function reference, if there is one. Or maybe someone else has a better idea that I haven't thought of? - JB
Johnathan Bell wrote:
I'm trying to create a generic "modulation" function where I can give it some parameters to set up the modulation and a property to modulate. My current way of thinking would require passing a function object into the shred so that the parameter to be modulated can be chosen at the time of the function calling... Now I know already that I can't do something like the following:
--code-- // A failed attempt at tremolo
SinOsc osc1 => Gain master => dac;
440 => osc1.freq;
SinOsc lfo => master.gain;
5 => lfo.freq; .3 => lfo.gain; --/code--
So thus I set up this function:
--code-- fun void tremolo(Gain noteGain) { SinOsc lfo => blackhole; 5.75 => lfo.freq; .3 => lfo.gain;
while (true) { 1-lfo.last() => noteGain.gain; // Assume "resolution" is a dur such as 10::ms, it is the resolution of our modulation resolution => now; } } --/code--
And spork it with a gain object to modify... That works great, but I'll need to code a separate function for every single possible parameter that I'd want to modulate, so is there a way of specifying the specific parameter on the function call instead of the whole object, for instance, the prototype could be:
--code-- fun void modulate(FunctionObject param) --/code--
And then the updated values would (in theory) be ChucK'ed directly to that "param" instead of object.parameter? I tried setting it up this way but I don't seem to know the object type for passing a function reference, if there is one. Or maybe someone else has a better idea that I haven't thought of?
Ideally one would be able to chuck a UGen directly to a property. That would really help the chuck-operator-as-patch-cord model for VCA/LFOs etc. One way of implementing functions-as-parameters is with functors or function classes. Those are the primary focus of LiCK, which provides Function.ck, IntFunction.ck, FloatFunction.ck, and so on, so that other classes in the API (e.g. ArrayList.ck) can accept them as parameters. https://github.com/heuermh/lick ChucK forum contributor kijjaz posted a nice template for doing parameter modulation that I've used a few times called ModulucK http://electro-music.com/forum/viewtopic.php?highlight=modedular&t=24297 michael
On Jun 9, 2011, at 11:18 AM, Michael Heuer wrote:
Johnathan Bell wrote:
I'm trying to create a generic "modulation" function where I can give it some parameters to set up the modulation and a property to modulate. My current way of thinking would require passing a function object into the shred so that the parameter to be modulated can be chosen at the time of the function calling... Now I know already that I can't do something like the following:
--code-- // A failed attempt at tremolo
SinOsc osc1 => Gain master => dac;
440 => osc1.freq;
SinOsc lfo => master.gain;
5 => lfo.freq; .3 => lfo.gain; --/code--
So thus I set up this function:
--code-- fun void tremolo(Gain noteGain) { SinOsc lfo => blackhole; 5.75 => lfo.freq; .3 => lfo.gain;
while (true) { 1-lfo.last() => noteGain.gain; // Assume "resolution" is a dur such as 10::ms, it is the resolution of our modulation resolution => now; } } --/code--
And spork it with a gain object to modify... That works great, but I'll need to code a separate function for every single possible parameter that I'd want to modulate, so is there a way of specifying the specific parameter on the function call instead of the whole object, for instance, the prototype could be:
--code-- fun void modulate(FunctionObject param) --/code--
And then the updated values would (in theory) be ChucK'ed directly to that "param" instead of object.parameter? I tried setting it up this way but I don't seem to know the object type for passing a function reference, if there is one. Or maybe someone else has a better idea that I haven't thought of?
Ideally one would be able to chuck a UGen directly to a property. That would really help the chuck-operator-as-patch-cord model for VCA/LFOs etc.
No kidding!! That's what I *want* and would make this a whole lot easier...
One way of implementing functions-as-parameters is with functors or function classes. Those are the primary focus of LiCK, which provides Function.ck, IntFunction.ck, FloatFunction.ck, and so on, so that other classes in the API (e.g. ArrayList.ck) can accept them as parameters.
I'm not sure that'll quite get me to where I want... I need to be able to specify functions as parameters from builtin objects such as SawOsc, LFO, etc... to do what I was talking about in my OP. Or am I missing something?
ChucK forum contributor kijjaz posted a nice template for doing parameter modulation that I've used a few times called ModulucK
http://electro-music.com/forum/viewtopic.php?highlight=modedular&t=24297
michael _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
It looks like modeulator does something similar to what I just ended up developing on my program, sorta... Once I finish the details I'll see what I can do to release the source code, at least the parts that make it "plug 'n' play"... In the interim, I've written a simple class for any float and int-based modulating parameters, "Param" ... Define these parameters globally, and spork 2 shreds, one to modulate the parameter's value with an LFO, and one to monitor the values and update the parameter in the appropriate object... The modulation stuff is all generic now, it can be anything that can be represented by a float or and int, and the updater shred(s) are simple enough to copy & paste... I could conceivably write a single updater shred that updates all the modulated parameters in the appropriate locations, and that should cut down on my memory footprint and represent the other portion of the patch cable setup... In any case, thanks! That was a good deal of inspiration for the next few mods I'm going to make to the patch.
Johnathan;
In the interim, I've written a simple class for any float and int-based modulating parameters, "Param" ... Define these parameters globally, and spork 2 shreds, one to modulate the parameter's value with an LFO, and one to monitor the values and update the parameter in the appropriate object... The modulation stuff is all generic now, it can be anything that can be represented by a float or and int, and the updater shred(s) are simple enough to copy & paste... I could conceivably write a single updater shred that updates all the modulated parameters in the appropriate locations, and that should cut down on my memory footprint and represent the other portion of the patch cable setup...
Yes. I agree with the style of your solution. As your analysis already makes clear; the core of the issue is a namespace one. Interestingly that's also what the relevant chapter in the new book on SuperCollider notes, when explaining the reasoning behind their solution (interesting reading material for those so inclined). ChucK right now has a fairly simple but quite strict name-space system and I feel that exactly this issue is a good reason to push for more powerful features there. Fortunately not all is lost and there are tricks; here is my own; not very full featured but it's compact to make up for it; http://wiki.cs.princeton.edu/index.php/Buses That's largely inspired by how I understood the SC solution. And there is more good news; I had forgotten where that trick was, online, so I googled it and in the process (re-) found this; http://cip.ablelemon.co.uk/ which is by Scott Hewitt. That looks a lot more extensive. I remember when Scott did that but at the time I didn't have the time for it so now I'll look at it too. Three cheers for Open Source and sharing which clearly helps us all! :-) Yours, Kas.
participants (3)
-
Johnathan Bell
-
Kassen
-
Michael Heuer