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 theHostConfigreference 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):.pteprograms, named entry points (model_function), prebuilt libraries for desktop, Android and iOS, aminimal-executorchexample.Receptive-field (sliding-window) models in the default
PrePostProcessor: an input tensor larger than itspreprocess_input_sizeis filled with ring-buffer history plus the fresh hop.Contextis 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) replacesSessionElement’s latency arithmetic: closed forms instead of the LCM loop,is_feasible(), correct struct and ring sizing for fractional and smaller host blocks. Derivation indocs/sphinx/latency.rst.Symbol policy from the shared tanh-tooling CMake modules (
cmake/tanh/): hidden visibility everywhere,libaniraexports namespaceaniraonly, plugins leak no backend runtime symbol; theanira_exportsCTest enforces it.CI on the shared
tanh-lab/ci-actionsworkflows: every backend and both linkages in the PR tier, install, sanitizer (ASan+UBSan, TSan, RTSan) and coverage legs, a preset for every leg inCMakePresets.json, and the npm publish gated behind the same tests as every other release artifact.
Changed#
Breaking: the latency calculation moves out of
SessionElementintoLatencyCalculator;SessionElementloses itscalculate_*,max_num_inferencesand gcd/lcm helpers. Reported latencies are unchanged for whole-sample host blocks; slot counts follow2·S.Breaking: backend linkage follows
BUILD_SHARED_LIBSandANIRA_<ENGINE>_LINKAGEis 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: linkanira::<engine>wherever your own code includes an engine header.Breaking (Windows install layout): DLLs install to
bin/, import libraries and archives tolib/.Breaking: logging goes through tanh-lib’s
thl::Loggerwith a real-time queue (#56):ANIRA_LOG_*/ANIRA_LOG_RT_*replace theLOG_*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: callprepare()where a drain was relied upon.Breaking (containers):
anira::Buffer<T>,anira::RingBufferandanira::MemoryBlock<T>are aliases over tanh-lib’sthl::corecontainers;RingBufferno longer derives fromBuffer<float>, and every real-time ring-buffer access uses the block API (#111).Context::get_instance()takes no arguments and returns aContext&; theContextConfigtravels withContext::create_session()(old two-step API deprecated for one minor release).anira::HighPriorityThreadis deprecated for one release.The active backend defaults to the first model backend that is available instead of the silent
CUSTOMbypass;HostConfig’s default reference tensor is the first streamable tensor.The export header is
anira/system/Exports.h;ANIRA_BUILDING/ANIRA_STATICreplaceANIRA_EXPORTS/ANIRA_STATIC_DEFINE(old spellings honoured).ExecuTorch is consumed as one merged
libexecutorch.aper 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()andContext::release_thread_pool()(Context::shutdown()is the explicit teardown), the never-releasedreset_non_blocking()variants, the unreachableContextConfig::operator==/!=, and the dead interpolation branch ofanira::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 afterm_num_structschunks (#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 orprepare()throws (#106);create_session()/release_session()/prepare_session()are thread-safe across sessions; a data race inContext::release_session()(found by the TSan leg).LatencyCalculator::least_common_multipleno longer overflowsint, theallow_smaller_bufferssweep no longer stalls for large blocks, and the send ring of a fractional host block reservesP - 1samples.JsonConfigLoaderdrops malformedtensor_shapeentries instead of lettingnlohmann::type_errorescape;LibtorchProcessorthrowsstd::runtime_erroron an unloadable model like the other backends;BackendBase::processno longer reads past the output vector.USE_ANIRA_WEBis defined in Emscripten builds only; installing onlib64hosts works with LibTorch and ExecuTorch;anira::HighPriorityThreadlinks 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 extractsnum_batcheswindows 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 withsession_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 }onContextConfig.Blockinglets idle inference threads sleep on a semaphore instead of spin-polling, eliminating idle CPU usage at effectively no throughput cost; coerced toSpinBackoffwith a warning on WebAssembly.Real-time factor and underrun reporting in the benchmark fixture (per-iteration RTF/
[underrun]marker, plus an optional summary line withrtf_mean/rtf_max/underrun count).The
advancedandcnn-sizebenchmarks now also cover theCUSTOM(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 }onContextConfig, 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 toInfoin debug builds,Errorin 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 defaultnum_threadsis now platform-dependent: half the available CPU cores (as before) on native builds,0on WebAssembly, since inference threads there are always supplied externally viaAniraWeb.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 aReferenceError(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 —
InferenceConfigis now owned per-processor instead of aliasing the originating session’s copy.Windows build failure in
Context::get_instance()caused by<windows.h>’smin/maxmacros mangling an unrelatedstd::min(...)call; fixed by definingNOMINMAX/WIN32_LEAN_AND_MEANbefore the include.Hardened
SessionElement::m_is_non_real_timetostd::atomic<bool>and unified the twonew_data_request()wait paths onto onewait_for_completion()helper — previously a default-blocking_ratiosession 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-onlypthread_*inheritsched/pthread_setattr_default_npcalls are gated behind!__ANDROID__(bionic lacks them) while keeping the portableSCHED_FIFOpath.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.frameworkvia a generated shim so anira’s<tensorflow/lite/...>includes resolve untouched.LiteRT inference backend (
anira::InferenceBackend::LITERT): runs.tflitemodels through Google’s nativeLiteRt*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/backendsrelease, pinned byANIRA_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=ONskips 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-engineANIRA_<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-checkaction (clang_tidy.yml)InstallConsumersmoke 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 macOSuniversal.
Changed#
Breaking: the
InferenceConfig::Defaultscompile-time constants were renamed from them_prefix to thek_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 mutableDefaults::m_num_parallel_processorsis 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_jsonis now consumed as a release download instead of a git submodule.CMake options and their validation were consolidated inline into
CMakeLists.txt(AniraOptions.cmakeand the redundant linkage knob were dropped).anira::calculate_min/anira::calculate_maxare nowinlinefree functions instead ofconst autolambdas (source-compatible: existing call sites and uses as a callable are unaffected)The internal logging helper
isLoggingEnabled()was renamed tois_logging_enabled()Migrated the shared clang configs (
.clang-format/.clang-tidy/.clangd) from thetanh-libsubmodule symlinks totanh-tooling(pinnedv0.1.4): committed as real files, kept in sync by theclang_check.ymldrift check, and the now-unusedtanh-libsubmodule was removed (configs are byte-identical, so lint/format results are unchanged)Adopted the default Claude Code config:
.claude/settings.jsonnow enables thetanh-toolsplugin from the tanh-tooling marketplace (its format/lint/type-check hooks supersede the previous bespoke.claude/hooks)CI now covers Windows-
arm64, Linux-aarch64and macOS-universallegs (shared + static) in addition to the mobile workflow.
Fixed#
Potential use-after-free in
Buffer::malloc_channels()when channel-pointer allocation failsInstalled
nlohmann_jsonconfig sofind_package(anira)works against the installed packageDisabled backends now compile to empty translation units (guarded
.cppbodies), andminimal-onnxruntimeis self-sufficient in static buildsValue-initialize the
const InferenceConfigin the install consumerclang-tidy violations and a CLAP static MSVC runtime mismatch; preserve the anira-before-
JuceHeaderinclude order on MSVC; qualifiedmem*calls withstd::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/aniranpm packageEmscripten/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/JSPrePostProcessorhooks for implementing custom inference backends and pre/post processing in JavaScript/TypeScriptWeb 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::Semaphorewrapper for macOS 10.13 supportmacOS 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_DEFINERefactored 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_functionargument formodel_datain the JsonConfigLoaderJSON 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)