Showing posts with label Pmono. Show all posts
Showing posts with label Pmono. Show all posts

Monday, February 23, 2009

Portamento

Before I do anymore GUI stuff a quick addition to my Moog synth itself, portamento!

Also known as slide or glissando, it's a nice feature of many analogue synths, here's the wiki page on it if you're not sure what I'm talking about. 

I've been wanting to add this to my synth since I created it but I thought it might be difficult, but after putting my faith in the hand of providence and searching the SuperCollider user mailing list, I found simple that portamento is in fact dead easy.

Here's my revised SynthDef 


 SynthDef("Moog",{

arg 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 oscArray = [Saw.ar(Lag.kr(freq, lagLev)), SinOsc.ar(Lag.kr(freq, lagLev)), Pulse.ar(Lag.kr(freq, lagLev))];
var oscArray2 = [Saw.ar(Lag.kr(freq, lagLev)), SinOsc.ar(Lag.kr(freq, lagLev)), Pulse.ar(Lag.kr(freq, lagLev))];
var ampEnv = EnvGen.ar(Env.adsr(attack, decay, sust, rel), gate, doneAction:2);
var filterEnv = EnvGen.ar(Env.adsr(attackf, decayf, sustf, relf), gate, doneAction:2);
var osc1 = Select.ar(oscType, oscArray);
var osc2 = Select.ar(oscType2, oscArray2);
var fade = Pan2.ar(XFade2.ar(osc1, osc2, pan , level * ampEnv, 0));
var filter = MoogFF.ar(fade, cutoff * filterEnv, gain);
Out.ar(0,filter)

}).store
)

All I've done here is encapsulated each of my frequency arguments for the oscillators in a lag Ugen. The slide time, or the time it takes for the pitch of each note to move from it's original value to the new note is set by the lagLev argument, in seconds.

To make this work you'll need to use a Pmono pattern, it won't work if a new synth is created with each note as it would be with a  Pbind pattern. 

And that's Jazz. 



Sunday, February 22, 2009

A simple GUI

Controlling a synth with text isn't always intuitive, so I've decided to start working towards creating a GUI for my little Moogesque synth. 

To begin with I've created a very simple interface with two sliders that allow me to control the filter cutoff frequency and the resonance gain. 

Here's the Moog synthdef again. 


 SynthDef("Moog",{

arg 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;


var oscArray = [Saw.ar(freq ), SinOsc.ar(freq), Pulse.ar(freq)];
var oscArray2 = [Saw.ar(freq), SinOsc.ar(freq), Pulse.ar(freq)];
var ampEnv = EnvGen.ar(Env.adsr(attack, decay, sust, rel), gate, doneAction:2);
var filterEnv = EnvGen.ar(Env.adsr(attackf, decayf, sustf, relf), gate, doneAction:2);
var osc1 = Select.ar(oscType, oscArray);
var osc2 = Select.ar(oscType2, oscArray2);
var fade = Pan2.ar(XFade2.ar(osc1, osc2, pan , level * ampEnv, 0));
var filter = MoogFF.ar(fade, cutoff * filterEnv, gain);
Out.ar(0,filter)

}).store
)

I've added a panner to it to center the sound, but other than that it's the same for now. 

This is my GUI code. 

It should be cross platform but I've only tried it on OS X.  

(
var window = Window.new("",Rect(400, 400, 140, 100)).front;
var cutoffSlider, cutoffRef, resgainSlider;

~resgainRef = PatternProxy(3);
~cutoffRef = PatternProxy(440);



cutoffSlider = Slider.new(window,Rect(10, 25, 100, 20));
 cutoffSlider.action_{
 var val;
 val = (10000*(cutoffSlider.value));
 val.postln;
 ~cutoffRef.source_(val);
  };


StaticText.new(window,Rect(10, 5, 100, 20))
 .string_("Cutoff")
 .action_{|v| };


resgainSlider = Slider.new(window,Rect(10, 65, 100, 20));
 resgainSlider.action_{
 var val;
 val = (4*(resgainSlider.value));
 val.postln;
 ~resgainRef.source_(val);
  };


StaticText.new(window,Rect(10, 45, 100, 20))
 .string_("Resonance Gain")
 .action_{|v| };
)

and here's a pattern incorporating the GUI elements I've created. 

(
Pmono("Moog",
 \freq, Pseq([440, 550, 660, 770, 660, 880], inf),
 \dur, 0.2,
 \oscType, Pseq([1,0,1,0,1], inf),
 \oscType2, Pseq([0,0,2,2,1], inf),
 \cutoff, (~cutoffRef),
 \gain, (~resgainRef)

).play


This time I've used a Pmono for a more authentic sound, but more on that later...