Browse Source

small progress made on the device params management

master
Weird Constructor 4 years ago
parent
commit
cd6612bebf
  1. 180
      src/slaughter.rs
  2. 87
      src/synth_device.rs

180
src/slaughter.rs

@ -32,6 +32,7 @@ use wctr_signal_ops::signals::{OpIn, Op, OpIOSpec, Event};
// allocated busses.
pub struct SlaughterParams {
dev_params: SynthDeviceParams,
params: SignalIOParams,
osc1_waveform: f32,
osc1_pulse_width: f32,
@ -49,7 +50,6 @@ pub struct SlaughterParams {
osc3_detune_coarse: f32,
osc3_detune_fine: f32,
noise_volume: f32,
master_level: f32,
filter_type: FilterType,
filter_freq: f32,
filter_resonance: f32,
@ -66,17 +66,19 @@ pub struct SlaughterParams {
pitch_decay: f32,
pitch_sustain: f32,
pitch_release: f32,
pitch_env_amt: f32,
}
impl SlaughterParams {
pub fn new() -> Self {
let mut p = SignalIOParams::new();
// TODO: init SynthDeviceParams
p.input("o1_vol", 0.0, 1.0, 1.0);
p.input("o2_vol", 0.0, 1.0, 1.0);
p.input("o3_vol", 0.0, 1.0, 1.0);
p.input("nse_vol", 0.0, 1.0, 1.0);
p.input("m_vol", 0.0, 1.0, 1.0);
p.input("o1_wav", 0.0, 1.0, 0.0);
p.input("o2_wav", 0.0, 1.0, 0.0);
p.input("o3_wav", 0.0, 1.0, 0.0);
@ -93,64 +95,56 @@ impl SlaughterParams {
p.input("f_freq", 0.0, 20000.0 - 20.0, 20000.0 - 20.0);
p.input("f_res", 0.0, 1.0, 1.0);
p.input("f_mod", 0.0, 1.0, 0.5);
p.input("amp_a", 0.0, 1.0, 0.0);
p.input("amp_d", 0.0, 1.0, 0.0);
p.input("amp_s", 0.0, 1.0, 0.0);
p.input("amp_r", 0.0, 1.0, 0.0);
p.input("mod_a", 0.0, 1.0, 0.0);
p.input("mod_d", 0.0, 1.0, 0.0);
p.input("mod_s", 0.0, 1.0, 0.0);
p.input("mod_r", 0.0, 1.0, 0.0);
p.input("pit_a", 0.0, 1.0, 0.0);
p.input("pit_d", 0.0, 1.0, 0.0);
p.input("pit_s", 0.0, 1.0, 0.0);
p.input("pit_r", 0.0, 1.0, 0.0);
p.input("v_uniso", 0.0, 1.0, 0.0);
p.input("v_detune", 0.0, 1.0, 0.0);
p.input("v_pan", 0.0, 1.0, 0.0);
p.input("vi_f", 0.0, 1.0, 0.0);
p.input("vi_amt", 0.0, 1.0, 0.0);
p.input("rist", 0.0, 1.0, 0.0);
p.input("v_mode", 0.0, 1.0, 0.0);
p.input("slide_t", 0.0, 1.0, 0.0);
p.input("amp_a", 0.0, 1.0, 1.0);
p.input("amp_d", 0.0, 1.0, 5.0);
p.input("amp_s", 0.0, 1.0, 0.5);
p.input("amp_r", 0.0, 1.0, 1.5);
p.input("mod_a", 0.0, 1.0, 1.0);
p.input("mod_d", 0.0, 1.0, 5.0);
p.input("mod_s", 0.0, 1.0, 1.0);
p.input("mod_r", 0.0, 1.0, 1.5);
p.input("pit_a", 0.0, 1.0, 1.0);
p.input("pit_d", 0.0, 1.0, 5.0);
p.input("pit_s", 0.0, 1.0, 0.5);
p.input("pit_r", 0.0, 1.0, 1.5);
p.input("pit_eamt", 0.0, 1.0, 0.0);
SlaughterParams {
// TODO: Assign SynthDeviceParams!
osc1_volume: p.v(0),
osc2_volume: p.v(1),
osc3_volume: p.v(2),
noise_volume: p.v(3),
master_level: p.v(4),
osc1_waveform: p.v(5),
osc2_waveform: p.v(6),
osc3_waveform: p.v(7),
osc1_pulse_width: p.v(8),
osc2_pulse_width: p.v(9),
osc3_pulse_width: p.v(10),
osc1_detune_coarse: p.v(11),
osc2_detune_coarse: p.v(12),
osc3_detune_coarse: p.v(13),
osc1_detune_fine: p.v(14),
osc2_detune_fine: p.v(15),
osc3_detune_fine: p.v(16),
filter_type: p.v(17).into(),
filter_freq: p.v(18),
filter_resonance: p.v(19),
filter_mod_amt: p.v(20),
amp_attack: p.v(21),
amp_decay: p.v(22),
amp_sustain: p.v(23),
amp_release: p.v(24),
mod_attack: p.v(25),
mod_decay: p.v(26),
mod_sustain: p.v(27),
mod_release: p.v(28),
pitch_attack: p.v(29),
pitch_decay: p.v(30),
pitch_sustain: p.v(31),
pitch_release: p.v(32),
osc1_waveform: p.v(4),
osc2_waveform: p.v(5),
osc3_waveform: p.v(6),
osc1_pulse_width: p.v(7),
osc2_pulse_width: p.v(8),
osc3_pulse_width: p.v(9),
osc1_detune_coarse: p.v(10),
osc2_detune_coarse: p.v(11),
osc3_detune_coarse: p.v(12),
osc1_detune_fine: p.v(13),
osc2_detune_fine: p.v(14),
osc3_detune_fine: p.v(15),
filter_type: p.v(16).into(),
filter_freq: p.v(17),
filter_resonance: p.v(18),
filter_mod_amt: p.v(19),
amp_attack: p.v(20),
amp_decay: p.v(21),
amp_sustain: p.v(22),
amp_release: p.v(23),
mod_attack: p.v(24),
mod_decay: p.v(25),
mod_sustain: p.v(26),
mod_release: p.v(27),
pitch_attack: p.v(28),
pitch_decay: p.v(29),
pitch_sustain: p.v(30),
pitch_release: p.v(31),
pitch_env_amt: p.v(32),
params: p,
}
}
@ -375,42 +369,48 @@ impl Op for SynthDevice<SlaughterVoice, SlaughterParams> {
self.params.osc2_volume = self.params.params.inputs[1].calc(regs);
self.params.osc3_volume = self.params.params.inputs[2].calc(regs);
self.params.noise_volume = self.params.params.inputs[3].calc(regs);
self.params.master_level = self.params.params.inputs[4].calc(regs);
self.params.osc1_waveform = self.params.params.inputs[5].calc(regs);
self.params.osc2_waveform = self.params.params.inputs[6].calc(regs);
self.params.osc3_waveform = self.params.params.inputs[7].calc(regs);
self.params.osc1_pulse_width = 1.0 - self.params.params.inputs[8].calc(regs);
self.params.osc2_pulse_width = 1.0 - self.params.params.inputs[9].calc(regs);
self.params.osc3_pulse_width = 1.0 - self.params.params.inputs[10].calc(regs);
self.params.osc1_detune_coarse = self.params.params.inputs[11].calc(regs);
self.params.osc2_detune_coarse = self.params.params.inputs[12].calc(regs);
self.params.osc3_detune_coarse = self.params.params.inputs[13].calc(regs);
self.params.osc1_detune_fine = self.params.params.inputs[14].calc(regs);
self.params.osc2_detune_fine = self.params.params.inputs[15].calc(regs);
self.params.osc3_detune_fine = self.params.params.inputs[16].calc(regs);
self.params.filter_type = self.params.params.inputs[17].calc(regs).into();
self.params.filter_freq = self.params.params.inputs[18].calc(regs);
self.params.filter_resonance = self.params.params.inputs[19].calc(regs);
self.params.filter_mod_amt = self.params.params.inputs[20].calc(regs);
self.params.amp_attack = self.params.params.inputs[21].calc(regs);
self.params.amp_decay = self.params.params.inputs[22].calc(regs);
self.params.amp_sustain = self.params.params.inputs[23].calc(regs);
self.params.amp_release = self.params.params.inputs[24].calc(regs);
self.params.mod_attack = self.params.params.inputs[25].calc(regs);
self.params.mod_decay = self.params.params.inputs[26].calc(regs);
self.params.mod_sustain = self.params.params.inputs[27].calc(regs);
self.params.mod_release = self.params.params.inputs[28].calc(regs);
self.params.pitch_attack = self.params.params.inputs[29].calc(regs);
self.params.pitch_decay = self.params.params.inputs[30].calc(regs);
self.params.pitch_sustain = self.params.params.inputs[31].calc(regs);
self.params.pitch_release = self.params.params.inputs[32].calc(regs);
// let a = self.values[0].calc(regs);
// let p = self.values[1].calc(regs);
// let v = self.values[2].calc(regs);
// let f = self.values[3].calc(regs);
// regs[self.out] = a * (((f * t) + p).sin() + v);
//d// println!("OUT: {}, {}", regs[self.out], self.out);
self.params.osc1_waveform = self.params.params.inputs[4].calc(regs);
self.params.osc2_waveform = self.params.params.inputs[5].calc(regs);
self.params.osc3_waveform = self.params.params.inputs[6].calc(regs);
self.params.osc1_pulse_width = 1.0 - self.params.params.inputs[7].calc(regs);
self.params.osc2_pulse_width = 1.0 - self.params.params.inputs[8].calc(regs);
self.params.osc3_pulse_width = 1.0 - self.params.params.inputs[9].calc(regs);
self.params.osc1_detune_coarse = self.params.params.inputs[10].calc(regs);
self.params.osc2_detune_coarse = self.params.params.inputs[11].calc(regs);
self.params.osc3_detune_coarse = self.params.params.inputs[12].calc(regs);
self.params.osc1_detune_fine = self.params.params.inputs[13].calc(regs);
self.params.osc2_detune_fine = self.params.params.inputs[14].calc(regs);
self.params.osc3_detune_fine = self.params.params.inputs[15].calc(regs);
self.params.filter_type = self.params.params.inputs[16].calc(regs).into();
self.params.filter_freq =
helpers::param_to_frequency(self.params.params.inputs[17].calc(regs));
self.params.filter_resonance = 1.0 - self.params.params.inputs[18].calc(regs);
self.params.filter_mod_amt = self.params.params.inputs[19].calc(regs);
self.params.amp_attack =
helpers::scalar_to_env_value(self.params.params.inputs[20].calc(regs));
self.params.amp_decay =
helpers::scalar_to_env_value(self.params.params.inputs[21].calc(regs));
self.params.amp_sustain = self.params.params.inputs[22].calc(regs);
self.params.amp_release =
helpers::scalar_to_env_value(self.params.params.inputs[23].calc(regs));
self.params.mod_attack =
helpers::scalar_to_env_value(self.params.params.inputs[24].calc(regs));
self.params.mod_decay =
helpers::scalar_to_env_value(self.params.params.inputs[25].calc(regs));
self.params.mod_sustain = self.params.params.inputs[26].calc(regs);
self.params.mod_release =
helpers::scalar_to_env_value(self.params.params.inputs[27].calc(regs));
self.params.pitch_attack =
helpers::scalar_to_env_value(self.params.params.inputs[28].calc(regs));
self.params.pitch_decay =
helpers::scalar_to_env_value(self.params.params.inputs[29].calc(regs));
self.params.pitch_sustain = self.params.params.inputs[30].calc(regs);
self.params.pitch_release =
helpers::scalar_to_env_value(self.params.params.inputs[31].calc(regs));
self.params.pitch_env_amt =
(self.params.params.inputs[32].calc(regs) - 0.5) * 2.0 * 36.0;
// TODO: init and copy SynthDeviceParams to SynthDevice here!
}
fn render(&mut self, num_samples: usize, offs: usize, input_idx: usize, bufs: &mut Vec<Vec<f32>>)

87
src/synth_device.rs

@ -116,10 +116,8 @@ pub trait Voice<P>: Copy + Clone {
outputs: &mut [f32]);
}
pub struct SynthDevice<V, P>
where V: Voice<P> {
sample_rate: f64,
pub struct SynthDeviceParams {
master_level: f32,
voices_unisono: i32,
voices_detune: f32,
voices_pan: f32,
@ -128,6 +126,77 @@ pub struct SynthDevice<V, P>
rise: f32,
slide: f32,
voice_mode: VoiceMode,
}
impl SynthDeviceParams {
pub fn new() -> SynthDeviceParams {
SynthDeviceParams {
master_level: 0.0,
voices_unisono: 1,
voices_detune: 0.0,
voices_pan: 0.5,
vibrato_freq: 0.0,
vibrato_amount: 0.0,
rise: 0.0,
slide: 0.0,
voice_mode: VoiceMode::Polyphonic,
}
}
pub fn new_with_params(p: &mut SignalIOParams) -> SynthDeviceParams {
let p = SynthDeviceParams::new();
p.init_params(p);
p
}
fn init_params(&mut self, p: &mut SignalIOParams) {
p.input("m_vol", 0.0, 1.0, 1.0);
p.input("v_uniso", 0.0, 1.0, 0.0);
p.input("v_detune", 0.0, 1.0, 0.0);
p.input("v_pan", 0.0, 1.0, 0.0);
p.input("vi_f", 0.0, 1.0, 0.0);
p.input("vi_amt", 0.0, 1.0, 0.0);
p.input("rise", 0.0, 1.0, 0.0);
p.input("slide_t", 0.0, 1.0, 0.0);
p.input("v_mode", 0.0, 1.0, 0.0);
self.master_level = p.v(0);
self.voices_unisono = p.v(1);
self.voices_detune = p.v(2);
self.voices_pan = p.v(3);
self.vibrato_freq = p.v(4);
self.vibrato_amount = p.v(5);
self.rise = p.v(6);
self.slide = p.v(7);
self.voice_mode = p.v(8);
}
fn exec(&mut self, t: f32, regs: &mut [f32]) {
self.params.master_level = self.params.params.inputs[4].calc(regs);
self.params.vibrato_freq =
helpers::param_to_vibrato_freq(self.params.params.inputs[34].calc(regs));
self.params.vibrato_amount = self.params.params.inputs[35].calc(regs);
self.params.rise = self.params.params.inputs[36].calc(regs);
// let a = self.values[0].calc(regs);
// let p = self.values[1].calc(regs);
// let v = self.values[2].calc(regs);
// let f = self.values[3].calc(regs);
// regs[self.out] = a * (((f * t) + p).sin() + v);
//d// println!("OUT: {}, {}", regs[self.out], self.out);
}
}
// HOW DO I GET THIS SORTED OUT?
// SynthDevice needs access to these params, and the voices too.
// The only way to provide both access is an Rc/RefCell.
// Or is it?
// I could copy the params to the SynthDevice on trait/exec(),
// then the access would be fast(er).
pub struct SynthDevice<V, P>
where V: Voice<P> {
sample_rate: f64,
mono_active: bool,
note_log: [i32; 128],
note_count: i32,
@ -135,6 +204,7 @@ pub struct SynthDevice<V, P>
voice_data: [VoiceData; 256],
voices: [V; 256],
events: [Event; 256],
dev_params: SynthDeviceParams,
pub params: P,
}
@ -174,14 +244,6 @@ impl<P, V: Voice<P>> SynthDevice<V, P> {
pub fn new(sample_rate: f64, params: P) -> Self {
SynthDevice {
sample_rate,
voices_unisono: 1,
voices_detune: 0.0,
voices_pan: 0.5,
vibrato_freq: helpers::param_to_vibrato_freq(0.0),
vibrato_amount: 0.0,
rise: 0.0,
slide: 0.0,
voice_mode: VoiceMode::Polyphonic,
mono_active: false,
note_count: 0,
active_notes: [false; 128],
@ -189,6 +251,7 @@ impl<P, V: Voice<P>> SynthDevice<V, P> {
voice_data: [VoiceData::new(sample_rate); 256],
voices: [V::new(sample_rate); 256],
events: [Event::new(); 256],
dev_params: SynthDeviceParams::new(),
params,
}
}

Loading…
Cancel
Save