gled-model 2.34.0

The data model of gled: projects, scenes, effects, animations, curves and assets
Documentation
//! Settings of a sound trigger: which frequency band it listens to and the
//! envelope it produces, stored with the curve that uses it.

use serde::{Deserialize, Serialize};

/// Highest frequency of the analysed spectrum, in Hz.
pub const MAX_FREQ: f32 = 24_000.0;
/// Number of frequency bins of the analysed spectrum.
pub const FREQ_BINS: usize = 256;

#[derive(Debug, Clone, PartialEq, Copy, Serialize, Deserialize)]
pub struct SoundTriggerParams {
    pub(crate) center_bin: usize,
    pub(crate) bin_radius: usize,
    pub attack_duration: f32,      // in seconds
    pub decay_duration: f32,       // in seconds
    pub(crate) sustain_level: f32, // 0.0 to 1.0
    pub release_duration: f32,     // in seconds
    /// Threshold to consider the continuous input "ON"
    pub sensitivity: f32,
    pub gate_activation_threshold: f32,
    pub gate_deactivation_threshold: f32,
    pub(crate) averaging_samples: usize,
    pub(crate) echo_samples: usize,
}
impl SoundTriggerParams {
    #[allow(clippy::too_many_arguments)]
    pub(crate) fn new(
        f_center: f32,
        f_radius: f32,
        attack_duration: f32,
        decay_duration: f32,
        sustain_level: f32,
        release_duration: f32,
        sensitivity: f32,
        gate_threshold: f32,
    ) -> Self {
        let mut ret = Self {
            center_bin: 0,
            bin_radius: 0,
            attack_duration,
            decay_duration,
            sustain_level,
            release_duration,
            sensitivity,
            gate_activation_threshold: gate_threshold,
            gate_deactivation_threshold: gate_threshold * 0.8,
            averaging_samples: 10,
            echo_samples: 20,
        };
        ret.set_filter_tune(f_center, f_radius);
        ret
    }
    pub fn set_filter_tune(&mut self, f_center: f32, f_radius: f32) {
        let f_per_bin = MAX_FREQ / FREQ_BINS as f32;
        let center_bin = ((f_center / f_per_bin).round() as usize).min(FREQ_BINS - 1);
        let bin_radius = (f_radius / f_per_bin).round() as usize;
        self.center_bin = center_bin;
        self.bin_radius = bin_radius.max(1);
        self.gate_deactivation_threshold = self.gate_activation_threshold * 0.9;
        //self.averaging_samples = (100f32.mul(averaging_time) as usize);
    }

    /// The band `set_filter_tune` was given, as far as the bins keep it:
    /// center and radius in Hz.
    pub(crate) fn filter_tune(&self) -> (f32, f32) {
        let f_per_bin = MAX_FREQ / FREQ_BINS as f32;
        (
            self.center_bin as f32 * f_per_bin,
            self.bin_radius as f32 * f_per_bin,
        )
    }
}

impl Default for SoundTriggerParams {
    fn default() -> Self {
        SoundTriggerParams::new(100., 50., 0.01, 0.0, 1.0, 0.1, 1., 0.5)
    }
}