1pub mod node;
39pub mod param;
40pub mod registry;
41pub mod schema;
42
43pub use aether_ndk_macro::aether_node;
44
45pub use aether_core::{
47 node::DspNode,
48 param::ParamBlock,
49 state::StateBlob,
50 BUFFER_SIZE, MAX_INPUTS,
51};
52
53#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
56pub struct ParamDef {
57 pub name: &'static str,
58 pub min: f32,
59 pub max: f32,
60 pub default: f32,
61}
62
63pub trait AetherNodeMeta {
65 fn type_name() -> &'static str;
66 fn param_defs() -> &'static [ParamDef];
67}
68
69pub trait DspProcess: Send {
72 fn process(
73 &mut self,
74 inputs: &NodeInputs,
75 output: &mut NodeOutput,
76 params: &mut ParamBlock,
77 sample_rate: f32,
78 );
79
80 fn capture_state(&self) -> StateBlob { StateBlob::EMPTY }
81 fn restore_state(&mut self, _state: StateBlob) {}
82}
83
84pub struct NodeInputs<'a> {
86 pub raw: &'a [Option<&'a [f32; BUFFER_SIZE]>; MAX_INPUTS],
87}
88
89impl<'a> NodeInputs<'a> {
90 pub fn get(&self, slot: usize) -> &[f32; BUFFER_SIZE] {
91 static SILENCE: [f32; BUFFER_SIZE] = [0.0f32; BUFFER_SIZE];
92 self.raw.get(slot).and_then(|s| *s).unwrap_or(&SILENCE)
93 }
94}
95
96pub type NodeOutput = [f32; BUFFER_SIZE];
98
99pub struct NodeAdapter<T: DspProcess + AetherNodeMeta> {
102 pub inner: T,
103}
104
105impl<T: DspProcess + AetherNodeMeta + 'static> DspNode for NodeAdapter<T> {
106 fn process(
107 &mut self,
108 inputs: &[Option<&[f32; BUFFER_SIZE]>; MAX_INPUTS],
109 output: &mut [f32; BUFFER_SIZE],
110 params: &mut ParamBlock,
111 sample_rate: f32,
112 ) {
113 let wrapped = NodeInputs { raw: inputs };
114 self.inner.process(&wrapped, output, params, sample_rate);
115 }
116
117 fn capture_state(&self) -> StateBlob { self.inner.capture_state() }
118 fn restore_state(&mut self, state: StateBlob) { self.inner.restore_state(state); }
119 fn type_name(&self) -> &'static str { T::type_name() }
120}
121
122pub fn into_node<T>(node: T) -> Box<dyn DspNode>
125where
126 T: DspProcess + AetherNodeMeta + 'static,
127{
128 Box::new(NodeAdapter { inner: node })
129}
130
131pub mod prelude {
133 pub use super::{
134 aether_node, into_node, AetherNodeMeta, DspProcess, NodeInputs,
135 NodeOutput, ParamDef,
136 };
137 pub use aether_core::param::ParamBlock;
138 pub use aether_core::state::StateBlob;
139 pub use aether_core::{BUFFER_SIZE, MAX_INPUTS};
140}