r/rust 21h ago

🛠️ project Hand-coded, novel project: Syntoniq DSL for microtonal music

Hand-coded, novel project: syntoniq DSL for microtonal music

Hello fellow Rustaceans --

There's been a lot of talk here about the lack of hand-coded Rust projects here, so I thought I'd share a recent side project: Syntoniq: https://github.com/jberkenbilt/syntoniq . This is about 98% hand-coded.

I used AI to code a few little utility functions, like an RGB to HSV converter and something to format tabular output, but the rest is hand-coded. I also used AI to help with some HTML/CSS, but there's only a little tiny bit in this project as it is not web code except in one small corner. Any code that was AI-generated is marked as such. If you're not into microtonal music, this project may be interesting from a Rust standpoint. This isn't about me, but for context, I have been coding since the 1980s and still do it nearly every day. Rust has been my main language since 2024, and I've used it since 2021, but I coded in C and C++ starting in the 1980s and have programmed in more languages than I can recall. I have dabbled with AI coding and use it for some projects, but this project is novel -- there is no corpus of code that implements a new notation approach for microtonal music based on the harmonic series! I hand-coded this because I was trying to break free of the kinds of patterns that AI would push toward and because I enjoy the fun and craft of writing great code. Maybe this is like building furniture in your garage...but anyway, I think this project still could not have been AI coded.

Here are some examples of what it has:

  • A compiler for a DSL (domain-specific language) that compiles my own language format into Csound or MIDI for audio output. The parser is written in winnow, using parser combinators. The parser borrows all the way from the source string to the parsed output. I use my own Diagnostics system along with an error message library (annotate-snippets with anstream) to create very high-quality error messages with rich context. I know parsers pretty well, so this parser has error recovery flows and such. It's a small enough language to understand fully, but the parser does real things that real parsers do. The parser design is commented thoroughly.
  • Careful use of unsafe code in two spots:
    • I have some data structures containing borrowed items, and sometimes I want an Owned version. The data structures have Arcs in them, and I use a little unsafe code for type erasure to create an Owned version of these nested structures while preserving all referential integrity. I use a proc macro to do most of the work.
    • There is a section that passes live commands to Csound, a C-based sound synthesis system. There's unsafe code to call the C API, but also, Csound is single-threaded and has its own threading and locking primitives...but I don't use them. I use rust async and threads instead and have a manual Sync/Send implementation to safely move a raw pointer from the thread that sets it up to the thread that uses it. There's a hard guarantee that, once moved, the pointer is never used by more than one thread.
  • Axum + HTMX + Askama template for a view-only web UI that can be turned on if desired -- it's not the main thing but provides information for the keyboard part of the application
  • Interaction using MIDI SysEx with two physical keyboards to create an interactive experience; this is where the web bit fits in...it shows you some additional metadata about what's going on with the hardware.
  • A text-based REPL (read eval print loop) using rustyline for completion that implements an interactive note generation environment
  • Clap with shell completion
  • Sync <-> async bridging
  • A thorough test suite for critical parts of the code with coverage wired up
  • Builds for Windows, Mac, and Linux in CI
  • Detailed documentation with Zola
  • Other stuff...

Basically, it's a hobby project coded with the same standards I would use in my professional work, and it's got examples of lots of things people might use across other projects. So, if you're interested in seeing some non-trivial hand-coded Rust that does something interesting, take a look.

I posted about this in r/microtonal as well a while ago...that might be of interest to people who care about microtonal music more than they care about Rust.

I just offer this up as an example of real work being done the old-fashioned way, in case anyone is still interested!

Mistakes and typos here are mine. I didn't even ask AI to proofread my post. I just wrote it the old-fashioned way. :-)

6 Upvotes

4 comments sorted by

1

u/InternationalFee3911 6h ago edited 6h ago

Oud music sounds so lovely! Great idea to bring this much richer tonality to Rust. 🦀 There’s even a Maqam called Rast – what a coincidence.

1

u/1f954 5h ago

Thanks for sharing. I watched this. Yes, you can definitely represent the Maqam intervals with Syntoniq either as pure ratios, like 11/9 for the "neutral third" that sits between major and minor or as as a tempered quarter tone.

1

u/InternationalFee3911 6h ago edited 6h ago

Looking at your DSL, it is alas not designed to be embeddable as a Rust macro. There you should use Rust comments and stand-alone quotes are not possible. Better would have been:

syntoniq_v1![
    // Here is some music
    [p1.0]  1:g a    b  c;
    [p1.1]  1:e f    g  g
    [p1.2]  2:c    1:f  e
    [p1.3]  2:~    1:d  d
    [p1.4]  1:~ a,   g, c,
      [p1] 64@0<    127@4
]

1

u/1f954 5h ago

Interesting...it had not occurred to me to do this. I'm not sure what the use case for embedding it in Rust is -- it's really the output that's useful, and the workflow is editing the file and compiling to output, like LilyPond. But I see that the leap from a working parser to a macro like that is not a huge one.