[chuck-users] Urgent shot in the dark -- Audible clicks when spawning shreds when SndBuf reads from disk

mike clemow gelfmuse at gmail.com
Sun Nov 8 09:29:01 EST 2009


This is a shot-in-the-dark...

At the last minute, the person who was responsible for doing the sound
with a Kyma system, couldn't get it to trigger sounds with MIDI (for
some reason or another) and I'm stepping up and doing the whole show
with pre-recorded material in ChucK.  (I know, I know -- I'm crazy.)

It's 9:25am here on the East Coast of the U.S.  We're onstage at 2pm
and 8pm.  I have a script that receives OSC messages from a Java
program.  The messages contain the string name of a file to play.
It's a simple stereo file (I'm already working with a very kludgy way
of playing stereo files--loading it twice into two buffers).  But
every time I spawn a new thread, the file loads from disk and there's
an audible click, or drop in audio.

Now, I know that one way around this is to pre-load all the files into
SndBuf objects and then trigger them to play using Events.  The only
trouble is that there are 73 files for this piece and some of them are
pretty large.  I'm afraid of eating all my RAM / bringing everything
to a grinding halt.

I'm posting my entire script at the end of the email.  If anyone has
any thoughts, please send them along.  Otherwise, we'll just deal with
the way things are.

Best,
Mike

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

// ---- CODE ---- //

"/Users/michaelclemow/chuck/Sandresky/sounds/" => string dirPrefix;

// osc event creator function
fun OscEvent createOscEvent( string address, int port ) {
    OscRecv recv;
    port => recv.port;
    recv.listen();
    recv.event( address ) @=> OscEvent oe;
    return oe;
}

// play file function
fun void playFile(string filename)
{
    SndBuf l, r;
    l.chunks(1024);
    r.chunks(1024);
    r.read(filename);
    l.read(filename);

    0.2 => l.gain => r.gain;

    l.channel(0);
    l => dac.chan(0);
    l => dac.chan(2);

    r.channel(1);
    r => dac.chan(1);
    r => dac.chan(3);

    l.pos(0);
    r.pos(0);
    l.play(1);
    r.play(1);

    r.length() => now;
    me.yield();
}

createOscEvent( "/play, s", 12000 ) @=> OscEvent oe;

string file;
9999 => int last;

fun void killLast()
{
    createOscEvent( "/killlast, i", 12000 ) @=> OscEvent kill;

    while( kill => now )
    {
        if( kill.nextMsg() )
        {
            kill.getInt() => int k;
            <<< "killing last id:", last >>>;
            Machine.remove( last );
        }
        me.yield();
    }
}

fun void playListen()
{
    while( oe => now )
    {
        if( oe.nextMsg() )
        {
            oe.getString() => file;

            // spawn player
            (spork ~playFile( dirPrefix + file )).id() => last;
            me.yield();

            <<< "playing", file, "id", last >>>;
        }
        me.yield();
    }
}

<<< "spawning listeners" >>>;
spork ~killLast();
spork ~playListen();
me.yield();

0 => int seconds;

// wait for messages and play files
<<< "listening..." >>>;
while(true)
{
    1::second => now;
    //<<< seconds++ >>>;
}

// --- END CODE --- //


More information about the chuck-users mailing list