Trying to change parameters of Synth with MIDI (even when it's not playing)

I have a midi device of 16 knobs (cc# 1 - 16) and 4 buttons (cc# 17 - 20). The buttons only output a MIDI number of 127. It doesn’t toggle back and forth between 0 and 127 like a lot of other MIDI Devices do, one of the drawbacks to my device.

I have a simple sine synth. I want knob 1 (cc#1) to control the frequency. I have a control bus and a MIDIdef that controls this parameter. Then knob 2 (cc#2) to control amplitude, and I have a control bus and MIDIdef to control that too.

I’d like the sine synth to play once whenever I hit a button (#cc 17). And I’d like to control the frequecy and amplitude when the Synth is not playing, so when I hit the button (#cc 17) the knobs are turned to the frequency and amplitude I want.

Then I’d like to re-trigger the synth over and over again. The problem I’m running into is the synth will play only once, when it’s on the server. So, when I run the code:

~sinesynth = Synth.new(\sine, [\freq, ~cc2.asMap, \mul, ~cc3.asMap]);

The synth is on the server, and I run the code:

~togValue = 0;

MIDIdef.cc(\toggle, { |val|
    if(val > 0) {
        ~togValue = 1 - ~togValue;
        ~sinesynth.set(\gate, ~togValue);
    };
}, ccNum: 17);

I’m able to play the Synth ONCE, and it’s only the first item in the array for the frequency argument (when I’ve tried other items by turning the knob, it will only play the first item for the one time I can play the synth), but when I hit the button again (cc# 17), I get this error message:

FAILURE IN SERVER /n_set Node 3715 not found
FAILURE IN SERVER /n_set Node 3715 not found
FAILURE IN SERVER /n_set Node 3715 not found

The entire block of code I’m using is below:

~cc2 = Bus.control(s, 1).set(0);
~cc3 = Bus.control(s, 1).set(0.1);


MIDIdef.cc(\cc2, { arg val; ~cc2.set(val.linexp(0, 127, 0, 4)) }, 1, 0);
MIDIdef.cc(\cc3, { arg val; ~cc3.set(val.linexp(0, 127, 0.1, 0.9)) }, 2, 0);


(
SynthDef.new(\sine, {
	arg gate=0, freq, mul;
	var env, sig;
	env = EnvGen.kr(Env([0,1,0], [0.01, 1]), gate, doneAction:2);
	sig = SinOsc.ar(Select.kr(0, [100, 200, 400, 800, 1600]), 0, mul);
	Out.ar(0, env*sig.dup);
}).add;
)

~sinesynth = Synth.new(\sine, [\freq, ~cc2.asMap, \mul, ~cc3.asMap]);



~togValue = 0;

MIDIdef.cc(\toggle, { |val|
    if(val > 0) {
        ~togValue = 1 - ~togValue;
        ~sinesynth.set(\gate, ~togValue);
    };
}, ccNum: 17);

If you want to be able to re-trigger the synth use doneAction = 0, doneAction = 2 will remove the synth after a gate = 0 message once the envelope has finished the release part. Note that if you use this method, then re-triggering the synth happens from the second node of the envelope, for that reason it might be better to modify the envelope to:

EnvGen.kr(Env([0, 0, 1, 0], [0, 0.01, 1]), gate, doneAction:0)

I would also suggest reading the help files on Env and EnvGen carefully. The concept of an envelope is easy to imagine, but the precise way in which it works is a little more complex than you might realize at first (at least that was the case for me)

1 Like

Such a simple mistake. Thanks Thor. Yeah, I’ll read the help files for Env and EnvGen.

I fixed the frequency problem too. I’m a dummy. Forgot to add a ‘which’ argument for the Select array so I can change the frequencies.