MIDIdef.noteOff & UGen release

hi everyone, I have this noob problem, I’m trying to interface a midi controller with SuperCollider and I’m trying this example of managing MIDI notes; everything works, but what I’m noticing is that the number of UGens in the server keeps growing and the UGens they seem not to be released;

can you help me? thank you

 ( 
SynthDef(\moog, {arg freq=440, amp=0.1, gate=1; 
    var signal, env; 
    signal = VarSaw.ar([freq, freq+2], 0, XLine.ar(0.7, 0.9, 0.13));   
    env = EnvGen.ar(Env.adsr(0.001,1,0,0.5), gate, doneAction:2); 
    Out.ar(0, signal*env); 
}).add; 
) 

( 
a = Array.fill(127, { nil }); 
MIDIdef.noteOn(\myOndef, {arg vel, key, channel, device;  
    a[key] = Synth(\moog, [\freq, key.midicps, \amp, vel/127]); 
     
    [key, vel].postln;  
}); 
MIDIdef.noteOff(\myOffdef, {arg vel, key, channel, device;  
    a[key].release; 
    [key, vel].postln;  
}); 
)

this is my status bar after some time i’m playing with the midi keyboard :

38,4 |< % 1e+01% 819u 91s [sclang]

Hi,

I tested this and it works. I haven’t tested it with an actual MIDI controller though.
I’ve modified the code a bit for debugging:


( 
a = Array.fill(127, { nil }); 
MIDIdef.noteOn(\myOndef, {arg vel, key, channel, device;  
	if(a[key] != nil, {
		a[key].release
	});
    a[key] = Synth(\moog, [\freq, key.midicps, \amp, vel/127]); 
     
	[key, vel].post; " on".postln;
}); 
MIDIdef.noteOff(\myOffdef, {arg vel, key, channel, device;  
    a[key].release; 
	[key, vel].post; " off".postln;
}); 
)

MIDIIn.doNoteOnAction(0, 0, 36, 127); // Test
MIDIIn.doNoteOffAction(0, 0, 36, 127);

On which OS are you, and which version of SC?
I’ve tested this on OSX 10.15 and SC 3.12.2

Linux Ubuntu 20.10 groovy
SuperCollider 3.10.4

your test, with only one single MIDIIn.doNoteOnAction and on single MIDIIn.doNoteOffAction, work, but if i use VMPK as MIDI Controller, i have the same result:

17,20 |< % 1e+01% 432u 48s

than I have evaluated this code snippet twice :

(                                                                                 
MIDIIn.doNoteOnAction(0, 0, 36, 127); // Test                                     
MIDIIn.doNoteOffAction(0, 0, 36, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 37, 127); // Test                                   
MIDIIn.doNoteOffAction(0, 0, 37, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 38, 127); // Test                                     
MIDIIn.doNoteOffAction(0, 0, 38, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 39, 127); // Test                                    
MIDIIn.doNoteOffAction(0, 0, 39, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 40, 127); // Test                                    
MIDIIn.doNoteOffAction(0, 0, 40, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 41, 127); // Test                                     
MIDIIn.doNoteOffAction(0, 0, 41, 127);                                            
MIDIIn.doNoteOnAction(0, 0, 42, 127); // Test                                     
MIDIIn.doNoteOffAction(0, 0, 42, 127);                                            
)

and i have :
4% 4% 126u 14s

the UGens seem not to be released;

if i use a Pbind, there is no increase in UGens number;

~play=Pbind(\instrument,\moog,\octave,5,\degree,Pseq([0,1,2,3,4,5,6,7].pyramid,inf),\amp,1,\dur,0.3);

~play.play;

I think if you’re calling

MIDIIn.doNoteOnAction(0, 0, 36, 127);                                      
MIDIIn.doNoteOffAction(0, 0, 36, 127);    

at the same time, the noteOn hasn’t registered a synth yet (waiting for server response), while noteOff want to release it already, so that leaves an unreleased synth.
I have the same behavior (7s per call).

Perhaps you can try to add a channel number in the MIDIdef?
The problem seems to happen when using a controller, I’ll try this this afternoon with a controller.

1 Like

with SystemClock which triggers the release after 5 seconds, I can contain the increase of the number of UGens, but playing very fast on the MIDI keyboard, however many UGens are not released;

MIDIdef.noteOff(\myOffdef, {arg vel, key, channel, device;   
    SystemClock.sched(5, {a[key].release;}); 
    [key, vel].post; " off".postln; 
});  
) 

My MIDI keyboard works, 0 UGens left.
Perhaps DetectSilence is an idea?

( 
SynthDef(\moog, {arg freq=440, amp=0.1, gate=1; 
    var signal, env, out; 
    signal = VarSaw.ar([freq, freq+2], 0, XLine.ar(0.7, 0.9, 0.13));   
    env = EnvGen.ar(Env.adsr(0.001,1,0,0.5), gate, doneAction:2); 
	out = signal * env;
	DetectSilence.ar(out, doneAction: 2);
    Out.ar(0, out); 
}).add; 
)
1 Like

your Synth works, but in reality I think that the problem I had was due to the vmpk MIDI client for Linux that somehow is too immediate in sending the noteOFF; because with another Akai MPK MIDI keyboard, I have tried it now, the other synth works without the DetectSilence.ar; thank you very much for your help anyway;

I think there is a thread somewhere on this site with a similar issue. I think the suggestion was to add Impulse.kr(0) to your gate like this:

EnvGen.ar(Env.adsr(0.001,1,0,0.5), gate + Impulse.kr(0), doneAction:2);

This will ensure the gate is opened and can effectively be closed.

1 Like