“Ooh look, a new blog post! It’s been three months since you last wrote one. What the heck?!” - readers of this blog (if there are any remaining)

Yeah…sorries! I’ve been “busy” doing “important stuff” (like browsing Reddit). Apologies to all those who really wanted more Learn You a Rust, but I haven’t thought of anything to write about. (If you have any ideas for complicated Rust concepts that you want me to talk about, hit me up on Twitter @eeeeeta9!)

This is the start of a series of posts about SQA, my pet audio project. (I suggest you take a brief glance at the linked README, else this post is going to be rather confusing.) At the time of writing, the version currently published to the world is the “beta 1” release of the codebase that will henceforth be referred to as “old”. Basically, I’m starting again, this time doing it in the open and blogging everything that’s going on. Why? Well, I think that SQA v1 isn’t really suitable for its usecase: a reliable, professional live theatre audio application with accurate timing

  • it’s currently none of the things emphasised.

So, I’m rebuilding it from the ground up, so that it:

  • has sample-accurate synchronization
  • doesn’t suffer from buffer underruns (hopefully. This, as it turns out, is rather hard!)
  • has a better UI and structure: SQAv1’s command line system is fundamentally broken, and doesn’t work well for non-trivial commands. It also currently doesn’t take timing into account at all, which is not ideal. More on this later™!
  • and probably more that I’ve forgotten at this precise moment, but that’ll become apparent later

Let’s get on with the devlog, then!

What happened this week?

Well… not really “this week” quite yet. Just a day, for now!

I’ve started by implementing bindings for the JACK Audio Connection Kit in Rust. These will be used in SQA’s new audio architecture. I chose JACK because it really fits SQA’s usecase the best:

  • all audio in SQA is mono (you just have lots of channels). The same is true in JACK (you have lots of ports).
  • JACK implements mixing for me (-ish, I still have to mix into ports). Using tools like qjackctl, you can arrange complicated patching setups (and store/load them) outside of SQA, meaning I don’t have to deal with that stuff. SQA just has to remember what you patched it into, and that’s easy (one string per port).
  • JACK is designed for pro audio, unlike things like PortAudio.
  • The JACK API is nice! (c.f. I wrote working, high-performance bare-bones bindings for it in under a day) In contrast, things like ALSA are hard to use (you’re constantly checking for errors, and there are some quirks you need to account for, not to mention the inane amount of functions you need to call for basic stuff). PulseAudio is nice-ish, but is not for pro audio.

That’s about it for now.

How will SQA work in future?

I plan to make three distinct crates for SQA (it’s nice to have distinct crates to speed up compile times, which was a pain point in SQAv1 development). Here they are:

  • sqa-ui, which will serve as a fancy user interface to the backend (we might even have different types, such as sqa-ui-gtk, sqa-ui-qt, etc.)
  • sqa-engine, which will be a library that provides a nice layer over JACK for you to throw a buffer of audio at, and specify exactly when you want it to play back
  • sqa-backend, which will be the main “server” component of SQA that does all the scheduling, playback, etc.

Work on sqa-engine is underway (hence the JACK bindings). The other two crates are a mere fantasy at this point.

That’s about it for this blog post. More to follow!