diff --git a/Cargo.toml b/Cargo.toml index 5ce298a..e2b2ff1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "Actuate" -version = "1.2.8" +version = "1.3.0" edition = "2021" authors = ["Ardura "] license = "GPL-3.0-or-later" diff --git a/README.md b/README.md index 59e1c9e..a0e7b43 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Actuate +# Actuate (Latest is v1.3.0) A Synthesizer, Sampler, and Granulizer built in Rust + Nih-Plug Written by Ardura @@ -75,11 +75,15 @@ Since Actuate 1.2.8 the new file browser and UI use native text editing. This cr - Unfortunately I don't know where this would be on Linux or Mac so I'm open to help from Ableton users! ## Roadmap +- [ ] Create an additive module +- [ ] Create filter release bypass toggle +- [ ] Find more things to add here + +(old items pre 1.3.0) - [x] Create a Preset Browser - [x] Add more reverb styles -- [ ] ~~Add more decay styles~~ Not doing -- [ ] Fix some bandpass glitching on certain filter types (need to find these scenarios still) -- [ ] Create different stereo spreading algorithms +- [x] Fix some bandpass glitching on certain filter types +- [x] Create different stereo spreading algorithms - [x] Make the GUI nicer - see Discussion https://github.com/ardura/Actuate/discussions/26 - [x] Look into making the preset loading more reliable - [x] Fix text input not working (right now it's a OS safe workaround) diff --git a/src/actuate_enums.rs b/src/actuate_enums.rs index 541d542..af84fd3 100644 --- a/src/actuate_enums.rs +++ b/src/actuate_enums.rs @@ -125,6 +125,13 @@ pub enum PitchRouting { Osc2_Osc3, } +#[derive(Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] +pub enum StereoAlgorithm { + Original, + CubeSpread, + ExpSpread, +} + // These let us output ToString for the ComboBox stuff + Nih-Plug or string usage impl fmt::Display for PresetType { diff --git a/src/actuate_gui.rs b/src/actuate_gui.rs index 5dc5a0c..c7de8ec 100644 --- a/src/actuate_gui.rs +++ b/src/actuate_gui.rs @@ -10,7 +10,7 @@ use nih_plug_egui::{create_egui_editor, egui::{self, Align2, Color32, Pos2, Rect use crate::{ actuate_enums::{ FilterAlgorithms, LFOSelect, ModulationDestination, ModulationSource, PresetType, UIBottomSelection}, - actuate_structs::ActuatePresetV126, audio_module::{AudioModule, AudioModuleType}, + actuate_structs::ActuatePresetV130, audio_module::{AudioModule, AudioModuleType}, Actuate, ActuateParams, CustomWidgets::{ slim_checkbox, toggle_switch, ui_knob::{self, KnobLayout}, @@ -34,7 +34,7 @@ use crate::{ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExecutor) -> Option> { let params: Arc = instance.params.clone(); let arc_preset_lib_name: Arc> = Arc::clone(&instance.preset_lib_name); - let arc_preset: Arc>> = Arc::clone(&instance.preset_lib); + let arc_preset: Arc>> = Arc::clone(&instance.preset_lib); let arc_preset_name: Arc> = Arc::clone(&instance.preset_name); let arc_preset_info: Arc> = Arc::clone(&instance.preset_info); let arc_preset_category: Arc> = Arc::clone(&instance.preset_category); @@ -762,7 +762,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe } } else { // Filter results - let results: Vec = arc_preset.lock().unwrap().clone(); + let results: Vec = arc_preset.lock().unwrap().clone(); let mut filtered_results: Vec = Vec::new(); for (index, preset) in results.iter().enumerate() { if (filter_acid.load(Ordering::SeqCst) && preset.tag_acid == true) || @@ -2219,13 +2219,22 @@ VCF: Voltage Controlled Filter model".to_string()); }); }, LFOSelect::Misc => { - ui.horizontal(|ui|{ - ui.label(RichText::new("Link Cutoff 2 to Cutoff 1") - .font(FONT) - ) - .on_hover_text("Filter 1 will control both filter cutoff values"); - let filter_cutoff_link = toggle_switch::ToggleSwitch::for_param(¶ms.filter_cutoff_link, setter); - ui.add(filter_cutoff_link); + ui.vertical(|ui|{ + ui.horizontal(|ui|{ + ui.label(RichText::new("Link Cutoff 2 to Cutoff 1") + .font(FONT) + ) + .on_hover_text("Filter 1 will control both filter cutoff values"); + let filter_cutoff_link = toggle_switch::ToggleSwitch::for_param(¶ms.filter_cutoff_link, setter); + ui.add(filter_cutoff_link); + }); + ui.horizontal(|ui|{ + ui.label(RichText::new("Stereo Behavior") + .font(FONT) + ) + .on_hover_text("The stereo algorithm to use for voice spreads"); + ui.add(ParamSlider::for_param(¶ms.stereo_algorithm, setter).with_width(180.0)); + }); }); }, LFOSelect::FM => { @@ -2776,7 +2785,7 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); if dialog.show(egui_ctx).selected() { if let Some(file) = dialog.path() { let opened_file = Some(file.to_path_buf()); - let unserialized: Option; + let unserialized: Option; (_, unserialized) = Actuate::import_preset(opened_file); if unserialized.is_some() { @@ -2897,7 +2906,7 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); ui.painter().text(popup_pos, Align2::CENTER_CENTER, "Loading...", LOADING_FONT, Color32::BLACK); let opened_file = Some(file.to_path_buf()); - let unserialized: Vec; + let unserialized: Vec; (default_name, unserialized) = Actuate::load_preset_bank(opened_file); let temppath = default_name.clone(); let path = Path::new(&temppath); @@ -3140,6 +3149,29 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); .with_width(268.0)); }); ui.separator(); + // Chorus + ui.horizontal(|ui|{ + ui.label(RichText::new("Chorus") + .font(FONT)); + let use_chorus_toggle = toggle_switch::ToggleSwitch::for_param(¶ms.use_chorus, setter); + ui.add(use_chorus_toggle); + }); + ui.vertical(|ui|{ + ui.add(CustomParamSlider::ParamSlider::for_param(¶ms.chorus_amount, setter) + .set_left_sided_label(true) + .set_label_width(84.0) + .with_width(268.0)); + ui.add(CustomParamSlider::ParamSlider::for_param(¶ms.chorus_range, setter) + .slimmer(0.7) + .set_left_sided_label(true) + .set_label_width(84.0) + .with_width(268.0)); + ui.add(CustomParamSlider::ParamSlider::for_param(¶ms.chorus_speed, setter) + .set_left_sided_label(true) + .set_label_width(84.0) + .with_width(268.0)); + }); + ui.separator(); // Phaser ui.horizontal(|ui|{ ui.label(RichText::new("Phaser") diff --git a/src/actuate_structs.rs b/src/actuate_structs.rs index 24776ae..60b1e5f 100644 --- a/src/actuate_structs.rs +++ b/src/actuate_structs.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; -use crate::{actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel}, audio_module::{AudioModuleType, Oscillator::{self, RetriggerStyle, SmoothStyle, VoiceType}}, fx::{delay::{DelaySnapValues, DelayType}, saturation::SaturationType, ArduraFilter, StateVariableFilter::ResonanceType}, LFOController}; +use crate::{actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel, StereoAlgorithm}, audio_module::{AudioModuleType, Oscillator::{self, RetriggerStyle, SmoothStyle, VoiceType}}, fx::{delay::{DelaySnapValues, DelayType}, saturation::SaturationType, ArduraFilter, StateVariableFilter::ResonanceType}, LFOController}; /// Modulation struct for passing mods to audio modules #[derive(Serialize, Deserialize, Clone)] @@ -22,7 +22,7 @@ pub struct ModulationStruct { /// This is the structure that represents a storable preset value #[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV126 { +pub struct ActuatePresetV130 { // Information pub preset_name: String, pub preset_info: String, @@ -269,6 +269,9 @@ pub struct ActuatePresetV126 { pub fm_decay_curve: Oscillator::SmoothStyle, pub fm_release_curve: Oscillator::SmoothStyle, + // Stereo + pub stereo_algorithm: StereoAlgorithm, + // EQ pub pre_use_eq: bool, pub pre_low_freq: f32, @@ -312,6 +315,11 @@ pub struct ActuatePresetV126 { pub phaser_rate: f32, pub phaser_feedback: f32, + pub use_chorus: bool, + pub chorus_amount: f32, + pub chorus_range: f32, + pub chorus_speed: f32, + pub use_buffermod: bool, pub buffermod_amount: f32, pub buffermod_depth: f32, diff --git a/src/audio_module.rs b/src/audio_module.rs index 7c75643..95ce3c4 100644 --- a/src/audio_module.rs +++ b/src/audio_module.rs @@ -36,9 +36,7 @@ pub(crate) mod Oscillator; pub(crate) mod frequency_modulation; use self::Oscillator::{DeterministicWhiteNoiseGenerator, OscState, RetriggerStyle, SmoothStyle}; use crate::{ - ActuateParams, - CustomWidgets::{ui_knob::{self, KnobLayout}, CustomVerticalSlider}, - PitchRouting, DARK_GREY_UI_COLOR, FONT_COLOR, LIGHTER_GREY_UI_COLOR, MEDIUM_GREY_UI_COLOR, SMALLER_FONT, YELLOW_MUSTARD + actuate_enums::StereoAlgorithm, ActuateParams, CustomWidgets::{ui_knob::{self, KnobLayout}, CustomVerticalSlider}, PitchRouting, DARK_GREY_UI_COLOR, FONT_COLOR, LIGHTER_GREY_UI_COLOR, MEDIUM_GREY_UI_COLOR, SMALLER_FONT, YELLOW_MUSTARD }; use crate::{CustomWidgets::{BeizerButton::{self, ButtonLayout}, BoolButton}, DARKER_GREY_UI_COLOR}; use CustomVerticalSlider::ParamSlider as VerticalParamSlider; @@ -1478,6 +1476,7 @@ Random: Sample uses a new random position every note".to_string()); uni_velocity_mod: f32, vel_gain_mod: f32, vel_lfo_gain_mod: f32, + stereo_algorithm: StereoAlgorithm, ) -> (f32, f32, bool, bool) { // If the process is in here the file dialog is not open per lib.rs @@ -1989,7 +1988,7 @@ Random: Sample uses a new random position every note".to_string()); }; let mut unison_angles = vec![0.0; unison_even_voices as usize]; for i in 1..(unison_even_voices + 1) { - let voice_angle = self.calculate_panning(i - 1, self.osc_unison); + let voice_angle = self.calculate_panning(i - 1, self.osc_unison, stereo_algorithm); unison_angles[(i - 1) as usize] = voice_angle; } @@ -3050,7 +3049,17 @@ Random: Sample uses a new random position every note".to_string()); summed_voices_r = (summed_voices_r + summed_voices_l * 0.8)/2.0; // Stereo Spreading code - let width_coeff = self.osc_stereo * 0.5; + let width_coeff = match stereo_algorithm { + StereoAlgorithm::Original => { + self.osc_stereo * 0.5 + } + StereoAlgorithm::CubeSpread => { + self.osc_stereo + }, + StereoAlgorithm::ExpSpread => { + self.osc_stereo * 1.8 + }, + }; let mid = (summed_voices_l + summed_voices_r) * 0.5; let stereo = (summed_voices_r - summed_voices_l) * width_coeff; summed_voices_l = mid - stereo; @@ -3484,7 +3493,7 @@ Random: Sample uses a new random position every note".to_string()); } } - fn calculate_panning(&mut self, voice_index: i32, num_voices: i32) -> f32 { + fn calculate_panning(&mut self, voice_index: i32, num_voices: i32, stereo_algorithm: StereoAlgorithm) -> f32 { // Ensure the voice index is within bounds. let voice_index = voice_index.min(num_voices - 1); @@ -3521,16 +3530,42 @@ Random: Sample uses a new random position every note".to_string()); // Calculate the pan angle for voices with index 0 and 1. let base_angle = ((voice_index / 2) as f32) / ((num_voices / 2) as f32 - 1.0) - 0.5; - // Determine the final angle based on even or odd index. - let angle = if voice_index % 2 == 0 { - -base_angle - } else { - base_angle - }; + let angle: f32; + match stereo_algorithm { + StereoAlgorithm::CubeSpread => { + let poly_base_angle = base_angle.powf(3.0)/0.3; + // Determine the final angle based on even or odd index. + angle = if voice_index % 2 == 0 { + -poly_base_angle + } else { + poly_base_angle + }; + }, + StereoAlgorithm::ExpSpread => { + let exp_base_angle = base_angle.exp() - 1.0; // Exponential transformation + let max_exp_angle = (1.0f32).exp() - 1.0; + let normalized_exp_angle = exp_base_angle / max_exp_angle; + + // Determine the final angle based on even or odd index. + angle = if voice_index % 2 == 0 { + -normalized_exp_angle + } else { + normalized_exp_angle + }; + }, + StereoAlgorithm::Original => { + // Determine the final angle based on even or odd index. + angle = if voice_index % 2 == 0 { + -base_angle + } else { + base_angle + }; + }, + } + if voice_index == 0 { self.two_voice_stereo_flipper = !self.two_voice_stereo_flipper; } - - angle * std::f32::consts::PI * sign // Use full scale for other cases + angle * std::f32::consts::PI * sign } } diff --git a/src/fx.rs b/src/fx.rs index 03ca058..2581b15 100644 --- a/src/fx.rs +++ b/src/fx.rs @@ -13,3 +13,4 @@ pub(crate) mod reverb; pub(crate) mod aw_galactic_reverb; pub(crate) mod simple_space_reverb; pub(crate) mod saturation; +pub(crate) mod chorus; diff --git a/src/fx/chorus.rs b/src/fx/chorus.rs new file mode 100644 index 0000000..1ee4c82 --- /dev/null +++ b/src/fx/chorus.rs @@ -0,0 +1,232 @@ +// A chorus based off Airwindows ChorusEnsemble written by Ardura + +use std::f32::consts::FRAC_PI_2; +use std::f32::consts::TAU; + +const TOTAL_SAMPLES: usize = 16386; +const LOOP_LIMIT: usize = 8176; +const RANGE_MULT: f32 = 981.19368; + +#[derive(Clone)] +pub struct ChorusEnsemble { + // Inputs + sample_rate: f32, + range: f32, + speed: f32, + amount: f32, + // Internals + raw_speed: f32, + raw_range: f32, + sweep: f32, + range2: f32, + range3: f32, + range4: f32, + left_buffer: [f32; TOTAL_SAMPLES], + right_buffer: [f32; TOTAL_SAMPLES], + gcount: usize, + airPrevL: f32, + airEvenL: f32, + airOddL: f32, + airFactorL: f32, + airPrevR: f32, + airEvenR: f32, + airOddR: f32, + airFactorR: f32, + fpFlip: bool, +} + +impl ChorusEnsemble { + pub fn new( + sample_rate: f32, + range: f32, + speed: f32, + amount: f32, + ) -> Self { + let mut scale = 1.0/44100.0; + scale *= sample_rate; + let calc_speed = (speed.powf(3.0) * 0.001)*scale; + let calc_range = range.powf(3.0) * RANGE_MULT; + let calc_range2 = calc_range * 2.0; + let calc_range3 = calc_range * 3.0; + let calc_range4 = calc_range * 4.0; + Self { + // Inputs + sample_rate: sample_rate, + range: calc_range, + speed: calc_speed, + amount: amount, + // Internals + raw_speed: speed, + raw_range: range, + sweep: FRAC_PI_2, + range2: calc_range2, + range3: calc_range3, + range4: calc_range4, + left_buffer: [0.0; TOTAL_SAMPLES], + right_buffer: [0.0; TOTAL_SAMPLES], + gcount: 0, + airPrevL: 0.0, + airEvenL: 0.0, + airOddL: 0.0, + airFactorL: 0.0, + airPrevR: 0.0, + airEvenR: 0.0, + airOddR: 0.0, + airFactorR: 0.0, + fpFlip: false, + } + } + + pub fn update(&mut self, sample_rate: f32, range: f32, speed: f32, amount: f32) { + if sample_rate != self.sample_rate { + self.sample_rate = sample_rate; + let mut scale = 1.0/44100.0; + scale *= sample_rate; + self.speed = (speed.powf(3.0) * 0.001)*scale; + } + if amount != self.amount { + self.amount = amount; + } + if range != self.raw_range { + self.raw_range = range; + self.range = range.powf(3.0) * RANGE_MULT; + self.range2 = self.range * 2.0; + self.range3 = self.range * 3.0; + self.range4 = self.range * 4.0; + } + if speed != self.raw_speed { + self.raw_speed = self.raw_speed; + // Scaled params + let mut scale = 1.0/44100.0; + scale *= sample_rate; + self.speed = (speed.powf(3.0) * 0.001)*scale; + } + } + + pub fn process(&mut self, left_in: f32, right_in: f32) -> (f32, f32) { + let mut left_out; + let mut right_out; + + // Left side input + self.airFactorL = self.airPrevL - left_in; + if self.fpFlip { + self.airEvenL += self.airFactorL; + self.airOddL -= self.airFactorL; + self.airFactorL = self.airEvenL; + } else { + self.airOddL += self.airFactorL; + self.airEvenL -= self.airFactorL; + self.airFactorL = self.airOddL; + } + self.airOddL = (self.airOddL - ((self.airOddL - self.airEvenL)/256.0)) / 1.0001; + self.airEvenL = (self.airEvenL - ((self.airEvenL - self.airOddL)/256.0)) / 1.0001; + self.airPrevL = left_in; + left_out = left_in + (self.airFactorL * self.amount); + //air, compensates for loss of highs in flanger's interpolation + + // Right side input + self.airFactorR = self.airPrevR - right_in; + if self.fpFlip { + self.airEvenR += self.airFactorR; + self.airOddR -= self.airFactorR; + self.airFactorR = self.airEvenR; + } else { + self.airOddR += self.airFactorR; + self.airEvenR -= self.airFactorR; + self.airFactorR = self.airOddR; + } + self.airOddR = (self.airOddR - ((self.airOddR - self.airEvenR)/256.0)) / 1.0001; + self.airEvenR = (self.airEvenR - ((self.airEvenR - self.airOddR)/256.0)) / 1.0001; + self.airPrevR = right_in; + right_out = right_in + (self.airFactorR * self.amount); + //air, compensates for loss of highs in flanger's interpolation + + if self.gcount < 1 || self.gcount > LOOP_LIMIT { + self.gcount = LOOP_LIMIT; + } + + let mut count = self.gcount; + self.left_buffer[count] = left_out; + self.left_buffer[count + LOOP_LIMIT] = left_out; + self.right_buffer[count] = right_out; + self.right_buffer[count + LOOP_LIMIT] = right_out; + self.gcount -= 1; + + let modulation = self.range * self.amount; + + // Structure of oneof the "ensemble" chorus voices + let mut offset = self.range + (modulation * (self.sweep).sin()); + count = self.gcount + offset.floor() as usize; + + left_out = self.left_buffer[count] * (1.0 - (offset - offset.floor())); + left_out += self.left_buffer[count + 1]; + left_out += self.left_buffer[count + 2] * (offset - offset.floor()); + left_out -= (self.left_buffer[count] - self.left_buffer[count + 1]) - (self.left_buffer[count + 1] - self.left_buffer[count + 2])/50.0; + + right_out += self.right_buffer[count] * (1.0 - (offset - offset.floor())); + right_out += self.right_buffer[count + 1]; + right_out += self.right_buffer[count + 2] * (offset - offset.floor()); + right_out -= (self.right_buffer[count] - self.right_buffer[count + 1]) - (self.right_buffer[count + 1] - self.right_buffer[count + 2])/50.0; + + // Voice 2 + offset = self.range2 + (modulation * (self.sweep + 1.0).sin()); + count = self.gcount + offset.floor() as usize; + + left_out += self.left_buffer[count] * (1.0 - (offset - offset.floor())); + left_out += self.left_buffer[count + 1]; + left_out += self.left_buffer[count + 2] * (offset - offset.floor()); + left_out -= (self.left_buffer[count] - self.left_buffer[count + 1]) - (self.left_buffer[count + 1] - self.left_buffer[count + 2])/50.0; + + right_out += self.right_buffer[count] * (1.0 - (offset - offset.floor())); + right_out += self.right_buffer[count + 1]; + right_out += self.right_buffer[count + 2] * (offset - offset.floor()); + right_out -= (self.right_buffer[count] - self.right_buffer[count + 1]) - (self.right_buffer[count + 1] - self.right_buffer[count + 2])/50.0; + + // Voice 3 + offset = self.range3 + (modulation * (self.sweep + 2.0).sin()); + count = self.gcount + offset.floor() as usize; + + left_out += self.left_buffer[count] * (1.0 - (offset - offset.floor())); + left_out += self.left_buffer[count + 1]; + left_out += self.left_buffer[count + 2] * (offset - offset.floor()); + left_out -= (self.left_buffer[count] - self.left_buffer[count + 1]) - (self.left_buffer[count + 1] - self.left_buffer[count + 2])/50.0; + + right_out += self.right_buffer[count] * (1.0 - (offset - offset.floor())); + right_out += self.right_buffer[count + 1]; + right_out += self.right_buffer[count + 2] * (offset - offset.floor()); + right_out -= (self.right_buffer[count] - self.right_buffer[count + 1]) - (self.right_buffer[count + 1] - self.right_buffer[count + 2])/50.0; + + // Voice 4 + offset = self.range4 + (modulation * (self.sweep + 3.0).sin()); + count = self.gcount + offset.floor() as usize; + + left_out += self.left_buffer[count] * (1.0 - (offset - offset.floor())); + left_out += self.left_buffer[count + 1]; + left_out += self.left_buffer[count + 2] * (offset - offset.floor()); + left_out -= (self.left_buffer[count] - self.left_buffer[count + 1]) - (self.left_buffer[count + 1] - self.left_buffer[count + 2])/50.0; + + right_out += self.right_buffer[count] * (1.0 - (offset - offset.floor())); + right_out += self.right_buffer[count + 1]; + right_out += self.right_buffer[count + 2] * (offset - offset.floor()); + right_out -= (self.right_buffer[count] - self.right_buffer[count + 1]) - (self.right_buffer[count + 1] - self.right_buffer[count + 2])/50.0; + + // Scale the added voices down + left_out *= 0.125; + right_out *= 0.125; + + self.sweep += self.speed; + if self.sweep > TAU { + self.sweep -= TAU; + } + + if self.amount != 1.0 { + // Mix dry and wet signals based on the amount parameter + left_out = left_in * (1.0 - self.amount) + left_out * self.amount; + right_out = right_in * (1.0 - self.amount) + right_out * self.amount; + } + + self.fpFlip = !self.fpFlip; + + (left_out, right_out) + } +} diff --git a/src/lib.rs b/src/lib.rs index 810abe2..a38a952 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,7 @@ If not, see https://www.gnu.org/licenses/. ##################################### Actuate - Synthesizer + Sampler/Granulizer by Ardura -Version 1.2.8 +Version 1.3.0 ##################################### @@ -25,8 +25,8 @@ This is the first synth I've ever written and first large Rust project. Thanks f */ #![allow(non_snake_case)] -use actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel}; -use actuate_structs::{ActuatePresetV126, ModulationStruct}; +use actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel, StereoAlgorithm}; +use actuate_structs::{ActuatePresetV130, ModulationStruct}; use flate2::{read::GzDecoder,write::GzEncoder,Compression}; use nih_plug::prelude::*; use nih_plug_egui::{ @@ -47,21 +47,7 @@ use audio_module::{ frequency_modulation, }; use fx::{ - abass::a_bass_saturation, - aw_galactic_reverb::GalacticReverb, - simple_space_reverb::SimpleSpaceReverb, - biquad_filters::{self, FilterType}, - buffermodulator::BufferModulator, - compressor::Compressor, - delay::{Delay, DelaySnapValues, DelayType}, - flanger::StereoFlanger, - limiter::StereoLimiter, - phaser::StereoPhaser, - reverb::StereoReverb, - saturation::{Saturation, SaturationType}, - ArduraFilter::{self, ResponseType}, - StateVariableFilter::{ResonanceType, StateVariableFilter}, - VCFilter::ResponseType as VCResponseType + abass::a_bass_saturation, aw_galactic_reverb::GalacticReverb, biquad_filters::{self, FilterType}, buffermodulator::BufferModulator, chorus::ChorusEnsemble, compressor::Compressor, delay::{Delay, DelaySnapValues, DelayType}, flanger::StereoFlanger, limiter::StereoLimiter, phaser::StereoPhaser, reverb::StereoReverb, saturation::{Saturation, SaturationType}, simple_space_reverb::SimpleSpaceReverb, ArduraFilter::{self, ResponseType}, StateVariableFilter::{ResonanceType, StateVariableFilter}, VCFilter::ResponseType as VCResponseType }; use old_preset_structs::{ @@ -70,8 +56,10 @@ use old_preset_structs::{ load_unserialized_v122, load_unserialized_v123, load_unserialized_v125, + load_unserialized_v126, ActuatePresetV123, - ActuatePresetV125 + ActuatePresetV125, + ActuatePresetV126, }; mod actuate_gui; @@ -189,7 +177,7 @@ pub struct Actuate { preset_name: Arc>, preset_info: Arc>, preset_category: Arc>, - preset_lib: Arc>>, + preset_lib: Arc>>, // Used for DC Offset calculations dc_filter_l: StateVariableFilter, @@ -234,6 +222,9 @@ pub struct Actuate { // Flanger flanger: StereoFlanger, + // Chorus + chorus: ChorusEnsemble, + // Limiter limiter: StereoLimiter, @@ -435,6 +426,9 @@ impl Default for Actuate { // Phaser phaser: StereoPhaser::new(), + // Chorus + chorus: ChorusEnsemble::new(44100.0, 0.5, 0.5, 0.8), + // Limiter limiter: StereoLimiter::new(0.5, 0.5), @@ -957,6 +951,15 @@ pub struct ActuateParams { #[id = "flanger_feedback"] pub flanger_feedback: FloatParam, + #[id = "use_chorus"] + pub use_chorus: BoolParam, + #[id = "chorus_amount"] + pub chorus_amount: FloatParam, + #[id = "chorus_speed"] + pub chorus_speed: FloatParam, + #[id = "chorus_range"] + pub chorus_range: FloatParam, + #[id = "use_limiter"] pub use_limiter: BoolParam, #[id = "limiter_threshold"] @@ -988,6 +991,10 @@ pub struct ActuateParams { #[id = "fm_release_curve"] pub fm_release_curve: EnumParam, + // Stereo Algorithm + #[id = "Stereo Algorithm"] + pub stereo_algorithm: EnumParam, + // UI Non-param Params #[id = "param_load_bank"] pub param_load_bank: BoolParam, @@ -2550,6 +2557,32 @@ impl ActuateParams { ) .with_value_to_string(formatters::v2s_f32_rounded(2)), + use_chorus: BoolParam::new("Chorus", false), + chorus_amount: FloatParam::new( + "Amount", + 0.8, + FloatRange::Linear { min: 0.0, max: 1.0 }, + ) + .with_value_to_string(formatters::v2s_f32_rounded(3)), + chorus_range: FloatParam::new( + "Range", + 0.5, + FloatRange::Linear { + min: 0.0, + max: 1.0 + } + ) + .with_value_to_string(formatters::v2s_f32_rounded(3)), + chorus_speed: FloatParam::new( + "Speed", + 0.5, + FloatRange::Linear { + min: 0.0, + max: 1.0, + }, + ) + .with_value_to_string(formatters::v2s_f32_rounded(3)), + use_limiter: BoolParam::new("Limiter", false), limiter_threshold: FloatParam::new( "Threshold", @@ -2645,6 +2678,8 @@ impl ActuateParams { let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), + + stereo_algorithm: EnumParam::new("Stereo Behavior", StereoAlgorithm::Original), // UI Non-Param Params are dummy params for my buttons //////////////////////////////////////////////////////////////////////////////////// @@ -4001,6 +4036,7 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_1, temp_mod_lfo_gain_1, + self.params.stereo_algorithm.value() ); // Sum to MONO fm_wave_1 = (wave1_l + wave1_r)/2.0; @@ -4032,6 +4068,7 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_2, temp_mod_lfo_gain_2, + self.params.stereo_algorithm.value() ); // Sum to MONO fm_wave_2 = (wave2_l + wave2_r)/2.0; @@ -4063,6 +4100,7 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_3, temp_mod_lfo_gain_3, + self.params.stereo_algorithm.value() ); // I know this isn't a perfect 3rd, but 0.01 is acceptable headroom wave3_l *= self.params.audio_module_3_level.value() * 0.33; @@ -4624,6 +4662,16 @@ impl Actuate { self.params.buffermod_amount.value(), ); } + // Chorus + if self.params.use_chorus.value() { + self.chorus.update( + self.sample_rate, + self.params.chorus_range.value(), + self.params.chorus_speed.value(), + self.params.chorus_amount.value() + ); + (left_output, right_output) = self.chorus.process(left_output, right_output); + } // Phaser if self.params.use_phaser.value() { self.phaser.set_sample_rate(self.sample_rate); @@ -4766,7 +4814,7 @@ impl Actuate { } - fn export_preset(saving_preset: Option, mut preset: ActuatePresetV126) { + fn export_preset(saving_preset: Option, mut preset: ActuatePresetV130) { if let Some(mut location) = saving_preset { if let Some(extension_check) = location.extension() { let extension = extension_check.to_string_lossy().to_string(); @@ -4787,7 +4835,7 @@ impl Actuate { preset.mod3_sample_lib.clear(); // Serialize to MessagePack bytes - let serialized_data = rmp_serde::to_vec::(&preset); + let serialized_data = rmp_serde::to_vec::(&preset); if let Err(err) = serialized_data { eprintln!("Error serializing data: {}", err); @@ -4809,7 +4857,7 @@ impl Actuate { } // import_preset() uses message packing with serde - fn import_preset(imported_preset: Option) -> (String, Option) { + fn import_preset(imported_preset: Option) -> (String, Option) { let return_name; if let Some(imported_preset) = imported_preset { @@ -4838,28 +4886,33 @@ impl Actuate { let file_string_data = decompressed_data.unwrap(); // Deserialize into preset struct - return default empty lib if error - let mut unserialized: ActuatePresetV126 = rmp_serde::from_slice(&file_string_data) + let mut unserialized: ActuatePresetV130 = rmp_serde::from_slice(&file_string_data) .unwrap_or(ERROR_PRESET.clone()); + // This if cascade tries to load each predecessor format of presets if unserialized.preset_name.contains("Error") { - unserialized = load_unserialized_v125(file_string_data.clone()); - if unserialized.preset_name.contains("Error") { - // Attempt to load the previous version preset type - unserialized = load_unserialized_v123(file_string_data.clone()); + unserialized = load_unserialized_v126(file_string_data.clone()); + if unserialized.preset_name.contains("Error") { + unserialized = load_unserialized_v125(file_string_data.clone()); if unserialized.preset_name.contains("Error") { - // Try loading the previous preset struct version - unserialized = load_unserialized_v122(file_string_data.clone()); - // Attempt to load the previous version preset type + unserialized = load_unserialized_v123(file_string_data.clone()); + if unserialized.preset_name.contains("Error") { // Try loading the previous preset struct version - unserialized = load_unserialized_v114(file_string_data.clone()); + unserialized = load_unserialized_v122(file_string_data.clone()); - // Attempt to load the oldest preset type + // Attempt to load the previous version preset type if unserialized.preset_name.contains("Error") { // Try loading the previous preset struct version - unserialized = load_unserialized_old(file_string_data.clone()); + unserialized = load_unserialized_v114(file_string_data.clone()); + + // Attempt to load the oldest preset type + if unserialized.preset_name.contains("Error") { + // Try loading the previous preset struct version + unserialized = load_unserialized_old(file_string_data.clone()); + } } } } @@ -4872,7 +4925,7 @@ impl Actuate { } // Load presets uses message packing with serde - fn load_preset_bank(loading_bank: Option) -> (String, Vec) { + fn load_preset_bank(loading_bank: Option) -> (String, Vec) { let return_name; if let Some(loading_bank) = loading_bank { @@ -4898,36 +4951,52 @@ impl Actuate { let file_string_data = decompressed_data.unwrap(); // Deserialize into preset struct - return default empty lib if error - let unserialized: Vec = rmp_serde::from_slice(&file_string_data) + let unserialized: Vec = rmp_serde::from_slice(&file_string_data) .unwrap_or(vec![ ERROR_PRESET.clone(); PRESET_BANK_SIZE ]); - // Attempt loading 1.2.5 bank if error + // Attempt loading 1.2.6 bank if error if unserialized[0].preset_name.contains("Error") { - let unserialized: Vec = rmp_serde::from_slice(&file_string_data) - .unwrap_or(vec![ - ERROR_PRESETV125.clone(); - PRESET_BANK_SIZE - ]); - // Convert each v1.2.3 entry into latest - let mut converted: Vec = Vec::new(); - for v125_preset in unserialized.iter() { - converted.push(old_preset_structs::convert_preset_v125(v125_preset.clone())); + // Deserialize into preset struct - return default empty lib if error + let unserialized: Vec = rmp_serde::from_slice(&file_string_data) + .unwrap_or(vec![ + ERROR_PRESETV126.clone(); + PRESET_BANK_SIZE + ]); + // Convert each v1.2.6 entry into latest + let mut converted: Vec = Vec::new(); + for v126_preset in unserialized.iter() { + converted.push(old_preset_structs::convert_preset_v126(v126_preset.clone())); } - // Attempt loading 1.2.3 bank if error + // Attempt loading 1.2.5 bank if error if unserialized[0].preset_name.contains("Error") { - let unserialized: Vec = rmp_serde::from_slice(&file_string_data) + let unserialized: Vec = rmp_serde::from_slice(&file_string_data) .unwrap_or(vec![ - ERROR_PRESETV123.clone(); + ERROR_PRESETV125.clone(); PRESET_BANK_SIZE ]); - // Convert each v1.2.3 entry into latest - let mut converted: Vec = Vec::new(); - for v123_preset in unserialized.iter() { - converted.push(old_preset_structs::convert_preset_v123(v123_preset.clone())); + // Convert each v1.2.5 entry into latest + let mut converted: Vec = Vec::new(); + for v125_preset in unserialized.iter() { + converted.push(old_preset_structs::convert_preset_v125(v125_preset.clone())); + } + + // Attempt loading 1.2.3 bank if error + if unserialized[0].preset_name.contains("Error") { + let unserialized: Vec = rmp_serde::from_slice(&file_string_data) + .unwrap_or(vec![ + ERROR_PRESETV123.clone(); + PRESET_BANK_SIZE + ]); + // Convert each v1.2.3 entry into latest + let mut converted: Vec = Vec::new(); + for v123_preset in unserialized.iter() { + converted.push(old_preset_structs::convert_preset_v123(v123_preset.clone())); + } + return (return_name, converted); } return (return_name, converted); } @@ -4944,7 +5013,7 @@ impl Actuate { setter: &ParamSetter, params: Arc, current_preset_index: usize, - arc_preset: &Vec, + arc_preset: &Vec, AMod1: &mut AudioModule, AMod2: &mut AudioModule, AMod3: &mut AudioModule, @@ -5350,6 +5419,13 @@ impl Actuate { setter.set_parameter(¶ms.fm_decay_curve, loaded_preset.fm_decay_curve); setter.set_parameter(¶ms.fm_release_curve, loaded_preset.fm_release_curve); + // Stereo Alg + Chorus Update 1.3.0 + setter.set_parameter(¶ms.use_chorus, loaded_preset.use_chorus); + setter.set_parameter(¶ms.chorus_amount, loaded_preset.chorus_amount); + setter.set_parameter(¶ms.chorus_range, loaded_preset.chorus_range); + setter.set_parameter(¶ms.chorus_speed, loaded_preset.chorus_speed); + setter.set_parameter(¶ms.stereo_algorithm, loaded_preset.stereo_algorithm); + // Assign the preset tags setter.set_parameter(¶ms.tag_acid, loaded_preset.tag_acid); setter.set_parameter(¶ms.tag_analog, loaded_preset.tag_analog); @@ -5424,7 +5500,7 @@ impl Actuate { ) } - fn save_preset_bank(preset_store: &mut Vec, saving_bank: Option) { + fn save_preset_bank(preset_store: &mut Vec, saving_bank: Option) { if let Some(mut location) = saving_bank { if let Some(extension_check) = location.extension() { let extension = extension_check.to_string_lossy().to_string(); @@ -5448,7 +5524,7 @@ impl Actuate { // Serialize to MessagePack bytes let serialized_data = - rmp_serde::to_vec::<&Vec>(&preset_store.as_ref()); + rmp_serde::to_vec::<&Vec>(&preset_store.as_ref()); if let Err(err) = serialized_data { eprintln!("Error serializing data: {}", err); @@ -5494,7 +5570,7 @@ impl Actuate { let AM2 = AM2c.lock().unwrap(); let AM3 = AM3c.lock().unwrap(); arc_lib.lock().unwrap()[self.current_preset.load(Ordering::Acquire) as usize] = - ActuatePresetV126 { + ActuatePresetV130 { preset_name: self.preset_name.lock().unwrap().clone(), preset_info: self.preset_info.lock().unwrap().clone(), preset_category: self.params.preset_category.value(), @@ -5744,6 +5820,8 @@ impl Actuate { pre_mid_gain: self.params.pre_mid_gain.value(), pre_high_gain: self.params.pre_high_gain.value(), + stereo_algorithm: self.params.stereo_algorithm.value().clone(), + use_fx: self.params.use_fx.value(), use_compressor: self.params.use_compressor.value(), comp_amt: self.params.comp_amt.value(), @@ -5765,6 +5843,10 @@ impl Actuate { reverb_amount: self.params.reverb_amount.value(), reverb_size: self.params.reverb_size.value(), reverb_feedback: self.params.reverb_feedback.value(), + use_chorus: self.params.use_chorus.value(), + chorus_amount: self.params.chorus_amount.value(), + chorus_range: self.params.chorus_range.value(), + chorus_speed: self.params.chorus_speed.value(), use_phaser: self.params.use_phaser.value(), phaser_amount: self.params.phaser_amount.value(), phaser_depth: self.params.phaser_depth.value(), @@ -6846,7 +6928,296 @@ lazy_static::lazy_static!( limiter_knee: 0.5, }; - static ref ERROR_PRESET: ActuatePresetV126 = ActuatePresetV126 { + static ref ERROR_PRESETV126: ActuatePresetV126 = ActuatePresetV126 { + preset_name: String::from("Error Loading"), + preset_info: String::from("Corrupt or incompatible versions"), + preset_category: PresetType::Select, + tag_acid: false, + tag_analog: false, + tag_bright: false, + tag_chord: false, + tag_crisp: false, + tag_deep: false, + tag_delicate: false, + tag_hard: false, + tag_harsh: false, + tag_lush: false, + tag_mellow: false, + tag_resonant: false, + tag_rich: false, + tag_sharp: false, + tag_silky: false, + tag_smooth: false, + tag_soft: false, + tag_stab: false, + tag_warm: false, + mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_level: 1.0, + mod1_audio_module_routing: AMFilterRouting::Filter1, + mod1_loaded_sample: vec![vec![0.0, 0.0]], + mod1_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod1_loop_wavetable: false, + mod1_single_cycle: false, + mod1_restretch: true, + mod1_prev_restretch: false, + mod1_grain_hold: 200, + mod1_grain_gap: 200, + mod1_start_position: 0.0, + mod1_end_position: 1.0, + mod1_grain_crossfade: 50, + mod1_osc_type: VoiceType::Sine, + mod1_osc_octave: 0, + mod1_osc_semitones: 0, + mod1_osc_detune: 0.0, + mod1_osc_attack: 0.0001, + mod1_osc_decay: 0.0001, + mod1_osc_sustain: 999.9, + mod1_osc_release: 5.0, + mod1_osc_retrigger: RetriggerStyle::Retrigger, + mod1_osc_atk_curve: SmoothStyle::Linear, + mod1_osc_dec_curve: SmoothStyle::Linear, + mod1_osc_rel_curve: SmoothStyle::Linear, + mod1_osc_unison: 1, + mod1_osc_unison_detune: 0.0, + mod1_osc_stereo: 0.0, + + mod2_audio_module_type: AudioModuleType::Off, + mod2_audio_module_level: 1.0, + mod2_audio_module_routing: AMFilterRouting::Filter1, + mod2_loaded_sample: vec![vec![0.0, 0.0]], + mod2_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod2_loop_wavetable: false, + mod2_single_cycle: false, + mod2_restretch: true, + mod2_prev_restretch: false, + mod2_grain_hold: 200, + mod2_grain_gap: 200, + mod2_start_position: 0.0, + mod2_end_position: 1.0, + mod2_grain_crossfade: 50, + mod2_osc_type: VoiceType::Sine, + mod2_osc_octave: 0, + mod2_osc_semitones: 0, + mod2_osc_detune: 0.0, + mod2_osc_attack: 0.0001, + mod2_osc_decay: 0.0001, + mod2_osc_sustain: 999.9, + mod2_osc_release: 5.0, + mod2_osc_retrigger: RetriggerStyle::Retrigger, + mod2_osc_atk_curve: SmoothStyle::Linear, + mod2_osc_dec_curve: SmoothStyle::Linear, + mod2_osc_rel_curve: SmoothStyle::Linear, + mod2_osc_unison: 1, + mod2_osc_unison_detune: 0.0, + mod2_osc_stereo: 0.0, + + mod3_audio_module_type: AudioModuleType::Off, + mod3_audio_module_level: 1.0, + mod3_audio_module_routing: AMFilterRouting::Filter1, + mod3_loaded_sample: vec![vec![0.0, 0.0]], + mod3_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod3_loop_wavetable: false, + mod3_single_cycle: false, + mod3_restretch: true, + mod3_prev_restretch: false, + mod3_grain_hold: 200, + mod3_grain_gap: 200, + mod3_start_position: 0.0, + mod3_end_position: 1.0, + mod3_grain_crossfade: 50, + mod3_osc_type: VoiceType::Sine, + mod3_osc_octave: 0, + mod3_osc_semitones: 0, + mod3_osc_detune: 0.0, + mod3_osc_attack: 0.0001, + mod3_osc_decay: 0.0001, + mod3_osc_sustain: 999.9, + mod3_osc_release: 5.0, + mod3_osc_retrigger: RetriggerStyle::Retrigger, + mod3_osc_atk_curve: SmoothStyle::Linear, + mod3_osc_dec_curve: SmoothStyle::Linear, + mod3_osc_rel_curve: SmoothStyle::Linear, + mod3_osc_unison: 1, + mod3_osc_unison_detune: 0.0, + mod3_osc_stereo: 0.0, + + filter_wet: 1.0, + filter_cutoff: 20000.0, + filter_resonance: 1.0, + filter_res_type: ResonanceType::Default, + filter_lp_amount: 1.0, + filter_hp_amount: 0.0, + filter_bp_amount: 0.0, + filter_env_peak: 0.0, + filter_env_attack: 0.0, + filter_env_decay: 0.0001, + filter_env_sustain: 999.9, + filter_env_release: 5.0, + filter_env_atk_curve: SmoothStyle::Linear, + filter_env_dec_curve: SmoothStyle::Linear, + filter_env_rel_curve: SmoothStyle::Linear, + filter_alg_type: FilterAlgorithms::SVF, + tilt_filter_type: ArduraFilter::ResponseType::Lowpass, + + filter_wet_2: 1.0, + filter_cutoff_2: 20000.0, + filter_resonance_2: 1.0, + filter_res_type_2: ResonanceType::Default, + filter_lp_amount_2: 1.0, + filter_hp_amount_2: 0.0, + filter_bp_amount_2: 0.0, + filter_env_peak_2: 0.0, + filter_env_attack_2: 0.0, + filter_env_decay_2: 0.0001, + filter_env_sustain_2: 999.9, + filter_env_release_2: 5.0, + filter_env_atk_curve_2: SmoothStyle::Linear, + filter_env_dec_curve_2: SmoothStyle::Linear, + filter_env_rel_curve_2: SmoothStyle::Linear, + filter_alg_type_2: FilterAlgorithms::SVF, + tilt_filter_type_2: ArduraFilter::ResponseType::Lowpass, + + filter_routing: FilterRouting::Parallel, + filter_cutoff_link: false, + + pitch_enable: false, + pitch_env_atk_curve: SmoothStyle::Linear, + pitch_env_dec_curve: SmoothStyle::Linear, + pitch_env_rel_curve: SmoothStyle::Linear, + pitch_env_attack: 0.0, + pitch_env_decay: 300.0, + pitch_env_sustain: 0.0, + pitch_env_release: 0.0, + pitch_env_peak: 0.0, + pitch_routing: PitchRouting::Osc1, + + pitch_enable_2: false, + pitch_env_peak_2: 0.0, + pitch_env_atk_curve_2: SmoothStyle::Linear, + pitch_env_dec_curve_2: SmoothStyle::Linear, + pitch_env_rel_curve_2: SmoothStyle::Linear, + pitch_env_attack_2: 0.0, + pitch_env_decay_2: 300.0, + pitch_env_release_2: 0.0, + pitch_env_sustain_2: 0.0, + pitch_routing_2: PitchRouting::Osc1, + + // LFOs + lfo1_enable: false, + lfo2_enable: false, + lfo3_enable: false, + + lfo1_freq: 2.0, + lfo1_retrigger: LFOController::LFORetrigger::None, + lfo1_sync: true, + lfo1_snap: LFOController::LFOSnapValues::Half, + lfo1_waveform: LFOController::Waveform::Sine, + lfo1_phase: 0.0, + + lfo2_freq: 2.0, + lfo2_retrigger: LFOController::LFORetrigger::None, + lfo2_sync: true, + lfo2_snap: LFOController::LFOSnapValues::Half, + lfo2_waveform: LFOController::Waveform::Sine, + lfo2_phase: 0.0, + + lfo3_freq: 2.0, + lfo3_retrigger: LFOController::LFORetrigger::None, + lfo3_sync: true, + lfo3_snap: LFOController::LFOSnapValues::Half, + lfo3_waveform: LFOController::Waveform::Sine, + lfo3_phase: 0.0, + + // Modulations + mod_source_1: ModulationSource::None, + mod_source_2: ModulationSource::None, + mod_source_3: ModulationSource::None, + mod_source_4: ModulationSource::None, + mod_dest_1: ModulationDestination::None, + mod_dest_2: ModulationDestination::None, + mod_dest_3: ModulationDestination::None, + mod_dest_4: ModulationDestination::None, + mod_amount_1: 0.0, + mod_amount_2: 0.0, + mod_amount_3: 0.0, + mod_amount_4: 0.0, + + // EQ + pre_use_eq: false, + pre_low_freq: 800.0, + pre_mid_freq: 3000.0, + pre_high_freq: 10000.0, + pre_low_gain: 0.0, + pre_mid_gain: 0.0, + pre_high_gain: 0.0, + + // FM + fm_attack: 0.5, + fm_attack_curve: SmoothStyle::Linear, + fm_decay: 0.5, + fm_decay_curve: SmoothStyle::Linear, + fm_release: 0.5, + fm_release_curve: SmoothStyle::Linear, + fm_sustain: 0.5, + fm_cycles: 1, + fm_one_to_three: 0.0, + fm_one_to_two: 0.0, + fm_two_to_three: 0.0, + + // FX + use_fx: true, + + use_compressor: false, + comp_amt: 0.5, + comp_atk: 0.5, + comp_rel: 0.5, + comp_drive: 0.5, + + use_abass: false, + abass_amount: 0.0011, + + use_saturation: false, + sat_amount: 0.0, + sat_type: SaturationType::Tape, + + use_delay: false, + delay_amount: 0.5, + delay_time: DelaySnapValues::Quarter, + delay_decay: 0.5, + delay_type: DelayType::Stereo, + + use_reverb: false, + reverb_model: ReverbModel::Default, + reverb_amount: 0.85, + reverb_size: 1.0, + reverb_feedback: 0.28, + + use_phaser: false, + phaser_amount: 0.5, + phaser_depth: 0.5, + phaser_rate: 0.5, + phaser_feedback: 0.5, + + use_buffermod: false, + buffermod_amount: 0.5, + buffermod_depth: 0.5, + buffermod_rate: 0.5, + buffermod_spread: 0.0, + buffermod_timing: 620.0, + + use_flanger: false, + flanger_amount: 0.5, + flanger_depth: 0.5, + flanger_rate: 0.5, + flanger_feedback: 0.5, + + use_limiter: false, + limiter_threshold: 0.5, + limiter_knee: 0.5, + }; + + // This gets updates to the latest preset type each format update + static ref ERROR_PRESET: ActuatePresetV130 = ActuatePresetV130 { preset_name: String::from("Error Loading"), preset_info: String::from("Corrupt or incompatible versions"), preset_category: PresetType::Select, @@ -7117,6 +7488,14 @@ lazy_static::lazy_static!( phaser_rate: 0.5, phaser_feedback: 0.5, + // 1.3.0 + stereo_algorithm: StereoAlgorithm::Original, + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + // 1.3.0 + use_buffermod: false, buffermod_amount: 0.5, buffermod_depth: 0.5, @@ -7135,7 +7514,7 @@ lazy_static::lazy_static!( limiter_knee: 0.5, }; - static ref DEFAULT_PRESET: ActuatePresetV126 = ActuatePresetV126 { + static ref DEFAULT_PRESET: ActuatePresetV130 = ActuatePresetV130 { preset_name: "Default".to_string(), preset_info: "Info".to_string(), preset_category: PresetType::Select, @@ -7390,6 +7769,14 @@ lazy_static::lazy_static!( sat_amount: 0.0, sat_type: SaturationType::Tape, + // 1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + // 1.3.0 + use_delay: false, delay_amount: 0.5, delay_time: DelaySnapValues::Quarter, diff --git a/src/old_preset_structs.rs b/src/old_preset_structs.rs index e703ed8..a8e5126 100644 --- a/src/old_preset_structs.rs +++ b/src/old_preset_structs.rs @@ -1,5 +1,5 @@ use crate::{ - audio_module::{ + actuate_enums::StereoAlgorithm, audio_module::{ AudioModuleType, Oscillator::{self, RetriggerStyle, SmoothStyle, VoiceType}, }, fx::{ @@ -7,7 +7,7 @@ use crate::{ saturation::SaturationType, ArduraFilter, StateVariableFilter::ResonanceType, - }, AMFilterRouting, ActuatePresetV126, FilterAlgorithms, FilterRouting, LFOController, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel + }, AMFilterRouting, ActuatePresetV130, FilterAlgorithms, FilterRouting, LFOController, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel }; use serde::{Deserialize, Serialize}; @@ -1460,305 +1460,333 @@ pub struct ActuatePresetV123 { pub limiter_knee: f32, } -// This takes the deserialized message pack and converts it into the latest struct -// This then attempts to return the newer preset format after -pub fn load_unserialized_v125(file_data: Vec) -> ActuatePresetV126 { - let old_unserialized: ActuatePresetV125 = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV125 { - preset_name: "Error Importing".to_string(), - preset_info: "Corrupted preset or incompatible version".to_string(), - preset_category: PresetType::Select, - tag_acid: false, - tag_analog: false, - tag_bright: false, - tag_chord: false, - tag_crisp: false, - tag_deep: false, - tag_delicate: false, - tag_hard: false, - tag_harsh: false, - tag_lush: false, - tag_mellow: false, - tag_resonant: false, - tag_rich: false, - tag_sharp: false, - tag_silky: false, - tag_smooth: false, - tag_soft: false, - tag_stab: false, - tag_warm: false, - mod1_audio_module_routing: AMFilterRouting::Filter1, - mod1_audio_module_type: AudioModuleType::Osc, - mod1_audio_module_level: 1.0, - mod1_loaded_sample: vec![vec![0.0, 0.0]], - mod1_sample_lib: vec![vec![vec![0.0, 0.0]]], - mod1_loop_wavetable: false, - mod1_single_cycle: false, - mod1_restretch: true, - mod1_prev_restretch: false, - mod1_grain_hold: 200, - mod1_grain_gap: 200, - mod1_start_position: 0.0, - mod1_end_position: 1.0, - mod1_grain_crossfade: 50, - mod1_osc_type: VoiceType::Sine, - mod1_osc_octave: 0, - mod1_osc_semitones: 0, - mod1_osc_detune: 0.0, - mod1_osc_attack: 0.0001, - mod1_osc_decay: 0.0001, - mod1_osc_sustain: 999.9, - mod1_osc_release: 5.0, - mod1_osc_retrigger: RetriggerStyle::Retrigger, - mod1_osc_atk_curve: SmoothStyle::Linear, - mod1_osc_dec_curve: SmoothStyle::Linear, - mod1_osc_rel_curve: SmoothStyle::Linear, - mod1_osc_unison: 1, - mod1_osc_unison_detune: 0.0, - mod1_osc_stereo: 0.0, - - mod2_audio_module_routing: AMFilterRouting::Filter1, - mod2_audio_module_type: AudioModuleType::Off, - mod2_audio_module_level: 1.0, - mod2_loaded_sample: vec![vec![0.0, 0.0]], - mod2_sample_lib: vec![vec![vec![0.0, 0.0]]], - mod2_loop_wavetable: false, - mod2_single_cycle: false, - mod2_restretch: true, - mod2_prev_restretch: false, - mod2_grain_hold: 200, - mod2_grain_gap: 200, - mod2_start_position: 0.0, - mod2_end_position: 1.0, - mod2_grain_crossfade: 50, - mod2_osc_type: VoiceType::Sine, - mod2_osc_octave: 0, - mod2_osc_semitones: 0, - mod2_osc_detune: 0.0, - mod2_osc_attack: 0.0001, - mod2_osc_decay: 0.0001, - mod2_osc_sustain: 999.9, - mod2_osc_release: 5.0, - mod2_osc_retrigger: RetriggerStyle::Retrigger, - mod2_osc_atk_curve: SmoothStyle::Linear, - mod2_osc_dec_curve: SmoothStyle::Linear, - mod2_osc_rel_curve: SmoothStyle::Linear, - mod2_osc_unison: 1, - mod2_osc_unison_detune: 0.0, - mod2_osc_stereo: 0.0, +/// This is the structure that represents a storable preset value +#[derive(Serialize, Deserialize, Clone)] +pub struct ActuatePresetV126 { + // Information + pub preset_name: String, + pub preset_info: String, + pub preset_category: PresetType, + // Preset tag information - made into bools to make my life easier + pub tag_acid: bool, + pub tag_analog: bool, + pub tag_bright: bool, + pub tag_chord: bool, + pub tag_crisp: bool, + pub tag_deep: bool, + pub tag_delicate: bool, + pub tag_hard: bool, + pub tag_harsh: bool, + pub tag_lush: bool, + pub tag_mellow: bool, + pub tag_resonant: bool, + pub tag_rich: bool, + pub tag_sharp: bool, + pub tag_silky: bool, + pub tag_smooth: bool, + pub tag_soft: bool, + pub tag_stab: bool, + pub tag_warm: bool, - mod3_audio_module_routing: AMFilterRouting::Filter1, - mod3_audio_module_type: AudioModuleType::Off, - mod3_audio_module_level: 1.0, - mod3_loaded_sample: vec![vec![0.0, 0.0]], - mod3_sample_lib: vec![vec![vec![0.0, 0.0]]], - mod3_loop_wavetable: false, - mod3_single_cycle: false, - mod3_restretch: true, - mod3_prev_restretch: false, - mod3_grain_hold: 200, - mod3_grain_gap: 200, - mod3_start_position: 0.0, - mod3_end_position: 1.0, - mod3_grain_crossfade: 50, - mod3_osc_type: VoiceType::Sine, - mod3_osc_octave: 0, - mod3_osc_semitones: 0, - mod3_osc_detune: 0.0, - mod3_osc_attack: 0.0001, - mod3_osc_decay: 0.0001, - mod3_osc_sustain: 999.9, - mod3_osc_release: 5.0, - mod3_osc_retrigger: RetriggerStyle::Retrigger, - mod3_osc_atk_curve: SmoothStyle::Linear, - mod3_osc_dec_curve: SmoothStyle::Linear, - mod3_osc_rel_curve: SmoothStyle::Linear, - mod3_osc_unison: 1, - mod3_osc_unison_detune: 0.0, - mod3_osc_stereo: 0.0, + // Modules 1 + /////////////////////////////////////////////////////////// + pub mod1_audio_module_type: AudioModuleType, + pub mod1_audio_module_level: f32, + pub mod1_audio_module_routing: AMFilterRouting, + // Granulizer/Sampler + pub mod1_loaded_sample: Vec>, + pub mod1_sample_lib: Vec>>, + pub mod1_loop_wavetable: bool, + pub mod1_single_cycle: bool, + pub mod1_restretch: bool, + pub mod1_prev_restretch: bool, + pub mod1_grain_hold: i32, + pub mod1_grain_gap: i32, + pub mod1_start_position: f32, + pub mod1_end_position: f32, + pub mod1_grain_crossfade: i32, - // Pitch Env - pitch_enable: false, - pitch_routing: PitchRouting::Osc1, - pitch_env_peak: 0.0, - pitch_env_attack: 0.0, - pitch_env_decay: 300.0, - pitch_env_sustain: 0.0, - pitch_env_release: 0.0, - pitch_env_atk_curve: Oscillator::SmoothStyle::Linear, - pitch_env_dec_curve: Oscillator::SmoothStyle::Linear, - pitch_env_rel_curve: Oscillator::SmoothStyle::Linear, + // Osc module knob storage + pub mod1_osc_type: VoiceType, + pub mod1_osc_octave: i32, + pub mod1_osc_semitones: i32, + pub mod1_osc_detune: f32, + pub mod1_osc_attack: f32, + pub mod1_osc_decay: f32, + pub mod1_osc_sustain: f32, + pub mod1_osc_release: f32, + pub mod1_osc_retrigger: RetriggerStyle, + pub mod1_osc_atk_curve: SmoothStyle, + pub mod1_osc_dec_curve: SmoothStyle, + pub mod1_osc_rel_curve: SmoothStyle, + pub mod1_osc_unison: i32, + pub mod1_osc_unison_detune: f32, + pub mod1_osc_stereo: f32, - pitch_enable_2: false, - pitch_routing_2: PitchRouting::Osc1, - pitch_env_peak_2: 0.0, - pitch_env_attack_2: 0.0, - pitch_env_decay_2: 300.0, - pitch_env_sustain_2: 0.0, - pitch_env_release_2: 0.0, - pitch_env_atk_curve_2: Oscillator::SmoothStyle::Linear, - pitch_env_dec_curve_2: Oscillator::SmoothStyle::Linear, - pitch_env_rel_curve_2: Oscillator::SmoothStyle::Linear, + // Modules 2 + /////////////////////////////////////////////////////////// + pub mod2_audio_module_type: AudioModuleType, + pub mod2_audio_module_level: f32, + pub mod2_audio_module_routing: AMFilterRouting, + // Granulizer/Sampler + pub mod2_loaded_sample: Vec>, + pub mod2_sample_lib: Vec>>, + pub mod2_loop_wavetable: bool, + pub mod2_single_cycle: bool, + pub mod2_restretch: bool, + pub mod2_prev_restretch: bool, + pub mod2_grain_hold: i32, + pub mod2_grain_gap: i32, + pub mod2_start_position: f32, + pub mod2_end_position: f32, + pub mod2_grain_crossfade: i32, - filter_wet: 1.0, - filter_cutoff: 20000.0, - filter_resonance: 1.0, - filter_res_type: ResonanceType::Default, - filter_lp_amount: 1.0, - filter_hp_amount: 0.0, - filter_bp_amount: 0.0, - filter_env_peak: 0.0, - filter_env_attack: 0.0, - filter_env_decay: 0.0001, - filter_env_sustain: 999.9, - filter_env_release: 5.0, - filter_env_atk_curve: SmoothStyle::Linear, - filter_env_dec_curve: SmoothStyle::Linear, - filter_env_rel_curve: SmoothStyle::Linear, - filter_alg_type: FilterAlgorithms::SVF, - tilt_filter_type: ArduraFilter::ResponseType::Lowpass, + // Osc module knob storage + pub mod2_osc_type: VoiceType, + pub mod2_osc_octave: i32, + pub mod2_osc_semitones: i32, + pub mod2_osc_detune: f32, + pub mod2_osc_attack: f32, + pub mod2_osc_decay: f32, + pub mod2_osc_sustain: f32, + pub mod2_osc_release: f32, + pub mod2_osc_retrigger: RetriggerStyle, + pub mod2_osc_atk_curve: SmoothStyle, + pub mod2_osc_dec_curve: SmoothStyle, + pub mod2_osc_rel_curve: SmoothStyle, + pub mod2_osc_unison: i32, + pub mod2_osc_unison_detune: f32, + pub mod2_osc_stereo: f32, - filter_wet_2: 1.0, - filter_cutoff_2: 20000.0, - filter_resonance_2: 1.0, - filter_res_type_2: ResonanceType::Default, - filter_lp_amount_2: 1.0, - filter_hp_amount_2: 0.0, - filter_bp_amount_2: 0.0, - filter_env_peak_2: 0.0, - filter_env_attack_2: 0.0, - filter_env_decay_2: 0.0001, - filter_env_sustain_2: 999.9, - filter_env_release_2: 5.0, - filter_env_atk_curve_2: SmoothStyle::Linear, - filter_env_dec_curve_2: SmoothStyle::Linear, - filter_env_rel_curve_2: SmoothStyle::Linear, - filter_alg_type_2: FilterAlgorithms::SVF, - tilt_filter_type_2: ArduraFilter::ResponseType::Lowpass, + // Modules 3 + /////////////////////////////////////////////////////////// + pub mod3_audio_module_type: AudioModuleType, + pub mod3_audio_module_level: f32, + pub mod3_audio_module_routing: AMFilterRouting, + // Granulizer/Sampler + pub mod3_loaded_sample: Vec>, + pub mod3_sample_lib: Vec>>, + pub mod3_loop_wavetable: bool, + pub mod3_single_cycle: bool, + pub mod3_restretch: bool, + pub mod3_prev_restretch: bool, + pub mod3_grain_hold: i32, + pub mod3_grain_gap: i32, + pub mod3_start_position: f32, + pub mod3_end_position: f32, + pub mod3_grain_crossfade: i32, - filter_routing: FilterRouting::Parallel, - filter_cutoff_link: false, + // Osc module knob storage + pub mod3_osc_type: VoiceType, + pub mod3_osc_octave: i32, + pub mod3_osc_semitones: i32, + pub mod3_osc_detune: f32, + pub mod3_osc_attack: f32, + pub mod3_osc_decay: f32, + pub mod3_osc_sustain: f32, + pub mod3_osc_release: f32, + pub mod3_osc_retrigger: RetriggerStyle, + pub mod3_osc_atk_curve: SmoothStyle, + pub mod3_osc_dec_curve: SmoothStyle, + pub mod3_osc_rel_curve: SmoothStyle, + pub mod3_osc_unison: i32, + pub mod3_osc_unison_detune: f32, + pub mod3_osc_stereo: f32, - // LFOs - lfo1_enable: false, - lfo2_enable: false, - lfo3_enable: false, + // Filters + pub filter_wet: f32, + pub filter_cutoff: f32, + pub filter_resonance: f32, + pub filter_res_type: ResonanceType, + pub filter_lp_amount: f32, + pub filter_hp_amount: f32, + pub filter_bp_amount: f32, + pub filter_env_peak: f32, + pub filter_env_attack: f32, + pub filter_env_decay: f32, + pub filter_env_sustain: f32, + pub filter_env_release: f32, + pub filter_env_atk_curve: Oscillator::SmoothStyle, + pub filter_env_dec_curve: Oscillator::SmoothStyle, + pub filter_env_rel_curve: Oscillator::SmoothStyle, + pub filter_alg_type: FilterAlgorithms, + pub tilt_filter_type: ArduraFilter::ResponseType, - lfo1_freq: 2.0, - lfo1_retrigger: LFOController::LFORetrigger::None, - lfo1_sync: true, - lfo1_snap: LFOController::LFOSnapValues::Half, - lfo1_waveform: LFOController::Waveform::Sine, - lfo1_phase: 0.0, + pub filter_wet_2: f32, + pub filter_cutoff_2: f32, + pub filter_resonance_2: f32, + pub filter_res_type_2: ResonanceType, + pub filter_lp_amount_2: f32, + pub filter_hp_amount_2: f32, + pub filter_bp_amount_2: f32, + pub filter_env_peak_2: f32, + pub filter_env_attack_2: f32, + pub filter_env_decay_2: f32, + pub filter_env_sustain_2: f32, + pub filter_env_release_2: f32, + pub filter_env_atk_curve_2: Oscillator::SmoothStyle, + pub filter_env_dec_curve_2: Oscillator::SmoothStyle, + pub filter_env_rel_curve_2: Oscillator::SmoothStyle, + pub filter_alg_type_2: FilterAlgorithms, + pub tilt_filter_type_2: ArduraFilter::ResponseType, - lfo2_freq: 2.0, - lfo2_retrigger: LFOController::LFORetrigger::None, - lfo2_sync: true, - lfo2_snap: LFOController::LFOSnapValues::Half, - lfo2_waveform: LFOController::Waveform::Sine, - lfo2_phase: 0.0, + pub filter_routing: FilterRouting, + pub filter_cutoff_link: bool, - lfo3_freq: 2.0, - lfo3_retrigger: LFOController::LFORetrigger::None, - lfo3_sync: true, - lfo3_snap: LFOController::LFOSnapValues::Half, - lfo3_waveform: LFOController::Waveform::Sine, - lfo3_phase: 0.0, + // Pitch Env + pub pitch_enable: bool, + pub pitch_routing: PitchRouting, + pub pitch_env_peak: f32, + pub pitch_env_attack: f32, + pub pitch_env_decay: f32, + pub pitch_env_sustain: f32, + pub pitch_env_release: f32, + pub pitch_env_atk_curve: Oscillator::SmoothStyle, + pub pitch_env_dec_curve: Oscillator::SmoothStyle, + pub pitch_env_rel_curve: Oscillator::SmoothStyle, - // Modulations - mod_source_1: ModulationSource::None, - mod_source_2: ModulationSource::None, - mod_source_3: ModulationSource::None, - mod_source_4: ModulationSource::None, - mod_dest_1: ModulationDestination::None, - mod_dest_2: ModulationDestination::None, - mod_dest_3: ModulationDestination::None, - mod_dest_4: ModulationDestination::None, - mod_amount_1: 0.0, - mod_amount_2: 0.0, - mod_amount_3: 0.0, - mod_amount_4: 0.0, + pub pitch_enable_2: bool, + pub pitch_routing_2: PitchRouting, + pub pitch_env_peak_2: f32, + pub pitch_env_attack_2: f32, + pub pitch_env_decay_2: f32, + pub pitch_env_sustain_2: f32, + pub pitch_env_release_2: f32, + pub pitch_env_atk_curve_2: Oscillator::SmoothStyle, + pub pitch_env_dec_curve_2: Oscillator::SmoothStyle, + pub pitch_env_rel_curve_2: Oscillator::SmoothStyle, - // EQ - pre_use_eq: false, - pre_low_freq: 800.0, - pre_mid_freq: 3000.0, - pre_high_freq: 10000.0, - pre_low_gain: 0.0, - pre_mid_gain: 0.0, - pre_high_gain: 0.0, + // LFOs + pub lfo1_enable: bool, + pub lfo2_enable: bool, + pub lfo3_enable: bool, - // FX - use_fx: true, + pub lfo1_freq: f32, + pub lfo1_retrigger: LFOController::LFORetrigger, + pub lfo1_sync: bool, + pub lfo1_snap: LFOController::LFOSnapValues, + pub lfo1_waveform: LFOController::Waveform, + pub lfo1_phase: f32, - use_compressor: false, - comp_amt: 0.5, - comp_atk: 0.5, - comp_rel: 0.5, - comp_drive: 0.5, + pub lfo2_freq: f32, + pub lfo2_retrigger: LFOController::LFORetrigger, + pub lfo2_sync: bool, + pub lfo2_snap: LFOController::LFOSnapValues, + pub lfo2_waveform: LFOController::Waveform, + pub lfo2_phase: f32, - use_abass: false, - abass_amount: 0.0011, + pub lfo3_freq: f32, + pub lfo3_retrigger: LFOController::LFORetrigger, + pub lfo3_sync: bool, + pub lfo3_snap: LFOController::LFOSnapValues, + pub lfo3_waveform: LFOController::Waveform, + pub lfo3_phase: f32, - use_saturation: false, - sat_amount: 0.0, - sat_type: SaturationType::Tape, + // Modulation + pub mod_source_1: ModulationSource, + pub mod_source_2: ModulationSource, + pub mod_source_3: ModulationSource, + pub mod_source_4: ModulationSource, + pub mod_dest_1: ModulationDestination, + pub mod_dest_2: ModulationDestination, + pub mod_dest_3: ModulationDestination, + pub mod_dest_4: ModulationDestination, + pub mod_amount_1: f32, + pub mod_amount_2: f32, + pub mod_amount_3: f32, + pub mod_amount_4: f32, - use_delay: false, - delay_amount: 0.0, - delay_time: DelaySnapValues::Quarter, - delay_decay: 0.0, - delay_type: DelayType::Stereo, + // FM + pub fm_one_to_two: f32, + pub fm_one_to_three: f32, + pub fm_two_to_three: f32, + pub fm_cycles: i32, + pub fm_attack: f32, + pub fm_decay: f32, + pub fm_sustain: f32, + pub fm_release: f32, + pub fm_attack_curve: Oscillator::SmoothStyle, + pub fm_decay_curve: Oscillator::SmoothStyle, + pub fm_release_curve: Oscillator::SmoothStyle, - use_reverb: false, - reverb_model: ReverbModel::Default, - reverb_amount: 0.5, - reverb_size: 0.5, - reverb_feedback: 0.5, + // EQ + pub pre_use_eq: bool, + pub pre_low_freq: f32, + pub pre_mid_freq: f32, + pub pre_high_freq: f32, + pub pre_low_gain: f32, + pub pre_mid_gain: f32, + pub pre_high_gain: f32, - use_phaser: false, - phaser_amount: 0.5, - phaser_depth: 0.5, - phaser_rate: 0.5, - phaser_feedback: 0.5, + // FX + pub use_fx: bool, - use_buffermod: false, - buffermod_amount: 0.5, - buffermod_depth: 0.5, - buffermod_rate: 0.5, - buffermod_spread: 0.0, - buffermod_timing: 620.0, + pub use_compressor: bool, + pub comp_amt: f32, + pub comp_atk: f32, + pub comp_rel: f32, + pub comp_drive: f32, - use_flanger: false, - flanger_amount: 0.5, - flanger_depth: 0.5, - flanger_rate: 0.5, - flanger_feedback: 0.5, + pub use_abass: bool, + pub abass_amount: f32, - use_limiter: false, - limiter_threshold: 0.5, - limiter_knee: 0.5, - }); - convert_preset_v125(old_unserialized) -} + pub use_saturation: bool, + pub sat_amount: f32, + pub sat_type: SaturationType, -// This takes the deserialized message pack and converts it into the latest struct -// This then attempts to return the newer preset format after -pub fn load_unserialized_v123(file_data: Vec) -> ActuatePresetV126 { - let old_unserialized: ActuatePresetV123 = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV123 { - preset_name: "Error Importing".to_string(), - preset_info: "Corrupted preset or incompatible version".to_string(), - preset_category: PresetType::Select, - tag_acid: false, - tag_analog: false, - tag_bright: false, - tag_chord: false, - tag_crisp: false, - tag_deep: false, - tag_delicate: false, - tag_hard: false, - tag_harsh: false, + pub use_delay: bool, + pub delay_amount: f32, + pub delay_time: DelaySnapValues, + pub delay_decay: f32, + pub delay_type: DelayType, + + pub use_reverb: bool, + pub reverb_model: ReverbModel, + pub reverb_amount: f32, + pub reverb_size: f32, + pub reverb_feedback: f32, + + pub use_phaser: bool, + pub phaser_amount: f32, + pub phaser_depth: f32, + pub phaser_rate: f32, + pub phaser_feedback: f32, + + pub use_buffermod: bool, + pub buffermod_amount: f32, + pub buffermod_depth: f32, + pub buffermod_rate: f32, + pub buffermod_spread: f32, + pub buffermod_timing: f32, + + pub use_flanger: bool, + pub flanger_amount: f32, + pub flanger_depth: f32, + pub flanger_rate: f32, + pub flanger_feedback: f32, + + pub use_limiter: bool, + pub limiter_threshold: f32, + pub limiter_knee: f32, +} + +// This takes the deserialized message pack and converts it into the latest struct +// This then attempts to return the newer preset format after +pub fn load_unserialized_v126(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetV126 = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV126 { + preset_name: "Error Importing".to_string(), + preset_info: "Corrupted preset or incompatible version".to_string(), + preset_category: PresetType::Select, + tag_acid: false, + tag_analog: false, + tag_bright: false, + tag_chord: false, + tag_crisp: false, + tag_deep: false, + tag_delicate: false, + tag_hard: false, + tag_harsh: false, tag_lush: false, tag_mellow: false, tag_resonant: false, @@ -1970,6 +1998,19 @@ pub fn load_unserialized_v123(file_data: Vec) -> ActuatePresetV126 { pre_mid_gain: 0.0, pre_high_gain: 0.0, + // FM + fm_one_to_two: 0.0, + fm_one_to_three: 0.0, + fm_two_to_three: 0.0, + fm_cycles: 1, + fm_attack: 0.0001, + fm_decay: 0.0001, + fm_sustain: 0.999, + fm_release: 0.0001, + fm_attack_curve: SmoothStyle::Linear, + fm_decay_curve: SmoothStyle::Linear, + fm_release_curve: SmoothStyle::Linear, + // FX use_fx: true, @@ -1993,7 +2034,7 @@ pub fn load_unserialized_v123(file_data: Vec) -> ActuatePresetV126 { delay_type: DelayType::Stereo, use_reverb: false, - //reverb_model: ReverbModel::Default, + reverb_model: ReverbModel::Default, reverb_amount: 0.5, reverb_size: 0.5, reverb_feedback: 0.5, @@ -2021,14 +2062,14 @@ pub fn load_unserialized_v123(file_data: Vec) -> ActuatePresetV126 { limiter_threshold: 0.5, limiter_knee: 0.5, }); - convert_preset_v123(old_unserialized) + convert_preset_v126(old_unserialized) } -// This takes the deserialized message pack and converts it into latest +// This takes the deserialized message pack and converts it into the latest struct // This then attempts to return the newer preset format after -pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { - let old_unserialized: ActuatePresetV114 = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV114 { +pub fn load_unserialized_v125(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetV125 = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV125 { preset_name: "Error Importing".to_string(), preset_info: "Corrupted preset or incompatible version".to_string(), preset_category: PresetType::Select, @@ -2051,6 +2092,7 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { tag_soft: false, tag_stab: false, tag_warm: false, + mod1_audio_module_routing: AMFilterRouting::Filter1, mod1_audio_module_type: AudioModuleType::Osc, mod1_audio_module_level: 1.0, mod1_loaded_sample: vec![vec![0.0, 0.0]], @@ -2080,6 +2122,7 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { mod1_osc_unison_detune: 0.0, mod1_osc_stereo: 0.0, + mod2_audio_module_routing: AMFilterRouting::Filter1, mod2_audio_module_type: AudioModuleType::Off, mod2_audio_module_level: 1.0, mod2_loaded_sample: vec![vec![0.0, 0.0]], @@ -2109,6 +2152,7 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { mod2_osc_unison_detune: 0.0, mod2_osc_stereo: 0.0, + mod3_audio_module_routing: AMFilterRouting::Filter1, mod3_audio_module_type: AudioModuleType::Off, mod3_audio_module_level: 1.0, mod3_loaded_sample: vec![vec![0.0, 0.0]], @@ -2138,6 +2182,29 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { mod3_osc_unison_detune: 0.0, mod3_osc_stereo: 0.0, + // Pitch Env + pitch_enable: false, + pitch_routing: PitchRouting::Osc1, + pitch_env_peak: 0.0, + pitch_env_attack: 0.0, + pitch_env_decay: 300.0, + pitch_env_sustain: 0.0, + pitch_env_release: 0.0, + pitch_env_atk_curve: Oscillator::SmoothStyle::Linear, + pitch_env_dec_curve: Oscillator::SmoothStyle::Linear, + pitch_env_rel_curve: Oscillator::SmoothStyle::Linear, + + pitch_enable_2: false, + pitch_routing_2: PitchRouting::Osc1, + pitch_env_peak_2: 0.0, + pitch_env_attack_2: 0.0, + pitch_env_decay_2: 300.0, + pitch_env_sustain_2: 0.0, + pitch_env_release_2: 0.0, + pitch_env_atk_curve_2: Oscillator::SmoothStyle::Linear, + pitch_env_dec_curve_2: Oscillator::SmoothStyle::Linear, + pitch_env_rel_curve_2: Oscillator::SmoothStyle::Linear, + filter_wet: 1.0, filter_cutoff: 20000.0, filter_resonance: 1.0, @@ -2249,6 +2316,7 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { delay_type: DelayType::Stereo, use_reverb: false, + reverb_model: ReverbModel::Default, reverb_amount: 0.5, reverb_size: 0.5, reverb_feedback: 0.5, @@ -2276,14 +2344,14 @@ pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV126 { limiter_threshold: 0.5, limiter_knee: 0.5, }); - convert_preset_v114(old_unserialized) + convert_preset_v125(old_unserialized) } -// This takes the deserialized message pack and converts it into latest +// This takes the deserialized message pack and converts it into the latest struct // This then attempts to return the newer preset format after -pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { - let old_unserialized: ActuatePresetV122 = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV122 { +pub fn load_unserialized_v123(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetV123 = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV123 { preset_name: "Error Importing".to_string(), preset_info: "Corrupted preset or incompatible version".to_string(), preset_category: PresetType::Select, @@ -2306,6 +2374,7 @@ pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { tag_soft: false, tag_stab: false, tag_warm: false, + mod1_audio_module_routing: AMFilterRouting::Filter1, mod1_audio_module_type: AudioModuleType::Osc, mod1_audio_module_level: 1.0, mod1_loaded_sample: vec![vec![0.0, 0.0]], @@ -2335,6 +2404,7 @@ pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { mod1_osc_unison_detune: 0.0, mod1_osc_stereo: 0.0, + mod2_audio_module_routing: AMFilterRouting::Filter1, mod2_audio_module_type: AudioModuleType::Off, mod2_audio_module_level: 1.0, mod2_loaded_sample: vec![vec![0.0, 0.0]], @@ -2364,6 +2434,7 @@ pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { mod2_osc_unison_detune: 0.0, mod2_osc_stereo: 0.0, + mod3_audio_module_routing: AMFilterRouting::Filter1, mod3_audio_module_type: AudioModuleType::Off, mod3_audio_module_level: 1.0, mod3_loaded_sample: vec![vec![0.0, 0.0]], @@ -2527,6 +2598,7 @@ pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { delay_type: DelayType::Stereo, use_reverb: false, + //reverb_model: ReverbModel::Default, reverb_amount: 0.5, reverb_size: 0.5, reverb_feedback: 0.5, @@ -2554,14 +2626,14 @@ pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV126 { limiter_threshold: 0.5, limiter_knee: 0.5, }); - convert_preset_v122(old_unserialized) + convert_preset_v123(old_unserialized) } // This takes the deserialized message pack and converts it into latest // This then attempts to return the newer preset format after -pub fn load_unserialized_old(file_data: Vec) -> ActuatePresetV126 { - let old_unserialized: ActuatePresetOld = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetOld { +pub fn load_unserialized_v114(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetV114 = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV114 { preset_name: "Error Importing".to_string(), preset_info: "Corrupted preset or incompatible version".to_string(), preset_category: PresetType::Select, @@ -2708,9 +2780,7 @@ pub fn load_unserialized_old(file_data: Vec) -> ActuatePresetV126 { tilt_filter_type_2: ArduraFilter::ResponseType::Lowpass, filter_routing: FilterRouting::Parallel, - ///////////////////////////////////////////////////////////////////////// - //filter_cutoff_link: false, - ///////////////////////////////////////////////////////////////////////// + filter_cutoff_link: false, // LFOs lfo1_enable: false, @@ -2811,12 +2881,827 @@ pub fn load_unserialized_old(file_data: Vec) -> ActuatePresetV126 { limiter_threshold: 0.5, limiter_knee: 0.5, }); - convert_preset(old_unserialized) + convert_preset_v114(old_unserialized) +} + +// This takes the deserialized message pack and converts it into latest +// This then attempts to return the newer preset format after +pub fn load_unserialized_v122(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetV122 = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV122 { + preset_name: "Error Importing".to_string(), + preset_info: "Corrupted preset or incompatible version".to_string(), + preset_category: PresetType::Select, + tag_acid: false, + tag_analog: false, + tag_bright: false, + tag_chord: false, + tag_crisp: false, + tag_deep: false, + tag_delicate: false, + tag_hard: false, + tag_harsh: false, + tag_lush: false, + tag_mellow: false, + tag_resonant: false, + tag_rich: false, + tag_sharp: false, + tag_silky: false, + tag_smooth: false, + tag_soft: false, + tag_stab: false, + tag_warm: false, + mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_level: 1.0, + mod1_loaded_sample: vec![vec![0.0, 0.0]], + mod1_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod1_loop_wavetable: false, + mod1_single_cycle: false, + mod1_restretch: true, + mod1_prev_restretch: false, + mod1_grain_hold: 200, + mod1_grain_gap: 200, + mod1_start_position: 0.0, + mod1_end_position: 1.0, + mod1_grain_crossfade: 50, + mod1_osc_type: VoiceType::Sine, + mod1_osc_octave: 0, + mod1_osc_semitones: 0, + mod1_osc_detune: 0.0, + mod1_osc_attack: 0.0001, + mod1_osc_decay: 0.0001, + mod1_osc_sustain: 999.9, + mod1_osc_release: 5.0, + mod1_osc_retrigger: RetriggerStyle::Retrigger, + mod1_osc_atk_curve: SmoothStyle::Linear, + mod1_osc_dec_curve: SmoothStyle::Linear, + mod1_osc_rel_curve: SmoothStyle::Linear, + mod1_osc_unison: 1, + mod1_osc_unison_detune: 0.0, + mod1_osc_stereo: 0.0, + + mod2_audio_module_type: AudioModuleType::Off, + mod2_audio_module_level: 1.0, + mod2_loaded_sample: vec![vec![0.0, 0.0]], + mod2_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod2_loop_wavetable: false, + mod2_single_cycle: false, + mod2_restretch: true, + mod2_prev_restretch: false, + mod2_grain_hold: 200, + mod2_grain_gap: 200, + mod2_start_position: 0.0, + mod2_end_position: 1.0, + mod2_grain_crossfade: 50, + mod2_osc_type: VoiceType::Sine, + mod2_osc_octave: 0, + mod2_osc_semitones: 0, + mod2_osc_detune: 0.0, + mod2_osc_attack: 0.0001, + mod2_osc_decay: 0.0001, + mod2_osc_sustain: 999.9, + mod2_osc_release: 5.0, + mod2_osc_retrigger: RetriggerStyle::Retrigger, + mod2_osc_atk_curve: SmoothStyle::Linear, + mod2_osc_dec_curve: SmoothStyle::Linear, + mod2_osc_rel_curve: SmoothStyle::Linear, + mod2_osc_unison: 1, + mod2_osc_unison_detune: 0.0, + mod2_osc_stereo: 0.0, + + mod3_audio_module_type: AudioModuleType::Off, + mod3_audio_module_level: 1.0, + mod3_loaded_sample: vec![vec![0.0, 0.0]], + mod3_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod3_loop_wavetable: false, + mod3_single_cycle: false, + mod3_restretch: true, + mod3_prev_restretch: false, + mod3_grain_hold: 200, + mod3_grain_gap: 200, + mod3_start_position: 0.0, + mod3_end_position: 1.0, + mod3_grain_crossfade: 50, + mod3_osc_type: VoiceType::Sine, + mod3_osc_octave: 0, + mod3_osc_semitones: 0, + mod3_osc_detune: 0.0, + mod3_osc_attack: 0.0001, + mod3_osc_decay: 0.0001, + mod3_osc_sustain: 999.9, + mod3_osc_release: 5.0, + mod3_osc_retrigger: RetriggerStyle::Retrigger, + mod3_osc_atk_curve: SmoothStyle::Linear, + mod3_osc_dec_curve: SmoothStyle::Linear, + mod3_osc_rel_curve: SmoothStyle::Linear, + mod3_osc_unison: 1, + mod3_osc_unison_detune: 0.0, + mod3_osc_stereo: 0.0, + + // Pitch Env + pitch_enable: false, + pitch_routing: PitchRouting::Osc1, + pitch_env_peak: 0.0, + pitch_env_attack: 0.0, + pitch_env_decay: 300.0, + pitch_env_sustain: 0.0, + pitch_env_release: 0.0, + pitch_env_atk_curve: Oscillator::SmoothStyle::Linear, + pitch_env_dec_curve: Oscillator::SmoothStyle::Linear, + pitch_env_rel_curve: Oscillator::SmoothStyle::Linear, + + pitch_enable_2: false, + pitch_routing_2: PitchRouting::Osc1, + pitch_env_peak_2: 0.0, + pitch_env_attack_2: 0.0, + pitch_env_decay_2: 300.0, + pitch_env_sustain_2: 0.0, + pitch_env_release_2: 0.0, + pitch_env_atk_curve_2: Oscillator::SmoothStyle::Linear, + pitch_env_dec_curve_2: Oscillator::SmoothStyle::Linear, + pitch_env_rel_curve_2: Oscillator::SmoothStyle::Linear, + + filter_wet: 1.0, + filter_cutoff: 20000.0, + filter_resonance: 1.0, + filter_res_type: ResonanceType::Default, + filter_lp_amount: 1.0, + filter_hp_amount: 0.0, + filter_bp_amount: 0.0, + filter_env_peak: 0.0, + filter_env_attack: 0.0, + filter_env_decay: 0.0001, + filter_env_sustain: 999.9, + filter_env_release: 5.0, + filter_env_atk_curve: SmoothStyle::Linear, + filter_env_dec_curve: SmoothStyle::Linear, + filter_env_rel_curve: SmoothStyle::Linear, + filter_alg_type: FilterAlgorithms::SVF, + tilt_filter_type: ArduraFilter::ResponseType::Lowpass, + + filter_wet_2: 1.0, + filter_cutoff_2: 20000.0, + filter_resonance_2: 1.0, + filter_res_type_2: ResonanceType::Default, + filter_lp_amount_2: 1.0, + filter_hp_amount_2: 0.0, + filter_bp_amount_2: 0.0, + filter_env_peak_2: 0.0, + filter_env_attack_2: 0.0, + filter_env_decay_2: 0.0001, + filter_env_sustain_2: 999.9, + filter_env_release_2: 5.0, + filter_env_atk_curve_2: SmoothStyle::Linear, + filter_env_dec_curve_2: SmoothStyle::Linear, + filter_env_rel_curve_2: SmoothStyle::Linear, + filter_alg_type_2: FilterAlgorithms::SVF, + tilt_filter_type_2: ArduraFilter::ResponseType::Lowpass, + + filter_routing: FilterRouting::Parallel, + filter_cutoff_link: false, + + // LFOs + lfo1_enable: false, + lfo2_enable: false, + lfo3_enable: false, + + lfo1_freq: 2.0, + lfo1_retrigger: LFOController::LFORetrigger::None, + lfo1_sync: true, + lfo1_snap: LFOController::LFOSnapValues::Half, + lfo1_waveform: LFOController::Waveform::Sine, + lfo1_phase: 0.0, + + lfo2_freq: 2.0, + lfo2_retrigger: LFOController::LFORetrigger::None, + lfo2_sync: true, + lfo2_snap: LFOController::LFOSnapValues::Half, + lfo2_waveform: LFOController::Waveform::Sine, + lfo2_phase: 0.0, + + lfo3_freq: 2.0, + lfo3_retrigger: LFOController::LFORetrigger::None, + lfo3_sync: true, + lfo3_snap: LFOController::LFOSnapValues::Half, + lfo3_waveform: LFOController::Waveform::Sine, + lfo3_phase: 0.0, + + // Modulations + mod_source_1: ModulationSource::None, + mod_source_2: ModulationSource::None, + mod_source_3: ModulationSource::None, + mod_source_4: ModulationSource::None, + mod_dest_1: ModulationDestination::None, + mod_dest_2: ModulationDestination::None, + mod_dest_3: ModulationDestination::None, + mod_dest_4: ModulationDestination::None, + mod_amount_1: 0.0, + mod_amount_2: 0.0, + mod_amount_3: 0.0, + mod_amount_4: 0.0, + + // EQ + pre_use_eq: false, + pre_low_freq: 800.0, + pre_mid_freq: 3000.0, + pre_high_freq: 10000.0, + pre_low_gain: 0.0, + pre_mid_gain: 0.0, + pre_high_gain: 0.0, + + // FX + use_fx: true, + + use_compressor: false, + comp_amt: 0.5, + comp_atk: 0.5, + comp_rel: 0.5, + comp_drive: 0.5, + + use_abass: false, + abass_amount: 0.0011, + + use_saturation: false, + sat_amount: 0.0, + sat_type: SaturationType::Tape, + + use_delay: false, + delay_amount: 0.0, + delay_time: DelaySnapValues::Quarter, + delay_decay: 0.0, + delay_type: DelayType::Stereo, + + use_reverb: false, + reverb_amount: 0.5, + reverb_size: 0.5, + reverb_feedback: 0.5, + + use_phaser: false, + phaser_amount: 0.5, + phaser_depth: 0.5, + phaser_rate: 0.5, + phaser_feedback: 0.5, + + use_buffermod: false, + buffermod_amount: 0.5, + buffermod_depth: 0.5, + buffermod_rate: 0.5, + buffermod_spread: 0.0, + buffermod_timing: 620.0, + + use_flanger: false, + flanger_amount: 0.5, + flanger_depth: 0.5, + flanger_rate: 0.5, + flanger_feedback: 0.5, + + use_limiter: false, + limiter_threshold: 0.5, + limiter_knee: 0.5, + }); + convert_preset_v122(old_unserialized) +} + +// This takes the deserialized message pack and converts it into latest +// This then attempts to return the newer preset format after +pub fn load_unserialized_old(file_data: Vec) -> ActuatePresetV130 { + let old_unserialized: ActuatePresetOld = + rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetOld { + preset_name: "Error Importing".to_string(), + preset_info: "Corrupted preset or incompatible version".to_string(), + preset_category: PresetType::Select, + tag_acid: false, + tag_analog: false, + tag_bright: false, + tag_chord: false, + tag_crisp: false, + tag_deep: false, + tag_delicate: false, + tag_hard: false, + tag_harsh: false, + tag_lush: false, + tag_mellow: false, + tag_resonant: false, + tag_rich: false, + tag_sharp: false, + tag_silky: false, + tag_smooth: false, + tag_soft: false, + tag_stab: false, + tag_warm: false, + mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_level: 1.0, + mod1_loaded_sample: vec![vec![0.0, 0.0]], + mod1_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod1_loop_wavetable: false, + mod1_single_cycle: false, + mod1_restretch: true, + mod1_prev_restretch: false, + mod1_grain_hold: 200, + mod1_grain_gap: 200, + mod1_start_position: 0.0, + mod1_end_position: 1.0, + mod1_grain_crossfade: 50, + mod1_osc_type: VoiceType::Sine, + mod1_osc_octave: 0, + mod1_osc_semitones: 0, + mod1_osc_detune: 0.0, + mod1_osc_attack: 0.0001, + mod1_osc_decay: 0.0001, + mod1_osc_sustain: 999.9, + mod1_osc_release: 5.0, + mod1_osc_retrigger: RetriggerStyle::Retrigger, + mod1_osc_atk_curve: SmoothStyle::Linear, + mod1_osc_dec_curve: SmoothStyle::Linear, + mod1_osc_rel_curve: SmoothStyle::Linear, + mod1_osc_unison: 1, + mod1_osc_unison_detune: 0.0, + mod1_osc_stereo: 0.0, + + mod2_audio_module_type: AudioModuleType::Off, + mod2_audio_module_level: 1.0, + mod2_loaded_sample: vec![vec![0.0, 0.0]], + mod2_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod2_loop_wavetable: false, + mod2_single_cycle: false, + mod2_restretch: true, + mod2_prev_restretch: false, + mod2_grain_hold: 200, + mod2_grain_gap: 200, + mod2_start_position: 0.0, + mod2_end_position: 1.0, + mod2_grain_crossfade: 50, + mod2_osc_type: VoiceType::Sine, + mod2_osc_octave: 0, + mod2_osc_semitones: 0, + mod2_osc_detune: 0.0, + mod2_osc_attack: 0.0001, + mod2_osc_decay: 0.0001, + mod2_osc_sustain: 999.9, + mod2_osc_release: 5.0, + mod2_osc_retrigger: RetriggerStyle::Retrigger, + mod2_osc_atk_curve: SmoothStyle::Linear, + mod2_osc_dec_curve: SmoothStyle::Linear, + mod2_osc_rel_curve: SmoothStyle::Linear, + mod2_osc_unison: 1, + mod2_osc_unison_detune: 0.0, + mod2_osc_stereo: 0.0, + + mod3_audio_module_type: AudioModuleType::Off, + mod3_audio_module_level: 1.0, + mod3_loaded_sample: vec![vec![0.0, 0.0]], + mod3_sample_lib: vec![vec![vec![0.0, 0.0]]], + mod3_loop_wavetable: false, + mod3_single_cycle: false, + mod3_restretch: true, + mod3_prev_restretch: false, + mod3_grain_hold: 200, + mod3_grain_gap: 200, + mod3_start_position: 0.0, + mod3_end_position: 1.0, + mod3_grain_crossfade: 50, + mod3_osc_type: VoiceType::Sine, + mod3_osc_octave: 0, + mod3_osc_semitones: 0, + mod3_osc_detune: 0.0, + mod3_osc_attack: 0.0001, + mod3_osc_decay: 0.0001, + mod3_osc_sustain: 999.9, + mod3_osc_release: 5.0, + mod3_osc_retrigger: RetriggerStyle::Retrigger, + mod3_osc_atk_curve: SmoothStyle::Linear, + mod3_osc_dec_curve: SmoothStyle::Linear, + mod3_osc_rel_curve: SmoothStyle::Linear, + mod3_osc_unison: 1, + mod3_osc_unison_detune: 0.0, + mod3_osc_stereo: 0.0, + + filter_wet: 1.0, + filter_cutoff: 20000.0, + filter_resonance: 1.0, + filter_res_type: ResonanceType::Default, + filter_lp_amount: 1.0, + filter_hp_amount: 0.0, + filter_bp_amount: 0.0, + filter_env_peak: 0.0, + filter_env_attack: 0.0, + filter_env_decay: 0.0001, + filter_env_sustain: 999.9, + filter_env_release: 5.0, + filter_env_atk_curve: SmoothStyle::Linear, + filter_env_dec_curve: SmoothStyle::Linear, + filter_env_rel_curve: SmoothStyle::Linear, + filter_alg_type: FilterAlgorithms::SVF, + tilt_filter_type: ArduraFilter::ResponseType::Lowpass, + + filter_wet_2: 1.0, + filter_cutoff_2: 20000.0, + filter_resonance_2: 1.0, + filter_res_type_2: ResonanceType::Default, + filter_lp_amount_2: 1.0, + filter_hp_amount_2: 0.0, + filter_bp_amount_2: 0.0, + filter_env_peak_2: 0.0, + filter_env_attack_2: 0.0, + filter_env_decay_2: 0.0001, + filter_env_sustain_2: 999.9, + filter_env_release_2: 5.0, + filter_env_atk_curve_2: SmoothStyle::Linear, + filter_env_dec_curve_2: SmoothStyle::Linear, + filter_env_rel_curve_2: SmoothStyle::Linear, + filter_alg_type_2: FilterAlgorithms::SVF, + tilt_filter_type_2: ArduraFilter::ResponseType::Lowpass, + + filter_routing: FilterRouting::Parallel, + ///////////////////////////////////////////////////////////////////////// + //filter_cutoff_link: false, + ///////////////////////////////////////////////////////////////////////// + + // LFOs + lfo1_enable: false, + lfo2_enable: false, + lfo3_enable: false, + + lfo1_freq: 2.0, + lfo1_retrigger: LFOController::LFORetrigger::None, + lfo1_sync: true, + lfo1_snap: LFOController::LFOSnapValues::Half, + lfo1_waveform: LFOController::Waveform::Sine, + lfo1_phase: 0.0, + + lfo2_freq: 2.0, + lfo2_retrigger: LFOController::LFORetrigger::None, + lfo2_sync: true, + lfo2_snap: LFOController::LFOSnapValues::Half, + lfo2_waveform: LFOController::Waveform::Sine, + lfo2_phase: 0.0, + + lfo3_freq: 2.0, + lfo3_retrigger: LFOController::LFORetrigger::None, + lfo3_sync: true, + lfo3_snap: LFOController::LFOSnapValues::Half, + lfo3_waveform: LFOController::Waveform::Sine, + lfo3_phase: 0.0, + + // Modulations + mod_source_1: ModulationSource::None, + mod_source_2: ModulationSource::None, + mod_source_3: ModulationSource::None, + mod_source_4: ModulationSource::None, + mod_dest_1: ModulationDestination::None, + mod_dest_2: ModulationDestination::None, + mod_dest_3: ModulationDestination::None, + mod_dest_4: ModulationDestination::None, + mod_amount_1: 0.0, + mod_amount_2: 0.0, + mod_amount_3: 0.0, + mod_amount_4: 0.0, + + // EQ + pre_use_eq: false, + pre_low_freq: 800.0, + pre_mid_freq: 3000.0, + pre_high_freq: 10000.0, + pre_low_gain: 0.0, + pre_mid_gain: 0.0, + pre_high_gain: 0.0, + + // FX + use_fx: true, + + use_compressor: false, + comp_amt: 0.5, + comp_atk: 0.5, + comp_rel: 0.5, + comp_drive: 0.5, + + use_abass: false, + abass_amount: 0.0011, + + use_saturation: false, + sat_amount: 0.0, + sat_type: SaturationType::Tape, + + use_delay: false, + delay_amount: 0.0, + delay_time: DelaySnapValues::Quarter, + delay_decay: 0.0, + delay_type: DelayType::Stereo, + + use_reverb: false, + reverb_amount: 0.5, + reverb_size: 0.5, + reverb_feedback: 0.5, + + use_phaser: false, + phaser_amount: 0.5, + phaser_depth: 0.5, + phaser_rate: 0.5, + phaser_feedback: 0.5, + + use_buffermod: false, + buffermod_amount: 0.5, + buffermod_depth: 0.5, + buffermod_rate: 0.5, + buffermod_spread: 0.0, + buffermod_timing: 620.0, + + use_flanger: false, + flanger_amount: 0.5, + flanger_depth: 0.5, + flanger_rate: 0.5, + flanger_feedback: 0.5, + + use_limiter: false, + limiter_threshold: 0.5, + limiter_knee: 0.5, + }); + convert_preset(old_unserialized) +} + +// This will get cloned each time we change preset styles in actuate +pub fn convert_preset_v126(preset: ActuatePresetV126) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { + preset_name: preset.preset_name, + preset_info: preset.preset_info, + preset_category: preset.preset_category, + tag_acid: preset.tag_acid, + tag_analog: preset.tag_analog, + tag_bright: preset.tag_bright, + tag_chord: preset.tag_chord, + tag_crisp: preset.tag_crisp, + tag_deep: preset.tag_deep, + tag_delicate: preset.tag_delicate, + tag_hard: preset.tag_hard, + tag_harsh: preset.tag_harsh, + tag_lush: preset.tag_lush, + tag_mellow: preset.tag_mellow, + tag_resonant: preset.tag_resonant, + tag_rich: preset.tag_rich, + tag_sharp: preset.tag_sharp, + tag_silky: preset.tag_silky, + tag_smooth: preset.tag_smooth, + tag_soft: preset.tag_soft, + tag_stab: preset.tag_stab, + tag_warm: preset.tag_warm, + mod1_audio_module_type: preset.mod1_audio_module_type, + mod1_audio_module_level: preset.mod1_audio_module_level, + // Added in 1.2.3 + mod1_audio_module_routing: preset.mod1_audio_module_routing, + mod1_loaded_sample: preset.mod1_loaded_sample, + mod1_sample_lib: preset.mod1_sample_lib, + mod1_loop_wavetable: preset.mod1_loop_wavetable, + mod1_single_cycle: preset.mod1_single_cycle, + mod1_restretch: preset.mod1_restretch, + mod1_prev_restretch: preset.mod1_prev_restretch, + mod1_grain_hold: preset.mod1_grain_hold, + mod1_grain_gap: preset.mod1_grain_gap, + mod1_start_position: preset.mod1_start_position, + mod1_end_position: preset.mod1_end_position, + mod1_grain_crossfade: preset.mod1_grain_crossfade, + mod1_osc_type: preset.mod1_osc_type, + mod1_osc_octave: preset.mod1_osc_octave, + mod1_osc_semitones: preset.mod1_osc_semitones, + mod1_osc_detune: preset.mod1_osc_detune, + mod1_osc_attack: preset.mod1_osc_attack, + mod1_osc_decay: preset.mod1_osc_decay, + mod1_osc_sustain: preset.mod1_osc_sustain, + mod1_osc_release: preset.mod1_osc_release, + mod1_osc_retrigger: preset.mod1_osc_retrigger, + mod1_osc_atk_curve: preset.mod1_osc_atk_curve, + mod1_osc_dec_curve: preset.mod1_osc_dec_curve, + mod1_osc_rel_curve: preset.mod1_osc_rel_curve, + mod1_osc_unison: preset.mod1_osc_unison, + mod1_osc_unison_detune: preset.mod1_osc_unison_detune, + mod1_osc_stereo: preset.mod1_osc_stereo, + mod2_audio_module_type: preset.mod2_audio_module_type, + mod2_audio_module_level: preset.mod2_audio_module_level, + // Added in 1.2.3 + mod2_audio_module_routing: preset.mod2_audio_module_routing, + mod2_loaded_sample: preset.mod2_loaded_sample, + mod2_sample_lib: preset.mod2_sample_lib, + mod2_loop_wavetable: preset.mod2_loop_wavetable, + mod2_single_cycle: preset.mod2_single_cycle, + mod2_restretch: preset.mod2_restretch, + mod2_prev_restretch: preset.mod2_prev_restretch, + mod2_grain_hold: preset.mod2_grain_hold, + mod2_grain_gap: preset.mod2_grain_gap, + mod2_start_position: preset.mod2_start_position, + mod2_end_position: preset.mod2_end_position, + mod2_grain_crossfade: preset.mod2_grain_crossfade, + mod2_osc_type: preset.mod2_osc_type, + mod2_osc_octave: preset.mod2_osc_octave, + mod2_osc_semitones: preset.mod2_osc_semitones, + mod2_osc_detune: preset.mod2_osc_detune, + mod2_osc_attack: preset.mod2_osc_attack, + mod2_osc_decay: preset.mod2_osc_decay, + mod2_osc_sustain: preset.mod2_osc_sustain, + mod2_osc_release: preset.mod2_osc_release, + mod2_osc_retrigger: preset.mod2_osc_retrigger, + mod2_osc_atk_curve: preset.mod2_osc_atk_curve, + mod2_osc_dec_curve: preset.mod2_osc_dec_curve, + mod2_osc_rel_curve: preset.mod2_osc_rel_curve, + mod2_osc_unison: preset.mod2_osc_unison, + mod2_osc_unison_detune: preset.mod2_osc_unison_detune, + mod2_osc_stereo: preset.mod2_osc_stereo, + mod3_audio_module_type: preset.mod3_audio_module_type, + mod3_audio_module_level: preset.mod3_audio_module_level, + // Added in 1.2.3 + mod3_audio_module_routing: preset.mod3_audio_module_routing, + mod3_loaded_sample: preset.mod3_loaded_sample, + mod3_sample_lib: preset.mod3_sample_lib, + mod3_loop_wavetable: preset.mod3_loop_wavetable, + mod3_single_cycle: preset.mod3_single_cycle, + mod3_restretch: preset.mod3_restretch, + mod3_prev_restretch: preset.mod3_prev_restretch, + mod3_grain_hold: preset.mod3_grain_hold, + mod3_grain_gap: preset.mod3_grain_gap, + mod3_start_position: preset.mod3_start_position, + mod3_end_position: preset.mod3_end_position, + mod3_grain_crossfade: preset.mod3_grain_crossfade, + mod3_osc_type: preset.mod3_osc_type, + mod3_osc_octave: preset.mod3_osc_octave, + mod3_osc_semitones: preset.mod3_osc_semitones, + mod3_osc_detune: preset.mod3_osc_detune, + mod3_osc_attack: preset.mod3_osc_attack, + mod3_osc_decay: preset.mod3_osc_decay, + mod3_osc_sustain: preset.mod3_osc_sustain, + mod3_osc_release: preset.mod3_osc_release, + mod3_osc_retrigger: preset.mod3_osc_retrigger, + mod3_osc_atk_curve: preset.mod3_osc_atk_curve, + mod3_osc_dec_curve: preset.mod3_osc_dec_curve, + mod3_osc_rel_curve: preset.mod3_osc_rel_curve, + mod3_osc_unison: preset.mod3_osc_unison, + mod3_osc_unison_detune: preset.mod3_osc_unison_detune, + mod3_osc_stereo: preset.mod3_osc_stereo, + filter_wet: preset.filter_wet, + filter_cutoff: preset.filter_cutoff, + filter_resonance: preset.filter_resonance, + filter_res_type: preset.filter_res_type, + filter_lp_amount: preset.filter_lp_amount, + filter_hp_amount: preset.filter_hp_amount, + filter_bp_amount: preset.filter_bp_amount, + filter_env_peak: preset.filter_env_peak, + filter_env_attack: preset.filter_env_attack, + filter_env_decay: preset.filter_env_decay, + filter_env_sustain: preset.filter_env_sustain, + filter_env_release: preset.filter_env_release, + filter_env_atk_curve: preset.filter_env_atk_curve, + filter_env_dec_curve: preset.filter_env_dec_curve, + filter_env_rel_curve: preset.filter_env_rel_curve, + filter_alg_type: preset.filter_alg_type, + tilt_filter_type: preset.tilt_filter_type, + filter_wet_2: preset.filter_wet_2, + filter_cutoff_2: preset.filter_cutoff_2, + filter_resonance_2: preset.filter_resonance_2, + filter_res_type_2: preset.filter_res_type_2, + filter_lp_amount_2: preset.filter_lp_amount_2, + filter_hp_amount_2: preset.filter_hp_amount_2, + filter_bp_amount_2: preset.filter_bp_amount_2, + filter_env_peak_2: preset.filter_env_peak_2, + filter_env_attack_2: preset.filter_env_attack_2, + filter_env_decay_2: preset.filter_env_decay_2, + filter_env_sustain_2: preset.filter_env_sustain_2, + filter_env_release_2: preset.filter_env_release_2, + filter_env_atk_curve_2: preset.filter_env_atk_curve_2, + filter_env_dec_curve_2: preset.filter_env_dec_curve_2, + filter_env_rel_curve_2: preset.filter_env_rel_curve_2, + filter_alg_type_2: preset.filter_alg_type_2, + tilt_filter_type_2: preset.tilt_filter_type_2, + filter_routing: preset.filter_routing, + /////////////////////////////////////////////////////////////////// + // Added in 1.1.4 + filter_cutoff_link: preset.filter_cutoff_link, + /////////////////////////////////////////////////////////////////// + // Added in pitch update 1.2.1 + pitch_enable: preset.pitch_enable, + pitch_routing: preset.pitch_routing, + pitch_env_peak: preset.pitch_env_peak, + pitch_env_atk_curve: preset.pitch_env_atk_curve, + pitch_env_dec_curve: preset.pitch_env_dec_curve, + pitch_env_rel_curve: preset.pitch_env_rel_curve, + pitch_env_attack: preset.pitch_env_attack, + pitch_env_decay: preset.pitch_env_decay, + pitch_env_release: preset.pitch_env_release, + pitch_env_sustain: preset.pitch_env_sustain, + pitch_enable_2: preset.pitch_enable_2, + pitch_env_peak_2: preset.pitch_env_peak_2, + pitch_env_atk_curve_2: preset.pitch_env_atk_curve_2, + pitch_env_dec_curve_2: preset.pitch_env_dec_curve_2, + pitch_env_rel_curve_2: preset.pitch_env_rel_curve_2, + pitch_env_attack_2: preset.pitch_env_attack_2, + pitch_env_decay_2: preset.pitch_env_decay_2, + pitch_env_release_2: preset.pitch_env_release_2, + pitch_env_sustain_2: preset.pitch_env_sustain_2, + pitch_routing_2: preset.pitch_routing_2, + /////////////////////////////////////////////////////////////////// + lfo1_enable: preset.lfo1_enable, + lfo2_enable: preset.lfo2_enable, + lfo3_enable: preset.lfo3_enable, + lfo1_freq: preset.lfo1_freq, + lfo1_retrigger: preset.lfo1_retrigger, + lfo1_sync: preset.lfo1_sync, + lfo1_snap: preset.lfo1_snap, + lfo1_waveform: preset.lfo1_waveform, + lfo1_phase: preset.lfo1_phase, + lfo2_freq: preset.lfo2_freq, + lfo2_retrigger: preset.lfo2_retrigger, + lfo2_sync: preset.lfo2_sync, + lfo2_snap: preset.lfo2_snap, + lfo2_waveform: preset.lfo2_waveform, + lfo2_phase: preset.lfo2_phase, + lfo3_freq: preset.lfo3_freq, + lfo3_retrigger: preset.lfo3_retrigger, + lfo3_sync: preset.lfo3_sync, + lfo3_snap: preset.lfo3_snap, + lfo3_waveform: preset.lfo3_waveform, + lfo3_phase: preset.lfo3_phase, + mod_source_1: preset.mod_source_1, + mod_source_2: preset.mod_source_2, + mod_source_3: preset.mod_source_3, + mod_source_4: preset.mod_source_4, + mod_dest_1: preset.mod_dest_1, + mod_dest_2: preset.mod_dest_2, + mod_dest_3: preset.mod_dest_3, + mod_dest_4: preset.mod_dest_4, + mod_amount_1: preset.mod_amount_1, + mod_amount_2: preset.mod_amount_2, + mod_amount_3: preset.mod_amount_3, + mod_amount_4: preset.mod_amount_4, + // 1.2.6 + fm_one_to_two: preset.fm_one_to_two, + fm_one_to_three: preset.fm_one_to_three, + fm_two_to_three: preset.fm_two_to_three, + fm_cycles: preset.fm_cycles, + fm_attack: preset.fm_attack, + fm_decay: preset.fm_decay, + fm_sustain: preset.fm_sustain, + fm_release: preset.fm_release, + fm_attack_curve: preset.fm_attack_curve, + fm_decay_curve: preset.fm_decay_curve, + fm_release_curve: preset.fm_release_curve, + // 1.2.6 + pre_use_eq: preset.pre_use_eq, + pre_low_freq: preset.pre_low_freq, + pre_mid_freq: preset.pre_mid_freq, + pre_high_freq: preset.pre_high_freq, + pre_low_gain: preset.pre_low_gain, + pre_mid_gain: preset.pre_mid_gain, + pre_high_gain: preset.pre_high_gain, + use_fx: preset.use_fx, + use_compressor: preset.use_compressor, + comp_amt: preset.comp_amt, + comp_atk: preset.comp_atk, + comp_rel: preset.comp_rel, + comp_drive: preset.comp_drive, + use_abass: preset.use_abass, + abass_amount: preset.abass_amount, + use_saturation: preset.use_saturation, + sat_amount: preset.sat_amount, + sat_type: preset.sat_type, + use_delay: preset.use_delay, + delay_amount: preset.delay_amount, + delay_time: preset.delay_time, + delay_decay: preset.delay_decay, + delay_type: preset.delay_type, + use_reverb: preset.use_reverb, + reverb_model: preset.reverb_model, + reverb_amount: preset.reverb_amount, + reverb_size: preset.reverb_size, + reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 + use_phaser: preset.use_phaser, + phaser_amount: preset.phaser_amount, + phaser_depth: preset.phaser_depth, + phaser_rate: preset.phaser_rate, + phaser_feedback: preset.phaser_feedback, + use_buffermod: preset.use_buffermod, + buffermod_amount: preset.buffermod_amount, + buffermod_depth: preset.buffermod_depth, + buffermod_rate: preset.buffermod_rate, + buffermod_spread: preset.buffermod_spread, + buffermod_timing: preset.buffermod_timing, + use_flanger: preset.use_flanger, + flanger_amount: preset.flanger_amount, + flanger_depth: preset.flanger_depth, + flanger_rate: preset.flanger_rate, + flanger_feedback: preset.flanger_feedback, + use_limiter: preset.use_limiter, + limiter_threshold: preset.limiter_threshold, + limiter_knee: preset.limiter_knee, + }; + new_format } // This will get cloned each time we change preset styles in actuate -pub fn convert_preset_v125(preset: ActuatePresetV125) -> ActuatePresetV126 { - let new_format: ActuatePresetV126 = ActuatePresetV126 { +pub fn convert_preset_v125(preset: ActuatePresetV125) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { preset_name: preset.preset_name, preset_info: preset.preset_info, preset_category: preset.preset_category, @@ -3064,6 +3949,13 @@ pub fn convert_preset_v125(preset: ActuatePresetV125) -> ActuatePresetV126 { reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 use_phaser: preset.use_phaser, phaser_amount: preset.phaser_amount, phaser_depth: preset.phaser_depth, @@ -3088,8 +3980,8 @@ pub fn convert_preset_v125(preset: ActuatePresetV125) -> ActuatePresetV126 { } // This will get cloned each time we change preset styles in actuate -pub fn convert_preset_v123(preset: ActuatePresetV123) -> ActuatePresetV126 { - let new_format: ActuatePresetV126 = ActuatePresetV126 { +pub fn convert_preset_v123(preset: ActuatePresetV123) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { preset_name: preset.preset_name, preset_info: preset.preset_info, preset_category: preset.preset_category, @@ -3337,6 +4229,13 @@ pub fn convert_preset_v123(preset: ActuatePresetV123) -> ActuatePresetV126 { reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 use_phaser: preset.use_phaser, phaser_amount: preset.phaser_amount, phaser_depth: preset.phaser_depth, @@ -3361,8 +4260,8 @@ pub fn convert_preset_v123(preset: ActuatePresetV123) -> ActuatePresetV126 { } // This will get cloned each time we change preset styles in actuate -fn convert_preset_v122(preset: ActuatePresetV122) -> ActuatePresetV126 { - let new_format: ActuatePresetV126 = ActuatePresetV126 { +fn convert_preset_v122(preset: ActuatePresetV122) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { preset_name: preset.preset_name, preset_info: preset.preset_info, preset_category: preset.preset_category, @@ -3610,6 +4509,13 @@ fn convert_preset_v122(preset: ActuatePresetV122) -> ActuatePresetV126 { reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 use_phaser: preset.use_phaser, phaser_amount: preset.phaser_amount, phaser_depth: preset.phaser_depth, @@ -3634,8 +4540,8 @@ fn convert_preset_v122(preset: ActuatePresetV122) -> ActuatePresetV126 { } // This will get cloned each time we change preset styles in actuate -fn convert_preset_v114(preset: ActuatePresetV114) -> ActuatePresetV126 { - let new_format: ActuatePresetV126 = ActuatePresetV126 { +fn convert_preset_v114(preset: ActuatePresetV114) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { preset_name: preset.preset_name, preset_info: preset.preset_info, preset_category: preset.preset_category, @@ -3883,6 +4789,13 @@ fn convert_preset_v114(preset: ActuatePresetV114) -> ActuatePresetV126 { reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 use_phaser: preset.use_phaser, phaser_amount: preset.phaser_amount, phaser_depth: preset.phaser_depth, @@ -3907,8 +4820,8 @@ fn convert_preset_v114(preset: ActuatePresetV114) -> ActuatePresetV126 { } // This will get cloned each time we change preset styles in actuate -fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV126 { - let new_format: ActuatePresetV126 = ActuatePresetV126 { +fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV130 { + let new_format: ActuatePresetV130 = ActuatePresetV130 { preset_name: preset.preset_name, preset_info: preset.preset_info, preset_category: preset.preset_category, @@ -4156,6 +5069,13 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV126 { reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, + //1.3.0 + use_chorus: false, + chorus_amount: 0.8, + chorus_range: 0.5, + chorus_speed: 0.5, + stereo_algorithm: StereoAlgorithm::Original, + //1.3.0 use_phaser: preset.use_phaser, phaser_amount: preset.phaser_amount, phaser_depth: preset.phaser_depth,