ddwPlug quark

FWIW – I just added temporary SynthDef caching for Plugs based on functions.

Before today’s change, the following pattern would generate a new SynthDef for the Plug for every event. With the change, only the first event creates a SynthDef and the rest reuse the same one.

(
p = Pbind(
	\type, \syn,
	\instrument, \default,
	\freq, Pexprand(200, 500, inf),
	\freqPlug, { |freq|
		// closed function here, possible to hit cache
		Plug({ |freqSynthArg|
			freqSynthArg * LFDNoise3.kr(3).exprange(0.95, 1.05)
		}, [freqSynthArg: freq])
	},
	\dur, Pexprand(0.2, 0.8, inf),
	\legato, Pexprand(0.7, 1.4, inf)
).play;
)

p.stop;

One usage had to be deprecated, though:

(
p = Pbind(
	\type, \syn,
	\instrument, \default,
	\freq, Plug {
		exprand(200, 500) * LFDNoise3.kr(3).exprange(0.95, 1.05)
	},
	\dur, Pexprand(0.2, 0.8, inf),
	\legato, Pexprand(0.7, 1.4, inf)
).play;
)

Without caching, there’s a new exprand value per event. Now there’s only one, the first time. I think it’s a good trade-off, though, because, when Jordan’s improved SynthDefs optimizations land, it will be more expensive to build the same SynthDef repeatedly. Now it will skip the rebuild in common sequencing cases.

hjh

1 Like

This is a really cool idea!

Does this depend on any other quarks?

One thing I was thinking about was that it would be nice to have some kind of recommendations or spotlight for quarks, perhaps that updates 3 times a year? This could be linked to in the help browser, but still be a webpage. As both the quarks gui and this forum aren’t ideal to search through.


FYI, you will be able to disable certain optimizations.

I’ll also add a little helper to do this with useful defaults for this exact situation, where you need reasonably fast compile times.

Something like this…

Synthdef.newFast(...)

Another option might be to disable the deduplication (which is the slow bit) when you have less than, say 20 ugens?

for searching Quarks there’s https://baryon.supercollider.online

I’ve just pushed an experimental branch implementing a couple of new features. They’re not well tested yet, so I’m not merging them into main right away.

One could be considered a bugfix: If you’re modulating a main synth control using a Plug, this could effectively move the access point for .set-ting that parameter from Syn to Plug. If you have more than one layer of modulation, previously it didn’t work. That’s fixed now. There’s an example in the updated help file.

The second is something that I’ve wanted to make work correctly for awhile. I had tried to use Plug implement filter frequency key tracking (to raise the filter frequency when the note frequency goes up). This was fine for a single note, but the old parameter mapping implementation didn’t adjust the key tracking when .set-ting \freq. Now you can tell the ffreq plug that it should be interested in the note frequency:

(
SynthDef(\filterKeyTrack, { |out, ffreq = 1000, freq = 440, baseFreq = 220, ratio = 1.7|
	var adjust = Lag.kr(freq, 0.08).log2 - baseFreq.log2;
	Out.kr(out, (ffreq * (ratio ** adjust)).clip(20, 20000));
}).add;

SynthDef(\sawFilt, { |out, gate = 1, freq = 440, ffreq = 1000, rq = 0.8, amp = 0.5, detun = 1.008|
	var sig = Saw.ar(Lag.kr(freq, 0.08) * [1, detun]).sum;
	sig = BLowPass4.ar(sig, ffreq, rq);
	sig = sig * EnvGen.kr(Env.adsr(0.01, 0.3, 0.6, 0.1), gate, doneAction: 2);
	Out.ar(out, (sig * amp).dup);
}).add;
)

TempoClock.tempo = 132/60;

(
p = Pmsyn(PmonoArtic(\sawFilt,
	\degree, Pxrand([0, 2, 3, 4, 7, 9], inf),
	\octave, Pwrand([3, 4, 5], [0.6, 0.3, 0.1], inf),
	\scale, [0, 1, 3, 5, 7, 8, 10],
	\dur, Pwrand([0.25, 0.5], [0.8, 0.2], inf),
	\legato, Pwrand([0.4, 1.05], [0.3, 0.7], inf),
	\ffreq, 300,
	\ffreqPlug, { |ffreq, freq|
		Plug(\filterKeyTrack,
			[ffreq: ffreq, freq: freq, baseFreq: 65, ratio: 2.2],
			map: (freq: \freq)
		)
	}
)).play;
)

p.stop;

Without the map: line, the filter frequency stays low and the higher notes are less clear; with the map, the note frequencies always get communicated to the key tracking synth, so the upper notes are brighter.

To try, check out the topic/refactorMap branch in GitHub - jamshark70/ddwPlug: SuperCollider dynamic per-note synth patching .

hjh

Found bugs in the previous approach, which are fixed now – if you tried the refactorMap branch, better update it.

hjh