I’m a newbie and I fear this is a basic question, but I have searched high and low for an answer and can’t seem to get one.
I simply want to be able to use my MIDI controller to control parameter values for effects I am creating in SuperCollider. For example, let my controller’s control value 1 affect the pitch of an oscillator. Here is a bit of simple code that explains my issue. When I adjust the MIDI controller’s knob, the “val.postln” code works and shows that my controller is getting through to SuperCollider. However, the pitch of the oscillator is not affected.
(
{
var sound, cc1=0.5;
MIDIClient.init;
MIDIIn.connectAll;
MIDIFunc.cc({|val, ccNum, chan, src|
val.postln; //this totally works!
cc1=val/127; //why isn’t this updating the value of cc1 used below
}, ccNum:1);
sound = SinOsc.ar(20 + (cc1*1000)); //even when val.postln is indicating changes, cc1 doesn’t change and the pitch of the oscillator remains constant. How do I need to code this so that the pitch changes when I move controller 1?!
Please try to wrap your code in three backticks ``` so it’s is displayed correctly! You can edit your original post with the three-dots menu.
You’re running into a fundamental distinction in SuperCollider that can be tricky when you first start. SynthDefs define a signal processing chain that can be run in the form of a Synth. Calling play on a function:
{
var sound;
sound = SinOsc.ar(100);
sound;
}.play
is shorthand for something like:
// describe the Synth
SynthDef(\temporarySynth12345, {
var sound;
sound = SinOsc.ar(100);
Out.ar(\out.kr(0), sound)
}).add;
// play it
Synth(\temporarySynth12345);
The code in a SynthDef / in a function you’re playing is only a description of the signal flow for the synth. it’s only executed ONCE - the structure is captured and turned into a Synth running on the audio server. In your case, your cc1 value is read ONCE, when you create the Synth - this value is baked into the Synth itself and never changes - this code is not re-executed and isn’t in any way live, so changes to cc1 are not reflected in your running Synth.
If you want to send values to a running Synth, you need \controls - these can be set from the outside. I’d suggest running through some tutorials on making SynthDefs, or possible the documentation a bit. But here’s a really simple example of I think what you were aiming for:
(
var synth, cc1=0.5;
MIDIClient.init;
MIDIIn.connectAll;
// Define your synth
SynthDef(\simpleSine, {
var sound, cc1;
cc1 = \cc1.kr(0.5); // a control called cc1
sound = SinOsc.ar(20 + (cc1 * 1000));
OffsetOut.ar(0, sound);
}).add;
MIDIFunc.cc({|val, ccNum, chan, src|
val.postln; //this totally works!
~synth.set(\cc1, val / 127);
}, ccNum:1);
)
(
// Play it
~synth = Synth(\simpleSine);
)