Exporting SuperCollider Projects to other Languages and Platforms

Nowadays nobody “needs” a real-time kernel, even because much of the project is already part of Linux. It’s basically a choice between lowering latency to a very low level, or keep more desktop performance in general and energy savings (more battery time). The user chooses their priorities, as it should be in freedom)))

But maybe in 2010 it was different. IDK Tim also mentioned rt kernel in the paper.

So to close the loop on this discussion in case others are wondering for future reference:

• There are no plans to support any form of SuperCollider project code export to other languages or platforms
• James McCartney’s developing a new music language though, which might be able to compile synthdefs to C++
@Spacechild1 might some day expose a raw process() function that reads/writes to I/O buffers, which would make it easier to embed in other platforms a la libpd
• Supernova’s also still a thing and can be a replacement for scsynth (but that doesn’t seem like a viable way to integrate work you do in SC into other platforms either IIUC)

Does that sound about right?

Thanks everyone for taking the time to reply and contribute to an interesting discussion.

There are code translators, if I remember correctly. However, I do not know which code translator supports SuperCollider.

The other way to export the sc code to another language would be to use AI like Gemini, Chat GPT 4, Microsoft Copilot or a well pre-trained AI tool for programming. However, I do not think they could do it perfectly in one go.

Following is an example using Gemini (not tested. I think ChatGPT gives better result, but not sure. I know a free ChatGPT4 service, but it is not in English):

my request:

translate the following supercollider code ```{SinOsc.ar}.play``` into python using pyo library

the returned code by Gemini:

from pyo import Server, Sine, sig2play

# Initialize Pyo server
s = Server().boot()

# Create a Sine oscillator with frequency 440 Hz
sine = Sine(freq=440)

# Play the sine wave
sig2play(sine)

# Start the server and play the sound
s.play()

# Stop the server after some time (optional)
s.stop()

Explanation:

  • We import the necessary classes from Pyo: Server , Sine , and sig2play .
  • We create a Pyo server instance (s ).
  • We create a Sine oscillator object with a frequency of 440 Hz (sine ).
  • We use sig2play to send the signal from the sine oscillator to the audio output.
  • We start the Pyo server to begin playback (s.play() ).
  • Optionally, we can stop the server after a certain time using s.stop() .

Key differences:

  • Pyo uses more descriptive object names than SuperCollider (e.g., Sine instead of SinOsc ).
  • Pyo doesn’t have an equivalent “ar” modifier, so we directly send the signal to the output.
  • You can control the duration of the sound by stopping the server manually or using additional Pyo functionalities.

Additional notes:

  • Adapt the code to your specific needs, such as changing the frequency, duration, or adding effects.
  • Explore the Pyo documentation for more functionalities: [[invalid URL removed]]([invalid URL removed])

I hope this helps!

The following is by Copilot free:

Sure, here’s how you can translate the SuperCollider code into Python using the Pyo library:

Python

from pyo import *

# Create a Server object.
s = Server().boot()

# Create a SinOsc object.
a = Sine().out()

# Start the Server.
s.start()

# Keep the script alive.
try:
    while True:
        pass
except KeyboardInterrupt:
    s.stop()

AI-generated code. Review and use carefully. More info on FAQ.

This Python code does the same thing as your SuperCollider code: it creates a sine wave oscillator and plays it. Please note that you need to have the Pyo library installed in your Python environment to run this code. You can install it using pip:

pip install pyo

Also, please be aware that this code will run indefinitely until you stop it manually. To stop the sound, you can simply press Ctrl+C in your terminal. This will raise a KeyboardInterrupt exception, which is caught by the try/except block in the code, and the server is then stopped. This is equivalent to calling .play on the SinOsc object in SuperCollider.

Please let me know if you need further assistance! :blush:

Show learn more suggestions

Thanks @prko for the suggestion, that’s a good point. That does seem like the most pragmatic way forward at this point, so I’ll give that a try and report back here if I find a reliable workflow to do this with a particular AI chat bot.

Well, I ended up trying to use Chat GPT to translate SuperCollider UGen source code into Max rnboscript for use in RNBO (as a way to accomplish the titled goal of this thread).

But as one might expect, this didn’t work particularly well, even after multiple attempts at refining Chat GPT’s output. I suspect b/c the version of Chat GPT I was using simply didn’t grasp the nuance of SuperCollider’s architecture vs that of the Max RNBO environment.

Maybe I just need more prompt engineering practice, but I ended up doing it the hard way and managed to figure out a methodology to translate SuperCollider UGen source code into a RNBO abstractions, which you can find on my Github here:

As an initial proof of concept I translated the PitchShift UGen source code, but plan to continue porting some of my other favorite UGens and adding them to this repo over time.

So I think this represents a viable way to translate SC UGen source code into Max RNBO (rnboscript), which can then be exported to the various platforms RNBO supports (Javascript for Web, VST3, Raspberry Pi, C++), allowing one way to export at least SC UGen code to other platforms.

Translating from the original C++ source to Max RNBO’s “rnboscript” language was a pretty straight forward process once I wrapped my head around w/ what was going on in the SC Server UGen code.

Basically all the unit pointer operations get abstracted away by using the RNBO Codebox~ “@state” variable decorator.

And b/c the code inside the RNBO Codebox~ object is run on a per sample basis, the “inNumSamples” argument for blocksize-based DSP gets abstracted away too, allowing the core DSP code to not have to sit w/in the while() and for() loops of the original SC source.

e.g this SC UGen C++ design pattern:

void PitchShift_next(PitchShift* unit, int inNumSamples) {
   ...
   remain = inNumSamples;
   while (remain) {
      nsmps = sc_min(remain, counter);
      remain -= nsmps;
      counter -= nsmps;
      LOOP(nsmps,
         iwrphase = (iwrphase + 1) & mask;
         //<UGen DSP code>
         dlybuf[iwrphase] = ZXP(in);
         ZXP(out) = value *= 0.5;);
      );
   }
}

…gets abstracted into this in RNBO Codebox~ code:

function PitchShift_next(i0) {
   var input : number = i0; //store input sample data
   var output : number = 0.0;
   var value : number = 0.0;
   ...
   counter -= 1;
   iwrphase = (iwrphase + 1) & mask;
   //<UGen DSP code>
   dlybuf[iwrphase] = input;
   output = value *= 0.5;);
   return output;
}

(There were also various SC specific functions I had to reimplement using my own functions and RNBO native operators, so I’m glossing over some nitty gritty details. But RNBO operator support is pretty good, so this was pretty straight forward too.)

Overall, I’m looking forward to porting more SC UGen source code to Max RNBO in the future so my favorite SC DSP can live on in the various platforms RNBO targets.

It seems not to have come up in this thread, but one constraint here is GPL (which prevented Apple from taking over the SC codebase when JMc went to work there).

IANAL, but… GPL states that “derivative works” should be released under the same license, or a more permissive license. It also prohibits linking across free vs non-free licenses (without express written exceptions from the copyright holder). I think this is meant to protect against closed-source projects absorbing GPL’ed libraries – which is not exactly the case here (and as IANAL, I’m not sure of the ramifications).

Per Cycling 74, “Code generated by RNBO from a patcher is dual licensed under the Cycling '74 License for Max-Generated Code for Export or GPLv3. RNBO engine source code to support the generated code is licensed under the MIT License” … which is also unclear for your case, because you’re not generating RNBO code from a patcher – you’re writing the code directly.

At minimum, you’d have to license your RNBOScript as GPLv3 (and have no reason to believe you would have a problem with that).

What I’m also not sure about is that MIT License for C74’s supporting code. It strikes me as a gray area – is the rnboscript “just data” that invokes proprietary functions, or is it “linking” to those functions? FSF FAQs suggest that it would be considered linking. (And, is a translation of GPLv3 code a “derivative work”? Intuitively, I’d think so, unless it’s clean-roomed.)

Also, (as I understand it) you can do anything you want privately – licensing only becomes an issue if you release it.

hjh

