[chuck-users] Some Summer Tidbits

mike clemow gelfmuse at gmail.com
Wed Aug 5 12:55:21 EDT 2009


I'm sorry, folks.  I accidentally hit "send" there.  **slaps forehead**

Basically, what I forgot to say was that using this method of
enveloping signals for granular synthesis puts almost all of the heavy
lifting on the UGens, which makes it perform really, really well in
realtime.  I was able to achieve well over a thousand
grains-per-second with this method in realtime without overloading
ChucK.  And that's specifying the parameters of each grain
individually on a per-grain basis in code!

The best part is that the envelope can be tailored to be any shape
because it's all done with wavetable coefficients!  That means that
you aren't limited to triangle, or ADSR shaped envelopes, which makes
a HUGE difference to the spectral properties of granular synthesis.

To make the long story short, I'd love to hear your feedback on these
classes, especially if you find them helpful, useful, improvable, etc.

ChucK on!

_Mike




On Wed, Aug 5, 2009 at 12:49 PM, mike clemow<gelfmuse at gmail.com> wrote:
> Dear Chuckists,
>
> With the exception of a protracted discussion about garbage collection
> (of which I have yet to read the conclusion), things have been
> generally "all quiet on the ChucKian front" this summer.
> Nevertheless, I know that there are those of you who are still busy
> digging into this and that project with ChucK.  I myself have been
> working (predictably, doggedly, stubbornly) on more granular synthesis
> stuff and wanted to share some recent classes that I find helpful to
> me in general (i.e. not just for granular synthesis).
>
> Part 1: INPUT
>
> I find that environments like Processing, SC, etc have very
> easy-to-use input calls like MouseX.kr etc, that easily bring the
> ability to add some interaction to your code, without having to set up
> a HidMsg, Hid pair and an event responder.  Sometimes you just want
> mouse input and want it right now.  I wanted to automate the process a
> little so that I could save some time by just telling ChucK to add the
> boiler plate listener for the mouse, keyboard, or a joystick in a
> separate thread and make the data available.  With the MouseInput
> class, for instance, you can just do this:
>
> MouseInput mi;
> spork ~ mi.listen();
> me.yield();
>
> while(true)
> {
>        mi => now;
>        <<< mi.deltaX, mi.deltaY, mi.wheelDeltaX, mi.wheelDeltaY,
> mi.buttonDown, mi.buttonUp >>>;
>        me.yield();
> }
>
> I find this easier to use.  Maybe you will too.  There's one for
> Keyboard input and joystick input too.  I'm sure they can be improved,
> so please share any ideas you have.
>
>
>
> Part 2: WAVETABLES AS ENVELOPES
>
> Concept: A positive, unipolar wavetable can be used as a cheap,
> flexible alternative to envelope UGens by driving it with a Phasor and
> multiplying its output with your signal.  The CurveEnvelope class:
>
> //
> // CurveTable Envelope
> //
>
> class CurveEnvelope
> {
>        // members and default params
>        Phasor drive => CurveTable curvetable => Gain multiplier;
>        3 => multiplier.op;                             // this is what makes the CurveTable an envelope!
>        0. => multiplier.gain;                  // we use this to gait the output, so start at 0.
>
>        UGen source, out;
>
>        0 => drive.op;                                  // stop the driver for now
>
>        dac @=> out;
>        1. => float gain;
>        1::second => dur length;
>        [0., 0., 0.,  1., 1., 0.,  2., 0.] => curvetable.coefs; // triangle window
>
>        // methods
>        fun void setEnvelopeCoefs( float _coefs[] )
>        {
>                _coefs => curvetable.coefs;
>        }
>
>        fun void connectSource( UGen src )
>        {
>                src @=> source;
>        }
>
>        fun void connectOutput( UGen destination )
>        {
>                destination @=> out;
>        }
>
>        fun void trigger()
>        {
>                source => multiplier => out;                    // connect things
>                gain => multiplier.gain;                                // open gait
>                1 => drive.op;
>                0. => drive.phase;                      // reset driver to beginning of envelope curve
>                1. / (length / second) => drive.freq;           // calculate speed of
> driver in Hz
>                length => now;                                                  // let it happen...
>                0. => multiplier.gain;                                  // close gait
>                0 => drive.op;
>                source =< multiplier =< out;                    // disconnect things
>        }
> }
>
>
> USAGE:
>
> CurveEnvelope ce;
> SinOsc s;
> ce.connectSource( s );
> ce.connectOutput( dac );
> ce.trigger();
>
> TriOsc t;
> ce.connectSource( t );
> ce.connectOutput( dac );
> ce.trigger();
> <<< "done" >>>;
>
>
>
> --
> http://michaelclemow.com
> http://semiotech.org
>



-- 
http://michaelclemow.com
http://semiotech.org


More information about the chuck-users mailing list