Commit 8c644497 authored by Aske Simon Christensen's avatar Aske Simon Christensen
Browse files

Cross-update parameter visualizations

parent 6394a3cc
...@@ -55,6 +55,7 @@ impl From<f32> for Sample { ...@@ -55,6 +55,7 @@ impl From<f32> for Sample {
pub trait SoundParameters { pub trait SoundParameters {
fn names() -> &'static [&'static str]; fn names() -> &'static [&'static str];
fn default_value(name: &str) -> f32; fn default_value(name: &str) -> f32;
fn influence(name: &'static str) -> Vec<&'static str>;
fn display<P: Index<&'static str, Output = f32>>(&self, name: &'static str, p: &P, sample_rate: f32) -> (String, String); fn display<P: Index<&'static str, Output = f32>>(&self, name: &'static str, p: &P, sample_rate: f32) -> (String, String);
fn build<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> Self; fn build<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> Self;
fn attack<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> f32; fn attack<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> f32;
......
...@@ -196,6 +196,42 @@ impl SoundParameters for OidosSoundParameters { ...@@ -196,6 +196,42 @@ impl SoundParameters for OidosSoundParameters {
(value, label) (value, label)
} }
fn influence(name: &'static str) -> Vec<&'static str> {
match name {
"width" => vec!["q_width"],
"sharpness" => vec!["q_sharpness"],
"harmonicity" => vec!["q_harmonicity"],
"decaylow" => vec!["q_decaydiff", "q_decaylow"],
"decayhigh" => vec!["q_decaydiff"],
"filterlow" => vec!["q_f_low"],
"fslopelow" => vec!["q_fs_low"],
"fsweeplow" => vec!["q_fsw_low"],
"filterhigh" => vec!["q_f_high"],
"fslopehigh" => vec!["q_fs_high"],
"fsweephigh" => vec!["q_fsw_high"],
"gain" => vec!["q_gain"],
"attack" => vec!["q_attack"],
"release" => vec!["q_release"],
"q_decaydiff" => vec!["decayhigh"],
"q_decaylow" => vec!["decaylow", "decayhigh", "q_decaydiff"],
"q_harmonicity" => vec!["harmonicity"],
"q_sharpness" => vec!["sharpness"],
"q_width" => vec!["width"],
"q_f_low" => vec!["filterlow"],
"q_fs_low" => vec!["fslopelow"],
"q_fsw_low" => vec!["fsweeplow"],
"q_f_high" => vec!["filterhigh"],
"q_fs_high" => vec!["fslopehigh"],
"q_fsw_high" => vec!["fsweephigh"],
"q_gain" => vec!["gain"],
"q_attack" => vec!["attack"],
"q_release" => vec!["release"],
_ => vec![]
}
}
fn build<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> OidosSoundParameters { fn build<P: Index<&'static str, Output = f32>>(p: &P, sample_rate: f32) -> OidosSoundParameters {
let mut params = OidosSoundParameters { let mut params = OidosSoundParameters {
modes: (p["modes"] * 100.0 + 0.5).floor().max(1.0) as u8, modes: (p["modes"] * 100.0 + 0.5).floor().max(1.0) as u8,
......
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::transmute;
use std::sync::RwLock; use std::sync::RwLock;
use vst2::api::Supported; use vst2::api::Supported;
use vst2::buffer::AudioBuffer; use vst2::buffer::AudioBuffer;
use vst2::event::Event; use vst2::event::Event;
use vst2::plugin::{CanDo, Category, Info, Plugin}; use vst2::host::Host;
use vst2::plugin::{CanDo, Category, HostCallback, Info, Plugin};
use cache::SoundCache; use cache::SoundCache;
use generate::{Sample, SoundGenerator, SoundParameters}; use generate::{Sample, SoundGenerator, SoundParameters};
...@@ -102,6 +104,8 @@ pub trait SynthInfo { ...@@ -102,6 +104,8 @@ pub trait SynthInfo {
} }
pub struct SynthPlugin<G: SoundGenerator, S: SynthInfo> { pub struct SynthPlugin<G: SoundGenerator, S: SynthInfo> {
host: Option<HostCallback>,
sample_rate: f32, sample_rate: f32,
time: usize, time: usize,
notes: Vec<Note>, notes: Vec<Note>,
...@@ -137,6 +141,8 @@ impl<G: SoundGenerator, S: SynthInfo> Default for SynthPlugin<G, S> { ...@@ -137,6 +141,8 @@ impl<G: SoundGenerator, S: SynthInfo> Default for SynthPlugin<G, S> {
let sample_rate = 44100.0; let sample_rate = 44100.0;
SynthPlugin { SynthPlugin {
host: None,
sample_rate: sample_rate, sample_rate: sample_rate,
time: 0, time: 0,
notes: Vec::new(), notes: Vec::new(),
...@@ -156,6 +162,14 @@ impl<G: SoundGenerator, S: SynthInfo> Default for SynthPlugin<G, S> { ...@@ -156,6 +162,14 @@ impl<G: SoundGenerator, S: SynthInfo> Default for SynthPlugin<G, S> {
} }
impl<G: SoundGenerator, S: SynthInfo> Plugin for SynthPlugin<G, S> { impl<G: SoundGenerator, S: SynthInfo> Plugin for SynthPlugin<G, S> {
fn new(host: HostCallback) -> SynthPlugin<G, S> {
SynthPlugin {
host: Some(host),
.. SynthPlugin::default()
}
}
fn get_info(&self) -> Info { fn get_info(&self) -> Info {
Info { Info {
presets: 0, presets: 0,
...@@ -230,6 +244,16 @@ impl<G: SoundGenerator, S: SynthInfo> Plugin for SynthPlugin<G, S> { ...@@ -230,6 +244,16 @@ impl<G: SoundGenerator, S: SynthInfo> Plugin for SynthPlugin<G, S> {
fn set_parameter(&mut self, index: i32, value: f32) { fn set_parameter(&mut self, index: i32, value: f32) {
self.param_values[index as usize] = value; self.param_values[index as usize] = value;
if let Some(ref mut host) = self.host {
for name in G::Parameters::influence(self.param_names[index as usize]) {
if let Some(p) = self.param_names.iter().position(|n| *n == name) {
self.param_values[p] = infinitesimal_change(self.param_values[p]).min(1.0);
host.automate(p as i32, self.param_values[p]);
}
}
}
self.build_sound_params(); self.build_sound_params();
} }
} }
...@@ -292,3 +316,9 @@ impl<G: SoundGenerator, S: SynthInfo> SynthPlugin<G, S> { ...@@ -292,3 +316,9 @@ impl<G: SoundGenerator, S: SynthInfo> SynthPlugin<G, S> {
} }
} }
} }
fn infinitesimal_change(value: f32) -> f32 {
let mut bits = unsafe { transmute::<f32, u32>(value) };
bits += 1;
unsafe { transmute::<u32, f32>(bits) }
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment