You are here: Home Blog First steps towards SnoRRRhea

First steps towards SnoRRRhea

For the Interaction Design class, I'm developing an alarm clock that wakes you up quite unconventionally.

The SnoRRRhea alarm clock is an alarm clock that wakes you up with your own sounds, which it will record during the night.  So if you snore or make other sounds, that's what you'll hear when it wakes you up.

The first step was to create the software; the recording component.  For this, I developed a SuperCollider patch that records sounds only when they reach a certain volume.  This way, no space is wasted on endless hours of silence (in case you're not snoring all night through).

The SuperCollider patch turned out to be quite simple, thanks to SuperCollider's expressiveness and readily available modules.  After looking around in the help files, I came up with the following first version:

( // first block
// allocate a Buffer
s = Server.local;
b = Buffer.alloc(s, 44100 * 10.0, 1); // a ten second 1 channel Buffer
)

// record for ten seconds
( // second block
SynthDef("Recordbuf save", { arg out=0,bufnum=0;
  var in, amp, env;

  in = SoundIn.ar(0);
  amp = Amplitude.kr(
    in,
    5.0, 5.0,
    add: -0.02
    );
  amp = max(0, amp);
  RecordBuf.ar(in, bufnum, run: amp);
  Out.ar(0, in);
  env = XLine.kr(400,1000, 10, doneAction: 2);
}).play(s,[\out, 0, \bufnum, b]);
)

// play it back
( // third block
SynthDef("RecordBuf play",{ arg out=0,bufnum=0;
  var playbuf;
  playbuf = PlayBuf.ar(1,bufnum);
  FreeSelfWhenDone.kr(playbuf); // frees the synth when the PlayBuf is finished
  Out.ar(out, playbuf);
}).play(s,[\out, 0, \bufnum, b]);
)

The first block (marked by starting and ending brackets ()) allocates a buffer with the length of ten seconds.  This is where we'll record our sounds, and play them back from.

The second block uses the SoundIn UGen (unit generator) to route sounds coming from the microphone into our patch.  The Amplitude UGen helps us measure the volume of the incoming sounds.  We feed the return value of Amplitude into the RecordBuf's run argument.  As you might have guessed, RecordBuf takes a buffer and records sounds to it.  In our case, we're recording in (the output of SoundIn) only if the Amplitude is high enough; we do this by passing the previously defined amp value into the run argument.

So when you execute the first block, you'll hear yourself for ten seconds while the patch is recording to the buffer.  This is what the Out UGen does, which we simply feed with the in variable.

After these ten seconds, we can execute the third block, which simply plays the recorded buffer until the ten seconds are over.

The second version is a slight variation.  It will play the recorded buffer immediately after the recording is finished:

// record and play it back afterwards

(
SynthDef("Recordbuf save and play", { arg out=0,bufnum=0;
  var in, amp, env, playbuf;

  in = SoundIn.ar(0);
  amp = Amplitude.kr(
    in,
    5.0, 5.0,
    add: -0.02
    );

  amp = max(0, amp);
  RecordBuf.ar(in, bufnum, run: amp);

  env = Env([0, 0, 1, 1], [10, 0.01, 10]);
  env = EnvGen.kr(env, doneAction: 2);

  playbuf = PlayBuf.ar(1, bufnum, trigger:env) * env;
  FreeSelfWhenDone.kr(playbuf); // frees the synth when the PlayBuf is finished
  Out.ar(out, playbuf);

}).play(s,[\out, 0, \bufnum, b]);

)

For the alarm clock, we'll want to play back the recorded sounds when the alarm clock goes off, but this is for another time.  Stay tuned!

Document Actions