Skip to main content

Crate nam_rs

Crate nam_rs 

Source
Expand description

§🎸 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) 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 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).

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):

[dependencies]
NeuralAmpModeler-rs = { version = "3.0.2", default-features = false }

Adding Off-RT Testing & Audio Signal Generators:

[dependencies]
NeuralAmpModeler-rs = { version = "3.0.2", default-features = false, features = ["testing"] }

Building Native PipeWire Standalone Audio Clients:

[dependencies]
NeuralAmpModeler-rs = { version = "3.0.2", features = ["standalone"] }

Β§Feature Flags Summary Table

Feature FlagDefaultDescription
standaloneYesEnables native Linux PipeWire audio backend and CLI execution (standalone module).
clap-pluginNoEnables CLAP (CLever Audio Plug-in) plugin format and egui GUI (clap module).
testingNoExposes off-RT test utilities, audio signal generators, and perceptual metrics (testing module).
stereoVia standaloneEnables 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.

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:

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

ModulePurposeKey Entry Points & Types
loaderModel deserialization & construction (.nam, .namb)loader::load_and_build_model, loader::LoadOptions
mathMathematical primitives, SIMD kernels, & activationsmath::activations
modelsNeural network architectures & static topologiesmodels::StaticModel, WaveNet, LSTM, ConvNet
dspDigital signal processing engine & oversamplingdsp::gate::GateParams, dsp::oversample::OversampleEngine
commonDiagnostics, atomic bitmasks, & SPSC queuescommon::RtStatusFlags, common::alloc_audit
standaloneNative PipeWire driver & CLI (requires standalone)PipeWire Graph Engine integration
clapCLAP DAW plugin & egui GUI (requires clap-plugin)CLAP plugin entrypoint
testingOff-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

Re-exportsΒ§

pub use common::*;

ModulesΒ§

clap
CLAP plugin format integration. Integration of NAM-rs as a plugin in CLAP (CLever Audio Plug-in) format.
common
Common host-agnostic infrastructure layer. Modules shared between the standalone version and plugin.
dsp
Digital signal processing (DSP) engine. Digital Signal Processing (DSP) module for generic operations before and after the neural engine in NAM-rs.
loader
Model loading and construction (.nam, .namb). Loading module for the NAM ecosystem.
math
Mathematical primitives and optimized SIMD kernels. Root module for mathematical operations and neural inference kernels.
models
Tensor definitions and neural network topologies. Neural Inference Architectures (Brain Engines) module for NAM-rs.
testing
Testing utilities (signal generation, perceptual metrics, WAV I/O). Testing utilities for NAM-rs cross-validation and signal generation.

MacrosΒ§

activation_simd_avx2
AVX2 activation slice kernel: 16-wide (dual __m256) loop then 8-wide (single __m256) remainder.
activation_simd_avx512
AVX-512 activation slice kernel: 16-wide (single __m512) loop.
config_table
Generates a SimdMathConfig with static descriptive fields only.
dispatch_simd
Macro for dynamic SIMD dispatch based on global configuration.
dot4x_simd4
4-wide SIMD loop β€” caller owns $i (used for __m128 f32 variants; ISA-neutral).
dot4x_simd8_avx2
8-wide SIMD loop β€” caller owns $i.
dot4x_simd8_avx2_tail2
8-wide SIMD loop + 2-wide tail β€” caller owns $i.
dot4x_simd16_avx2
16-wide SIMD loop β€” caller owns $i.
gain_kernel_avx2
8-wide SIMD loop + scalar tail (caller owns i).
gain_kernel_avx512_masked
16-wide SIMD loop + masked tail (caller owns i).
gain_kernel_avx512_scalar
16-wide SIMD loop + scalar tail (caller owns i).
gain_simd_avx2
8-wide SIMD loop only (caller handles tail).
gain_simd_avx512
16-wide SIMD loop only (caller handles tail).
gemm_batch_frame_loop_avx2
4-frame batch outer loop β€” caller owns $f and $num_frames.
gemm_batch_inner_dual_avx2
Dual-column inner loop + odd tail β€” caller owns $in_c.
gemm_batch_outc_loop_avx2
8-wide output channel loop + scalar tail β€” caller owns $out_c.
gemv_4gate_inner_dual_avx2
8-wide SIMD dual-column inner loop + odd tail β€” caller owns $in_c.
gemv_4gate_simd_outer_avx2
8-wide SIMD outer loop + scalar tail β€” caller owns $out_c and $in_c.
gemv_f32_inner_loop_avx2
8-accumulator inner loop (step 8) for batched f32 GEMV with AVX2 β€” caller owns $in_c.
gemv_kernel
GEMV kernel macro β€” generates platform-specific FMADD accumulate loops.
impl_convolve_mono
Generates a mono convolution function (single coeff set, one input channel).
impl_convolve_mono_dual
Generates a mono dual convolution function (two coeff sets, one input channel).
impl_convolve_stereo
Generates a stereo convolution function (single coeff set, two input channels).
impl_convolve_stereo_dual
Generates a stereo dual convolution function (two coeff sets, two input channels).
wavenet_simd_avx2
8-wide SIMD loop only (caller handles scalar tail via #[cold] fn).