NeuralAmpModeler-rs 3.0.0

An opinionated, high-performance Neural Amp Modeler (NAM) client and core implementation in Rust for Linux/PipeWire and CLAP plugins.
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2026 Fรกbio Henrique de Lima Silva (fhl.bsb@gmail.com) All rights reserved.
#![warn(missing_docs)]

//! # ๐ŸŽธ Neural Amp Modeler (NAM-rs)
//!
//! **NAM-rs** is a high-performance, real-time inference engine and DSP foundation in Rust for
//! [Neural Amp Modeler (NAM)](https://www.neuralampmodeler.com/) neural network models
//! (WaveNet A1 and A2, LSTM, ConvNet, Linear) and impulse response (.wav) convolutions.
//!
//! > **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.
//! > It's currently in **public alpha** stage (despite the version number).
//! > In Rust code, import modules via `use nam_rs::...`, and run the standalone CLI binary as `nam-rs`.
//! > Feedback, bug reports, suggestions and testing are very welcome!
//! > Official project repository & issues: <https://github.com/fabiohl/nam-rs>
//!
//! ---
//!
//! ## ๐Ÿ’ก Overview
//!
//! This crate serves as the shared foundation ("heart") of the NAM-rs ecosystem, providing:
//! - **SIMD-Accelerated Inference Kernels**: Native `x86-64-v3` (AVX2 + FMA) and `AVX-512` math routines.
//! - **Flexible Model Loader**: Parser and builder for `.nam` (JSON) and `.namb` (binary profile) files.
//! - **Lock-Free DSP Engine**: Zero heap allocations on the audio processing hot-path.
//! - **Multi-Target Substrate**: Powering both the standalone PipeWire CLI (`main.rs`) and DAW plugins (CLAP format).
//!
//! ---
//!
//! ## ๐Ÿ›  Feature Flags & Recommended Dependency Setup
//!
//! NAM-rs uses Cargo feature flags to isolate backends and keep downstream compilation lean.
//!
//! > โš ๏ธ **Important for Library Integrators:**
//! > By default, Cargo enables the `standalone` feature, which pulls in native Linux PipeWire (`libpipewire`) system dependencies.
//! > When integrating `nam-rs` as a library into third-party crates (DAWs, audio plugins, or server pipelines), it is **strongly recommended**
//! > to disable default features (`default-features = false`) to avoid pulling unused system audio drivers or conflicting dependencies into your build tree.
//!
//! ### `Cargo.toml` Configuration Examples
//!
//! **Pure Core DSP & Model Inference (Recommended for third-party crates):**
//! ```toml
//! [dependencies]
//! NeuralAmpModeler-rs = { version = "3.0.0", default-features = false }
//! ```
//!
//! **Adding Off-RT Testing & Audio Signal Generators:**
//! ```toml
//! [dependencies]
//! NeuralAmpModeler-rs = { version = "3.0.0", default-features = false, features = ["testing"] }
//! ```
//!
//! **Building Native PipeWire Standalone Audio Clients:**
//! ```toml
//! [dependencies]
//! NeuralAmpModeler-rs = { version = "3.0.0", features = ["standalone"] }
//! ```
//!
//! ### Feature Flags Summary Table
//!
//! | Feature Flag  | Default          | Description                                                                                        |
//! |:------------- |:----------------:|:-------------------------------------------------------------------------------------------------- |
//! | `standalone`  | Yes              | Enables native Linux PipeWire audio backend and CLI execution (`standalone` module).               |
//! | `clap-plugin` | No               | Enables CLAP (CLever Audio Plug-in) plugin format and egui GUI (`clap` module).                    |
//! | `testing`     | No               | Exposes off-RT test utilities, audio signal generators, and perceptual metrics (`testing` module). |
//! | `stereo`      | Via `standalone` | Enables multi-channel / stereo dual-model loader support.                                          |
//!
//! ---
//!
//! ## ๐Ÿš€ Quick Start โ€” Loading & Building a Model
//!
//! The [`loader::load_and_build_model`] function reads `.nam` (JSON) or `.namb` (binary) files and
//! constructs optimized [`models::StaticModel`] instances ready for real-time execution.
//!
//! ```rust
//! use std::path::Path;
//! use nam_rs::loader::{load_and_build_model, LoadOptions};
//! use nam_rs::SystemSnapshot;
//!
//! // Capture system capabilities (SIMD feature set, CPU topology)
//! let sys = SystemSnapshot::capture();
//!
//! // Load a model file (.nam or .namb)
//! let model_pair = load_and_build_model(
//!     Path::new(concat!(
//!         env!("CARGO_MANIFEST_DIR"),
//!         "/tests/fixtures/models/linear_test.nam",
//!     )),
//!     &sys,
//!     false, // mono execution (set true for stereo)
//!     LoadOptions::default(),
//! )
//! .expect("Failed to load model");
//!
//! assert_eq!(model_pair.architecture, "Linear");
//! assert!(model_pair.model_l.is_some());
//! assert!(model_pair.model_r.is_none()); // Mono load: right channel is None
//! assert!(model_pair.sample_rate > 0);
//! ```
//!
//! ---
//!
//! ## โšก FastMath & SIMD Vector Activations
//!
//! High-performance scalar activation functions are available directly in [`math::activations`]:
//!
//! ```rust
//! use nam_rs::math::activations::{tanh, sigmoid};
//!
//! // Padรฉ [5,4] rational approximant, clamped to [-1.0, 1.0]
//! let t = tanh(1.0);
//! assert!((t - 0.761594).abs() < 1e-3);
//! assert!(tanh(10.0) <= 1.0);
//! assert!(tanh(-10.0) >= -1.0);
//!
//! // Degree-17 minimax polynomial, clamped to [0.0, 1.0]
//! let s = sigmoid(0.0);
//! assert!((s - 0.5).abs() < 1e-2);
//! assert!(sigmoid(10.0) > 0.999);
//! assert!(sigmoid(-10.0) < 0.001);
//! ```
//!
//! For slice-based processing that automatically selects vectorized SIMD kernels (AVX2/AVX-512),
//! use `tanh_slice` and `sigmoid_slice` from [`math::activations`].
//!
//! ---
//!
//! ## ๐Ÿ—บ Crate Module Map
//!
//! | Module       | Purpose                                                         | Key Entry Points & Types                                         |
//! |:------------ |:--------------------------------------------------------------- |:---------------------------------------------------------------- |
//! | [`loader`]   | Model deserialization & construction (`.nam`, `.namb`)          | [`loader::load_and_build_model`], [`loader::LoadOptions`]        |
//! | [`math`]     | Mathematical primitives, SIMD kernels, & activations            | [`math::activations`]                                            |
//! | [`models`]   | Neural network architectures & static topologies                | [`models::StaticModel`], WaveNet, LSTM, ConvNet                  |
//! | [`dsp`]      | Digital signal processing engine & oversampling                 | [`dsp::gate::GateParams`], [`dsp::oversample::OversampleEngine`] |
//! | [`common`]   | Diagnostics, atomic bitmasks, & SPSC queues                     | [`common::RtStatusFlags`], [`common::alloc_audit`]               |
//! | `standalone` | Native PipeWire driver & CLI (requires `standalone`)            | PipeWire Graph Engine integration                                |
//! | `clap`       | CLAP DAW plugin & egui GUI (requires `clap-plugin`)             | CLAP plugin entrypoint                                           |
//! | `testing`    | Off-RT test utilities & perceptual metrics (requires `testing`) | Audio validation and f64 Oracles                                 |
//!
//! ---
//!
//! ## ๐Ÿ›ก Real-Time Safety & Performance Guarantees
//!
//! NAM-rs is engineered for **absolute real-time safety** on the audio processing thread (`SCHED_FIFO`).
//! The following guarantees are enforced at the architecture level:
//!
//! ### 1. Zero Heap Allocations on Hot-Path
//! Heap objects (`Box`, `Vec`, `Arc`, `String`) are **never** allocated or dropped on the real-time audio thread.
//! All dynamic resources are allocated off-RT and swapped via lock-free SPSC channels ([`common::spsc`]).
//! Compile-time allocation auditing is available via [`common::alloc_audit`].
//!
//! ### 2. Zero Blocking I/O
//! No `println!`, `eprintln!`, `format!`, file I/O, or blocking synchronization primitives are permitted on the RT thread.
//! State transitions are signaled atomically via [`common::RtStatusFlags`].
//!
//! ### 3. Denormal Protection (FTZ + DAZ)
//! Subnormal (denormal) floating-point numbers cause severe performance degradation (up to 100ร— slowdown).
//! NAM-rs configures **Flush-To-Zero (FTZ)** and **Denormals-Are-Zero (DAZ)** at initialization and periodically
//! reasserts them on the hot path ([`math::common::set_daz_ftz`]).
//!
//! ### 4. Panic-Free Hot Path
//! Stack unwinding (panics) breaks hard real-time determinism.
//! Processing hot paths avoid `unwrap()`/`expect()` in favor of explicit fallback bounds checks.
//!
//! ### 5. Lock-Free Cache-Isolated Concurrency
//! Shared structures RT โ†” Main use `#[repr(align(128))]` to eliminate false sharing on CPU cache lines.
//! Inter-thread SPSC buffers use `Acquire`/`Release` atomic ordering.
//!
//! ---
//!
//! ## ๐Ÿ“œ License
//!
//! Licensed under the **Apache License, Version 2.0**.
//! Official repository: <https://github.com/fabiohl/nam-rs>

