Skip to main content

SinthOP

Two synths in a row, I know. I almost didn’t write about this one, but it’s the first thing I write in C I feel is good enough to make public, so it deserves a spot on the project list.

I wrote this synth for the OSdev class in my current degree. As a final project of the subject, we could make basically anything. Some ideas provided by the teachers being to install a bunch of VMs on proxmox (which I didn’t pick because it seemed too boring), to make a kernel module or modify the kernel (which I didn’t do because it seemed too time consuming) or to make a multithreaded program.

We were allowed to come up with more ideas, but I didn’t really have any, so I stuck to the multithreaded idea because it seemed the most interesting. We could use any language or tooling we wanted, I could have used rust. But I didn’t. It seemed - again - too boring. I already know rust, and I’ve already dabbled with multithreaded code at various levels. So I asked the teacher. I know there’s a subject about parallelism and concurrency, so I asked what they used there, that way I have a tiny bit of a headstart, when it’s my time to do that subject. They use C and OpenMP, so I used that.

Since my friend arf made a synthesiser, I’ve always wanted to do the same. When he first showed it, I was completely baffled, I had absolutely zero idea how I would even begin to make one.

But then I got to play with portaudio. I started to mess with C++ and sound for my uni’s gamedev club, to write the sound module of the game engine they’re building. I enjoyed working with it. It’s simple, straight forward and relatively low level. There’s a buffer for the sound output, and when it’s empty, a function that’s supposed to fill it back up is run. So having now worked with portaudio, making a synth no longer seemed like a mystical impossible task.

When the opportunity to write whatever program I wanted in C for uni presented itself, I had to take it. It was fun working on the project. Getting to use C for something more personal than just class was a good experience. It was also nice to do all the software synthesis. It works completely differently than synth0; While synth0 is all about working with the PIO, moving bits around, modulating waves and filtering with passive components, this one is all about the math of making a wave from scratch and the coordination between reading midi, generating the waves and sending them out to the audio port.

About the point of the project, to make a multithreaded program: The multithreaded version actually sucks. While this one is off-tune for some reason I don’t care enough to investigate, the version using OpenMP is flat out bad. On my laptop, it misses a lot of blocks of samples, making it sound choppy and stuttery. On my computer, it looks weirdly rounded, and some parts of the wave are out of place:

img

Which is definitely because of how I manage the shared memory: I don’t.

So at the end, I basically scammed the teacher and the whole class by presenting the multithreaded version and demoing a binary I built of the non multithreaded version.

Oh, and before I end the article, I have to explain why it’s called SInthOP! It’s called like that because the code of the subject I made this for is SIOP ("Sistemes Operatius"), pronounced see-op, so I added the nth from “see-nth” (synth) in the middle to make SInthOP.