Are there any patten library (attempts), i.e. Event frameworks, in frontends other than sclang?

I see there are alot of external binding for scsynth (i.e. the server-side of SC), but are there any half-reasonable implementations of (event) pattern libraries in such ports?

I know a lot of languages have stream support etc., but that’s not quite enough to “hit the ground running” pattern-wise when using such ports, i.e. one would minimally need an sclang-Event-like machinery and a player for those (In the sclang library paradigm, Events types come with their own “mini players”, which are sometimes chained by “bigger” players like Pmono).

So, does anyone know if any scsynth frontents other than sclang also have a minimally working Event-like framework (not necessarily 100% replication of the sclang one)?

I found an overview in a 10-years old paper of H. H. Rutz:

Overtone [Clojure], pkaudio [Python] scruby, and ScalaCollider have attempted this “musical scheduling” part of SC as well. I would definitely appreciate a more up-to-date answer though, especially stuff that’s maintained/working.

I see ScalaCollider has its own pattern library that’s in active development, although it seems to be a “reboot” rather than a straight port attempt. (Lots of things on the todo list there makes me think that pretty “alpha” software. And exactly 7 bug reports, including closed ones, strikes me as pretty small user base…)

I also found Overtone’s Leipzig which seems to be one of their attempts; it seems to be in a similar shape as Scala’s maturity-wise and syntax-wise looks a lot more like “old school” CSound scores than any patterns.

Haskell seems to have gained Vivid on the composition side since that paper was written. The syntax looks oddly cluttered though; obviously they do the the scheduling though monads, but all they seem to provide a sclang-Routine equivalent(s), not “further up” patterns.

Not sure what happened with the Ruby and Python projects… Actually I think I found (the right) scruby, but frankly I don’t see where it ever had any kind of score support.

Have you looked at Tidal?

Yes I have some idea what it does, but it’s rather limited in scope. It fires its own fixed SC synths as “SuperDirt” etc. And the code base seems in even more flux than others… Lost of conceptual changes posted on their blog (it was discussed/mentioned here recently in another thread). On the plus side it has a somewhat greater-than-1 userbase.

I’m mostly interested in something that comes in a general purpose language binding so I can do my own GUIs to go along with my patterns. Tidal is not just a library but also a DSL (domain specific language).


Somewhat of an aside: speaking of Clojure, I found basically something that’s closest to what my interests are (“generalized” note expression/modulation–which can also have speech applications), namely Steven Yi’s Score, but it doesn’t target SC as a backend or even other popular backend, but comes with its own, named Pink. (Actually a bit later CSound support was appanrely added to Yi’s Score–terribly generic name alas, which makes searches very difficult.)

One can basically “fake” that to large extent in SC using chained events like PmonoArtic, but to get a decent “language” on top one needs “non-static” patterns, in the sense of heavy of instancing of sub-patterns, and the SC pattern library is quite brittle in this area (Pproto etc.)

The notes for Yi’s Score say among other things

The library currently offers two styles of score generation. One is styled after SuperCollider’s Patterns. Patterns in SC generate values without context, and map directly to standard Clojure sequences. gen-notes and gen-score in src/score/core.clj are functions for use with the score generation style. With this it is simple enough to emulate any feature in SC Patterns using standard Clojure sequence-related functions.
The other score generation style is CMask-based. In CMask, rather than have sequences, generator functions are used that function within a context of time. […]

Alas between what’s possible to implement and what’s actually implemented in that Score, there seems to be a large gap given the sparse/few demos it has.

Overtone is the closest target - it seems maintained though not so actively developed, but it seems possible to build something like the patterns library in it. However, it’s not clear to me whether Closure supports native coroutines - if not, it gets significantly harder to write Patterns/Streams in an elegant way.

If you care about realtime playback (vs offline generation of scores), you’ll have to use one of the Lisp/Java/Haskell based solutions, none of the other languages can reasonably support realtime scheduling.

