Constants that are shared across Supercollider and c++

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 :slight_smile:

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.

  1. 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.
  2. 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:
  3. 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 :smiley:

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