Something went wrong. Try again.
YAML-based live configuration of MicroFreak datyoma.tngl.io/mfctl
microfreak
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136#[cfg(test)]pub(super) mod tests;
use mfctl_derive::author;
use crate::parameter::{DecodeError, RegisterCodec, StoredValue, unsigned};
macro_rules! integer_control { ($name:ident, $scalar:ty, $minimum:expr, $maximum:expr) => { #[author] #[serde(transparent)] #[garde(transparent)] pub struct $name(#[garde(range(min = $minimum, max = $maximum))] pub $scalar);
impl crate::parameter::RegisterCodec for $name { fn encode(&self) -> crate::parameter::StoredValue { crate::parameter::encode_bin( (self.0 as i32 - $minimum as i32) as u16, ($maximum - $minimum) as u16, ) }
fn decode( raw: crate::parameter::StoredValue, ) -> Result<Self, crate::parameter::DecodeError> { let index = crate::parameter::decode_bin::<Self>(raw, ($maximum - $minimum) as u16)?; Ok(Self(($minimum as i32 + i32::from(index)) as $scalar)) } } };}
#[author]#[serde(transparent)]#[garde(transparent)]pub struct Percent(#[garde(range(min = 0.0, max = 100.0))] pub f64);
impl Default for Percent { fn default() -> Self { Self(0.0) }}
impl RegisterCodec for Percent { fn encode(&self) -> StoredValue { StoredValue((self.0 * 32767.0 / 100.0).round() as u16) }
fn decode(raw: StoredValue) -> Result<Self, DecodeError> { Ok(Self(f64::from(unsigned::<Self>(raw)?) * 100.0 / 32767.0)) }}
#[author]#[serde(transparent)]#[garde(transparent)]pub struct Bipolar(#[garde(range(min = -100.0, max = 100.0))] pub f64);
impl Default for Bipolar { fn default() -> Self { Self(0.0) }}
impl RegisterCodec for Bipolar { fn encode(&self) -> StoredValue { StoredValue(if self.0 == 100.0 { 32767 } else { (self.0 * 32768.0 / 100.0).round() as i32 as u16 }) }
fn decode(raw: StoredValue) -> Result<Self, DecodeError> { Ok(Self(if raw.0 == 32767 { 100.0 } else { f64::from(raw.0 as i16) * 100.0 / 32768.0 })) }}
// Attack, decay/release and cycling hold share the firmware's register knots.// Registers 32760..32767 decode to the final time entry.pub(super) const TIME_REGISTERS: [f64; 10] = [ 0.0, 3640.0, 7280.0, 10920.0, 14560.0, 18200.0, 21840.0, 25480.0, 29120.0, 32760.0,];
pub(super) fn interpolate(value: f64, from: &[f64; 10], to: &[f64; 10]) -> f64 { let i = from.partition_point(|entry| *entry < value); match i { 0 => to[0], 10 => to[9], _ => to[i - 1] + (value - from[i - 1]) * (to[i] - to[i - 1]) / (from[i] - from[i - 1]), }}
macro_rules! time_control { ($name:ident, $maximum:literal, [$($time:literal),+]) => { #[author] #[serde(transparent)] #[garde(transparent)] pub struct $name(#[garde(range(max = $maximum))] pub u16);
impl $name { const TIMES: [f64; 10] = [$($time as f64),+]; }
impl crate::parameter::RegisterCodec for $name { fn encode(&self) -> crate::parameter::StoredValue { crate::parameter::StoredValue( crate::patch::value::interpolate( f64::from(self.0), &Self::TIMES, &crate::patch::value::TIME_REGISTERS, ).round() as u16, ) }
fn decode( raw: crate::parameter::StoredValue, ) -> Result<Self, crate::parameter::DecodeError> { let register = f64::from(crate::parameter::unsigned::<Self>(raw)?); Ok(Self(crate::patch::value::interpolate( register, &crate::patch::value::TIME_REGISTERS, &Self::TIMES, ).round() as u16)) } } };}
pub(super) use {integer_control, time_control};