Monophonic buffer playback?

What would be the best way for limiting synth polyphony on buffer playback? Do I need to create different groups, and then apply some node/synth limitation within the group - is it possible? Or is there more simple solution for monophonic playback with “addAction: \addReplace” argument? (I tried the last one, but without success, it always gives a "FAILURE IN SERVER /s_new Node 1 not found " error message.)

P.S With polyphony limit I mean restrictions that don’t allow more than one synth at time - when a new instance is triggered the previous one is immediately canceled.

IMO (I’m biased because I wrote the class), the easiest way to limit polyphony is with the ddwVoicer quark.

Otherwise, you’d have to work out your own way to keep track of which nodes are playing, and delete the oldest one when starting a new one. This is not terribly difficult if you’re reasonably familiar with arrays but it does take a bit of logic. I’m not at the computer now so I don’t have an example handy.

Welcome to the forum btw!
hjh

Ok, then server architecture and the nodes is the way to go. This is at least something, I try the quark later.

Non-Voicer way:

(
var n = 5;  // allow at most 5 nodes

var nodes = Array(n);

var playNode = { |args|
	if(nodes.size >= n) {
		nodes.first.release(0.01);
		nodes.removeAt(0);
	};
	nodes = nodes.add(Synth(\default, args));
	nodes.last
};

var stream = Pbind(
	\degree, Pwhite(-7, 7, inf),
	\dur, Pexprand(0.1, 0.4, inf),
	\sustain, 2
).asStream;

r = Routine {
	var event;
	var msgFunc = SynthDescLib.at(\default).msgFunc;
	var args;
	while {
		event = stream.next(Event.default);
		event.notNil
	} {
		var node;
		// here, I have to replicate some of the
		// value conversions that the default event
		// does automatically
		args = event.use {
			~freq = ~freq.value;
			~sustain = ~sustain.value;
			~amp = ~db.dbamp;
			msgFunc.valueEnvir
		};
		s.makeBundle(s.latency, {
			node = playNode.(args);
		});
		// schedule release
		thisThread.clock.sched(event[\sustain], {
			if(nodes.includes(node)) {
				s.makeBundle(s.latency, { node.release });
				nodes.remove(node);
			};
		});
		event.delta.wait;
	};
}.play;
)

r.stop;

Or, with Voicer:

v = Voicer(5, \default);

(
p = Pbind(
	\type, \voicerNote,
	\voicer, v,
	\degree, Pwhite(-7, 7, inf),
	\dur, Pexprand(0.1, 0.4, inf),
	\sustain, 2
).play;
)

p.stop;

hjh

1 Like