Generating Pbinds for arbitrary synthdefs

Hello all

Something I find myself doing often when using my synthdefs is looking up all arguments and then copy/pasting them into pbinds to test them out with their default values so I wrote this silly function that takes a synthdef name as input and then spits out a pbind for it in the post window so I can easily copy-paste from there and have something to work from.

(
(
~postPatFor = {|synthDef=\default|
	var controls = SynthDescLib.global.synthDescs.at(synthDef).controls;
	"Pbind(%instrument, %%,".format("\\", "\\", synthDef.asSymbol).postln;
	controls.do{|control| 
		var name = control.name;
		var val = control.defaultValue;

		// Check that synth doesn't have a duration of 0 by default (making sc explode)
		val = if(name == \dur && val == 0.0, { 1.0 }, { val });
		"\t%%, %,".format("\\", name, val).postln
	};
	").play".postln;
};

~postPatFor.value(\default)

)

)

For the default synth this spits out:

Pbind(\instrument, \default,
	\t_gate, 1.0,
	\dur, 1.0,
	\attack, 0.0010000000474975,
	\release, 0.99000000953674,
	\out, 0.0,
	\freq, 442.0,
	\cutoff, 2500.0,
	\rq, 0.20999999344349,
	\pan, 0.0,
	\amp, 0.5,
).play

That you can then copy-paste to a document and play immediately.

8 Likes

This is very handy indeed!
Thanks for making this.
I am going to use it a lot.

I am not sure that this is helpful for anyone apart from myself at all but I made a few changes.
For my purposes this makes things more ready to use:

(
(
~postPatFor = {|synthDef=\fmx|
	var controls = SynthDescLib.global.synthDescs.at(synthDef).controls;
	"(
Pdef(0,
Pbind(
	%instrument, %%,".format("\\", "\\", synthDef.asSymbol).postln;
	controls.do{|control| 
		var name = control.name;
		var val = control.defaultValue;
		
		// Check that synth doesn't have a duration of 0 by default (making sc explode)
		val = if(name == \dur && val == 0.0, { 1.0 }, { val });
		"\t%%, %,".format("\\", name, val).postln
	};
	")
).play;
)".postln;
};
~postPatFor.value(\fmx)
)
)

I couldn’t figure out how to get it to adhere to cleaner indentation tho.

That’s cool. Hmm. Maybe I can hack this so that it spits out a Pbindef instead, even more useful!

I did this variation for my own library that spits out a Pdef, if that can be of inspiration (it’s very, very ugly but works !):


MKGenPat{
	*new{|synthDefName=\default, wrapInPdef=true, randomize=true|
		this.synthDefExists(synthDefName).if({
			this.postPatFor(synthDefName, wrapInPdef, randomize)
		})
	}

	*synthDefExists{|synthDefName|
		^SynthDescLib.global.synthDescs.at(synthDefName).isNil.not;
	}

	*postPatFor {|synthDef=\default, wrapInPdef=true, randomize=true|
		var controls = SynthDescLib.global.synthDescs.at(synthDef).controls;

		if(wrapInPdef, {"Pdef('%', ".format(MKSynthLib.emojis.choose).postln});
		if(wrapInPdef, "\t".post);
		"Pbind(".postln;
		if(wrapInPdef, "\t".post);
		"\t%instrument, %%,".format("\\", "\\", synthDef.asSymbol).postln;
		controls.do{|control| 
				var name = control.name;
				var val = control.defaultValue;

				// Check that synth doesn't have a duration of 0 by default (making sc explode)
				val = if(name == \dur && val == 0.0, { 1.0 }, { val });
				val = if(randomize && val.isKindOf(Number), { val * rrand(0.9,1.1) }, { val });
				if(wrapInPdef, "\t".post);
				"\t%%, %,".format("\\", name, val).postln
		};
		if(wrapInPdef, "\t".post);
		")".postln;

		if(wrapInPdef, {")".postln});
	}

}

This is wonderful, i was planning to write this for ages, i always forget what args are used by my synthdefs