Monday, October 28, 2013
Installing SuperCollider on Windows 7 and 8 and dealing with 'Device unavailable' could not initialize audio'
A few years ago when I first started with SuperCollider the Windows port was something of a poor relation to the lead OSX platform and the up and coming Linux port, but things have changed since then and the latest Windows version seems pretty good so far. The only downside I've found so far is driver and hardware support issues, although this may not be much of a problem depending on what hardware you have.
Installing the latest Windows port is theoretically pretty easy, just head over to the Sourceforge repository and download the latest version of the installer. All being well it should install itself without any bother from the super easy to use config GUI and you'll be ready to go.
I had no trouble at all setting it up on my Windows 7 laptop, everything worked right first time, no issues at all. My Windows 8 desktop on the other hand was a bit tougher.
I'm not sure, but I don't think it was an OS issue, it seems more likely that it was a hardware driver issue with my motherboard's crappy on board sound .
After using the installer and trying to boot the server for the first time I got this error:
'SC_PortAudioDriver: PortAudio failed at Pa_OpenDefaultStream with error: 'Device unavailable'
could not initialize audio'
Very helpful. After some Googling it seemed like a driver problem and the solution was something I already happened to have installed, ASIO4ALL. This is a universal ASIO driver which gives ASIO support to a whole range of crappy Windows sound cards that don't usually support it. Windows SuperCollider apparently plays nicely with ASIO sound cards, so using this should help.
The next thing I needed to do was to get SuperCollider to talk to my sound hardware in ASIO mode, which was pretty easily achieved by running this line of code:
Server.local.options.device ="ASIO4ALL"
Which I added to my startup file so it runs every time I open up the SC IDE.
And, success! Well nearly, because for reasons I really don't understand sometimes it works and sometimes it doesn't. Often when I boot the server ASIO4ALL says that the output device is unavailable and I have to disable it and enable it again to make it work. I think I might be better of getting a discrete sound card.
In short,
SuperCollider on Windows is pretty easy to get going if you are lucky with your sound hardware. If not Try ASIO4ALL, it's free and is very easy to install. It might be helpful.
Wednesday, July 20, 2011
Detuning oscillators.
I'm still not entirely sure how PmonoArtic works, perhaps it will forever remain a mystery, but I do know how the important part of this synth def I came up with works. Well more or less anyway.
(
SynthDef("aSynth",{
arg lagLev = 0.2, freq= 440, cutoff = 500, gate = 0.5;
var osc1 = Mix.fill(8, { SinOsc.ar(freq + 10.0.rand, 0, 0.05) }); var filterEnv = EnvGen.ar(Env.adsr(0.02, 0.1, 0.05, 1), gate, doneAction:2);
var filterOutput = MoogFF.ar(osc1, cutoff * filterEnv, 3.3); Out.ar(0, filterOutput);
}).store
)
(
PmonoArtic("aSynth",
\freq, Pseq([440,330,440,330,550,770,880], inf),
\legato, Pwrand(#[0.5, 1.0], #[0.1, 0.9], inf),
\dur, 0.3,
\cutoff, Pwhite(5000, 10000, inf)
).play
)
This is inspired by something I read on the SC Users list and it's an attempt at a synth that's more analoguesque. It didn't work quite as well as I had anticipated, so I think I'll have to try some more advanced techniques, but I suppose it's a start.
The significant bit is this line:
var osc1 = Mix.fill(8, { SinOsc.ar(freq + 10.0.rand, 0, 0.05) });
Here I'm using the Mix command along with fill to create an array of eight different oscillators all tuned slightly differently, randomly assigned plus or minus 10hz from the frequency passed to the sythdef. It's supposed to give it a vaguely chorus like effect by layering detuned oscillators, which it does a bit, but the effect isn't quite as noticeable as I thought. Increasing the number of oscillators doesn't help much and increasing the frequency that they can change by sounds pretty horrible.
The mix and fill commands are pretty simple to use, by the way.
On it's own you can use Mix.new(array) to mix an array of channels together, or you can use Mix.fill(n, function) to create a whole new array of channels with the function you specify.
I could be wrong, but I think that when you use Mix.fill in a synth def it will only evaluate the function when the synth is loaded, so if you're using random varaibles like I am above, they'll only be random once when it's run.
Tuesday, July 5, 2011
I've forgotten everything I ever learned about SuperCollider.
Several versions of SC have come out since I last used it and of course lots of the quarks and plugins I had from previous versions now no longer work, so I've had to start from scratch with a fresh install. This is probably no bad thing as it means I need to work from the ground up and remind myself how it all works.
I've done this before I think, but now it's time to do again, a SuperCollider Theramin, this time with a phase effect.
{SinOsc.ar(MouseY.kr(1,880),SinOsc.kr(MouseX.kr(0,100)))}.play
Wednesday, April 20, 2011
I'm still alive.
Monday, November 30, 2009
'Harmoniser' with Tartini
(
SynthDef("Harm", {|offSet1, offSet2, output, osc1, osc2, mix, pitch1, pitch2, fader|
var sound = SoundIn.ar;
var pitch = Tartini.kr(sound)[0];
var amp = Amplitude.ar(sound);
pitch = Median.kr(5, pitch); // smooth
pitch = pitch.min(10000).max(10); // limit
pitch1 = pitch.cpsmidi.round + 40;
pitch2 = pitch.cpsmidi.round + 60;
pitch1 = pitch1.midicps;
pitch2 = pitch2.midicps;
osc1 = Saw.ar(pitch1, amp * 2); // resynthesise
osc2 = Pulse.ar(pitch2, 0.2, amp * 2);
mix = Mix.ar([osc1, osc2]);
fader = XFade2.ar(sound, mix, -0.5);
output = FreeVerb.ar(fader, 0.3, 0.1, 0.9); // bit of reverb just to taste
Out.ar(0, output);
}).memStore;
)
x = Synth("Harm");
Here Im using Tartini to determine the pitch of the input, then using fairly roundabout method converting it to two lots of midi notes, adding to it to increase the pitch then sending it to some oscillators and finally mixing it back with the original input. If you change the numbers that I've added to the pitches here,
pitch1 = pitch.cpsmidi.round + 40;
pitch2 = pitch.cpsmidi.round + 60;
you should be able to change the 'harmony'.
There may be a better method to shift the synthesised pitches, I'm not sure but this does seem to work.
It sort of sound okay with some guitar or vocal input, but really bad with anything more complex.
Friday, October 30, 2009
Installing bbcut2 in OS X
Everything went smoothly with the exception of bbcut, which took a bit of work. I had the same problem when I installed it the first time round, but I ended up taking such as circuitous route to getting it working that I couldn't remember what I'd done by the time I'd finished. This time I took a more systematic approach and I've isolated the problem.
The latest version of the extension pack provided with the standard SC install includes some, but not all of the Ugens and classes that come with bbcut. If you follow the install instructions that come with bbcut you'll end up with conflicts and the class library won't compile.
To get it to work you'll need to leave out the three ugens in the bbcut2 ugens folder and the machinelistening classes from the bbcut2 classes folder when moving the bbcut folders to your SC directory. These seem to be the source of the conflicts and if you copy over the rest of the files as described in the bbcut2 help file it should all be okay.
If you've already copied these into your SC folder you'll need to make sure you delete the version of the files that come with bbcut and replace the them with the versions that come with the standard SC download, they are different and only the ones from the standard SC download will work. And that's jazz.
I've no idea how this goes on other platforms but I imagine there might be similar problems.
à bientôt.
Sunday, October 18, 2009
Wicki - not wiki
What's the Wicki system? I'm not entirely sure, but it seems to be a way of learning to play music with a type writer style keyboard. There's some background info available here and here.
This bit of code is a class that creates a Wicki keyboard, it is a bit long so I won't reproduce it on this blog, but you can download it here, along with a bit of test code. You can use the keyboard to record and playback sequences of notes, which are stored in an array, probably easier than typing frequencies or midi values directly into patterns and do things like transpose the entire sequence.
As with all SC classes you'll need to put it in the extensions folder and recompile the language before it'll work. The wickiTest file in the zip shows of some of the class methods, but it doesn't mention the startRecording and stopRecording methods. If you want to record an a array of notes you'll need to set it up by doing something like
m.startRecording
and then
m.stopRecording
when you're done.
Saturday, October 3, 2009
From Den Haag
It's a fantastic track and it's pretty rare to see the complete source for a song written entirely in SC, so it's worth a look.
Thursday, September 17, 2009
Comb Filter Effect
The gui should be mostly self explanatory I think, but if you want to use this with other inputs besides the test sound you'll need to set the input bus and send your sound through that.
// parrallel comb filters implemented as effect return
// send the synth defs(
(
SynthDef("ImpulseTest", {|bus = 3|
Out.ar(bus, [Impulse.ar(SinOsc.kr(0.23).range(0.5,23), 0.5)]);
}).send(s);
);
(
SynthDef("CombUnit",{| d1 = 0.001, d2 = 0.001, d3 = 0.001, d4 = 0.001, d5 = 0.001,
t1 = 1, t2 = 1, t3 = 1, t4 = 1, t5 = 1,
f1 = 20000, f2 = 20000, f3 = 20000, f4 = 20000, f5 = 20000,
vol = 1, inBus = 3, outBus = 0|
var in, out, c1, c2, c3, c4, c5;
in = In.ar(inBus, 1);
c1 = LPF.ar(CombC.ar(in, 1, d1, t1), f1);
c2 = LPF.ar(CombC.ar(in, 1, d2, t2), f2);
c3 = LPF.ar(CombC.ar(in, 1, d3, t3), f3);
c4 = LPF.ar(CombC.ar(in, 1, d4, t4), f4);
c5 = LPF.ar(CombC.ar(in, 1, d5, t5), f5);
out = (c1 + c2 + c3 + c4 + c5) * 0.2;
Out.ar([outBus, outBus + 1], out * vol);
}).send(s);
);
)
// create the synth
(
var grp, node, testNode, wComb, testRunning = 0, inputBus = 3;
s.sendMsg("s_new", "CombUnit", node = s.nextNodeID, 1, 1);
// s.sendMsg("g_new",grp = s.nextNodeID,1,1); // create group @ tail of default node
wComb = SCWindow("C O M A", Rect(100, 300, 720, 220))
.onClose_({
if(testRunning == 1, s.sendMsg("n_free", testNode));
s.sendMsg("n_free", node);
})
.front;
// input bus
SCNumberBox(wComb, Rect(10, 10, 30, 20))
.value_(3)
.action_({|v|
inputBus = v.value;
s.sendMsg("n_set", node, "inBus", inputBus);
if(testRunning == 0, s.sendMsg("n_set", testNode, "bus", inputBus));
});
SCStaticText(wComb, Rect(45, 10, 100, 20))
.string_("Input Bus");
// output bus
SCNumberBox(wComb, Rect(150, 10, 30, 20))
.value_(0)
.action_({|v| s.sendMsg("n_set", node, "outBus", v.value)});
SCStaticText(wComb, Rect(185, 10, 100, 20))
.string_("Output Bus");
// audio test
SCButton(wComb, Rect(300, 10, 100, 20))
.states_([
["Start Test", Color.green, Color.black],
["Stop Test", Color.red, Color.black]
])
.action_({
if(testRunning == 0, {
s.sendMsg("s_new", "ImpulseTest", testNode = s.nextNodeID, 0, 1, "bus", inputBus);
testRunning = 1;
},{
s.sendMsg("n_free", testNode);
testRunning = 0;
});
});
// comb frequencies
SCStaticText(wComb, Rect(10, 40, 100, 20)).string_("Comb Frequencies");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(10, 60 + (i * 25), 40, 20))
.value_(950);
SCStaticText(wComb, Rect(55, 60 + (i * 25), 15, 20)).string_("Hz");
SCSlider(wComb, Rect(80, 60 + (i * 25), 130, 20))
.value_(0.5)
.action_({|v| var time, freq;
freq = [1, 20000, 6].asSpec.map(v.value);
time = 1.0 / freq;
s.sendMsg("n_set", node, i, time);
box.value_(freq.asInteger);
})
};
// resonances
SCStaticText(wComb, Rect(250, 40, 100, 20)).string_("Resonances");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(250, 60 + (i * 25), 30, 20))
.value_(50);
SCStaticText(wComb, Rect(285, 60 + (i * 25), 15, 20)).string_("%");
SCSlider(wComb, Rect(300, 60 + (i * 25), 150, 20))
.value_(0.5)
.action_({|v|
s.sendMsg("n_set", node, i+5, [0, 9, 4].asSpec.map(v.value));
box.value_(v.value * 100);
});
};
// low pass frequencies
SCStaticText(wComb, Rect(555, 40, 100, 20)).string_("Low Pass Frequencies");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(490, 60 + (i * 25), 40, 20)).value_(20000);
SCStaticText(wComb, Rect(535, 60 + (i * 25), 15, 20)).string_("Hz");
SCSlider(wComb, Rect(555, 60 + (i * 25), 150, 20))
.value_(1)
.action_({ |v| var freq;
freq = [20, 20000, \exp].asSpec.map(v.value);
s.sendMsg("n_set", node, i+10, freq);
box.value_(freq);
});
};
// volume control
SCStaticText(wComb, Rect(10, 190, 70, 20)).string_("Volume");
SCSlider(wComb, Rect(80, 190, 625, 20))
.value_(1)
.action_({|v| s.sendMsg("n_set", node, "vol", [0, 1, 4].asSpec.map(v.value))});
)
Friday, August 21, 2009
More 140 character SuperCollider Tweets
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
Sunday, August 9, 2009
Recreating the THX sound
//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
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
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.
Thursday, June 18, 2009
A Generative Looper.
I can't get it to work at the moment but maybe it's just me.
Tuesday, June 16, 2009
More Dominator Deconstruction.
(
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.
Sunday, June 14, 2009
Deconstructing the Dominator
I thought I'd have a go myself, but I decided to take a more direct approach and look it up. I found this wikipedia article about it, it turns out that Human Resource were using a Roland Alpha Juno 2 to create that sound, a mid 80's digital/analogue hybrid synth. There's a good explanation of it's features here, importantly though, it does have a chorus unit built in, which Dan did identify as being the key feature of the sound.
Here's my re-construction attempt, I did start out to try and recreate the functions of an Alpha Juno 2, but in the end I mostly just improvised.
(
SynthDef(\aj2, {
arg freq = 440, gate = 1, lagLev = 0.01, predelay=0.01, speed=0.05, depth=0.01, ph_diff=0.5;
var width1, width2, width3, osc1, osc2, osc3, filterOut, mix, sig, modulators, numDelays = 8, lfo;
width1 = SinOsc.ar(4, 0, 0.8, 0.2).abs;
width2 = SinOsc.ar(6, 0, 0.8, 0.2).abs;
width3 = SinOsc.ar(2, 0, 0.8, 0.2).abs;
lfo = SinOsc.kr(5, 0, 5);
osc1 = Pulse.ar(Lag.kr(freq + lfo), width1);
osc2 = Pulse.ar(Lag.kr((freq/2) + lfo), 0.5);
osc3 = Pulse.ar(Lag.kr((freq*2) + lfo), width3);
mix = Mix.new([osc1, osc2, osc3]);
modulators = Array.fill(numDelays, {arg i;
SinOsc.kr(speed * rrand(0.94, 1.06), ph_diff * i, depth, predelay);});
sig = DelayC.ar(mix, 0.5, modulators);
sig = sig.sum;
Out.ar(0, sig.dup)
}).store
)
p = Pmono(\aj2, \dur, 0.24, \midinote, Pseq([40, 67, 64, 62, 62, 62, 62, 62], inf)).play;
I've got three pulse width modulated square wave oscillators here, modulated with low frequency SinOscs and some vibrato added with another low frequency SinOsc. These are put through a chorus efect taken from the ixi-audio.com tutorial, featured here before.
My patch is mostly based on random guesswork and a little bit of research, but it sounds okay, though probably not as good as Dan's scientific attempt.
Monday, June 8, 2009
2 channel bitcrusher
( var name, func, specs, componentType, componentSubtype, builder;
name = "Decimator"; // name of your plugin
func = {
| sampleRate, bitRate|
var decOut, in;
in = AudioIn.ar([1]); //Input from AU host
decOut = Decimator.ar(in, sampleRate , bitRate).dup;
Out.ar([0,1], decOut);//Output to AU host
};
specs = #[
[0, 20000 , \Linear, 10000,\Hertz ] ,
[0, 16 , \Linear, 8,\Indexed ]
];
componentType = \aufx;
componentSubtype = \DECI;
builder = AudioUnitBuilder.new(name, componentSubtype,func, specs, componentType);
builder.makeInstall;
)
Sunday, May 31, 2009
Tuesday, May 19, 2009
Simple Phaser effect.
(
SynthDef(\phaser, { arg out=0, in=0;
var input,dsig, mixed;
input = SoundIn.ar(in, 1);
dsig = AllpassL.ar(input, 4, SinOsc.ar(2, 0, 0.005, 0.005), 0);
mixed = input + dsig;
Out.ar([out, out+1], mixed);
}).load(s);
)
a = Synth(\phaser, addAction:\addToTail)
Very similar to flange, but with a shorter delay time and no feedback, it's got a more otherworldly sound.