Basic question - getting value from MIDI controller


#1

Hey, I’m new to SuperCollider, so please excuse a very basic question. I’m trying to just control the frequency of a SinOsc with a MIDI-controller slider. Why doesn’t this work, and how can I get it to work? (Isn’t global-variable “a” just being set to the incoming value from the MIDI controller?

s.boot;
(
SynthDef(\testOsc, {
    | freq=440 |

    Out.ar([0, 1], SinOsc.ar(freq, 0, 0.5));
}).add;
)

(
MIDIClient.init;
MIDIIn.connectAll;
a = MIDIFunc.cc({arg first; first.postln}, 13, 0);
z = Synth.new(\testOsc, [\freq, a]);
z.scope;
)

#2

i think from the docs that you’re using it wrong. see one of the examples from the bottom of http://doc.sccode.org/Classes/MIDIFunc.html

b = MIDIFunc.cc({arg ...args; args.postln}, 1, 1); // match cc1, chan 1
b.free; // cleanup

the first argument to .cc is a callback function which is called on every midi event and the arguments ...args contains the stuff you want, so you need to put the logic inside the cb function. see the func description here for how to craft it http://doc.sccode.org/Classes/MIDIFunc.html#*new and get the midi values.


#3

Hi htor,

Thanks for your help. Since ...args returns an array, a[0] should return the first value of that array (or b as you have it), correct? However, this still does not work:

z = Synth.new(\testOsc, [\freq, a[0]]);

#4

Ah, okay, I think I understand better. We need to set a variable to the value of arg[0] with an anonymous function inside of MIDIFunc.cc. Am I close with this one? (Still doesn’t compile unfortunately…)

(
MIDIClient.init;
MIDIIn.connectAll;
a = MIDIFunc.cc({arg ...args; v = args[0] }, 13, 0);
z = Synth.new(\testOsc, [\freq, v]);
z.scope;
)

#5

Just setting a variable won’t update the synth. (It takes the value of the variable at the time of constructing the synth and doesn’t keep a “link”.) What you can do instead depends on what you want to achieve:

  1. if you want to update the frequency of an already sounding synth, you can use the set method in the MIDIFunc.cc, e.g. z.set(\freq, args[…]). Make sure the Synth is already alive before you try to call set on it.

  2. if instead you want to sound a completely new note at the time of receiving a cc message, you can instantiate a new Synth in the MIDIFunc

To get a feeling about the contents of arguments like arg or args, you can use methods like postln or debug(“my message”), e.g. args.debug(“value of args”) in the MIDIFunc. These will print out the contents to the post window.