bbx_dsp/plugin.rs
1//! Plugin DSP trait for FFI integration.
2//!
3//! This module defines the `PluginDsp` trait that consumers implement
4//! to define their plugin's DSP processing chain.
5
6use bbx_midi::MidiEvent;
7
8use crate::context::DspContext;
9
10/// Trait for plugin-specific DSP implementations.
11///
12/// Consumers implement this trait to define their audio processing chain.
13/// The FFI layer uses this trait to manage the DSP lifecycle.
14///
15/// # Example
16///
17/// ```ignore
18/// use bbx_dsp::{PluginDsp, context::DspContext};
19/// use bbx_dsp::blocks::effectors::gain::GainBlock;
20///
21/// pub struct PluginGraph {
22/// pub gain: GainBlock<f32>,
23/// }
24///
25/// impl PluginDsp for PluginGraph {
26/// fn new() -> Self {
27/// Self { gain: GainBlock::new(0.0) }
28/// }
29///
30/// fn prepare(&mut self, context: &DspContext) {
31/// // Initialize blocks for the given sample rate/buffer size
32/// }
33///
34/// fn reset(&mut self) {
35/// // Clear filter states, etc.
36/// }
37///
38/// fn apply_parameters(&mut self, params: &[f32]) {
39/// // Map parameter array to block fields
40/// }
41///
42/// fn process(&mut self, inputs: &[&[f32]], outputs: &mut [&mut [f32]], midi_events: &[MidiEvent], context: &DspContext) {
43/// // Process audio and MIDI through the chain
44/// }
45/// }
46/// ```
47pub trait PluginDsp: Default + Send + 'static {
48 /// Create a new instance with default configuration.
49 fn new() -> Self;
50
51 /// Prepare the DSP chain for playback.
52 ///
53 /// Called when audio specs change (sample rate, buffer size, channels).
54 fn prepare(&mut self, context: &DspContext);
55
56 /// Reset all DSP state.
57 ///
58 /// Called to clear filter histories, oscillator phases, etc.
59 fn reset(&mut self);
60
61 /// Apply parameter values from a flat array.
62 ///
63 /// The parameter indices are plugin-specific, typically defined
64 /// via generated constants from `parameters.json`.
65 fn apply_parameters(&mut self, params: &[f32]);
66
67 /// Process a block of audio with MIDI events.
68 ///
69 /// - `inputs`: Array of input channel buffers
70 /// - `outputs`: Array of output channel buffers
71 /// - `midi_events`: MIDI events with sample-accurate timing (sorted by sample_offset)
72 /// - `context`: DSP context with sample rate, buffer size, etc.
73 fn process(
74 &mut self,
75 inputs: &[&[f32]],
76 outputs: &mut [&mut [f32]],
77 midi_events: &[MidiEvent],
78 context: &DspContext,
79 );
80
81 /// Called when a note-on event is received.
82 ///
83 /// Default implementation does nothing (suitable for effect plugins).
84 #[allow(unused_variables)]
85 fn note_on(&mut self, note: u8, velocity: u8, sample_offset: u32) {}
86
87 /// Called when a note-off event is received.
88 ///
89 /// Default implementation does nothing (suitable for effect plugins).
90 #[allow(unused_variables)]
91 fn note_off(&mut self, note: u8, sample_offset: u32) {}
92
93 /// Called when a control change event is received.
94 ///
95 /// Default implementation does nothing.
96 #[allow(unused_variables)]
97 fn control_change(&mut self, cc: u8, value: u8, sample_offset: u32) {}
98
99 /// Called when a pitch bend event is received.
100 ///
101 /// Default implementation does nothing.
102 #[allow(unused_variables)]
103 fn pitch_bend(&mut self, value: i16, sample_offset: u32) {}
104}