Skip to main content

simple_gain/
simple_gain.rs

1//! Simplest Possible Node: Gain Control
2//!
3//! This example shows the absolute minimum code needed to create
4//! a custom DSP node using the #[aether_node] macro.
5//!
6//! Run with: cargo run --example simple_gain -p aetherdsp-ndk
7
8use aether_ndk::prelude::*;
9
10/// Simple gain/volume control
11///
12/// This is the simplest possible DSP node - it just multiplies
13/// the input signal by a gain factor.
14#[aether_node]
15pub struct SimpleGain {
16    /// Gain amount (0.0 = silence, 1.0 = unity, 2.0 = double)
17    #[param(name = "Gain", min = 0.0, max = 2.0, default = 1.0)]
18    gain: f32,
19}
20
21impl DspProcess for SimpleGain {
22    fn process(
23        &mut self,
24        inputs: &NodeInputs,
25        output: &mut NodeOutput,
26        params: &mut ParamBlock,
27        _sample_rate: f32,
28    ) {
29        // Get input buffer (or silence if not connected)
30        let input = inputs.get(0);
31
32        // Get current gain value (smoothed automatically)
33        let gain = params.get(0).current;
34
35        // Process each sample
36        for (i, out) in output.iter_mut().enumerate() {
37            *out = input[i] * gain;
38            params.tick_all(); // Advance parameter smoothing
39        }
40    }
41}
42
43fn main() {
44    println!("AetherDSP NDK - Simple Gain Example");
45    println!("====================================\n");
46
47    // The #[aether_node] macro generated:
48    // - Default impl (using parameter defaults)
49    // - AetherNodeMeta trait (type_name, param_defs)
50    // - PARAM_COUNT constant
51
52    let gain = SimpleGain::default();
53
54    println!("✓ Created {} node", SimpleGain::type_name());
55    println!("✓ Parameter count: {}", SimpleGain::PARAM_COUNT);
56    println!("\nParameters:");
57
58    for def in SimpleGain::param_defs() {
59        println!("  • {} [{:.1}–{:.1}] default={:.2}",
60            def.name, def.min, def.max, def.default);
61    }
62
63    // Wrap for use in the engine
64    let _boxed: Box<dyn aether_ndk::DspNode> = into_node(gain);
65
66    println!("\n✓ Node wrapped and ready for the graph!");
67    println!("\n💡 This node can now be:");
68    println!("  • Added to an AudioGraph");
69    println!("  • Connected to other nodes");
70    println!("  • Controlled via parameters");
71    println!("  • Processed in real-time");
72}