Getting Started#

Prerequisites#

  • A C++20 compiler (Clang, GCC or MSVC)

  • CMake 3.25 or newer

  • Optional: just for the recipes in the justfile; Doxygen, Graphviz and Python 3 to build this documentation

The third-party dependencies (nlohmann_json for State, miniaudio for AudioIO, googletest and google-benchmark for the tests) are fetched by CMake. The Net component links the platform HTTP stack (NSURLSession, WinHTTP, libcurl or HttpURLConnection over JNI) and is off by default.

Build#

cmake --preset desktop-debug          # or: cmake . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build --preset desktop-debug --parallel
ctest --preset desktop-debug

With just:

just build            # cmake --preset desktop-debug + build
just test             # build + ctest
just build-release

The CMake presets in CMakePresets.json cover desktop, iOS (simulator and device), Android, Windows, WebAssembly and the sanitizer configurations.

CMake options#

Option

Default

Description

BUILD_SHARED_LIBS

ON

Build as shared libraries

TANH_BUILD_CORE

ON

Build the Core component

TANH_BUILD_STATE

ON

Build the State component

TANH_BUILD_DSP

ON

Build the DSP (and Resonator) component

TANH_BUILD_MODULATION

ON

Build the Modulation component

TANH_BUILD_AUDIO_IO

ON

Build the AudioIO component

TANH_BUILD_NET

OFF

Build the Net component (links a platform HTTP stack)

TANH_WITH_TESTS

ON

Build test targets

TANH_WITH_EXAMPLES

ON

Build the example projects (iOS audio-io app)

TANH_WITH_DOCS

OFF

Add the sphinx-docs target (Doxygen + Sphinx)

TANH_WITH_INSTALL

ON

Add install targets and the tanh CMake package

TANH_WITH_PACKAGING

OFF

Add CPack targets (top-level builds only)

TANH_WITH_RTSAN / _ASAN / _USAN / _TSAN / _MSAN / _LSAN

OFF

Enable the respective sanitizer (RTSan needs Clang 20+)

TANH_WITH_JOURNALD

OFF

Linux: route platform logs to systemd-journald

TANH_LOG_COMPILED_MAX_LEVEL

AUTO

Most verbose log level compiled in (1 Error .. 4 Debug)

Consume#

As a subdirectory or through FetchContent:

set(TANH_WITH_TESTS OFF)
set(TANH_WITH_EXAMPLES OFF)
add_subdirectory(modules/tanh-lib)

target_link_libraries(app PRIVATE tanh::Core tanh::DSP)

tanh::Core links no platform-specific system library by default (the Android log library is the only exception), so it can be embedded by permissively licensed projects without extra system dependencies. Emscripten builds are detected as their own platform and use the plain stdout/stderr log sink.

Install and find_package#

cmake . -B build -DTANH_WITH_TESTS=OFF -DTANH_WITH_EXAMPLES=OFF
cmake --build build
cmake --install build --prefix /opt/tanh
find_package(tanh REQUIRED COMPONENTS Core)   # Core State DSP Resonator Modulation AudioIO Net
target_link_libraries(app PRIVATE tanh::Core)

test/install is a minimal consumer of the installed package; CI builds it against a fresh install prefix in the merge queue (just test-install locally). The exported target names match the in-tree ALIAS targets, so consumers link the same tanh::<Component> whether they add_subdirectory or find_package. A parent project that embeds tanh-lib via FetchContent and installs its own package can leave TANH_WITH_INSTALL on: the components join its install prefix and the parent’s Config.cmake re-resolves them with find_dependency(tanh COMPONENTS Core).

Run the tests#

just test                                   # everything through ctest
just test-filter PATTERN                    # ctest -R PATTERN
./build/desktop/Debug/test/dsp/test_dsp     # one suite directly
./build/desktop/Debug/test/dsp/test_dsp --gtest_filter="TestSuite.TestName"

just test-audio runs the AudioIO suite; just test-hardware additionally runs the tests that need a real audio device.

Rings reference fixtures#

The Rings resonator tests compare output against reference data generated from the original Mutable Instruments code. Without fixtures, these tests are skipped (the build still succeeds).

To generate fixtures (requires SSH access to the tanh-lab/mutable-instrument-api repository):

./test/dsp/generate_reference_fixtures.sh

This clones the upstream repository, builds the reference generators and writes .bin fixtures to test/dsp/fixtures/. Then rebuild and run:

cmake --build build --target test_dsp
./build/test/dsp/test_dsp

The fixture files are not checked into version control.

Build this documentation#

just docs
# or
cmake -S . -B build/docs -DTANH_WITH_DOCS=ON -DTANH_WITH_TESTS=OFF -DTANH_WITH_EXAMPLES=OFF
cmake --build build/docs --target sphinx-docs

The HTML lands in build/docs/docs/sphinx/html/. Sphinx and its extensions are installed into a virtual environment inside the build tree; Doxygen and Graphviz have to be on the PATH.