Skip to content

Commit

Permalink
Some fixes for the polysynth example.
Browse files Browse the repository at this point in the history
  • Loading branch information
prokopyl committed Apr 3, 2024
1 parent 2870f3c commit 5fb548e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 29 deletions.
21 changes: 14 additions & 7 deletions plugin/examples/polysynth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![doc = include_str!("../README.md")]
#![deny(missing_docs, clippy::missing_docs_in_private_items, unsafe_code)]

use crate::params::PolySynthParams;
use crate::params::{PolySynthParamModulations, PolySynthParams};
use crate::poly_oscillator::PolyOscillator;
use clack_extensions::state::PluginState;
use clack_extensions::{audio_ports::*, note_ports::*, params::*};
Expand Down Expand Up @@ -38,20 +38,23 @@ impl DefaultPluginFactory for PolySynthPlugin {
fn get_descriptor() -> PluginDescriptor {
use clack_plugin::plugin::features::*;

PluginDescriptor::new("org.rust-audio.clack.polysynth", "Clack PolySynth Example")
.with_features([SYNTHESIZER, MONO, INSTRUMENT])
PluginDescriptor::new(
"org.rust-audio.clack-hotreload.polysynth",
"Clack PolySynth Example (Hot reload version)",
)
.with_features([SYNTHESIZER, MONO, INSTRUMENT])
}

fn new_shared(_host: HostHandle) -> Result<Self::Shared<'_>, PluginError> {
fn new_shared(_host: HostHandle) -> Result<PolySynthPluginShared, PluginError> {
Ok(PolySynthPluginShared {
params: PolySynthParams::new(),
})
}

fn new_main_thread<'a>(
_host: HostMainThreadHandle<'a>,
shared: &'a Self::Shared<'a>,
) -> Result<Self::MainThread<'a>, PluginError> {
shared: &'a PolySynthPluginShared,
) -> Result<PolySynthPluginMainThread<'a>, PluginError> {
Ok(PolySynthPluginMainThread { shared })
}
}
Expand All @@ -62,6 +65,8 @@ impl DefaultPluginFactory for PolySynthPlugin {
pub struct PolySynthAudioProcessor<'a> {
/// The oscillator bank.
poly_osc: PolyOscillator,
/// The modulation values for the plugin's parameters.
modulation_values: PolySynthParamModulations,
/// A reference to the plugin's shared data.
shared: &'a PolySynthPluginShared,
}
Expand All @@ -77,6 +82,7 @@ impl<'a> PluginAudioProcessor<'a, PolySynthPluginShared, PolySynthPluginMainThre
) -> Result<Self, PluginError> {
Ok(Self {
poly_osc: PolyOscillator::new(16, audio_config.sample_rate as f32),
modulation_values: PolySynthParamModulations::new(),
shared,
})
}
Expand Down Expand Up @@ -112,10 +118,11 @@ impl<'a> PluginAudioProcessor<'a, PolySynthPluginShared, PolySynthPluginMainThre
for event in event_batch.events() {
self.poly_osc.handle_event(event);
self.shared.params.handle_event(event);
self.modulation_values.handle_event(event);
}

// Received the updated volume parameter
let volume = self.shared.params.get_volume();
let volume = self.shared.params.get_volume() + self.modulation_values.volume();

// With all the events out of the way, we can now handle a whole batch of sample
// all at once.
Expand Down
4 changes: 2 additions & 2 deletions plugin/examples/polysynth/src/oscillator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Oscillator implementation.
//!
//! This is where all of the DSP math happens.
//! This is where all the DSP math happens.
use std::f32::consts::{PI, TAU};

Expand All @@ -10,7 +10,7 @@ use std::f32::consts::{PI, TAU};
#[derive(Copy, Clone)]
pub struct SquareOscillator {
/// The ratio between the frequency (in Hz) and the per-sample phase increment.
/// This is only dependant on the sample rate.
/// This is only dependent on the sample rate.
frequency_to_phase_increment_ratio: f32,
/// The per-sample phase increment.
phase_increment: f32,
Expand Down
74 changes: 54 additions & 20 deletions plugin/examples/polysynth/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,43 @@ impl PolySynthParams {
}
}

/// Manages the parameter modulations for our plugin.
///
/// For now, it only manages a single, `volume` parameter.
///
/// This struct will only be used by the [`PolySynthAudioProcessor`], to store temporary modulations
/// applied to the parameters by the host's automation, LFOs, etc.
///
/// This value needs to be stored separately, as it must not be changing the value of the parameter
/// that the user set when saving the plugin's state.
pub struct PolySynthParamModulations {
/// The modulation amount of the volume parameter, in a -1..1 scale
volume_mod: f32,
}
impl PolySynthParamModulations {
/// Initializes the modulation values.
/// There is no modulation applied by default.
pub fn new() -> Self {
Self { volume_mod: 0.0 }
}

/// Returns the current modulation value.
#[inline]
pub fn volume(&self) -> f32 {
self.volume_mod
}

/// Handles an incoming event.
/// This will update the modulation value of the parameter if the event is a matching `ParamMod`.
pub fn handle_event(&mut self, event: &UnknownEvent) {
if let Some(CoreEventSpace::ParamMod(event)) = event.as_core_event() {
if event.param_id() == 1 {
self.volume_mod = event.amount() as f32
}
}
}
}

/// Implementation of the State extension.
///
/// Our state "serialization" is extremely simple and basic: we only have the value of the
Expand Down Expand Up @@ -87,26 +124,24 @@ impl<'a> PluginMainThreadParams for PolySynthPluginMainThread<'a> {
}

fn get_info(&mut self, param_index: u32, info: &mut ParamInfoWriter) {
if param_index != 0 {
return;
if param_index == 0 {
info.set(&ParamInfo {
id: 1.into(),
flags: ParamInfoFlags::IS_AUTOMATABLE | ParamInfoFlags::IS_MODULATABLE,
cookie: Default::default(),
name: b"Volume",
module: b"",
min_value: 0.0,
max_value: 1.0,
default_value: DEFAULT_VOLUME as f64,
})
}
info.set(&ParamInfo {
id: 1.into(),
flags: ParamInfoFlags::IS_AUTOMATABLE,
cookie: Default::default(),
name: b"Volume",
module: b"",
min_value: 0.0,
max_value: 1.0,
default_value: DEFAULT_VOLUME as f64,
})
}

fn get_value(&mut self, param_id: u32) -> Option<f64> {
if param_id == 1 {
Some(self.shared.params.get_volume() as f64)
} else {
None
match param_id {
1 => Some(self.shared.params.get_volume() as f64),
_ => None,
}
}

Expand All @@ -116,10 +151,9 @@ impl<'a> PluginMainThreadParams for PolySynthPluginMainThread<'a> {
value: f64,
writer: &mut ParamDisplayWriter,
) -> std::fmt::Result {
if param_id == 1 {
write!(writer, "{0:.2} %", value * 100.0)
} else {
Err(std::fmt::Error)
match param_id {
1 => write!(writer, "{0:.2} %", value * 100.0),
_ => Err(std::fmt::Error),
}
}

Expand Down

0 comments on commit 5fb548e

Please sign in to comment.