In general, people put too much blame on the GPL license even when it’s not even the main cause of the problem they are talking about.

Some clarification on the previous post:

–1. GPL and Derivative Works

  • Correct: The GPL does indeed require that derivative works also be distributed under the GPL. This is intended to ensure that all modifications and extensions of GPL software remain free and open under the same terms. This is a very good thing and the SC community should not tolerate changing this., in my opinion.

– 2. Prohibition of Linking Across Free vs Non-Free Licenses

  • Partially Correct: The GPL restricts linking GPL-covered code with code covered by more restrictive, particularly proprietary, without special permission. This is because such combinations can effectively restrict the freedom guaranteed by the GPL,

– 3. Cycling 74 and Dual Licensing

  • Clarification Needed:Cy cling 74 and dual licensing of code generated by RNBO from a patcher under both the Cycling '74 License and GPLv3 is a very specific case. The MIT License mention for supporting code, however, requires careful consideration as to how it interacts with other code, particularly in the context of GPL

MIT

  • Gray Area: Whether the rnboscript is “just data” that invokes functions or effectively “linking” to the functions can indeed be a gray area.

The FSF typically considers linking proprietary software with GPL software as creating a combined work, thus requiring the entire combination to be released under the GPL.

I imagine, if Apple had taken ownership of SC back in 2002 (they, like a lot of tech companies, have a clause in the employment contract by which Apple owns any employee’s independent, outside projects – JMc’s choice of GPL was a hard NO to Apple on that), then in terms of integration, there would be SC4Logic and only SC4Logic. No Linux, no Windows. It’s a trade-off, but I think on balance, Apple ownership would have stifled a lot of what we take for granted.

hjh

1 Like

GPL Express Written Exceptions: The GPL allows for additional permissions or exceptions , which can permit actions otherwise restricted by the GPL. These are often specific to a project or a distribution.

In the case of SuperCollider, it would be complex because of the number of contributors.

In short, all that was written about SuperCollider would not apply to your GPL project because of the number of authors. In practice, almost everything that was attributed to GPL in this forum has little to do with FSF and GPL.

JMC did a great job protecting SuperCollider, it was just right The dev community could have constructed a renewed relationship with this man after his retirement, which sadly was not exactly what happened.

Is there any where one can read about the history of SuperCollider in more detail, all these little bits of information that surface here in dribs and drabs are fascinating!

2 Likes

JMC did some interviews. He often talks about a few earlier programs that precede SuperCollider.

BTW the Pyr we see in the codebase comes from one of these programs called Pyrate.

It’s very cool to hear him saying that “Oh, I bought an Apple computer, plugged this program into this other one, and real-time granular synthesis worked”

Today people with all the tooling struggle so much :joy:

In the case of his job, I think releasing SC with a GPL license before signing anything is all the protection we need.

His preface to the SC Book is also insightful.

Yea, sorry this wasn’t more clear. I nested the original GPLv3 license w/in the “SuperCollider Source” folder originally included in the repo, but I’ve since moved it to the top level of the repo to make it more obvious.

Going by Cycling’s and SuperCollider’s licensing requirements, my initial instinct is that the RNBO code I made should be licensed under GPLv3, but yes, since the code in the repository isn’t exported in the form of generated code, I can see how it makes things less clear.

:man_shrugging: well, for the time being the repo I made has a GPLv3 license attached to it, but if the SC community feels this is too problematic or insufficient, I’m happy to take the repo down - just let me know.

I’d caution against this. The word AI gets thrown around a lot, and its mostly marketing hype. These things can’t program, and what you’re getting is a mashup of the internet’s greatest hits. Translating from one language to another is way beyond their capabilities.

1 Like

Yea, long thread, but as I mentioned above the AI translation didn’t work, and I ended up translating SC PitchShift Ugen code into a Max RNBO object manually, as an initial proof of concept.

So now that I’ve gone through the process I can envision doing it for other SC Ugens too so this code can be exported to the platforms RNBO supports.

But as discussed above there are some uncertainties about the incompatibilities between SC’s GPLv3 license and Max’s dual licensing scheme.