- CMake 3.15+
- C++17 compiler (clang, gcc, or MSVC)
- Git (CMake FetchContent downloads LabSound's dependencies automatically)
LabSound is expected as a sibling directory:
some_folder/
LabSound/ # https://github.com/LabSound/LabSound
LabSoundC/ # this project
Or set -DLABSOUND_ROOT=/path/to/LabSound at configure time.
cd LabSoundC
cmake -B build .
cmake --build buildThis produces:
| Artifact | Path |
|---|---|
| Static library | build/libLabSoundC.a |
| Shared library | build/libLabSoundC.dylib (macOS) / .so (Linux) / .dll (Windows) |
| Smoke test | build/labsoundc_smoke |
| Demo app | build/labsoundc_demo |
| Option | Default | Description |
|---|---|---|
LABSOUNDC_BUILD_SHARED |
ON |
Build the shared library (needed for Python) |
LABSOUNDC_BUILD_EXAMPLES |
ON |
Build smoke test and demo |
LABSOUND_USE_RTAUDIO |
platform | Use RtAudio backend (default on macOS, Linux) |
LABSOUND_USE_MINIAUDIO |
platform | Use miniaudio backend (default on Windows, iOS, Android) |
macOS links automatically against AudioToolbox, AudioUnit, Accelerate, CoreAudio, Cocoa.
Linux requires one of: ALSA (-DLABSOUND_ASOUND=ON), PulseAudio (-DLABSOUND_PULSE=ON), or JACK (-DLABSOUND_JACK=ON). PulseAudio is the default. Install the dev packages:
# Debian/Ubuntu
sudo apt install libpulse-dev # or libasound2-dev / libjack-devWindows uses WASAPI via miniaudio by default. No extra dependencies.
./build/labsoundc_smoke # prints registry, plays 440 Hz for 1 second
./build/labsoundc_demo # plays 4 procedural audio effects
./build/labsoundc_demo 1 # just the red alertThe Python bindings use ctypes and load the shared library at runtime. No compilation step for Python itself — just build the shared library and point Python at it.
cd LabSoundC
cmake -B build .
cmake --build build --target LabSoundC_sharedOption A — environment variable (recommended):
export LABSOUNDC_LIB=/path/to/LabSoundC/build/libLabSoundC.dylibOption B — the module auto-searches ../../build/ relative to labsoundc/__init__.py, so running from within the repo works without any configuration:
cd LabSoundC/bindings/python
python3 examples/demo_red_alert.py # finds ../../../build/libLabSoundC.dylibOption C — install system-wide (copy the .dylib somewhere on your library path):
# macOS
sudo cp build/libLabSoundC.dylib /usr/local/lib/
# Linux
sudo cp build/libLabSoundC.so /usr/local/lib/
sudo ldconfigFor development, just add the bindings directory:
export PYTHONPATH=/path/to/LabSoundC/bindings/python:$PYTHONPATHOr copy/symlink labsoundc/ into your project's package directory.
There is no setup.py or pyproject.toml — the binding is a single-file module with zero Python dependencies. Copy it wherever you need it.
cd LabSoundC/bindings/python
python3 examples/demo_red_alert.py # Star Trek red alert
python3 examples/demo_bird.py # twittering bird chirps
python3 examples/demo_marble.py # marble rattling in a tin can
python3 examples/demo_train.py # train passing left to rightimport labsoundc as ls
with ls.Context() as ctx:
osc = ctx.create_node("Oscillator")
gain = ctx.create_node("Gain")
gain.param("gain").value = 0.25
ls.connect(osc.output(0), gain.input(0))
ls.connect(gain.output(0), ctx.destination_node.input(0))
osc.start()
import time; time.sleep(1)The Zig bindings link against the LabSoundC static library. You must build the C library first, then use the Zig build system.
cd LabSoundC
cmake -B build .
cmake --build buildcd bindings/zig
zig build runThe build.zig expects the CMake build output at ../../build/. It links:
libLabSoundC.afrom../../build/LabSound.frameworkfrom../../build/bin/LabSoundRtAudiofrom../../build/bin/libnyquistfrom../../build/_deps/libnyquist-build/lib/- macOS frameworks (AudioToolbox, AudioUnit, Accelerate, CoreAudio, Cocoa)
- libc++ (for C++ runtime)
If your CMake build directory is elsewhere, edit the paths at the top of build.zig:
const labsoundc_lib_path = b.path("../../build"); // adjust
const labsound_framework_path = b.path("../../build/bin"); // adjustCopy labsoundc.zig into your project and add it as a module:
// In your build.zig
const ls_mod = b.addModule("labsoundc", .{
.root_source_file = b.path("path/to/labsoundc.zig"),
});
ls_mod.addIncludePath(b.path("path/to/LabSoundC/include"));
exe.root_module.addImport("labsoundc", ls_mod);
exe.addLibraryPath(b.path("path/to/LabSoundC/build"));
exe.linkSystemLibrary("LabSoundC");
// ... plus LabSound, backend, and platform libs as shown in build.zigThen in your source:
const ls = @import("labsoundc");
pub fn main() !void {
var ctx = ls.Context.init(null);
defer ctx.deinit();
const osc = ctx.createNode("Oscillator");
const dest = ctx.destinationNode();
ls.connect(&ctx, osc.output(&ctx, 0), dest.input(&ctx, 0));
osc.start(&ctx, 0.0);
std.time.sleep(std.time.ns_per_s);
}cd LabSoundC/bindings/zig
zig build run # plays all 4 procedural effects
zig build run -- 1 # just the red alert