2008/5/22 Peter Todd <chuck@xinaesthetic.net>:
I'd suggest it can even be generalised a little more than Kassen has described; grains may be purely synthesised, rather than using a signal in a buffer.

Yes! Shakers are great for this.

The following simple example uses a set of parallel shakers. Each is playing a random harmonic of the current note and is retriggered after a amount of time that's a sub-harmonic of the current pitch. The result is a sort of random-ish noise that still conveys a hint of melody. I added some volume modulation to spice it up. To demonstrate how different sounds can still get a perception of pitch across the sounds used are randomised every time the code is run.

No waranties, no refunds.
Please copy, please remix.

====================
8 => int grains;

64 => int root;
root => int note;
[0, 3, 9, 5, 7] @=> int melody[];

//a different sound every time we play it!
Std.rand2(0,22) => int offset;
now => time start;



repeat(grains) spork ~synth();
me.yield();


while(1)
    {
    for ( 0=> int n; n < melody.cap(); n++)
        {
        root + melody[n] => note;
        4::second => now;
        }
    }


fun void synth()
    {
    Shakers s => dac;
    me.id() + offset => s.preset;

    while(9)
        {
        //the "*1.0" is just to force the fraction into becoming a float
        Std.mtof(note) * (  (Std.rand2(1,3)* 1.0) / Std.rand2(1, 2) )=> s.freq;

        //add volume modulation
        s.noteOn( ((now - start)% second) /second);

     //the time betwee triggers affects the perception of pitch
        Std.rand2(8, 16)::second / Std.mtof(note) => now;       
        }
    }
========================

Cheers,
Kas.