Changelog#

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[v2.3.0] - 2026-09-02#

anira v2.3.0 is the last release of the 2.x line. Development continues on the v3 branch (the versioned C ABI, docs/anira-v3-architecture.md); 2.x receives fixes only.

Added#

  • One-sided streaming (#98, #99, #110): generators are driven by output demand, analysers read through PrePostProcessor::get_output(), and the HostConfig reference stream may be an input or an output (m_tensor_is_input, HostConfig::k_first_streamable). Mirrored in the WebAssembly/TS wrapper.

  • ExecuTorch backend (ANIRA_WITH_EXECUTORCH, static-only): .pte programs, named entry points (model_function), prebuilt libraries for desktop, Android and iOS, a minimal-executorch example.

  • Receptive-field (sliding-window) models in the default PrePostProcessor: an input tensor larger than its preprocess_input_size is filled with ring-buffer history plus the fresh hop.

  • Context is immortal and owns the inference thread pool exactly while sessions exist (#104); Context::shutdown() for hosts that unload live, release_core_if_idle()/has_core() reclaim the core.

  • LatencyCalculator (#66) replaces SessionElement’s latency arithmetic: closed forms instead of the LCM loop, is_feasible(), correct struct and ring sizing for fractional and smaller host blocks. Derivation in docs/sphinx/latency.rst.

  • Symbol policy from the shared tanh-tooling CMake modules (cmake/tanh/): hidden visibility everywhere, libanira exports namespace anira only, plugins leak no backend runtime symbol; the anira_exports CTest enforces it.

  • CI on the shared tanh-lab/ci-actions workflows: every backend and both linkages in the PR tier, install, sanitizer (ASan+UBSan, TSan, RTSan) and coverage legs, a preset for every leg in CMakePresets.json, and the npm publish gated behind the same tests as every other release artifact.

Changed#

  • Breaking: the latency calculation moves out of SessionElement into LatencyCalculator; SessionElement loses its calculate_*, max_num_inferences and gcd/lcm helpers. Reported latencies are unchanged for whole-sample host blocks; slot counts follow 2·S.

  • Breaking: backend linkage follows BUILD_SHARED_LIBS and ANIRA_<ENGINE>_LINKAGE is gone: LibTorch (shared-only) is disabled in static builds, ExecuTorch (static-only) in shared builds.

  • Breaking: no public header includes an engine header, and the engines are explicit imported targets that anira links PRIVATE (anira::onnxruntime, anira::tflite, anira::litert, anira::libtorch, anira::executorch). Migration: link anira::<engine> wherever your own code includes an engine header.

  • Breaking (Windows install layout): DLLs install to bin/, import libraries and archives to lib/.

  • Breaking: logging goes through tanh-lib’s thl::Logger with a real-time queue (#56): ANIRA_LOG_*/ANIRA_LOG_RT_* replace the LOG_* stream macros, ContextConfig::m_log_level -> ContextConfig::m_log (anira::LogConfig), and the host owns the sinks.

  • Breaking: InferenceHandler::reset() is wait-free and safe on the audio thread. Migration: call prepare() where a drain was relied upon.

  • Breaking (containers): anira::Buffer<T>, anira::RingBuffer and anira::MemoryBlock<T> are aliases over tanh-lib’s thl::core containers; RingBuffer no longer derives from Buffer<float>, and every real-time ring-buffer access uses the block API (#111).

  • Context::get_instance() takes no arguments and returns a Context&; the ContextConfig travels with Context::create_session() (old two-step API deprecated for one minor release). anira::HighPriorityThread is deprecated for one release.

  • The active backend defaults to the first model backend that is available instead of the silent CUSTOM bypass; HostConfig’s default reference tensor is the first streamable tensor.

  • The export header is anira/system/Exports.h; ANIRA_BUILDING/ANIRA_STATIC replace ANIRA_EXPORTS/ANIRA_STATIC_DEFINE (old spellings honoured).

  • ExecuTorch is consumed as one merged libexecutorch.a per platform, and the CMake >= 3.24 desktop floor is gone. The test suite builds as per-component binaries (test_utils, test_scheduler, test_backends, test_handler).

  • Pins: tanh-lib 751b2b1, anira-project/backends v2.4.0 (ExecuTorch 1.3.1, pre-isolated static desktop LiteRT).

Removed#

  • Context::release_instance() and Context::release_thread_pool() (Context::shutdown() is the explicit teardown), the never-released reset_non_blocking() variants, the unreachable ContextConfig::operator==/!=, and the dead interpolation branch of anira::calculate_percentile.

Fixed#

  • Backend runtime symbols are no longer exported from binaries embedding anira, which crashed hosts that ship their own runtime (Ableton Live 12 bundles ONNX Runtime).

  • One-sided streaming: SessionElement::prepare() no longer hangs for generators or crashes for analysers, push-only pipelines no longer stall after m_num_structs chunks (#99), latency vectors are index-aligned with the outputs (#98).

  • Session lifecycle: Context::create_session() no longer leaks the session count when a processor constructor or prepare() throws (#106); create_session()/release_session()/prepare_session() are thread-safe across sessions; a data race in Context::release_session() (found by the TSan leg).

  • LatencyCalculator::least_common_multiple no longer overflows int, the allow_smaller_buffers sweep no longer stalls for large blocks, and the send ring of a fractional host block reserves P - 1 samples.

  • JsonConfigLoader drops malformed tensor_shape entries instead of letting nlohmann::type_error escape; LibtorchProcessor throws std::runtime_error on an unloadable model like the other backends; BackendBase::process no longer reads past the output vector.

  • USE_ANIRA_WEB is defined in Emscripten builds only; installing on lib64 hosts works with LibTorch and ExecuTorch; anira::HighPriorityThread links again in a Windows consumer of a shared anira; the JUCE example links under clang on Linux.

  • Tests and CI: the macOS test-discovery race with CMake 4.4.0 (DISCOVERY_MODE PRE_TEST), the intermittently failing one-sided blocking-deadline tests, downloads retried after transient failures, and compile caching that works for the first time (ACTIONS_CACHE_SERVICE_V2).

[v2.2.1] - 2026-07-04#

Added#

  • Batched overlapping-window extraction: a pop_samples_from_buffer(...) overload that extracts num_batches windows in one native call (also exposed to WebAssembly/TS), avoiding per-batch JS↔Wasm boundary crossings for batched/windowed models (e.g. HybridNN/GuitarLSTM).

  • PrePostProcessor::before_inference() / after_inference() hooks, run on the inference thread right before/after the backend runs, letting stateful models (e.g. recurrent hidden-state feedback) splice state between consecutive inferences when combined with session_exclusive_processor = true. Wired up end-to-end in Anira Web (registerPrePostProcessor/beforeInference()/afterInference() on the TS side).

  • Configurable inference-thread wait strategy: anira::WaitStrategy { SpinBackoff, Blocking } on ContextConfig. Blocking lets idle inference threads sleep on a semaphore instead of spin-polling, eliminating idle CPU usage at effectively no throughput cost; coerced to SpinBackoff with a warning on WebAssembly.

  • Real-time factor and underrun reporting in the benchmark fixture (per-iteration RTF/[underrun] marker, plus an optional summary line with rtf_mean/rtf_max/underrun count).

  • The advanced and cnn-size benchmarks now also cover the CUSTOM (no-inference) backend, and the benchmark CI workflow builds with tests enabled and runs the benchmark gtest suites.

  • Configurable log level: anira::LogLevel { Debug, Info, Warning, Error } on ContextConfig, gating anira’s own logging and forwarded to the ONNX Runtime, LiteRT and LibTorch backends (TFLite excepted — no runtime logging control in that prebuilt library). Defaults to Info in debug builds, Error in release builds.

  • Anira version mismatch reporting in Context::get_instance: a differing major version between sessions is now reported as an error, a differing minor/patch as a warning.

  • Context::get_num_inference_threads() / InferenceHandler::get_num_inference_threads(): number of inference threads currently active process-wide (also exported to WASM).

Changed#

  • ContextConfig’s default num_threads is now platform-dependent: half the available CPU cores (as before) on native builds, 0 on WebAssembly, since inference threads there are always supplied externally via AniraWeb.spinUpInferenceWorker().

Fixed#

  • Stateful in-order dispatch (session_exclusive_processor = true) no longer allocates on the audio thread — SessionElement’s pending-dispatch queue is now pre-sized and fed through an explicit producer token.

  • Web: the audio worklet now polyfills performance.now() before the WASM module loads, fixing a ReferenceError (observed in Firefox) whenever a blocking-ratio deadline was read from the audio thread.

  • The advanced benchmark no longer instantiates ONNX Runtime for the stateful RNN model, whose fixed 2048-sample ONNX export failed warm-up at other buffer sizes.

  • Use-after-free when a pooled backend processor outlived the session that created it — InferenceConfig is now owned per-processor instead of aliasing the originating session’s copy.

  • Windows build failure in Context::get_instance() caused by <windows.h>’s min/max macros mangling an unrelated std::min(...) call; fixed by defining NOMINMAX/WIN32_LEAN_AND_MEAN before the include.

  • Hardened SessionElement::m_is_non_real_time to std::atomic<bool> and unified the two new_data_request() wait paths onto one wait_for_completion() helper — previously a default-blocking_ratio session in non-real-time mode could free an in-flight buffer while the inference thread was still writing to it. Non-real-time mode also now works on WebAssembly once an inference worker is running.

[v2.2.0] - 2026-06-23#

Added#

  • Android support (arm64-v8a + x86_64): the library, the prebuilt backends, and the full gtest suite running on a KVM-accelerated emulator, all wired into CI (build_test_mobile.yml). The glibc-only pthread_*inheritsched / pthread_setattr_default_np calls are gated behind !__ANDROID__ (bionic lacks them) while keeping the portable SCHED_FIFO path.

  • iOS support (device + simulator): the library and prebuilt backends shipped as an xcframework, with the full gtest suite running on the simulator in CI. Per-SDK xcframework slice selection; TFLite is consumed as a TensorFlowLiteC.framework via a generated shim so anira’s <tensorflow/lite/...> includes resolve untouched.

  • LiteRT inference backend (anira::InferenceBackend::LITERT): runs .tflite models through Google’s native LiteRt* C API / CompiledModel runtime. Enabled by default (ANIRA_WITH_LITERT=ON) as the modern TensorFlow-Lite-family backend; wired into the examples and benchmarks.

  • Data-driven backend downloads: prebuilt backends are fetched at configure time from the anira-project/backends release, pinned by ANIRA_BACKENDS_VERSION.

  • Live backend integrity check: when GitHub is reachable, anira fetches each asset’s published SHA256 and re-downloads any backend whose archive changed upstream or downloaded incompletely, instead of a committed hash lock. ANIRA_BACKENDS_SKIP_REMOTE_CHECK=ON skips the remote query for offline/reproducible builds.

  • Bring-your-own-backend knobs: ANIRA_<ENGINE>_ROOTDIR (prebuilt tree), ANIRA_<ENGINE>_URL + ANIRA_<ENGINE>_SHA256 (custom source), and per-engine ANIRA_<ENGINE>_LINKAGE=shared|static.

  • clang-tidy conformance across the library, tests and benchmark sources, enforced in CI via the tanh-lab/ci-actions/clang-tidy-check action (clang_tidy.yml)

  • InstallConsumer smoke test that builds against the installed package to catch packaging regressions.

  • Release pipeline now publishes every tested arch×linkage artifact with backend-consistent naming: Android (static), iOS (xcframework), and Linux/macOS/Windows × shared/static, including macOS universal.

Changed#

  • Breaking: the InferenceConfig::Defaults compile-time constants were renamed from the m_ prefix to the k_ prefix to match the constant-naming convention (m_warm_up → k_warm_up, m_session_exclusive_processor → k_session_exclusive_processor, m_blocking_ratio → k_blocking_ratio). The mutable Defaults::m_num_parallel_processors is unchanged.

  • LiteRT is now the default TensorFlow-Lite-family backend. The legacy TensorFlow Lite backend (the older TfLite* C API, ANIRA_WITH_TFLITE) is the same runtime exposed through a different C API, so the two are now mutually exclusive — enable the legacy path with -DANIRA_WITH_LITERT=OFF -DANIRA_WITH_TFLITE=ON.

  • nlohmann_json is now consumed as a release download instead of a git submodule.

  • CMake options and their validation were consolidated inline into CMakeLists.txt (AniraOptions.cmake and the redundant linkage knob were dropped).

  • anira::calculate_min / anira::calculate_max are now inline free functions instead of const auto lambdas (source-compatible: existing call sites and uses as a callable are unaffected)

  • The internal logging helper isLoggingEnabled() was renamed to is_logging_enabled()

  • Migrated the shared clang configs (.clang-format/.clang-tidy/.clangd) from the tanh-lib submodule symlinks to tanh-tooling (pinned v0.1.4): committed as real files, kept in sync by the clang_check.yml drift check, and the now-unused tanh-lib submodule was removed (configs are byte-identical, so lint/format results are unchanged)

  • Adopted the default Claude Code config: .claude/settings.json now enables the tanh-tools plugin from the tanh-tooling marketplace (its format/lint/type-check hooks supersede the previous bespoke .claude/hooks)

  • CI now covers Windows-arm64, Linux-aarch64 and macOS-universal legs (shared + static) in addition to the mobile workflow.

Fixed#

  • Potential use-after-free in Buffer::malloc_channels() when channel-pointer allocation fails

  • Installed nlohmann_json config so find_package(anira) works against the installed package

  • Disabled backends now compile to empty translation units (guarded .cpp bodies), and minimal-onnxruntime is self-sufficient in static builds

  • Value-initialize the const InferenceConfig in the install consumer

  • clang-tidy violations and a CLAP static MSVC runtime mismatch; preserve the anira-before-JuceHeader include order on MSVC; qualified mem* calls with std:: and added <cstring>

  • Windows shared-DLL copy, the examples target list, and arm64 LibTorch in CI

[v2.1.0] - 2026-06-14#

Added#

  • anira Web: the C++ library compiled to WebAssembly via Emscripten, published as the @anira-project/anira npm package

    • Emscripten/embind C++ wrappers exposing the core API (InferenceHandler, InferenceConfig, PrePostProcessor, ProcessingSpec, InferenceThread, Buffer, RingBuffer, HostConfig) to JavaScript

    • TypeScript API layer wrapping these bindings (AniraWeb, plus typed wrappers for InferenceHandler, InferenceConfig, ModelData, TensorShape, ProcessingSpec, BufferF, RingBuffer, HostConfig and the embind Vector types)

    • New ONNXRuntimeWebBackend (onnxruntime-web), plus JSBackendBase/JSPrePostProcessor hooks for implementing custom inference backends and pre/post processing in JavaScript/TypeScript

    • Web Audio API integration with an AudioWorklet base class and Web Worker–based off-thread inference

    • WASM build tooling (BuildWasm.cmake, DetectEmscripten.cmake, CMake presets), npm publish workflows, and dedicated Web API documentation (Sphinx + TypeDoc)

  • anira::Semaphore wrapper for macOS 10.13 support

  • macOS universal binary support: anira can now be built as a universal binary (arm64 + x86_64) when no pre-built backends are enabled (e.g. for a custom CoreML backend)

  • tanh-lib submodule with clang-format and clang-tidy support

  • Unregistering of pre/post processors and a prePostRegistry

  • Validation that the maximum inference time must be greater than 0

  • Function for freeing the stack pointer

  • Sponsor information in the README

Changed#

  • Enforce stateful model inference ordering via single-in-flight dispatch instead of spin-wait

  • MSVC: support static linking via ANIRA_STATIC_DEFINE

  • Refactored processPrePost

  • Improved GitHub Actions workflows (node24, new workflow versions, no env vars)

  • Added Prettier formatting

Fixed#

  • Fixed a Windows build bug

  • Fixed the documentation build step

  • Fixed npm version drift (pinned onnxruntime-web to 1.19.2)

[v2.0.3] - 2025-11-07#

Added#

  • JSON configuration loader (JsonConfigLoader) with nlohmann_json dependency, including unit tests

  • Option to load LibTorch models as binary data

  • model_function argument for model_data in the JsonConfigLoader

  • JSON gain example config and JUCE plugin example with JSON inference config loading

  • no_grad options for torch tensors and the inference stage (Fixes #45)

Fixed#

  • JUCE plugin example failing to compile when MODEL_TO_USE is set to 6

  • No-inference-engine CI build (JsonConfigLoader excluded from the no_inference_engine build)

  • Missing preprocessor flag in RaveFunkDrumConfig.h

[v2.0.2] - 2025-08-03#

Added#

  • New pop_data methods with wait_until

  • Support for TFlite Binary Models

Changed#

  • Improved latency calculation to take parallel processing into account

  • All operating systems now use std::steady_clock for benchmarking

  • Tests for Inference Manager and Session Element now use fixed number of threads 2, which is available on all gh runners

Fixed#

  • Ringbuffer initialization now initializes the buffer with zero values

  • Fixed the realtime sanitizer build option

  • Fixed blocking operation in the InferenceHandler process method

[v2.0.1] - 2025-07-31#

Changed#

  • Updated CI to build anira without inference engines to avoid missing preprocessor flags

Fixed#

  • Ensure missing preprocessor flags are set for disabled backends

  • Add virtual destructor to PrePostProcessor to avoid polymorphic cleanup issues

[v2.0.0] - 2025-07-28#

Added#

  • New custom trained RAVE model in examples

  • Defaults struct inside InferenceConfig

  • Support for offline audio processing

  • Option to disable std::cout and std::cerr output

  • Possibility to load ONNX models as binary files

  • InferenceHandler reset method with comprehensive tests

  • Dynamic ring buffer allocation with overflow protection

  • Test cases for latency calculation, dynamic ring buffer allocation, and inference struct calculation

  • Custom latency preparation functionality

  • Jack dependency for Linux JUCE applications

  • Comprehensive Doxygen documentation with beautiful Shibuya theme

  • Added ProcessingSpecs to the InferenceConfig class for better handling of input and output tensor specifications

  • Added changelog documentation page

Changed#

  • Major update: New shape handling and sizes management

  • Major update: Support for non-audio input and non-audio output

  • Major update: Support for multiple streamable and non-streamable tensors

  • Major update: Input tensor sample rate must not be equal to output tensor sample rate anymore

  • Refined latency calculation system:

    • Now supports smaller buffer sizes than host config (with allow_smaller_buffers flag)

    • Moved calculation logic to SessionElement

    • Better handling of models with internal latency

  • Renamed HostAudioConfig to HostConfig

  • Renamed AudioBuffer to Buffer

  • Improved catchup and handling of missing samples

  • Different backends can have different shapes while maintaining consistent processingSpecs

  • Removed USE_CONTROLLED_BLOCKING preprocessor definition

  • Removed external host thread possibility

  • Complete documentation overhaul with new theme and structure

Fixed#

  • Race condition in InferenceThread where derived class context was destroyed before base class destructor (PR #31)

  • Project version compatibility when adding as subdirectory (PR #30)

  • Internal latency management issues (PR #32)

  • Build bugs and compiler warnings

  • GitHub workflow issues

  • Install script for nlohmann library

  • CMakeLists configuration issues

[v1.0.3] - 2025-01-24#

Fixed#

  • Fixed bug where version could not be detected when imported as a submodule

Added#

  • Possibility to package as .deb package

  • New checks and tests

[v1.0.2] - 2024-12-06#

Added#

  • Full support for armv7l platform on Linux

  • Benchmarks part of test suite when making pull requests

  • Multiple improvements in CMake build chain

Changed#

  • Bela examples now in separate repository

Fixed#

  • Fixed Windows test suite

[v1.0.1] - 2024-11-20#

Fixed#

  • Fixes #11: Issue where the concurrentqueue lib would not be found in the prebuilt binaries or installed lib

[v1.0.0] - 2024-11-13#

Added#

  • Major update with API changes (see anira usage guide or examples for more information)

  • Multichannel support

  • Support for input and output of multiple tensors including threadsafe methods to retrieve and pass their state in the anira::PrePostProcessor

  • New anira::Context that uses the same thread pool independent of the anira::InferenceConfig the anira::InferenceHandler has been initialized with

  • CLAP plugin example

  • Enhanced inference job submission

[v0.1.3] - 2024-09-23#

Changed#

  • Updated libtorch to 2.4.1

Fixed#

  • Fixes issue libomp not bundled with libtorch for macOS arm64

  • x86_64 macOS stays with 2.2.2 since new version binaries are not built by pytorch

[v0.1.2] - 2024-09-14#

Added#

  • New timestamps via counting inference buffers

  • Enhanced thread synchronization and data sharing between threads

  • Windows Ninja generator support

  • Enhanced Windows dynamic libs

  • New default values in InferenceConfig

  • Updated documentation

Changed#

  • Default threadsafe structs switched to atomic

  • Port to new organization

Fixed#

  • Solved debug build issues with Windows

[v0.1.1] - 2024-08-28#

Added#

  • New Bela support and examples

  • New thread synchronisation option with raw atomics

[v0.1.0] - 2024-05-20#

Changed#

  • New anira::InferenceConfig layout

[v0.0.8] - 2024-05-15#

Improved#

  • Improved latency calculation

[v0.0.7] - 2024-04-27#

Changed#

  • Version 0.0.7 release

[v0.0.6] - 2024-04-17#

Changed#

  • Version 0.0.6 release

[v0.0.5] - 2024-04-11#

Changed#

  • Version 0.0.5 release

[v0.0.4] - 2024-04-01#

Changed#

  • Version 0.0.4 release

[v0.0.3] - 2024-03-30#

Changed#

  • Updated Windows CI workflow

[v0.0.2] - 2024-03-27#

Changed#

  • Version 0.0.2 release

[v0.0.1] - 2024-03-23#

Added#

  • Initial release (Version 0.0.1)