Skip to content

Instantly share code, notes, and snippets.

@triss
Created October 23, 2013 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save triss/7121667 to your computer and use it in GitHub Desktop.
Save triss/7121667 to your computer and use it in GitHub Desktop.
Grabbing sounds and mangling them
s.boot;
// ----------------------------------
// grabbing sound and playing it back
// ----------------------------------
// in supercollider we usually store sound in buffers...
// we'll need to allocate an empty one... this one's 10 seconds long
~buffer = Buffer.alloc(s, 10 * s.sampleRate);
// ^ urgh... s in the above line represents the "server" you want to make
// the buffer on.
// <rambly guff you might not need to worry about too much now>
// the server is the part of sc that makes sound - it's actually a separate
// bit of software to the language we write in... allowing us to specify which
// server we're working on means we can do fancy things like make noise on other
// peoples machines easily... unfortunately it also means we have to pass "s" to
// all the buffer making/reading bits of SC (as well as in a few other places)
// - even when we're working on just one computer. Bit annoying but easy enough
// to get used to.
// </rambly guff you might not need to worry about too much now>
// we can make something that'll record in to a buffer really easily
~recorder = { RecordBuf.ar(SoundIn.ar(0), ~buffer) }.play;
// stop the recorder recording and throw it away
~recorder.free;
// the simplest way to play a buffer back is as follows
~buffer.play;
// but it's not easy to do a lot to the buffer when we play stuff back that way
// the usual way is to play back a buffer is with PlayBuf
~player = { PlayBuf.ar(1, ~buffer) }.play;
~player.free;
// we can do fancier things with it like change the speed/pitch of playback...
~octaveUpPlayer = { PlayBuf.ar(1, ~buffer, BufRateScale.kr(~buffer) * 2) }.play;
~octaveDownPlayer = { PlayBuf.ar(1, ~buffer, BufRateScale.kr(~buffer) / 2) }.play;
(
~randomSpeedPlayer = {
var randomSpeed;
// get a random speed between 4 octaves below and 4 above 3 times per second
randomSpeed = TRand.kr(0.25, 4, Impulse.kr(3));
// note in the line below i've turned on looping for PlayBuf
PlayBuf.ar(1, ~buffer, randomSpeed * BufRateScale.kr(~buffer), loop: 1);
}.play;
)
(
~wigglySpeedPlayer = {
var wigglySpeed;
// make a sine wave that goes up and down between -2 and 2 once
// every 32 seconds - negative values' mean we go backwards
wigglySpeed = SinOsc.kr(1 / 32).range(-2, 2);
PlayBuf.ar(1, ~buffer, wigglySpeed * BufRateScale.kr(~buffer), loop: 1);
}.play;
)
(
~wigglySpeedVolumeBeingChoppedPlayer = {
var wigglySpeed, ampChopper, loopPlayer;
wigglySpeed = SinOsc.kr(1 / 32).range(-4, 8);
// chop the volume 3 times per second between 0 and 1
ampChopper = LFPulse.kr(3).range(0, 1);
loopPlayer = PlayBuf.ar(1, ~buffer, wigglySpeed * BufRateScale.kr(~buffer), loop: 1);
loopPlayer * ampChopper;
}.play;
)
(
~ampModPlayer = {
var ampMod, loopPlayer;
// a modulator at 110Hz
ampMod = SinOsc.ar(110);
loopPlayer = PlayBuf.ar(1, ~buffer, loop: 1);
loopPlayer * ampMod;
}.play;
)
// lets tidy up after ourselves. There are ways around having to do this
// ourselves (doneActions... you seen those yet?) but for now we'll deal
// with doing it manually
~octaveUpPlayer.free;
~octaveDownPlayer.free;
~randomSpeedPlayer.free;
~wigglySpeedPlayer.free;
~wigglySpeedVolumeBeingChoppedPlayer.free;
~ampModPlayer.free;
// <some stuff you might be wondering wtf about......>
// BufRateScale
// BufRateScale.kr() in the above is about dealing with buffer's that run at
// different sample rates to our server... it handles buffers being at say 48000
// or 96000 rather than 44100 or whatever you're running at for us by returning
// a ratio that PlayBuf uses to scale playback speeds so buffers play back at
// appropriate speeds
// don't worry about it too much and just plug it in.
// It's the number we times its output by that's important musically
// Number of channels
// The 1 specified as the first argument for PlayBuf is about the number of
// channels our buffer has.... it has to be the same as the number of channels
// in our buffer...
// Stereo buffers
// if you want to use a stereo buffer you'll need to allocate it like so:
~stereoBuffer = Buffer.alloc(s, 10 * s.sampleRate, 2);
// and record into it like so - inputs 0 and 1 of your sound card
~stereoRecorder = { RecordBuf.ar(SoundIn.ar([0, 1]), ~stereoBuffer) }.play;
// when playing back just set the number of channels to 2 too
~stereoPlayer = { PlayBuf.ar(2, ~stereoBuffer) }.play;
~stereoPlayer.free;
// What if i want to load in a soundfile instead of recording it?
~myLovelyBuffer = Buffer.read(s, "/path/to/my/lovely/sample.wav");
// </some stuff you might be wondering wtf about......>
// retriggering a buffer
(
~retriggerer = {
var trigger;
trigger = Impulse.kr(10); // ten times a second
// when ever the trigger thing argument gets fed a 1 it'll restart
PlayBuf.ar(1, ~buffer, trigger: trigger, loop: 1)
}.play;
)
~retriggerer.free;
// jumping around in a buffer
(
~jumpArounder = {
var randomPosition, trigger;
// lets trigger a jump to a new position 3 times per second
trigger = Impulse.kr(3);
// here we choose a new position in the soundfile to jump to.
// - BufFrames.kr returns the number of frames in our buffer (its length)
// - we're getting a number between 0 and that each time this
// TRand gets triggered.
randomPosition = TRand.kr(0, BufFrames.kr(~buffer), trigger);
// more sane waves often make for more more sane patterns... you could try
// plugging something like this in instead....
// don't forget you'll also need to make a sinePos variable.
// sinePos = SinOsc.kr(1/8).range(0, BufFrames.kr(~buffer));
PlayBuf.ar(1, ~buffer, trigger: trigger, startPos: randomPosition, loop: 1)
}.play
)
~jumpArounder.free;
// we can do a shitload more interesting things if we
// - make synthDef's with some nifty parameters to control
// - control playback from the language
// - add envelopes etc.
// - route the sounds in to other fx
// - starting working with some sense of tempo
// i'll knock up some code that does this over the next day or two.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment