NeuralAmpModeler-rs 3.0.2

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

//! Implementation of the CLAP render extension.
//!
//! NAM is deterministic and causal, so it has no hard realtime requirement.
//! In offline mode (bounce/export), `AdaptiveCompute` is forced to `Off`
//! so the model always processes at maximum quality without soft-degrade.
//!
//! See: `clap/ext/render.h`

use crate::clap::plugin::{NamClapMainThread, RENDER_MODE_OFFLINE, RENDER_MODE_REALTIME};
use clack_extensions::render::{PluginRender, PluginRenderImpl, RenderMode};
use clack_plugin::prelude::*;
use std::sync::atomic::Ordering;

/// Type alias for the CLAP render extension registration.
pub type NamPluginRender = PluginRender;

impl<'a> PluginRenderImpl for NamClapMainThread<'a> {
    fn has_hard_realtime_requirement(&self) -> bool {
        false
    }

    fn set(&mut self, mode: RenderMode) -> Result<(), PluginError> {
        let old_val = self.shared.cold.render_mode.load(Ordering::Acquire);
        let val = match mode {
            RenderMode::Realtime => RENDER_MODE_REALTIME,
            RenderMode::Offline => RENDER_MODE_OFFLINE,
        };

        if old_val != val {
            let old_mode = if old_val == RENDER_MODE_OFFLINE {
                "Offline"
            } else {
                "Realtime"
            };
            let new_mode = if val == RENDER_MODE_OFFLINE {
                "Offline"
            } else {
                "Realtime"
            };
            log::info!(
                "Render mode changed: {old_mode} -> {new_mode} \
                 (oversample={}, adaptive_compute=Off in Offline mode)",
                if val == RENDER_MODE_OFFLINE {
                    "max quality"
                } else {
                    "host-budget"
                }
            );
        }

        self.shared.cold.render_mode.store(val, Ordering::Release); // pairs with Acquire load em processor/events.rs:136
        Ok(())
    }
}