2026-06-06 16:40:30 -05:00
2026-06-05 14:16:20 -05:00
2026-06-05 14:16:20 -05:00
2026-06-05 14:16:20 -05:00
2026-06-06 16:40:30 -05:00
2026-06-06 00:45:21 -05:00
2026-06-05 14:16:20 -05:00
2026-06-06 16:40:30 -05:00
2026-06-06 16:40:30 -05:00

sonobulus

A QML C++ digital synthesizer app utilizing state-space modelling for complex physically-based audio synthesis.

This project is a spinoff of metabolus which used a traditional oscillator -> envelope -> filter model + QT Widgets. The general project architecture (like audio engine and midi interface) will function largely the same, but with a revamped UI framework. I'm smarter now.

State Space Theory

This synthesizer is an attempt to create more complex and tunable audio effects than previously possible with the traditional model. State-space modelling is able to represent physical dynamical systems and their responses to certain inputs. For example, we can create a model of a fixed string with a certain elasticity and observe its position in response to being struck with a hammer- the resulting time-variant response function should closely relate to a single piano tone. The mathematical model involves a vector of states (e.g. position, velocity, tension) and a vector of inputs (e.g. impulse of velocity). The system's matrices tune the system's output behavior (e.g. air pressure) as a result of the states and inputs. Behavior can quickly get very complex, much more complex than simple oscillators can produce. For an oscillator based synthesizer, many additions are usually added to approach the complexity needed to model real world instruments: filters, envelopes, low-frequency modulators, post-processing plugins, etc., whereas a state-based model can already include all kinds of behavior built-in. There are quite a few modern synthesizers that use this approach already, but the 80's style stayed away due to the real-time computing requirements (hundreds or even thousands of calculations for a single sample at 44.1k samples per second). Hopefully, at the bare minimum, this synthesizer aims to produce somewhat well-sounding instruments and music performance.

Development plan:

  • Build & project setup, get working hello-world program.
  • QML hello-world program: basic increment/reset counter
  • RtAudio hello-world: basic sine output
  • Connect UI control to sound output, add a slider for frequency control
  • Add note control a keyboard. Coordinate on-off events to start and stop tone generation
  • Add note control via a MIDI interface using RtMidi. Ideally should be able to connect to external midi controllers/apps (like musescore)
  • Create a UI scope to visualize the synthesized composite waveform
  • Check cross-platform combatibility for Windows & Linux, especially MIDI interfacing
  • Checkpoint at a rudimentary keyboard instrument producing a basic sine output
  • Will flesh out future goals when I do the math on how complicated implementing state-space modelling in c++ is

Build Instructions

Prerequisites: CMake: https://cmake.org/download/
Qt6::QML: https://www.qt.io/development/download-qt-installer-oss
Note: you must export the Qt install location to your environment. E.g. add the following to a powershell profile: $env:Qt6_DIR = "C:\Qt\6.10.1\msvc2022_64"

Compiler that supports C++20. Builds have been tested with GCC12 & MSVC17

Clone repository

git clone https://git.vxbard.net/homeburger/sonobulus.git
git clone --recurse-submodules https://git.vxbard.net/homeburger/sonobulus.git # if there's submodules
git submodule update --init --recursive # if you cloned without submodules and need them

Build:

# configure
> cmake -S . -B build
# build
> cmake --build build -j

Execute:

> .\build\Debug\sonobulus.exe
> .\build\Release\sonobulus.exe
$ ./build/sonobulus

Configurations

There is a plan eventually to use config files so app behavior can be tweaked without needing to recompile. Will flesh out more once more of the app's structure takes shape.

Instrument Profiles

Later into the app's development I have this vision: the state-space model of an instrument can be saved to a file. The app can allow parameter tweaking and re-saving of an instruments matrices. Far far into the future there may be a dynamic process for constructing your own instrument models and a way for the app to load and play those instruments. At the end of the day, a state-space model is just a set of 2 n-dimensional matrix equations and a profile would only need to be able to represent each element in the matrices.

Description
A digital synthesizer using QML and RtAudio/RtMidi focused on state space modelling
Readme 136 KiB
Languages
C++ 72.8%
Python 18.1%
CMake 5.8%
QML 3.3%