Teaser: ddwPlug quark

Did you ever want to patch a signal directly to a synth argument?

Watch this… all sounds produced from the (modulation-deficient) \default SynthDef.

Also, search here for “superstructure” and… nobody is talking about this except me :laughing: – now it’s not only talk.

hjh

14 Likes

I’ve put up a preliminary version.

Quarks.install("https://github.com/jamshark70/ddwPlug.git");

Here’s a pattern playing \default with enveloped vibrato:

(
p = Pbind(
	\type, \syn,
	\instrument, \default,
	\dur, Pwhite(1, 5, inf) * 0.25,
	\legato, 0.98,
	// frequency stuff
	\degree, Pwhite(-7, 7, inf),
	\freqPlug, { |freq|  // <-- base value gets patched here
		// lazy: I'll just use an ad-hoc function
		Plug({ |freq, depth|
			(depth ** LFTri.kr(4)) * freq
		}, [
			freq: freq,
			depth: Plug({ EnvGen.kr(Env([1, 1.06], [0.7], 4)) })
		])
	}
).play;
)

p.stop;

(Edit: I documented the Syn class, but not Plug yet… soon.)

hjh

4 Likes

One big piece that I didn’t have working before is the ability to add Plugs after the fact. This is now prototyped but not documented yet. (I’ll check it into the public repository after a bit more testing, and documenting it.)

Here’s a quick video starting with default parameter values for the default SynthDef. Then, the familiar set interface 1/ changes a numeric value and 2/ patches a Plug (synth) into freq. Now, at risk of banging the drum perhaps a little too much – when someone asks how to run a signal into a synth parameter, the story so far is that it’s time to learn about buses and mapping (and probably order of execution, especially for audio signals). With this alternate architecture, the story is “just set the control to a Plug instance.”

And of course, new controls exposed by new Plugs can themselves be set to Plugs.

Now… c’mon: this is pretty cool. It seems to answer a long-standing problem.

hjh

4 Likes

That looks extremely appealing, looking forward to trying it out.

Yes that looks quite intuitive - seems to blur the boundaries with Ndef.

OK, pushed the latest changes @ GitHub - jamshark70/ddwPlug: SuperCollider dynamic per-note synth patching .

It is somewhere in between Synth and Ndef. Ndef is good for relatively persistent structures, long-lasting, with easy and comprehensive malleability. Syn is not quite as flexible in terms of on-the-fly routing, but it’s disposable and it’s designed for polyphony. If you want to throw a bunch of signals on the table and patch them arbitrarily, Ndef (NodeProxy) would be the way to go. If you want to play a polyphonic pattern with a SynthDef and dynamically add modulation that wasn’t written into the original SynthDef, Syn is made for this (while NodeProxy would be clumsy).

I also designed it around Synth’s interface because everybody knows Synth, and the simple case of Syn (no plugs) is basically identical to Synth. Syn.new, set, release, free are the main operations and those are generally compatible (with extensions for ‘set’ especially, because of the tree structure). If there were interest, Syn could even be moved into core, and the help updated to steer new users toward Syn, and then everybody gets improved patchability for free. Now… I’m not seriously proposing this (it’s way premature). But I could imagine it.

I decided to do this now because, in my live coding set up, I was getting frustrated with limitations of my prepared instruments. If I wanted to modulate a parameter in some way, or pass the signal through some per-note fx on the way out, previously, the only way was to copy the SynthDef, add stuff to it, and add another variant of the Factory wrapper – a lot of pollution in the codebase. This way, I can just set a property xxxPlug in the player process, and the Event type uses Syn to wire it up for me. I should even be able to save the plug-ged setting as a preset if I like the result.

Early in my SC time, I had thought to use crucial library nested Patches as composable Voicer sources, but a Patch is bound to specific buses, so polyphony never really worked, and I stopped using it. So this is an almost 20-year wishlist item for me, finally achieved.

hjh

1 Like

It is so good! Will you include it in a core library? (I hope…)

I think it’s premature to add it to core. I have a few test cases which cover a lot of territory, but I don’t have a good sense at this time of what I missed (except that I realize offhand that I’ve done very little testing of arrayed arguments – I can think of one potential bad behavior, just didn’t have time to check it yet).

Also, I haven’t adapted Pmono yet. I think that would be essential.

I think if anyone’s interested in promoting this approach, the best thing to do would be to download it and use it, a lot, and log bugs. It needs to get beaten up a bit in a larger range of real-world use cases. For my part on that, I’ll probably switch my live coding instruments to use Syn under the hood, and then just jamming is also testing.

hjh

3 Likes