geedback_clap

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 0d0a147613b2b7a58f85bd6e5b7150f4d52f3cf6
parent 4d672ff9b5a54f0b4c7c51fcb4209f26a7a2877b
Author: minerva-jupiter <ryouturn@gmail.com>
Date:   Fri,  5 Jun 2026 19:01:19 +0900

feat: add oscillator waveform selection parameters

- Assign integer discriminants to the Waveform enum.
- Implement a from_int conversion method for the Waveform enum.
- Add IntParam fields for oscillator waveform selection to GeedbackClapParams.
- Update the audio processing loop to use selected waveforms dynamically instead of static defaults.
- Implement a helper function for mapping waveform integer values to display names.

Diffstat:
Msrc/lib.rs | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 60 insertions(+), 12 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs @@ -3,14 +3,30 @@ use std::sync::Arc; #[derive(PartialEq, Clone, Copy)] pub enum Waveform { - Sine, - Triangle, - TriangleSawtooth, - Sawtooth, - ReverseSawtooth, - Square, - WidePulse, - NarrowPulse, + Sine = 0, + Triangle = 1, + TriangleSawtooth = 2, + Sawtooth = 3, + ReverseSawtooth = 4, + Square = 5, + WidePulse = 6, + NarrowPulse = 7, +} + +impl Waveform { + fn from_int(value: i32) -> Self { + match value { + 0 => Waveform::Sine, + 1 => Waveform::Triangle, + 2 => Waveform::TriangleSawtooth, + 3 => Waveform::Sawtooth, + 4 => Waveform::ReverseSawtooth, + 5 => Waveform::Square, + 6 => Waveform::WidePulse, + 7 => Waveform::NarrowPulse, + _ => Waveform::Sine, + } + } } struct GeedbackClap { @@ -19,7 +35,6 @@ struct GeedbackClap { // Oscillator States phases: [f64; 3], phases_mod: [f64; 3], - waveforms: [Waveform; 3], mixes: [f64; 3], sample_rate: f32, @@ -40,6 +55,13 @@ struct GeedbackClapParams { pub quat_y: FloatParam, #[id = "quat_z"] pub quat_z: FloatParam, + + #[id = "osc1_wave"] + pub osc1_wave: IntParam, + #[id = "osc2_wave"] + pub osc2_wave: IntParam, + #[id = "osc3_wave"] + pub osc3_wave: IntParam, } impl Default for GeedbackClap { @@ -48,7 +70,6 @@ impl Default for GeedbackClap { params: Arc::new(GeedbackClapParams::default()), phases: [0.0; 3], phases_mod: [0.0; 3], - waveforms: [Waveform::Sine, Waveform::Sine, Waveform::Sine], mixes: [0.3, 0.3, 0.3], sample_rate: 44100.0, } @@ -91,10 +112,31 @@ impl Default for GeedbackClapParams { }, ) .with_smoother(SmoothingStyle::Linear(50.0)), + + osc1_wave: IntParam::new("Osc 1 Wave", 0, IntRange::Linear { min: 0, max: 7 }) + .with_value_to_string(format_waveform_name()), + osc2_wave: IntParam::new("Osc 2 Wave", 0, IntRange::Linear { min: 0, max: 7 }) + .with_value_to_string(format_waveform_name()), + osc3_wave: IntParam::new("Osc 3 Wave", 0, IntRange::Linear { min: 0, max: 7 }) + .with_value_to_string(format_waveform_name()), } } } +fn format_waveform_name() -> Arc<dyn Fn(i32) -> String + Send + Sync> { + Arc::new(|value| match value { + 0 => "Sine".to_string(), + 1 => "Triangle".to_string(), + 2 => "Tri-Saw".to_string(), + 3 => "Sawtooth".to_string(), + 4 => "Rev-Saw".to_string(), + 5 => "Square".to_string(), + 6 => "Wide Pulse".to_string(), + 7 => "Narrow Pulse".to_string(), + _ => "Unknown".to_string(), + }) +} + impl GeedbackClap { fn calculate_wave(&self, phase: f64, wave: Waveform, morph: f64) -> f64 { let m = (morph + 1.0) * 0.5; @@ -185,6 +227,13 @@ impl Plugin for GeedbackClap { let qy = self.params.quat_y.smoothed.next() as f64; let qz = self.params.quat_z.smoothed.next() as f64; + // Waveform selection (no smoothing needed for discrete enum) + let waves = [ + Waveform::from_int(self.params.osc1_wave.value()), + Waveform::from_int(self.params.osc2_wave.value()), + Waveform::from_int(self.params.osc3_wave.value()), + ]; + // Mapping Quaternions (X, Y, Z) to Oscillator frequencies and morphs let freqs = [ 110.0 * 2.0_f64.powf(qy * 2.5), @@ -207,8 +256,7 @@ impl Plugin for GeedbackClap { self.phases_mod[i] = (self.phases_mod[i] + freqs[i] / sample_rate) % 1.0; let modulation = (self.phases_mod[i] * 2.0 * std::f64::consts::PI).sin() * fm_depths[i]; - let osc_out = - self.calculate_wave(self.phases[i] + modulation, self.waveforms[i], morphs[i]); + let osc_out = self.calculate_wave(self.phases[i] + modulation, waves[i], morphs[i]); mixed_output += osc_out * self.mixes[i]; self.phases[i] = (self.phases[i] + freqs[i] / sample_rate) % 1.0; }