Is there any way to get original SynthDef code back from .scsyndef file?

Hi.
I wish everyone is being well.

When I excute code below, It post out the source code of ‘default’ SynthDef.

SynthDescLib.global.synthDescs[\default].def.postcs;

In the same way,
I made another SynthDef, save it as .scsydef file, load to SynthDescLib.global, then try same way.

But It doesn’t responds as it was.

SynthDef()
-> SynthDef:nil

I wonder why there is such a difference.
And I wonder if there is any other way to read the SynthDef’s code back.

Thank you very much.

No.

You’re asking if a binary SynthDef can be decompiled into the original source code. That’s completely impossible in every sense.

Someone very clever might be able to figure out a way to write some kind of source code that would produce the same arrangement of unit generators. But I don’t recall hearing of anyone actually doing it. I’d be happy to be wrong about that, though.

hjh

Thanks for your clear explanation.

I was thinking it would be great if there was a feature within SuperCollider that allows saving synthdef files which can be edited later.

Have a good day!

Best way to do that and retain how you coded it is as an .scd file.

The binary representation has gone through optimizations and sorts that increase efficiency, but would greatly decrease readability.

/*
Josh Parmenter
www.realizedsound.net/josh
*/

I presume you are aware of the SynthDef store method? It does save the defFile, and loads it. The file is kept so you can retrieve it.

or maybe I am missing what you are trying to do.

What the OP wants is to save a binary scsyndef file, and then do some process on the binary file to recover the original source code, character for character, to be able to edit it.

… which is a very complicated way to approach something that can already be done in a simple, direct way (by saving the source code).

hjh

2 Likes

What the OP wants is to save a binary scsyndef file, and then do some process on the binary file to recover the original source code, character for character, to be able to edit it.

Yes, you’re right.

Thanks!

ok since that is not possible then maybe @josh proposal via mine is the least worse option short of miracles :slight_smile:

For what it’s worth – I’ve made some progress toward this (in a different, somewhat more complex context). The resulting code is fairly well ludicrous and not especially intelligible, but it might be useful in cases where you have a scsyndef file for which the original code was lost. It’s absolutely not anything close to the original source code! Be clear about that. But in some emergency cases, it may be better than nothing.

hjh

1 Like

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

4 Likes