SuperCollider 4: First Thoughts

I’d be interested to know what the required skills are. I have literally zero knowledge of software development and also zero time at the moment to make a contribution, but can imagine taking part at some time in the future…SC has really changed my life and I guess it’d be nice to give back somehow!

Here’s a great vid from @elifieldsteel targeted at non-developers that shows how to make contributions (a simple correction of a typo in the help in this case)

1 Like

| Sciss
June 7 |

  • | - |

fmiramar:

and some crucial features are missing (e.g. it is not strictly possible to interchange data back and forth between the server and the client)

this is noted here: a new NRT mode with full OSC socket · Issue #279 · supercollider/supercollider · GitHub and closed for unknown reasons (I guess since it was stale - I think it should still be an active issue)

My 2 cents on new features I would like to see: having non-realtime (NRT) mode fully working like the realtime (RT) mode. Of course the NRT is working properly, but its language implementation is too verbose when compared with the RT (e.g. there is no SCTweet made using NRT nor we have an {}.ren…

This is perfectly possible without changing the server. In fact, I have implemented it in (muttering) another language that starts with p, inpired on the NRTClock by Jonathan L. and changing the timing mechanishm of the library to run in logical time only. The problem of implementing it in sclang is that it involves changinges in low level C primitives, and we are back to the development support problem (note: I couldn’t do it low level in sclang). To have an nrt thread or subprocess in the server comunication with sclang would be a plus for sure.

But there are also other technical problems if you whant to mix rt and nrt at the same interpreter session, the library keeps global states regarding resources on the server, for example, it is not the same to define a synth, bus or buffer for rt and nrt. That is solvable but then there is yet another problem, to run the same code in rt and nrt without modifications due to time and asynchromic behaviour being different. So, I opted not to mix them. In any case is a work that requires some design is not as trivial as it seems.

1 Like

To have fully compatible code, I think you would need to modify the server (unless I’ve misunderstood you) to wait on ‘advance messages’ from the lang. For example NRT server sends a /tr message to the lang, and then must wait before continuing calculation to see if any new work has been added. I think the pattern would be NRT clock sends a message saying server can calculate until the next time in its queue, but this can be overridden by messages in return that could generate new tasks.

2 Likes

| muellmusik
June 7 |

  • | - |

lucas:

This is perfectly possible without changing the server. In fact, I have implemented it in (muttering) another language that starts with p, inpired on the NRTClock by Jonathan L. and changing the timing mechanishm of the library to run in logical time only.

To have fully compatible code, I think you would need to modify the server (unless I’ve misunderstood you) to wait on ‘advance messages’ from the lang. For example NRT server sends a /tr message to the lang, and then must wait before continuing calculation to see if any new work has been added. I think the pattern would be NRT clock sends a message saying server can calculate until the next time in its queue, but this can be overridden by messages in return that could generate new tasks.

That would be a nice plus. What I did was to run everything offline. It generates the score in logical time, as fast as possible, and then renders by calling the server command. Is like having:


s.options = ...
s.boot();

// this happens at time zero.

SynthDef(\a, ...).add;
SynthDef(\b, ...).add;

b = Buffer(...);
c = Buffer(...);

// always starts from time zero (absolute time), can spawn other timer routines or resources in different moments.

fork {
loop {

Synth(\a, [buf, b]);
1.wait;
// etc.
}

};

// always starts from time zero (absolute time)

Pbind(...);

s.render(); // set file name etc.

then you can run sclang [script.sc](http://script.sc) and have the audio file back. Suppose that s.render runs the script in nrt, generates the score file and then calls the server command that writes the sound file. The only difference is that everything is synchronous.

A problem I imagine about sending a stream of nrt commands is how to tell how much time to compute and then it will not be possible to go back. It should implement a non sequential rendering strategy for that. And that is something beyond my reach, instead, an nrt score sorts timed events with ease.

where might we find your script?

GUI’s are limiting.
How far can a slider go? In graphics a colour slider goes from 0 to 1, or 0 to 256. In script I can push the red part of a colour up to 23145 and have some functions working with it and eventually come down in the 0-1 range. Or, one can use negative colour values … Not with a GUI (predefined by someone else).
The nice thing is that SuperCollider lets me make a quick slider … and I always set the wrong values to find the really interesting regions.
The same for Modular Synth simulations like VCV Rack. They are very very fun to goof around with, yet limiting in the “wrong way”.

What does a “negative note” sound like?

(regarding limitations, one should mindfully set them for one self. Cage’s “frameworks” for chance, Goehtes “In der Beschränkung zeigt sich erst der Meister, Und das Gesetz nur kann uns Freiheit geben.”)

It’s interesting that NRT came up. That is what I would have thought as being a potential for an other DSL next to the real time one. Seems they exist , time to investigate.

4 Likes

Pd has a nice feature where you can temporarily advance the scheduler as fast as possible with the [fast-forward( message, so you can, for example, render your output to disk without leaving the interactive mode.

AFAICT, the proposed NRTClock would go in a similar direction. I think this would be a great alternative to the existing NRT mode!

1 Like

where might we find your script?

https://sc3.readthedocs.io/en/latest/intro/nonrealtime.html
https://github.com/smrg-lm/sc3

Also the scheduler in nrt simply schedules clocks in one thread:

code

2 Likes

Yeah in principle this is a good step but not complete. FWIW, there have been various ScoreClocks and ScoreNetAddrs of sorts (i.e. capture OSC messages then render NRT later) over the years, though none have made it into the main distro.

For the server side interacting with the language, it could have an nrt space that receives chunks of osc commands as nrt scores, with time zero as the reference point, each chunk should be self contained regarding allocation of resources and processed in queued order, the language can sync when queued task are done but is not strictly necessary because each chunk renders sequentially, out ugens write to output buses that point to a file on disk. Commands timetag map to file sample position at a given sample rate, because cmd chunks are executed sequentially they can reuse resources and even read from the output buses that may contain previously rendered data. That’s a global idea for organizing non sequential rendering, I think is good in some aspects.

I think non-sequential rendering, while maybe useful (do you have a case in mind?) is perhaps a slightly separate issue.

I’m thinking more of just the not uncommon case where what happens in the lang may depend on what happens in the server, and may require sequential server-lang interaction. Since that may not be possible to know at the time of starting rendering, I think we need some kind of advance handshake. That’s all I was saying really. Hope that makes sense!

1 Like

I didn’t really have a case in mind, just thought it more “natural” for nrt thinking. Regarding the handshake, if the server was attending rt at the same time I thought in a different “space”, an nrt thread and commands addressed to it and enqueued, when the queue is empty it syncs, similar to asynchronous commands. But all this depends on the implementation.

1 Like

All of the arguments against SC4 <> DAW have been sharp & well taken… this thread has made a few breaths more enlightening.

The beauty of SC ( as we may have seen only to some degree, w/ LNX studio…) is that it makes for not just another ball & chain beat machine… in sharply contrast, SC goes so far beyond in terms of possibility as to surpass the extent where it could serve as the power & foundation for the next Ableton… while still inviting an ever greater creative experience

So much at times as to become to an an extent overwhelming… it invokes in my own imagination, to how great SC could be made more manageable, and smoother overall experience… but certainly, as I feel many of us strongly agree, only never at the exchange of sacrificing an iota’s fraction of creative freedom or unique power in expresiveness that SC delivers… everyone’s arguments have affected a great clarity on this.

Thanks to everyone for their input.

Some thinks I would be glad to see:

  • Combining code and documentation in sclang - this helps on creating documented and readable code while also maintaining an up-to-date documentation (see Python, Julia, Java, …)
  • Allow adding new classes in sclang interpreter
  • Add import/namespaces and an optional type system with IDE support for both
  • Adding webserver to sclang: This would allow to use a website instead of Qt for GUIs (so it can be easily controlled from another device instead of writing touchOSC files or else) and would allow to exchange data via JSON API instead of using OSC/Files
  • WebAssembly build of scsynth
  • Adding a high level abstraction/fail checking for busses instead of relying on integers: the multi channel expansions allow to easily overwrite into busses you use otherwhise

And when one could dream: no more boundaries between sclang and scsynth - sclang with direct access to the float arrays of scysnth.

2 Likes

It may seem like a small thing, perhaps, but it would be really nice to be able to declare sclang variables anywhere in a block, not only at the start. (Even if it were implemented as some kind of “syntactic sugar”…)

It would make for much cleaner code (there are very few languages nowadays where you have to predeclare variables at the top of a block or function, as you had to with C in the old days).

3 Likes

I have many problems with sclang, but this is probably one of the biggest. It might have been a viable tradeoff in the late 90s to make the language fast enough for soft realtime purposes, but in 2021 this is just ridiculous. Same thing with having to “compile” classes. Every modern dynamic scripting language lets you define new classes at runtime…

1 Like

I think that defining variables anywhere and not having to recompile to add classes would be a great, contained issue for a bounty or fundraising! I would happily throw a little money at solving these, if indeed it is possible. New users are slow to get involved with writing their own classes and methods due to how cumbersome it is and of course you can’t do it while livecoding at all.

3 Likes

Recompiling is a bit cumbersome indeed, but e.g. if you work in scide, it’s just ctrl+shift+L to recompile and recompilation goes pretty fast. I find it quite painless, once you know it. But indeed, live-coding is a use case I hadn’t thought of before. I often also use "Event"s as objects, in which case no recompilation is needed, and it can also be used for live-coding (but one has to be a bit careful not to try to redefine existing methods - it’s good enough but not ideal). What I found confusing (especially in the beginning) is the different syntax between e.g. methods and functions (e.g. to return a value).

Declaring variables everywhere on the other hand… for sure +1 for that request.

Yes I am also managing as you describe… But one more issue is that it would be great to be able to have classes that are interpreted so that you don’t need to maintain separate .sc and .scd files - you might want a class that is only used in a certain piece etc etc. You might want to generate methods programmatically… (And really the syntax should not be different!)