Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a set_callback to params #184

Open
PanieriLorenzo opened this issue Dec 14, 2024 · 2 comments
Open

Add a set_callback to params #184

PanieriLorenzo opened this issue Dec 14, 2024 · 2 comments

Comments

@PanieriLorenzo
Copy link

The with_callback method takes ownership of the parameter, it would be ergonomic to also have an option to borrow a parameter with a set_callback method, for instance for changing the handler after the parameters have been constructed.

The way I structure plugins, I have a parameters module that handles all parameter configuration, the problem is that I have to pass in callbacks for each parameter as I have to access the parameters from deep within a processing graph, and this creates coupling between my graph module and the params module. I would instead like the constructor of the plugin to "plug in" all the callbacks after the params module is done configuring them, and thus fully decouple the params module and graph.

@PanieriLorenzo
Copy link
Author

PanieriLorenzo commented Dec 14, 2024

i.e. this is what my parameter constructor looks like:

// params.rs
pub fn param_builder(
    mix_callback: Arc<dyn Fn(f32) + Send + Sync>,
    threshold_callback: Arc<dyn Fn(f32) + Send + Sync>,
) -> ClipParams {
    ClipParams {
        editor_state: default_state(),
        mix: FloatParam::new("mix", 0.0, FloatRange::Linear { min: 0.0, max: 1.0 })
            .with_callback(mix_callback),
        threshold: FloatParam::new("threshold", 0.0, FloatRange::Linear { min: 0.0, max: 1.0 })
            .with_callback(threshold_callback),
    }
}

// lib.rs
impl Default for MyPlugin {
    fn default() -> Self {
        let mix_receiver = FloatParamReceiver::new();
        let threshold_receiver = FloatParamReceiver::new();
        let params = Arc::new(param_builder(
            mix_receiver.clone().callback,
            threshold_receiver.clone().callback,
        ));
        let graph = Arc::new(graph_builder(mix_receiver, threshold_receiver));
        // ...
    }
}

And I would like it to look like this (this is a simplification):

// params.rs
pub fn param_builder() -> ClipParams {
    ClipParams {
        editor_state: default_state(),
        mix: FloatParam::new("mix", 0.0, FloatRange::Linear { min: 0.0, max: 1.0 }),
        threshold: FloatParam::new("threshold", 0.0, FloatRange::Linear { min: 0.0, max: 1.0 }),
    }
}

// lib.rs
impl Default for MyPlugin {
  fn default() -> Self {
    let params = param_builder();
    // ParamReceiver is a custom type that decouples front-end and back-end of parameters
    let mix_receiver = ParamReceiver::new();
    let threshold_receiver = ParamReceiver::new():
    // the "graph" is the backend of my plugin, that does all the DSP
    let graph = graph_builder(mix_receiver.clone(), threshold_receiver.clone());
    params.mix.set_callback(mix_receiver.get_callback());
    params.threshold.set_callbac(threshold_receiver.get_callback());
    // ...
  }
}

@PanieriLorenzo
Copy link
Author

PanieriLorenzo commented Dec 16, 2024

I found a different way to do this, I just store the parameters in individual Arcs and pass a clone of each into the graph. Maybe this new method is still useful for someone?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant