I want to have one place I define constants and reference them from both c++ and SuperCollider. I figure I can create a tool to generate a C++ header and some kind of file that can be included in multiple .SCD files, but I don’t understand how to create a constant that can be shared like this.
Currently I have a main .scd file which I supply to sclang. Then in my c++ code I load SynthDefs from a binary .scsyndef file that I load using OSC and /d_loadDir. This all works marvelously.
Is there a way I can define a single file (like an include) and put it in multiple places which contains constants I can reference?
Thanks,
Paul
C++ and sclang are completely different languages, so you can’t do that. What you can do is generate a .sc
or .scd
file and a corresponding C++ header file. For example, with CMake this can be done with configure_file
(configure_file — CMake 3.30.1 Documentation).
Right, my plan was to generate both a header file and .scd file from a generic source. [thanks for the configure_file option in CMake, I didn’t know about that] What I don’t know is how to create an .scd file that can be included into multiple places?
What do I use to include a file? Should I use this? Where do I put it? [I tried this and it doesn’t work]
executeFile("path/to/myConstants.sc");
And how should I define the constants? I saw example using a class and const, but sclang complained about that syntax. Also, I found a post mentioned that the “const” identifier wasn’t very useful. I tried this below, but it failed, though now it seems it doesn’t like the underscore?
var MY_CONST = 7;
Or should I use a global with tilde? Does that make it global to call other .scd files automatically?
I’m continuing to experiment, but is there a standard way?
I found a way that works, but now just wondering if this is the best way? ChatGTP helped me with this
TriggerIDs.sc:
(
~triggerFootMainGate = 43;
)
Main.scd:
s.boot;
s.waitForBoot
{
var mOut;
this.executeFile(thisProcess.nowExecutingPath.dirname ++ "/TriggerIds.sc");
o = OSCFunc({
arg msg, time;
// Paams are: NodeId, -1, TriggerId, Volumne, Buf, Loop, GateVal
if(msg[2] == -1 && msg[3] == 40, { ~sendFootTrigger.value(msg[5], msg[4], msg[6], msg[7]) });
if(msg[2] == -1 && msg[3] == ~triggerFootMainGate, { if(~previousSampler.isKindOf(Synth), {~previousSampler.set(\gateval, msg[4]) }); });
},'/trg');
}
Util.scd: (that build into scsythdef’s)
this.executeFile(thisProcess.nowExecutingPath.dirname ++ "../TriggerIds.sc");
[
SynthDef(\trigDetector, {
arg ctlBus, deviceId;
...
]
If you use a SC class file (.sc
) and put it into the extension/Quark directory, you wouldn’t have to manually include it. It could look like this:
MyConstants {
classvar <foo = 1;
classvar <bar = 2;
}
(<
makes sure that the members are read-only)
Then you can simply access your constants like this:
MyConstants.foo; // -> 1
MyConstants.bar; // -> 2
1 Like
This worked, but here are some issues I ran into trying to get it work.
- The location for me was /root/.local/share/SuperCollider/downloaded-quarks. I figured this out by looking at the output of sclang. Not sure if this is different on every system.
- The variable name can’t start with a capital or you get a strange “ERROR: syntax error, unexpected CLASSNAME, expecting NAME or WHILE”. Forgot about this rule, but the error text didn’t help me one bit slight_smile:
- You need to install the quark using Quarks.install, but just once. Afterwards, if these a problem in your code, like using capitals, you will get an error when you try to run any .scd file.
Thanks @Spacechild1 !
Naturally, this is different on every OS. Note that you can also add your own search paths to sclang.
The variable name can’t start with a capital
Good ol’ sclang
You need to install the quark using Quarks.install, but just once.
No, you don’t need to install it as a quark. For example, you can just put it into the extension directory (see Platform.userExtensionDir
), but again, you can also add your own custom search path. Have a look at the LanguageConfig
class!
1 Like