cloudseedcore_rs/
reverb.rs

1use crate::bridge::*;
2use crate::{ParamId, Program};
3
4/// A stereo reverb.
5///
6/// This is a safe wrapper around the CloudSeedCore ReverbController.
7pub struct ReverbController {
8    inner: cxx::UniquePtr<CloudSeedReverb>,
9    max_block_size: u32,
10}
11
12// SAFETY: the underlying CloudSeedCore ReverbController written in C++ is single-threaded.
13unsafe impl Send for ReverbController {}
14
15impl ReverbController {
16    /// Creates a reverb instance with the given sample rate
17    /// and maximum block size that will be passed to `process`.
18    pub fn new(sample_rate: f32, max_block_size: u32) -> Self {
19        let inner = cs_new_reverb(sample_rate, max_block_size);
20        Self {
21            inner,
22            max_block_size,
23        }
24    }
25
26    /// Returns the maximum block size that can be passed to `process` for this instance.
27    pub fn max_block_size(&self) -> u32 {
28        self.max_block_size
29    }
30
31    /// Processes a stereo signal.
32    /// All buffers must be at least `num_samples` long.
33    /// Panics if `num_samples` is greater than `max_block_size`.
34    pub fn process(
35        &mut self,
36        in_l: &[f32],
37        in_r: &[f32],
38        out_l: &mut [f32],
39        out_r: &mut [f32],
40        num_samples: u32,
41    ) {
42        assert!(num_samples <= self.max_block_size);
43
44        self.inner
45            .as_mut()
46            .unwrap()
47            .process(in_l, in_r, out_l, out_r, num_samples);
48    }
49
50    /// Clears internal buffers, ending any ongoing reverb tail.
51    pub fn reset(&mut self) {
52        self.inner.as_mut().unwrap().reset();
53    }
54
55    /// Updates the reverb's sample rate in Hz.
56    pub fn set_sample_rate(&mut self, sample_rate: f32) {
57        self.inner.as_mut().unwrap().set_sample_rate(sample_rate);
58    }
59
60    /// Applies a normalized parameter value in range 0..1
61    /// to the parameter with the given id.
62    pub fn set_parameter(&mut self, id: ParamId, value: f32) {
63        let id: u8 = id.into();
64        self.inner.as_mut().unwrap().set_parameter(id as u32, value);
65    }
66
67    /// Returns the normalized parameter value in range 0..1 for the given parameter id.
68    pub fn get_parameter(&self, id: ParamId) -> f32 {
69        let id: u8 = id.into();
70        self.inner.as_ref().unwrap().get_parameter(id as u32)
71    }
72
73    /// Returns a snapshot of all current parameter values.
74    /// The returned [Program] can be used to serialize parameter state.
75    pub fn get_program(&self) -> Program {
76        // fill a temporary array using the cxx bridge, then convert to typed Program
77        let mut vals = [0.0f32; 45];
78        self.inner.as_ref().unwrap().get_all_parameters(&mut vals);
79        Program::from_array(vals)
80    }
81
82    /// Loads a program, ending any ongoing reverb tail.
83    pub fn set_program(&mut self, program: &Program) {
84        let params = program.to_array();
85        self.inner.as_mut().unwrap().load_program(&params);
86    }
87}