[chuck-users] extending UGens thoughts

Kassen signal.automatique at gmail.com
Sun Oct 16 18:57:55 EDT 2011

Fellow ChucKists,

A few days ago I was talking with my friend Casper Schipper about the
exciting new thing that extending UGens now works. Here are some modest
proposals for extending that;

* Reserve a ".tick()" function name for automatically overwriting the base
class's tick function.

Rationale; while we can (as I demonstrated with a quick example on this
list) spork a shred that will make a UGen like Step or Impulse output a
signal that shred will not be at the right place in the overall execution
order as shreds (by definition) can't run while the Ugen-graph updates.
Another down-side to that strategy is that unchucking the UGen in that case
won't freeze its behaviour nor save CPU. This is inconvenient, it can harm
sound quality and generally makes our own work a sort of "second
rate citizen". With custom UGens that behave like build-in ones libraries
shared by the community wouldn't need much of a extra manual which will make
code more consistent and sharing possibly more popular. This special
function would be called instead of the normal tick and would -clearly- need
to be of type float or a compilation error would be thrown. Overwriting
.tick() would be entirely optional, for a class foo that extends LiSa we may
just wish to set some behaviour in some default way that we happen to use a
lot today and have LiSa herself deal with the processing.

* Reserve a "pull" float for pulling any UGens after our Ugen in the graph.

Rationale; to preserve correct execution order and to have maximum
flexibility in our own creations we'd like our custom UGens to have inputs.
Currently this would be very hard to accomplish, even when we disregard
UGen-graph execution order. "pull" would be a float that would be computed
from our UGen's inputs (depending on our .op), if it's used in the tick
function, and replace all uses of that variable in this call of the
function. By that I mean we don't tick all of the UGens behind us multiple
times just because we need the value a few times. For that reason I think
it's more clear to abstract this away as a float, instead of having it be a
explicit function. "pull" in the context of a function named "tick" wouldn't
need to be declared, I imagine. That's elegant (I think), it's also a
exception to what we have so far in that it would be a highly context
dependant special variable but UGens are a unusual type in general and even
with regard to timing, our big focus, behave quite unusually.

So, let's have a example of what this would look like. Let's say I'd like to
have a new UGen that would add a small bit of noise to a signal (example
intentionally kept simple). I'll write that UGen and use it on a arbitrary

class AddNoise extends UGen
    float amnt; //some internal state

    fun float tick() //tick function
        return (pull * (1 - amnt) + Std.rand2f(-1 * amnt, amnt); //here we
pull, if we don't have a input we'll just get some noise but if we wish we
could detect that condition and deal with it,

    fun float amount(float in) //way of setting the behaviour
      if (in  > 1) 1 => in;
      else if (in < 0) 0 => in;
      in => amnt;
      return in;

   fun float amount() {return amnt;} //overloaded get function as those are

//let's go!
adc => AddNoise an => dac;
.1 => an.amount;

minute => now;

This, to me, looks simple, expressive and realistic. Particularly I can't
see any big things here that would backfire if at some point we'd like to be
able to pre-compile external UGens into some sort of module format. This
should also -as far as I can see- play nicely with the existing UGen graph
functionality, for example the detection of feedback loops.

Note that Casper and me were brainstorming about our wishes, any glaring
errors in this post are mine. Also note that this proposal could make
.tick() a thing you could explicitly call manually, possibly for all UGens.
I don't see a big problem with that, it might even be useful and/or fun.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cs.princeton.edu/pipermail/chuck-users/attachments/20111017/90010420/attachment.html>

More information about the chuck-users mailing list