Skip to content

feat: add NAM neural amp modeler stage#243

Merged
OpenSauce merged 3 commits into
mainfrom
feat/nam-stage
May 30, 2026
Merged

feat: add NAM neural amp modeler stage#243
OpenSauce merged 3 commits into
mainfrom
feat/nam-stage

Conversation

@OpenSauce
Copy link
Copy Markdown
Owner

Summary

Adds a Neural Amp Modeler (NAM) stage that runs WaveNet .nam models (via the nam-rs crate) as a registered, composable amp-chain stage. Drop .nam files into a folder; all models load into memory at startup and are selectable per stage.

What's included

Core (rustortion-core)

  • src/nam/NamLoader scans a folder and parses every *.nam into memory (tolerant: bad files skipped, missing dir is fine), feeding a process-global registry so to_runtime resolves models by name without changing its signature.
  • src/amp/stages/nam.rsNamStage (wraps nam-rs WaveNet) + NamConfig. process() = input-gain → model → output-gain → dry/wet mix. Passthrough on no model / not found / sample-rate mismatch / build error (warns, never panics).
  • Nam wired into StageType/StageConfig (category: Amp).

UI (rustortion-ui)

  • NAM stage card: model pick-list (from the registry), input/output level (±24 dB), mix, and a read-only native-rate / "not found" info line. Selection routes through the existing NeedsStageRebuild → rebuild_stage → ReplaceStage path.
  • One line added to gui_stage_registry!; apply_stage_config de-consted (model name is a String). EN + ZH_CN keys; minimap abbreviation NAM.

Standalone

  • nam_dir setting (default ./nam, serde-defaulted so old configs load); registry populated in Manager::new.

Plugin

  • Registry populated from ~/.config/rustortion/nam in initialize() (off the audio thread). NamSlotParams added (input/output/mix/bypass) for host visibility, automation lanes, and persistence — parity with the other 10 stages.

Behaviour

  • Sample-rate mismatch → load + warn (flagged in the info line), no panic.
  • Model choice + knobs persist in presets and DAW project state (chain_state serializes model_name).

Notes

  • Sample-rate mismatch is warn-only (no resampling around the model); plugin per-slot params follow the existing convention (declared for host visibility/persistence — there is no generic slot→engine real-time sync for any stage yet).

Testing

  • make lint clean (-D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery).
  • make test — all tests pass, including the RT no-alloc suite.

Add a Neural Amp Modeler (NAM) stage that runs WaveNet .nam models via the
nam-rs crate as a registered, composable amp-chain stage.

- core: nam module with a folder loader and a process-global parsed-model
  registry; NamStage/NamConfig wrapping nam-rs WaveNet, with input/output
  gain, dry/wet mix, and passthrough fallback on missing model, sample-rate
  mismatch, or build error (warn, never panic)
- ui: NAM stage card with model pick-list, gain/mix sliders, and a read-only
  native-rate info line; EN + ZH_CN locale keys
- standalone: nam_dir setting (default ./nam); registry populated at startup
- plugin: registry populated from ~/.config/rustortion/nam in initialize();
  NamSlotParams added for host visibility/automation parity with other stages

Models are loaded from a nam/ folder into memory at startup and selected
per stage; the choice persists in presets and DAW project state.
Copilot AI review requested due to automatic review settings May 30, 2026 19:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Neural Amp Modeler (NAM) stage to the Rustortion amp chain, including model discovery/loading, a process-global model registry, UI controls, and standalone/plugin integration so .nam models can be selected and used at runtime.

Changes:

  • Introduces rustortion-core::nam (loader + process-global registry) and a new NamStage/NamConfig wired into StageType/StageConfig.
  • Adds NAM UI stage card (model picker + gain/mix controls) and i18n/minimap support.
  • Loads NAM models on startup in standalone and plugin, and adds plugin-exposed per-slot NAM parameters.

Reviewed changes

Copilot reviewed 16 out of 18 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
rustortion-ui/src/stages/nam.rs New NAM stage UI card (model selection + gain/mix) and message/apply plumbing.
rustortion-ui/src/stages/mod.rs Registers NAM stage in the GUI stage registry; de-const apply function.
rustortion-ui/src/i18n/mod.rs Adds EN/ZH_CN translation keys for NAM UI labels.
rustortion-ui/src/components/minimap.rs Adds “NAM” abbreviation for minimap rendering.
rustortion-standalone/src/settings/mod.rs Adds nam_dir setting with serde default for backward compatibility.
rustortion-standalone/src/audio/manager.rs Initializes NAM loader and populates global registry at standalone startup.
rustortion-plugin/src/params.rs Adds NamSlotParams and nests an 8-slot NAM param array for host visibility/persistence.
rustortion-plugin/src/lib.rs Initializes NAM loader/registry from ~/.config/rustortion/nam during plugin init.
rustortion-core/src/preset/stage_config.rs Adds StageType::Nam and StageConfig::Nam, wiring NAM into runtime creation and bypass accessors.
rustortion-core/src/nam/registry.rs New process-global registry for parsed NAM models (name → Arc<NamModel>).
rustortion-core/src/nam/mod.rs New NAM module exports (loader + registry).
rustortion-core/src/nam/loader.rs New directory scanner/parser for *.nam model files (tolerant loading).
rustortion-core/src/lib.rs Exposes the new nam module from rustortion-core.
rustortion-core/src/amp/stages/nam.rs Implements NamStage + NamConfig and stage parameter handling.
rustortion-core/src/amp/stages/mod.rs Exposes the new nam stage module.
rustortion-core/Cargo.toml Adds nam-rs dependency (currently via git branch).
nam/.gitkeep Adds an (empty) default NAM models directory to the repo.
Cargo.lock Records the resolved nam-rs git dependency in the lockfile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rustortion-core/src/amp/stages/nam.rs Outdated
Comment on lines +8 to +11
/// Convert decibels to a linear amplitude multiplier.
fn db_to_linear(db: f32) -> f32 {
10.0_f32.powf(db / 20.0)
}
Comment on lines +52 to +55
"input_gain_db" => {
self.input_gain = db_to_linear(value);
Ok(())
}
Comment on lines +56 to +59
"output_gain_db" => {
self.output_gain = db_to_linear(value);
Ok(())
}
Comment on lines +128 to +135
let native_sample_rate = model.sample_rate() as f32;
let sample_rate_mismatch = (native_sample_rate - sample_rate).abs() > 1.0;
if sample_rate_mismatch {
warn!(
"NAM model '{name}' native rate {native_sample_rate} Hz differs from engine \
rate {sample_rate} Hz; tone may be affected"
);
}
Comment thread rustortion-core/src/nam/loader.rs Outdated
Comment on lines +38 to +40
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) != Some("nam") {
Comment thread rustortion-ui/src/stages/nam.rs Outdated
Comment on lines +71 to +72
// Read-only model info: native rate / mismatch warning.
let info_line: Element<'_, Message> = match model_name.as_deref() {
Comment on lines +60 to +66
let model_selector = row![
text(tr!(nam_model)).width(Length::FillPortion(3)),
pick_list(models, model_name.clone(), move |name| {
Message::Stage(idx, StageMessage::Nam(NamMessage::ModelSelected(name)))
})
.placeholder(tr!(nam_no_model))
.width(Length::FillPortion(7)),
Comment thread rustortion-core/Cargo.toml Outdated
realfft = "3.5"
arc-swap = "1.8"
assert_no_alloc = { version = "1.1", features = ["warn_debug"] }
nam-rs = { git = "https://github.com/OpenSauce/nam-rs", branch = "main" }
OpenSauce added 2 commits May 30, 2026 21:12
Switch from the git branch dependency to the crates.io release now that
nam-rs 0.1.0 is published. The lockfile records a checksum, so builds are
fully reproducible.
- validate input/output gain to +/-24 dB in set_parameter (rejects NaN/inf)
  and clamp gain/mix in to_stage for hand-edited presets
- reuse shared db_to_lin helper instead of a local duplicate
- log read_dir entry errors in the NAM loader instead of silently dropping them
- add a '(None)' pick-list entry so a selected model can be cleared to passthrough
- correct the misleading info-line comment (engine rate isn't available in the view)
@OpenSauce OpenSauce merged commit 5a03229 into main May 30, 2026
7 checks passed
@OpenSauce OpenSauce deleted the feat/nam-stage branch May 30, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants