Agreed, and there are dope hackers here, of course ![]()
Iām out. Peace
Agreed, and there are dope hackers here, of course ![]()
Iām out. Peace
Just a follow-up. I wanted to share a small research prototype Iāve been working on, related to my earlier post Iām replying to now.
The project explores a split between graph construction and real-time DSP execution. On the Haskell side, I build synthesis graphs with a small DSL, validate dependencies, detect cycles, topologically sort the graph, and lower it into a simple IR. That IR is then passed through FFI into a C++20 runtime that executes the DSP graph in blocks.
At the moment, itās minimal but is well-documented. The full pipeline is implemented there.
What interests me about this direction is treating synthesis graphs as āprogramsā rather than dynamic runtime objects. In the foreseeable future, we could make graph analysis, rewriting, stronger validation, and optimizations like kernel/UGen fusion more approachable (not possible with sc), while keeping the runtime side relatively small and deterministic, and the plugins code very simple (q_lib is my starting point there).
Iām not presenting this as a replacement for sc. Quite the opposite, its separation between language and server is part of what made me interested in this space in the first place. Iām posting here because Iād love feedback from people who have thought deeply about synthesis graphs, scheduling, SynthDefs, UGens, or alternative client/runtime boundaries.
BTW, Iād like to acknowledge the very fruitful exchange with many members of this community(@Spacechild1, @Stephane_Letz, @Sam_Pluta , @scztt, etc).
The documentation itself, in the Modules notes and comments, for example, we can find references to sc, supernova and faust ideas, etc. The real documentation is found there, start with ./src/MetaSonic/Types.hs and follow the pipeline and the C++ side later.
Iād be especially interested in reactions on whether this seems like a useful design direction (as a concept, or in my implementation), and what would be most important to tackle next if I keep working on it.
EDIT: Since this post, Iāve added a ROADMAP.md to the repository that goes into more detail on tinysynthās design and what Iām considering working on next (useful if you want to contribute code). It also recaps some design differences from scāfor instance, MIDI and UI are managed at the tinysynth layer rather than going through the language->server route we are used to. Also, pattern-like and other DSL features belong to a layer above this repo (metasonic-core), not public yet. If the design idea interests you, that file is probably the best place to start now alongside the source (src/MetaSonic/*.hs): ROADMAP.md
EDIT2: The project now has a small blog at MetaSonic / tinysynth blog ā MetaSonic. Two posts so far ā one on what MetaSonic can learn from @asynth 's sapf, and one on what Miller Pucketteās observations on software and music performance mean for the design (after watching his keynote talk).
I was asked about whatās happening at the āUGensā level, and it seems very appropriate to share, as it both connects to the original motivation of this thread and coincides with a piece of documentation published this week.
In a nutshell, it is a very different approach compared to traditional SC and PD frameworks. Like Faust, it is also functional-style ā processors are composable function objects, not nodes in a runtime graph. On the other hand, there is no framework whatsoever. The functional style and the type system depend on nothing but the C++20 standard library (unlike Faust, which requires its own compiler and type system). C++20 specifically because it brings features that make this style of DSP code practical: concepts for constraining generic interfaces (so containers and buffers satisfy structural requirements checked at compile time rather than failing deep in template errors), constexpr broad enough to evaluate oscillators at compile time, and user-defined literals for type-safe units. The core DSP library is header-only, and processors compose freely ā you build complex processors from simpler ones, and the compiler inlines the entire composition into a single optimized function. It gives a bit of the āfeelā of writing a SynthDef, but at the UGen level, with no boilerplate.
The primitive DSP layer for MetaSonicās C++ runtime (tinysynth) builds on Joel de Guzmanās Q DSP Library. Some of you may know Joel from his Boost work (Spirit, Phoenix and Fusion).
What makes Q interesting from an SC perspective is what it removes. Thereās no Unit base class, no InterfaceTable, no block-processing callback. A processor is just a struct with operator() ā construct it with typed parameters, call it with samples, compose it freely.
The blog post covers all of this in detail:
https://smoge.github.io/metasonic-bridge/posts/2026-03-30-inside_q_lib_how_it_works.html
This link gives 404 error.
Found it, should be:
https://smoge.github.io/metasonic-bridge/posts/2026-03-30-inside_q_lib_how_it_works.html
Thank you, @TXMod I updated the link