If you want to write Synths in the same language you write patterns, Vivid and ScalaCollider are the two options I know of.

If the requirement is a library that’s well-tested, relatively free of technical debt, and with an active community maintaining it, it doesn’t exist. In an unfunded context, it takes many years to build libraries like this - and years of development work without full time maintainers means a large accumulation of technical debt, the likes of which you’ve been encountering. If there was a triangle expression of this, it would be something like “cheap” <> “free of technical debt” <> “powerful” - since most of these projects are maxed out on column 1, you get a strictly limited mixture of columns 2 and 3 :slight_smile:

1 Like

I see there’s also a FoxDot for Python now, which does appear to go a little beyond merely using Python’s list comprehensions, but I’ll have to take a closer look. Those “pattern strings” they use look a bit more like Tidal stuff (i.e. a DSL) and of course it’s annoying to have your pattern be a language level string without no finer structure exposed, although I may be jumping to conclusions here in that regard… E.g. they write P["x--(-[--])o"] which is surely cool for live coding but not otherwise.

They actually have quite a few patterns, but not event patterns, FoxDot currently only does “uninterpreted”/base SC patterns. (Annoyingly they use the PChain name for a Markov chain.) Their design philosophy seems to be that you send (separate) numerical patterns straight to the synth’s parameters.

It’s not SuperCollider based, but one my friend uses PYO which is a Python library, heavily influenced by SuperCollider, and which has a nascent event/pattern library. I have not used it myself but heard good things about it.

1 Like

I see it does have (somewhat confusingly named) “Events” (plural) objects which in a first example look like Pbind(s):

e = Events(instr=MyInstrument, degree=EventSlide(scl, segment=3, step=1),
           beat = 1/4., db = -12, signal = "output", outs = 2,
           attack = 0.001, decay = 0.05, sustain = 0.7, release = 0.05).play()

But I’m not seeing much in the way of processing them (other than writing custom processors). I don’t see a simple Pchain equivalent, for example. The Events objects can be played directly; so it seems to be the same paradigm as FoxDot’s.

(They do a post-processing example at synth/bus level, but that’s not composign events.)

If you add a SynthDef in SC while SuperDirt is running you get instant access in TidalCycles. The default Pbind symbols are already usable, so if you can use your synth with Pbind, you can use it with Tidal. The only possible issue is that you won’t be able to use Tidal’s effect parameters, because to do that you need to send your synth’s signal to SuperDirt’s bus for efects, which is just a tweak in your Out.ar(…).

There’s a bunch of examples on how to integrate Tidal and Supercollider in the SuperDirt repo. I encourage you to take a look at it.

It would be nice for there to be a full JS implementation of SC’s client-side. It’d be easier for more people to get into SC and the JS GUI ecosystem is very rich. There’s @crucialfelix’s supercolliderjs

Which looks like a really great start to achieving this. It doesn’t implement patterns though yet, which could be something to do with the real-time concerns others mentioned.

I’m not really knowledgeable on whether node can do real-time well enough, but it seems possible(??)

If it can, it seems like a ‘reactive event streams’ library like RXJS could implement everything that the SC pattern system does. I think they work according to the same fundamental design patterns.

So maybe an idea would be to add an RXJS (/equivalent) -based patterns implementation to @crucialfelix’s supercolliderjs.

That’d be cool. I’d like to contribute to that effort.

Sadly JavaScript is a really poor language for anything realtime / timing sensitive. I’m afraid a pattern library would be a disaster, at least if it was meant to play back vs just generating events ahead of time. From what I know, this is even a big problem when scaling large web backend services (built in node / JS) - the garbage collector can cause unreliable response times and big latency spikes.

1 Like

Just to play devil’s advocate: a patterns library wouldn’t need to do anything really fast. There are plenty of ‘music’ extensions for Chrome that don’t seem to suffer any significant timing issues. See here and here.

