nam_rs/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 Fรกbio Henrique de Lima Silva (fhl.bsb@gmail.com) All rights reserved.
3#![warn(missing_docs)]
4
5//! # ๐ธ Neural Amp Modeler (NAM-rs)
6//!
7//! **NAM-rs** is a high-performance, real-time inference engine and DSP foundation in Rust for
8//! [Neural Amp Modeler (NAM)](https://www.neuralampmodeler.com/) neural network models
9//! (WaveNet A1 and A2, LSTM, ConvNet, Linear) and impulse response (.wav) convolutions.
10//!
11//! > **Notice:** The public crate is published on crates.io as [**`NeuralAmpModeler-rs`**](https://crates.io/crates/NeuralAmpModeler-rs) since some dude took my name during the phase na-rs wa in development.
12//! > It's currently in **public alpha** stage (despite the version number).
13//! > In Rust code, import modules via `use nam_rs::...`, and run the standalone CLI binary as `nam-rs`.
14//! > Feedback, bug reports, suggestions and testing are very welcome!
15//! > Official project repository & issues: <https://github.com/fabiohl/nam-rs>
16//!
17//! ---
18//!
19//! ## ๐ก Overview
20//!
21//! This crate serves as the shared foundation ("heart") of the NAM-rs ecosystem, providing:
22//! - **SIMD-Accelerated Inference Kernels**: Native `x86-64-v3` (AVX2 + FMA) and `AVX-512` math routines.
23//! - **Flexible Model Loader**: Parser and builder for `.nam` (JSON) and `.namb` (binary profile) files.
24//! - **Lock-Free DSP Engine**: Zero heap allocations on the audio processing hot-path.
25//! - **Multi-Target Substrate**: Powering both the standalone PipeWire CLI (`main.rs`) and DAW plugins (CLAP format).
26//!
27//! ---
28//!
29//! ## ๐ Feature Flags & Recommended Dependency Setup
30//!
31//! NAM-rs uses Cargo feature flags to isolate backends and keep downstream compilation lean.
32//!
33//! > โ ๏ธ **Important for Library Integrators:**
34//! > By default, Cargo enables the `standalone` feature, which pulls in native Linux PipeWire (`libpipewire`) system dependencies.
35//! > When integrating `nam-rs` as a library into third-party crates (DAWs, audio plugins, or server pipelines), it is **strongly recommended**
36//! > to disable default features (`default-features = false`) to avoid pulling unused system audio drivers or conflicting dependencies into your build tree.
37//!
38//! ### `Cargo.toml` Configuration Examples
39//!
40//! **Pure Core DSP & Model Inference (Recommended for third-party crates):**
41//! ```toml
42//! [dependencies]
43//! NeuralAmpModeler-rs = { version = "3.0.2", default-features = false }
44//! ```
45//!
46//! **Adding Off-RT Testing & Audio Signal Generators:**
47//! ```toml
48//! [dependencies]
49//! NeuralAmpModeler-rs = { version = "3.0.2", default-features = false, features = ["testing"] }
50//! ```
51//!
52//! **Building Native PipeWire Standalone Audio Clients:**
53//! ```toml
54//! [dependencies]
55//! NeuralAmpModeler-rs = { version = "3.0.2", features = ["standalone"] }
56//! ```
57//!
58//! ### Feature Flags Summary Table
59//!
60//! | Feature Flag | Default | Description |
61//! |:------------- |:----------------:|:-------------------------------------------------------------------------------------------------- |
62//! | `standalone` | Yes | Enables native Linux PipeWire audio backend and CLI execution (`standalone` module). |
63//! | `clap-plugin` | No | Enables CLAP (CLever Audio Plug-in) plugin format and egui GUI (`clap` module). |
64//! | `testing` | No | Exposes off-RT test utilities, audio signal generators, and perceptual metrics (`testing` module). |
65//! | `stereo` | Via `standalone` | Enables multi-channel / stereo dual-model loader support. |
66//!
67//! ---
68//!
69//! ## ๐ Quick Start โ Loading & Building a Model
70//!
71//! The [`loader::load_and_build_model`] function reads `.nam` (JSON) or `.namb` (binary) files and
72//! constructs optimized [`models::StaticModel`] instances ready for real-time execution.
73//!
74//! ```rust
75//! use std::path::Path;
76//! use nam_rs::loader::{load_and_build_model, LoadOptions};
77//! use nam_rs::SystemSnapshot;
78//!
79//! // Capture system capabilities (SIMD feature set, CPU topology)
80//! let sys = SystemSnapshot::capture();
81//!
82//! // Load a model file (.nam or .namb)
83//! let model_pair = load_and_build_model(
84//! Path::new(concat!(
85//! env!("CARGO_MANIFEST_DIR"),
86//! "/tests/fixtures/models/linear_test.nam",
87//! )),
88//! &sys,
89//! false, // mono execution (set true for stereo)
90//! LoadOptions::default(),
91//! )
92//! .expect("Failed to load model");
93//!
94//! assert_eq!(model_pair.architecture, "Linear");
95//! assert!(model_pair.model_l.is_some());
96//! assert!(model_pair.model_r.is_none()); // Mono load: right channel is None
97//! assert!(model_pair.sample_rate > 0);
98//! ```
99//!
100//! ---
101//!
102//! ## โก FastMath & SIMD Vector Activations
103//!
104//! High-performance scalar activation functions are available directly in [`math::activations`]:
105//!
106//! ```rust
107//! use nam_rs::math::activations::{tanh, sigmoid};
108//!
109//! // Padรฉ [5,4] rational approximant, clamped to [-1.0, 1.0]
110//! let t = tanh(1.0);
111//! assert!((t - 0.761594).abs() < 1e-3);
112//! assert!(tanh(10.0) <= 1.0);
113//! assert!(tanh(-10.0) >= -1.0);
114//!
115//! // Degree-17 minimax polynomial, clamped to [0.0, 1.0]
116//! let s = sigmoid(0.0);
117//! assert!((s - 0.5).abs() < 1e-2);
118//! assert!(sigmoid(10.0) > 0.999);
119//! assert!(sigmoid(-10.0) < 0.001);
120//! ```
121//!
122//! For slice-based processing that automatically selects vectorized SIMD kernels (AVX2/AVX-512),
123//! use `tanh_slice` and `sigmoid_slice` from [`math::activations`].
124//!
125//! ---
126//!
127//! ## ๐บ Crate Module Map
128//!
129//! | Module | Purpose | Key Entry Points & Types |
130//! |:------------ |:--------------------------------------------------------------- |:---------------------------------------------------------------- |
131//! | [`loader`] | Model deserialization & construction (`.nam`, `.namb`) | [`loader::load_and_build_model`], [`loader::LoadOptions`] |
132//! | [`math`] | Mathematical primitives, SIMD kernels, & activations | [`math::activations`] |
133//! | [`models`] | Neural network architectures & static topologies | [`models::StaticModel`], WaveNet, LSTM, ConvNet |
134//! | [`dsp`] | Digital signal processing engine & oversampling | [`dsp::gate::GateParams`], [`dsp::oversample::OversampleEngine`] |
135//! | [`common`] | Diagnostics, atomic bitmasks, & SPSC queues | [`common::RtStatusFlags`], [`common::alloc_audit`] |
136//! | `standalone` | Native PipeWire driver & CLI (requires `standalone`) | PipeWire Graph Engine integration |
137//! | `clap` | CLAP DAW plugin & egui GUI (requires `clap-plugin`) | CLAP plugin entrypoint |
138//! | `testing` | Off-RT test utilities & perceptual metrics (requires `testing`) | Audio validation and f64 Oracles |
139//!
140//! ---
141//!
142//! ## ๐ก Real-Time Safety & Performance Guarantees
143//!
144//! NAM-rs is engineered for **absolute real-time safety** on the audio processing thread (`SCHED_FIFO`).
145//! The following guarantees are enforced at the architecture level:
146//!
147//! ### 1. Zero Heap Allocations on Hot-Path
148//! Heap objects (`Box`, `Vec`, `Arc`, `String`) are **never** allocated or dropped on the real-time audio thread.
149//! All dynamic resources are allocated off-RT and swapped via lock-free SPSC channels ([`common::spsc`]).
150//! Compile-time allocation auditing is available via [`common::alloc_audit`].
151//!
152//! ### 2. Zero Blocking I/O
153//! No `println!`, `eprintln!`, `format!`, file I/O, or blocking synchronization primitives are permitted on the RT thread.
154//! State transitions are signaled atomically via [`common::RtStatusFlags`].
155//!
156//! ### 3. Denormal Protection (FTZ + DAZ)
157//! Subnormal (denormal) floating-point numbers cause severe performance degradation (up to 100ร slowdown).
158//! NAM-rs configures **Flush-To-Zero (FTZ)** and **Denormals-Are-Zero (DAZ)** at initialization and periodically
159//! reasserts them on the hot path ([`math::common::set_daz_ftz`]).
160//!
161//! ### 4. Panic-Free Hot Path
162//! Stack unwinding (panics) breaks hard real-time determinism.
163//! Processing hot paths avoid `unwrap()`/`expect()` in favor of explicit fallback bounds checks.
164//!
165//! ### 5. Lock-Free Cache-Isolated Concurrency
166//! Shared structures RT โ Main use `#[repr(align(128))]` to eliminate false sharing on CPU cache lines.
167//! Inter-thread SPSC buffers use `Acquire`/`Release` atomic ordering.
168//!
169//! ---
170//!
171//! ## ๐ License
172//!
173//! Licensed under the **Apache License, Version 2.0**.
174//! Official repository: <https://github.com/fabiohl/nam-rs>
175
176#[cfg(not(target_arch = "x86_64"))]
177compile_error!("NAM-rs requires x86_64 architecture");
178
179/// Common host-agnostic infrastructure layer.
180pub mod common;
181pub use common::*;
182
183/// Infrastructure for standalone execution (PipeWire + CLI).
184#[cfg(feature = "standalone")]
185pub mod standalone;
186#[cfg(feature = "standalone")]
187pub use standalone::*;
188
189/// CLAP plugin format integration.
190#[cfg(feature = "clap-plugin")]
191pub mod clap;
192
193/// Digital signal processing (DSP) engine.
194pub mod dsp;
195/// Model loading and construction (.nam, .namb).
196pub mod loader;
197/// Mathematical primitives and optimized SIMD kernels.
198pub mod math;
199/// Tensor definitions and neural network topologies.
200pub mod models;
201/// Testing utilities (signal generation, perceptual metrics, WAV I/O).
202#[cfg(any(test, feature = "testing"))]
203pub mod testing;
204
205// Backward compatibility with older GLIBC versions (e.g. for Flatpak/Bitwig).
206// Redirects math symbols to the stable GLIBC_2.2.5 version.
207// Since external dependencies use these symbols, we declare global wrappers
208// that intercept calls and jump (jmp) via PLT to the compatible versions.
209#[cfg(all(target_os = "linux", target_env = "gnu"))]
210core::arch::global_asm!(
211 ".global log10f",
212 ".type log10f, @function",
213 "log10f:",
214 " jmp log10f_compat@PLT",
215 ".symver log10f_compat, log10f@GLIBC_2.2.5",
216 ".global atan2f",
217 ".type atan2f, @function",
218 "atan2f:",
219 " jmp atan2f_compat@PLT",
220 ".symver atan2f_compat, atan2f@GLIBC_2.2.5",
221 ".global acosf",
222 ".type acosf, @function",
223 "acosf:",
224 " jmp acosf_compat@PLT",
225 ".symver acosf_compat, acosf@GLIBC_2.2.5"
226);