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 {
pub trait SoundParameters {
fn names() -> &'static [&'static str];
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 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;
......
......@@ -196,6 +196,42 @@ impl SoundParameters for OidosSoundParameters {
(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 {
let mut params = OidosSoundParameters {
modes: (p["modes"] * 100.0 + 0.5).floor().max(1.0) as u8,
......
use std::collections::{HashMap, VecDeque};
use std::marker::PhantomData;
use std::mem::transmute;
use std::sync::RwLock;
use vst2::api::Supported;
use vst2::buffer::AudioBuffer;
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 generate::{Sample, SoundGenerator, SoundParameters};
......@@ -102,6 +104,8 @@ pub trait SynthInfo {
}
pub struct SynthPlugin<G: SoundGenerator, S: SynthInfo> {
host: Option<HostCallback>,
sample_rate: f32,
time: usize,
notes: Vec<Note>,
......@@ -137,6 +141,8 @@ impl<G: SoundGenerator, S: SynthInfo> Default for SynthPlugin<G, S> {
let sample_rate = 44100.0;
SynthPlugin {
host: None,
sample_rate: sample_rate,
time: 0,
notes: Vec::new(),
......@@ -156,6 +162,14 @@ impl<G: SoundGenerator, S: SynthInfo> Default 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 {
Info {
presets: 0,
......@@ -230,6 +244,16 @@ impl<G: SoundGenerator, S: SynthInfo> Plugin for SynthPlugin<G, S> {
fn set_parameter(&mut self, index: i32, value: f32) {
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();
}
}
......@@ -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