For what it’s worth… after fixing a lot of bugs in the original prototype, and after trimming it down and simplifying it for regular SynthDefs, I now have some code where I can do this:
SynthDescDecompiler.fromDescLib(\default).streamOut;
… and get…
SynthDef('default', {
var x0 = Control.names(['out']).ir([0]);
var x1 = Control.names(['freq', 'amp', 'pan', 'gate']).kr([440, 0.1, 0, 1]);
var x2 = VarSaw.ar(x1[0], 0, 0.3);
var x3 = (x2 * 0.3);
var x4 = Linen.kr(x1[3], 0.01, 0.7, 0.3, 2);
var x5 = Rand.new(-0.4, 0.0);
var x6 = (x1[0] + x5);
var x7 = VarSaw.ar(x6, 0, 0.3);
var x8 = (x7 * 0.3);
var x9 = Rand.new(0.0, 0.4);
var x10 = (x1[0] + x9);
var x11 = VarSaw.ar(x10, 0, 0.3);
var x12 = (x11 * 0.3);
var x13 = Sum3(x12, x8, x3);
var x14 = Rand.new(4000, 5000);
var x15 = Rand.new(2500, 3200);
var x16 = XLine.kr(x14, x15, 1, doneAction: 0);
var x17 = LPF.ar(x13, x16);
var x18 = (x17 * x4);
var x19 = Pan2.ar(x18, x1[2], x1[1]);
var x20 = OffsetOut.ar(x0, [x19[0], x19[1]]);
})
If you .add
this and play it, it does sound like the original default SynthDef.
So (in theory), you could read a SynthDesc from a .scsyndef file, run this class on it, and get something that will probably work (although, as noted before, it scores pretty low on readability).
I’m pretty sure it’s not completely finished. There are a lot of UGen special cases that I haven’t found. (In most UGens, the order of inputs written in ar
or kr
matches the order of inputs in the object. Several of them reorder the inputs: EnvGen, Klang/Klank, even PlayBuf etc. has numChannels
which has to be inferred from the size of the output channels array. Those have to be handled individually, and I haven’t made a comprehensive review.) And it doesn’t try to find parallel chains and collapse them into a loop. But I think it already covers a lot of territory.
hjh