Even SuperCollidists aren't immune to the memetic allure of Twitter, there's been a whole load of 140 character SuperCollider programmes appearing both on Twitter and on the SC Users list. Thankfully someone has been kind enough to collect them all up and put them on this page here, at the SC Wiki. Smashing.
Here's a couple of my favorites,
from Fredrik Olofsson
{RHPF.ar(GbmanN.ar([2300,1150]),LFSaw.ar(Pulse.ar(4,[1,2]/8,1,LFPulse.ar(1/8)/5+1))+2)}.play
And from the Venerable Dan
{LocalOut.ar(a=DynKlank.ar(`[LocalIn.ar.clip2(LFPulse.kr([1,2,1/8]).sum/2)**100*100],Impulse.ar(10)));HPF.ar(a).clip2!2}.play//#supercollider
Friday, August 21, 2009
Sunday, August 9, 2009
Recreating the THX sound
In a similar vein to the recreation of the rave hoover here's another reverse engineer and recreation of a famous sound, the tooth shattering TXH Deep Note. You can read the full story on EarSlap, but here's the final code.
Apparently the original took 20,000 lines of C code! This is a tad more efficient and sounds very close to the original.
//inverting init sort, louder bass, final volume envelope, some little tweaks
(
{
var numVoices = 30;
var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort.reverse;
var finalPitches = (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps;
var outerEnv = EnvGen.kr(Env([0, 0.1, 1], [8, 4], [2, 4]));
var ampEnvelope = EnvGen.kr(Env([0, 1, 1, 0], [3, 21, 3], [2, 0, -4]), doneAction: 2);
var snd = Mix
({|numTone|
var initRandomFreq = fundamentals[numTone] + LFNoise2.kr(0.5, 6 * (numVoices - (numTone + 1)));
var destinationFreq = finalPitches[numTone] + LFNoise2.kr(0.1, (numTone / 3));
var sweepEnv =
EnvGen.kr(
Env([0, rrand(0.1, 0.2), 1], [rrand(5.5, 6), rrand(8.5, 9)],
[rrand(2.0, 3.0), rrand(4.0, 5.0)]));
var freq = ((1 - sweepEnv) * initRandomFreq) + (sweepEnv * destinationFreq);
Pan2.ar
(
BLowPass.ar(Saw.ar(freq), freq * 6, 0.6),
rrand(-0.5, 0.5),
(1 - (1/(numTone + 1))) * 1.5
) / numVoices
}!numVoices);
Limiter.ar(BLowPass.ar(snd, 2000 + (outerEnv * 18000), 0.5, (2 + outerEnv) * ampEnvelope));
}.play;
)
Apparently the original took 20,000 lines of C code! This is a tad more efficient and sounds very close to the original.
Saturday, July 25, 2009
Auto chiptunes with Moog
Wow, it's been a while since I've posted, but It's been a busy month.
Here's an update to Dan's auto chiptune thing that I modified in my last post. This time I decided to mate it with my Moog synthdef in an attempt to create a pitch tracking interface for my synth. Surprisingly it works pretty well.
Here's an update to Dan's auto chiptune thing that I modified in my last post. This time I decided to mate it with my Moog synthdef in an attempt to create a pitch tracking interface for my synth. Surprisingly it works pretty well.
(
SynthDef("chiptune", { |oscType =0, oscType2 = 1, pan = 0, level = 0.5, cutoff = 500, gain = 3.3, attack = 0.1, decay = 0.1, sust = 0.7, rel = 0.2, attackf = 0.1, decayf = 0.1, sustf = 0.9, relf = 0.2, gate = 1, freq =440, lagLev = 0.2|
var son, pitch, amp, wibble, oscArray, oscArray2, ampEnv, filterEnv, osc1, osc2, fade, filter;
son = SoundIn.ar;
pitch = Tartini.kr(son)[0];
amp = Amplitude.ar(son);
pitch = Median.kr(5, pitch); // smooth
pitch = pitch.min(10000).max(10); // limit
pitch = pitch.cpsmidi.round.midicps; // coerce
oscArray = [Saw.ar(Lag.kr(pitch, lagLev)), SinOsc.ar(Lag.kr(pitch, lagLev)), Pulse.ar(Lag.kr(pitch, lagLev))];
oscArray2 = [Saw.ar(Lag.kr(pitch, lagLev)), SinOsc.ar(Lag.kr(pitch, lagLev)), Pulse.ar(Lag.kr(pitch, lagLev))];
ampEnv = EnvGen.ar(Env.adsr(attack, decay, sust, rel), gate, doneAction:2);
filterEnv = EnvGen.ar(Env.adsr(attackf, decayf, sustf, relf), gate, doneAction:2);
osc1 = Select.ar(oscType, oscArray);
osc2 = Select.ar(oscType2, oscArray2);
fade = Pan2.ar(XFade2.ar(osc1, osc2, pan , level * ampEnv, 0));
filter = MoogFF.ar(fade, cutoff * filterEnv, gain);
wibble = FreeVerb.ar(filter, 0.3, 0.1, 0.9); // bit of reverb just to taste
Out.ar(0, wibble.dup);
}).memStore;
)
Sunday, July 5, 2009
Auto Chiptune
A while ago now Dan posted some auto chip tune generating code on his blog, I've been meaning to write about this for ages, but I've only just got round to it. It takes any MP3 file and converts it to chiptune like sounds by using Tartini to follow the pitch and then re synthesising with a pulse wave. Here's the original code as taken from his blog.
Just for the hell of it I decided to adapt it to use live audio input and give it three different oscillators to choose from. Here's my version, you can change the oscillator with the \oscType parameter.
sounds pretty good with guitar.
s.boot;
(
SynthDef("help_mp3_01", { |bufnum = 0|
var son, pitch, amp, wibble;
son = DiskIn.ar(2, bufnum).mean;
pitch = Tartini.kr(son)[0];
amp = Amplitude.ar(son);
pitch = Median.kr(5, pitch); // smooth
pitch = pitch.min(10000).max(10); // limit
pitch = pitch.cpsmidi.round.midicps; // coerce
wibble = Pulse.ar(pitch, 0.2, amp * 2); // resynthesise
wibble = FreeVerb.ar(wibble, 0.3, 0.1, 0.9); // bit of reverb just to taste
Out.ar(0, wibble.dup);
}).memStore;
)
// Now let's create the MP3 object and cue it into a Buffer.
m = MP3("../mp3s/Gimme A Pig Foot And A Bottle Of Beer.mp3");
m.start;
b = Buffer.cueSoundFile(s, m.fifo, 0, 2);
// Off we go:
x = Synth("help_mp3_01", [\bufnum, b.bufnum], addAction:\addToTail);
// Please remember to tidy up after yourself:
x.free;
b.close; b.free;
m.finish;
Just for the hell of it I decided to adapt it to use live audio input and give it three different oscillators to choose from. Here's my version, you can change the oscillator with the \oscType parameter.
(
SynthDef("chiptune", { |oscType = 0|
var son, pitch, amp, wibble, oscArray;
son = SoundIn.ar;
pitch = Tartini.kr(son)[0];
amp = Amplitude.ar(son);
pitch = Median.kr(5, pitch); // smooth
pitch = pitch.min(10000).max(10); // limit
pitch = pitch.cpsmidi.round.midicps; // coerce
oscArray = [Pulse.ar(pitch, 0.2, amp * 2), SinOsc.ar(pitch, 0, amp * 2), Saw.ar(pitch, amp * 2)];
wibble = Select.ar(oscType, oscArray); // resynthesise
wibble = FreeVerb.ar(wibble, 0.3, 0.1, 0.9); // bit of reverb just to taste
Out.ar(0, wibble.dup);
}).memStore;
)
// Off we go:
x = Synth("chiptune", [\oscType, 1], addAction:\addToTail);
// Please remember to tidy up after yourself:
x.free;
sounds pretty good with guitar.
Thursday, June 25, 2009
SuperCollider 3.3.1 is out - Safari 4 fix.
SuperCollider 3.3.1 is out now and it works with Safari 4! I don't know about you but that's a weight off my mind.
Thursday, June 18, 2009
A Generative Looper.
What's a generative looper? It's a type of cartilaginous fish, but it's also a interesting new project from Arthur Carabot, via the SC Users list. Here's the source and here's an intructional video.
I can't get it to work at the moment but maybe it's just me.
I can't get it to work at the moment but maybe it's just me.
Tuesday, June 16, 2009
More Dominator Deconstruction.
Another attempt at the rave hoover sound, this time from Wouter Snoei on the SC-Users list, probably the best so far and based on further research into the Alpha Juno 2. Here's the code,
Wouter's come up with a more accurate version of the pulse width modulation, certainly more accurate than my complete guess work and it sounds great.
Here's a little line of code taken from Wouter's post that may offer a bit of an explaination of what's going on with the modulation.
{ LFSaw.ar( 200, 1 ).range(0,1) * (1-LFPulse.ar( 400, 0, 2/3 )) }.plot;
If you run it you should get this plot,

You can see the waveform is a sort of flattened saw wave, this might explain why Dan had trouble identifying what it was.
(
SynthDef( "hoover", { |freq = 220, amp = 0.1, lgu = 0.1, lgd = 1, gate = 1|
var pwm, mix, env;
freq = freq.cpsmidi.lag(lgu,lgd).midicps;
freq = SinOsc.kr( { 2.9 rrand: 3.1 }!3, {2pi.rand}!3 ).exprange( 0.995, 1.005 ) * freq;
pwm = SinOsc.kr( {2.0 rrand: 4.0}!3 ).range(0.125,0.875);
// the saw/pulses
mix = (LFSaw.ar( freq * [0.25,0.5,1], 1 ).range(0,1)
* (1 - LFPulse.ar(freq * [0.5,1,2], 0, pwm))).sum * 0.1;
// the bass
mix = mix + LFPar.ar( freq * 0.25, 0, 0.1 );
// eq for extra sharpness
mix = BPeakEQ.ar( mix, 6000, 1, 3 );
mix = BPeakEQ.ar( mix, 3500, 1, 6 );
// kind of chorus
mix = mix + CombC.ar( mix.dup, 1/200,
SinOsc.kr( 3, [0.5pi, 1.5pi] ).range(1/300,1/200),
0.0 ) * 0.5;
env = EnvGen.kr( Env.asr, gate );
Out.ar( 0, mix * env * amp );
}).store;
)
(
p = Pmono(\hoover,
\dur, Pseq([0.25,0.5,7, 0.25]* 0.24, inf),
\lgu, 0.15,
\lgd, Pseq([ 0.1, 0.1, 1.5, 0.25], inf ),
\midinote, Pseq([20, 67, 62, 20] , inf)).play;
)
p.stop;
(
p = Pmono(\hoover, \dur, 0.24,
\lgu, 0.2,
\lgd, Pseq([1,1,2,0.5,2,2,2,2], inf ),
\midinote, Pseq([55, 40, 67, 55, 40, 55, 53, 52], inf)).play;
)
p.stop;
Wouter's come up with a more accurate version of the pulse width modulation, certainly more accurate than my complete guess work and it sounds great.
Here's a little line of code taken from Wouter's post that may offer a bit of an explaination of what's going on with the modulation.
{ LFSaw.ar( 200, 1 ).range(0,1) * (1-LFPulse.ar( 400, 0, 2/3 )) }.plot;
If you run it you should get this plot,

You can see the waveform is a sort of flattened saw wave, this might explain why Dan had trouble identifying what it was.
Subscribe to:
Posts (Atom)