[chuck-users] Keyboard Stuff

Hans Aberg haberg at math.su.se
Sat Apr 18 04:08:30 EDT 2009


On 18 Apr 2009, at 08:26, Kassen wrote:

> I agree with you here but I feel that voice cycling is quite  
> different from GC. Of course they can be similar; a voice that's no  
> longer used might become garbage, depending on the structure used

It was not intended as a far reaching analogy - only that one may end  
up programming side issues rather than the main task.

>> If there was a simple way, if that now was needed, to just being  
>> able to add generators and the program could sort out which ones  
>> were needed for the sound output, would that not be great?
>
> Yes, and it does this; ChucK only calculates UGens that are  
> connected (directly or through other UGens) to the dac or to  
> blackhole. No other UGens take cpu (at least not for calculating  
> sound). The problem with not calculating ones that are silent (as I  
> think you are sugesting) is that I might do things like have a  
> sample player connected through a envelope to fade it in and out  
> while it plays. If we wouldn't calculate the sample player we'd have  
> no way of knowing where in the sample it should be playing when it  
> is faded back in again.

Yes, it may be a difficulty issue and not always possible. In the case  
of the fader, it must able report back to the source that it is not  
needed. - So there might be needed something similar to lazy  
evaluation or ray back-tracing. Such things must then be supported by  
the programming language.

> ... what you likely need is a series of parallel sound sources and a  
> way to link those to notes.

I will probably just start off with a few generators which will be  
allocated if available. There is a problem with key roll over on a  
typing keyboard, but one can learn to avoid it.

>> Each new key, which initiates a sound generator, adds in CPU power  
>> after being allowed to settle down and not producing sound anymore  
>> about as much as 3 times when as full program at startup time. So  
>> there is a quick buildup of from these idle generators.

> Yes. One of the factors here, aside from the BeeThree's is that you  
> use two Echo's and a reverb for each voice. Because both of those  
> effects are linear and time-invariant it doesn't matter (for the  
> sound) whether we send a BeeThree through it's effects, then mix the  
> effects together or whether we mix the BeeThree's and send all of  
> them through the effect chain. Now; while this may not matter to the  
> sound the second option does save us rather a lot of UGens, and  
> especially reverbs take a lot of CPU.

I might try to simplify that. The echo effects may not be necessary at  
this point, I just want some pitches.

> > Such a resource consuming problem might be fixed if each sound  
> generator could turn itself to sleep. Say there is a cutoff-level,  
> or something.
>
> Yes. there are two ways of doing that. First of all you can  
> "unchuck" (or disconnect) a UGen and when you do it will no longer  
> consume CPU. Like this;
>
> SinOsc s;
>
> while(1)
>     {
>     if ( s.isConnectedTo(dac) )    s =< dac;
>     else                         s => dac;
>     second => now;
>     }

Thanks. I was just about to look for this.

> Another way of making a UGen stop consuming cpu is to make the shred  
> that contained it's defininition (which is also the namespace  
> containing it) leave the VM. like this;
>
> JCRev r => dac;
> .5 => r.mix;
>
> repeat(20)
>     {
>     spork ~ play ( Std.rand2(1,5) * 200, Std.rand2f(.5,2)::second );
>     .5::second => now;
>     }
> 5::second => now;
>
> fun void play( float freq, dur length)
>     {
>     SinOsc s => Envelope e => r;
>     .5 => s.gain;
>     freq => s.freq;
>     .5::length => e.duration;
>     1 => e.keyOn;
>     .5::length => now;
>
>     1 => e.keyOff;
>     .5::length => now;
>     }
>
> Note, that while both methods free the CPU again neither frees the  
> memory used by the UGen.

THat is less of a problem, in view of virtual memory.

> I think that in the case of the last example we can free the memory  
> as well by making the function read like;
>
>
> fun void play( float freq, dur length)
>     {
>     SinOsc s => Envelope e => r;
>     .2 => s.gain;
>     freq => s.freq;
>     .5::length => e.duration;
>     1 => e.keyOn;
>     .5::length => now;
>
>     1 => e.keyOff;
>     .5::length => now;
>
>     null @=> s;
>     null @=> e;
>     }
>
> that's a bit hacky though.

It's good to get an idea of it. I did look a bit at the dynamic  
allocation of arrays.

> Hope that clarifies.

Yes. Thank you.

   Hans




More information about the chuck-users mailing list