Triggering a synth exclusively until it's freed

Hello everyone,

for an art show visitors can trigger long sounds (bufplay) through Midi NoteOne.

Sounds should be triggered exclusively to avoid stacking. Imagine a nervous kid hitting the trigger :slight_smile:

Is there a smart way that a synth can only be triggered if the previous one has freed it self?

Any hints are welcome. Cheers, Bernhard

If you know how long the synth lasts you can store the time it was last created and check enough time has past.

If not, you can use onFree to set a flag.

Thanks Jordan.

Think I can do somthing with the undocumented Ugens PlayBufAlt, PlayBufCF or PlayBufFree.

I found a help file elsewhere:

https://quark.sccode.org/wslib/wslib-help/PlayBufCF.html

PlayBufCF does a crossfade. That’s ok as well for avoiding stacking of sounds. If I put MIDIFunc for triggering inside the synth I schould be fine…

I never used onFree nor the Interface class. Totally dummy here…:frowning:

With plain SC (and I’m not at the computer, so I might miss some details) – if you declare a variable outside the response function, then you can remember how much time passed, and use that to decide whether to fire or not.

var lastTime = -1000;

MIDIdef.noteOn(\trigger, { |vel, note|
    var now = SystemClock.seconds;
    if(now - lastTime > ... fill in your wait time here ...) {
        ... play your synth ...
        lastTime = now;
    }
});

Or, if you don’t need it to be 100% exclusive but you’d like to suppress excessive triggers coming in too fast – I made a SC version of the Max speedlim object – ddwSpeedLim quark (not sure of the caps, maybe it’s ddwSpeedlim). You’d write a SpeedLim object into the MIDIdef (in place of the function) and then it would respect the minimum time that you give it – if that time is 0.5, then the kid could keep smacking the button at top speed but it would trigger only twice per second.

hjh

If you use NodeWatcher, you can check if the synth is playing before making a new one:

(
x = nil;  // x holds synth

MIDIdef.noteOn(\trigger, { |vel, note|
	
	if (not(x.class == Synth and: {x.isPlaying})) {
		x = Synth.new("default");
		NodeWatcher.register(x, true);
	}
	
});
)

x.free;

Best,
Paul

Thank you Paul, this works perfectly!