#[cfg(not(target_arch = "x86_64"))]
compile_error!("NAM-rs requires x86_64 architecture");

/// Common host-agnostic infrastructure layer.
pub mod common;
pub use common::*;

/// Infrastructure for standalone execution (PipeWire + CLI).
#[cfg(feature = "standalone")]
pub mod standalone;
#[cfg(feature = "standalone")]
pub use standalone::*;

/// CLAP plugin format integration.
#[cfg(feature = "clap-plugin")]
pub mod clap;

/// Digital signal processing (DSP) engine.
pub mod dsp;
/// Model loading and construction (.nam, .namb).
pub mod loader;
/// Mathematical primitives and optimized SIMD kernels.
pub mod math;
/// Tensor definitions and neural network topologies.
pub mod models;
/// Testing utilities (signal generation, perceptual metrics, WAV I/O).
#[cfg(any(test, feature = "testing"))]
pub mod testing;

// Backward compatibility with older GLIBC versions (e.g. for Flatpak/Bitwig).
// Redirects math symbols to the stable GLIBC_2.2.5 version.
// Since external dependencies use these symbols, we declare global wrappers
// that intercept calls and jump (jmp) via PLT to the compatible versions.
#[cfg(all(target_os = "linux", target_env = "gnu"))]
core::arch::global_asm!(
    ".global log10f",
    ".type log10f, @function",
    "log10f:",
    "    jmp log10f_compat@PLT",
    ".symver log10f_compat, log10f@GLIBC_2.2.5",
    ".global atan2f",
    ".type atan2f, @function",
    "atan2f:",
    "    jmp atan2f_compat@PLT",
    ".symver atan2f_compat, atan2f@GLIBC_2.2.5",
    ".global acosf",
    ".type acosf, @function",
    "acosf:",
    "    jmp acosf_compat@PLT",
    ".symver acosf_compat, acosf@GLIBC_2.2.5"
);