This is getting a bit off-topic, but it depends exactly what Chrome features those extensions use. You can even run Csound inside Chrome (wia wasm and particularly via WAAW). But nonetheless

Early adopters of AW have noticed intermittent drop-outs in the audio stream. Since the promise of the technology was exactly to provide a robust and resilient environment for JS (and now WASM)-generated audio, this is clearly a significant issue. Two related difficulties seem to have been identified: 1. Thread priority. 2. Garbage collection.
[…]
In the end, it is accepted that the Web platform, as implemented by a JS engine, is not designed as a realtime system. The regrettable aspect of this situation is that five years ago we already had an audio computing environment for browsers that offered realtime safe operation, in the form of PNaCl modules using the Pepper audio API.

And the wasm Csound demo does make some “pops” on my machine sometimes.

Sure. The hope would be that a JS patterns library wouldn’t need to work at audio-rate, but at a control-rate, which is a large enough difference for us to possibly avoid these issues. It’s the sequencers/schedulers in those Chrome projects that are relevant to this question, as they seem to handle high tempos without any noticeable timing problems.

check out gibbber - https://gibber.cc/
timing seems not to be a problem

1 Like

also maybe slightly OT but have a look at Miguel Negrao’s FPlib quark esp the FRP bit - there are some interesting things including pattern like objects that have “now” values…

I did some sketches of Patterns using supercollider.js


These use JavaScript’s generators which are very close to supercollider’s Routine. It’s almost like JavaScript is slowly catching up to 2000s supercollider :wink:

I can think of another way to write patterns using just generator functions (not classes like I show above).

Since I split supercollider.js into multiple packages, I intended to port all the patterns and publish that.

4 Likes

It’s true that Node was single threaded up until recently. That does mean that the timer function may not be able to happen exactly as scheduled. There are worker threads now.

But all supercollider clients work ahead of time and send OSC messages with timestamps. If you send fast streams of OSC messages to scsynth (eg granular synthesis) with no timestamp then you will get all kinds of weird jitter and odd sonic artifacts. So in a way, there is no such thing as real time.

I used to go through hell trying to make sclang schedule things in advance so the music could keep playing while I loaded files. sclang is extremely weak and unstable under stress.

For any runtime you are going to have to learn it’s innards if you want to push it hard.

2 Likes

What’s your main priority: having a customized / atlernative pattern system or a customized gui control?

IMO the SC pattern system is so flexible that you can tweak it into many directions. It has its known quirks and shaky areas, but as a whole I think it’s hard to find a comparably powerful sequencing gear. There exist a number of possibilities for live-coding as well. Main exception: super-fast sequencing with more than some hundred events per second. In that case you can go to demand rate ugens or think about combos of pattern and demand rate sequencing.

If it’s only about a customized gui control I don’t know if this pays to use another environment. Sure, gui writing in SC is a pain, but if you are fine with doing it once for your needs and not all the time, it’s sufficient I suppose. E.g., as we talked about control of different environments recently, if you’d write something like VarGui that can be used as embeddable View with the possibility to add sliders on the fly – I think that’s not so hard, as standard classes like EZSlider etc. are already there.

Check out this 2018 paper by HH Rutz https://www.academia.edu/keypass/OElOVkE3KzZDN05RMHVTNUF1a2FSRXdGR1dORFNvSElucXk4MDRpSkZIQT0tLWkwbGpOeGNTVndGcEc0aEdNSkVhYVE9PQ==--eec35f33fe6dfe5fbd0765753cfb36e1c4da5208/t/hrcDj-NH0rz7s-YaPba/resource/work/37754598/A_Pattern_System_for_Sound_Processes?auto=download

For the sake of completeness, there’s also Lua2SC: https://github.com/sonoro1234/Lua2SC. I think it also has something like patterns, but maybe @Victor_Bombi can tell you more :slight_smile:

2 Likes