I want to generate scsyndef files using a makefile. I use sclang and reference a file as follows, but sclang doesn’t exit when there’s an error. Is there some way around this?
// Define the first SynthDef and add it to the library
SynthDef("test1", { |out=0, freq=440, amp=0.5, pan=0|
var sig = SinOsc.ar(freq) * amp;
Out.ar(out, Pan2.ar(sig, pan));
asdf // Works fine without this line, but with it never exits.
}).writeDefFile("bin");
0.exit();
Ok, after trying this, it seems to do what you want.
fork {
// Define the first SynthDef and add it to the library
SynthDef("test1", { |out=0, freq=440, amp=0.5, pan=0|
var sig = SinOsc.ar(freq) * amp;
Out.ar(out, Pan2.ar(sig, pan));
}).writeDefFile("bin");
3.wait;
thisProcess.shutdown;0.exit;
}
I think I’m not being clear. I mean if there’s a syntax error. I couldn’t get either example to work if there’s a syntax error, in my example just typing in junk.
@smoge my original code worked without adding the syntax error. Why would I need the fork?
@jamshark70 the protect is for runtime errors I think?
Unless I’m misunderstanding, I didn’t see a solution when there is a syntax error?
I think there might be a risk of you exiting the process before evaluating and writing all your SynthDefs. The server is not running, but still I think there is a similar problem there, or I’m mistaken? I’d just give some time for the script before killing the language process.
Correct. If there’s a syntax error in the file, none of it will run and you’re hosed at that point.
I guess you could guard against syntax errors by starting sclang with a wrapper script that is carefully proofread, and this script would try to compile a script from another file. The outer script could detect syntax errors in the inner script if compileFile returned nil.
Additionally, I like the idea of building the synths as “modules” which I believe could load more quickly since they are already compiled. The rest of my project is built with makefiles, so just trying to duplicate that ability with sclang.
It reads the file and, if it compiles successfully, gives you a Function. Then you can .value the function. If compilation failed, it returns nil (IIRC). This way you can tell the difference between syntax error and execution returned nil.
OK, I think this solution works. The only question is if I could send a parameter rather than hardcode he “test.csd” file. If not, I suppose I could build a .scd file each time.
To my surprise, you can just declare args at the top of the scd file, even without braces. I really didn’t think that would work, but I tried it and it does, e.g.
test.scd:
arg xyz;
... Do stuff...
|| syntax isn’t allowed in this case, but the arg keyword does define parameters that you can then pass in the .value call.
Maybe I’m missing something @jamshark70 , but I want to pass the string “test.scd” to the compile.scd script when I call it with sclang. I’m exploring storing the name in a file, with little luck. Though it is cool you could pass args to writeDefFile.
One more update. I appears that sometimes the build can fail in such a way that it never exits. In my particular case I wanted to the output file to be named differently, as it always chooses the name of the last SynthDef in the .scd file. I initially tried to create a synthdef at the end:
SynthDef('basics');
But now I know it needs to be
SynthDef('basics', {});
This particular error cauesd my previous script to get stuck. So now I’m using the try code block mentioned before. Maybe not the last revision, but the best so far.