This project is an early-stage effort to rewrite and redesign the core signal processing layers of Flocking in C. The goal is to support instruments that can be deployed without modification across different devices and platforms, with a particular emphasis on the Web and embedded platforms such as Eurorack.
- Provide the signal processing infrastructure to support the development of an interpreted and/or transpiled-to-C minimal "signal expression language."
- Live repatching without compilation: provide a highly mutable audio graph, so that instruments can be dynamically reconfigured while they are running (on platforms where this is appropriate).
- Vastly portable: support deployment on the Web (via Web Assembly), desktop and mobile operating systems (macOS, Windows, Linux, iOS), specialized audio OS-based environments (Bela), and microcontroller-based systems (Daisy).
- Fully externalized state: Provide a means for fully externalizing all state via a Nexus-like RESTful API, including:
- Creating signals
- Getting signal values/representations
- Connecting/disconnecting signals or updating their values
- Deleting signals
- Provide first-class support for using signal generators in non-audio environments such as video processing tools like Bubbles.
- Make it easier to compose signal processing algorithms from smaller, self-contained pieces; avoid Flocking's (and SuperCollider's) formal distinction between unit generators and synths.
- Support variable sample block sizes that can be mixed together in the same graph, including single-sample graphs.
- Support cyclical graphs, multiplexing/demultiplexing of signals, and multiple channels
- Provide an architecture that is supportive of multiple processes, including a realtime process that:
- Allocates no memory
- Takes no locks
- Communicates via a lock-free message queue and/or circular buffers
The design of this project is still in flux, and will more fully emerge as I become more familiar with C and the constraints of each of the core environments on which it will run (Web, desktop/mobile, and Daisy, in particular). However, there are a few abstractions that are beginning to crystallize:
- The core library, consisting of Signals (which can be individual signal generators or compositions of them) and the Evaluator (which draws samples from Signals), will be completely platform-agnostic and must be integrated with a particular audio API. It will be usable 1) directly in C/C++ applications, 2) in Audio Worklets by being compiled to Web Assembly with JavaScript API bindings, 3) within other languages that provide interoperability with the C ABI.
- A set of Hosts will be developed, which will provide platform-specific logic for connecting to audio input and output devices, encoding/decoding audio files, and mapping hardware-specifc buses (e.g. GPIO, analog pins, or I2S) to Signals.
Meson and the XCode command line tools are required to build the Signaletic library:
brew install meson
xcode-select --install
libsignaletic uses the Emscripten compiler for Web Assembly support. Docker is used to support cross-platform builds.
- Install Docker Desktop.
Docker is also used to cross-compile the Signaletic examples for embedded platforms such as the Daisy STM32 platform. If you want to build these directly on your host using gcc and make, the GCC ARM embedded toolkit and the Daisy Toolchain must be installed.
brew install gcc-arm-embedded
- Follow the Daisy Toolchain installation instructions.
- Install Meson using the Meson Installer
- Install Docker Desktop.
On Windows, use a VS Command Prompt or set the appropriate environment variables so that MSVC is the default compiler.
cd libsignaletic
meson setup build/native
meson compile -C build/native
To remove all previous build artifacts and rebuild, run rm -r build/native && meson setup build/native
or run meson setup build/native --wipe
.
At the root of the Signaletic repository:
- Build the Docker image:
docker build . -t signaletic
- Run the cross-compilation script in Docker:
docker run --platform=linux/amd64 -v `pwd`:/signaletic signaletic /signaletic/cross-build-all.sh
- Native:
meson test -C build/native -v
- Node.js wasm:
node build/wasm/run_tests.js
- Browser wasm: Open
libsignaletic/tests/test-libsignaletic.html
using VS Code's Live Server plugin or other web server.
- Build libsignaletic
./build/native/libsignaletic-console-example
- Build libsignaletic Web Assembly
- Open
hosts/web/examples/midi-to-freq/index.html
using VS Code's Live Server plugin or other web server.
- If you haven't already, build the Docker image
docker build . -t signaletic
docker run --platform=linux/amd64 -v `pwd`:/signaletic signaletic /signaletic/cross-build-all.sh
- Use the Daisy Web Programmer to flash the
build/signaletic-bluemchen-looper.bin
binary to the Daisy board, or runmake program
while connected to an ST-Link Mini debugger.
Signaletic's core is written in C using the C99 standard (due to the use of C++ style comments, for loops with initial declarations, and float math functions like sinef and powf). It is currently compiled and tested on LLVM on macOS, GCC on Ubuntu Linux, and the Visual Studio C compiler on Windows.
On the Daisy platform, Signaletic is compiled using Daisy's own toolchain, which uses the gnu11 standard for C and gnu++14 for C++. Compiling the Daisy Host and examples is currently supported using GCC on macOS.
On the Web, Signaletic is compiled using the Emscripten compiler toolchain.
Signaletic is developed by Colin Clark and is licenced under the MIT License.