Control a parameter from a midi controller

Hello,

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?!

OffsetOut.ar(0, sound);

}.play;

)

Thanks!

Ray

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. :slight_smile:

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);    
)
1 Like

oh my god, that’s it! I’ve got it working now, thank you so much for taking the time and effort, I really appreciate it!! :slight_smile: :slight_smile: :slight_smile:

1 Like