diff --git a/Cargo.lock b/Cargo.lock index 554d052..2659b87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,15 +4,15 @@ version = 3 [[package]] name = "Actuate" -version = "1.3.3" +version = "1.3.4" dependencies = [ "dirs", "egui_file", - "flate2", "hound", "lazy_static", "nih_plug", "nih_plug_egui", + "noisy_float", "num-complex", "num-traits", "once_cell", @@ -20,7 +20,6 @@ dependencies = [ "pitch_shift", "rand", "rand_pcg", - "rmp-serde", "serde", "serde_json", ] @@ -56,12 +55,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "ahash" version = "0.8.11" @@ -140,7 +133,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", ] @@ -357,15 +350,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam" version = "0.8.4" @@ -491,7 +475,7 @@ dependencies = [ [[package]] name = "egui_file" version = "0.18.0" -source = "git+https://github.com/ardura/egui_file.git?rev=33c96389cd1c5e40c5d2ece87ef7f86a1df53cb2#33c96389cd1c5e40c5d2ece87ef7f86a1df53cb2" +source = "git+https://github.com/ardura/egui_file.git?rev=b75a8504d3008a7694708e8951cb8f226fa61007#b75a8504d3008a7694708e8951cb8f226fa61007" dependencies = [ "nih_plug_egui", ] @@ -549,16 +533,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "flate2" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" -dependencies = [ - "crc32fast", - "miniz_oxide 0.8.0", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -796,15 +770,6 @@ dependencies = [ "adler", ] -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - [[package]] name = "nih_log" version = "0.3.1" @@ -908,6 +873,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[package]] +name = "noisy_float" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978fe6e6ebc0bf53de533cd456ca2d9de13de13856eda1518a285d7705a213af" +dependencies = [ + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.6" @@ -1043,12 +1017,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pathdiff" version = "0.2.1" @@ -1202,28 +1170,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rmp" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - [[package]] name = "rustc-demangle" version = "0.1.24" diff --git a/Cargo.toml b/Cargo.toml index 27fabe4..7d51e6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "Actuate" -version = "1.3.3" +version = "1.3.4" edition = "2021" authors = ["Ardura "] license = "GPL-3.0-or-later" @@ -14,7 +14,6 @@ members = ["xtask"] crate-type = ["cdylib","lib"] [dependencies] -flate2 = "1.0.27" hound = "3.5.0" lazy_static = "1.4.0" @@ -23,7 +22,8 @@ nih_plug = { git = "https://github.com/ardura/nih-plug.git", rev = "de315f902d7b nih_plug_egui = { git = "https://github.com/ardura/nih-plug.git", rev = "de315f902d7b5a75f80bc9d4164e4485bf2b34a1" } # egui_file fork for nih-plug/Actuate -egui_file = { git = "https://github.com/ardura/egui_file.git", rev = "33c96389cd1c5e40c5d2ece87ef7f86a1df53cb2" } +egui_file = { git = "https://github.com/ardura/egui_file.git", rev = "b75a8504d3008a7694708e8951cb8f226fa61007" } +#older one 33c96389cd1c5e40c5d2ece87ef7f86a1df53cb2 num-complex = "0.4.4" num-traits = "0.2.17" @@ -32,10 +32,10 @@ parking_lot = "0.12.1" pitch_shift = "1.0.0" rand = "0.8.5" rand_pcg = "0.3.1" -rmp-serde = "1.1.2" serde = "1.0.188" serde_json = "1.0.107" dirs = "5.0.1" +noisy_float = "0.2.0" [profile.release] opt-level = 3 diff --git a/README.md b/README.md index 327f451..edf61b2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Actuate (Latest is v1.3.3) +# Actuate (Latest is v1.3.4) A Subtractive and Additive Synthesizer, Sampler, and Granulizer built in Rust + Nih-Plug Written by Ardura diff --git a/src/CustomWidgets.rs b/src/CustomWidgets.rs index 3407454..7c74182 100644 --- a/src/CustomWidgets.rs +++ b/src/CustomWidgets.rs @@ -5,4 +5,5 @@ pub(crate) mod CustomVerticalSlider; pub(crate) mod toggle_switch; pub(crate) mod ui_knob; pub(crate) mod slim_checkbox; +pub(crate) mod ComboBoxParam; diff --git a/src/CustomWidgets/ComboBoxParam.rs b/src/CustomWidgets/ComboBoxParam.rs new file mode 100644 index 0000000..9431272 --- /dev/null +++ b/src/CustomWidgets/ComboBoxParam.rs @@ -0,0 +1,114 @@ +// This came as a result of cleaning up the Actuate GUI and needing a combobox to param solution +// Ardura +// ---------------------------------------------------------------------------- + +use nih_plug::prelude::{Param, ParamSetter}; +use nih_plug_egui::egui::{ComboBox, Response, Ui, Widget}; + +pub struct ParamComboBox<'a, P: Param> { + param: &'a P, + setter: &'a ParamSetter<'a>, + + id_name: String, + + options: Vec, // Options for the ComboBox +} + +impl<'a, P: Param> ParamComboBox<'a, P> { + pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>, options: Vec, id_name: String) -> Self { + Self { param, setter, options, id_name } + } + + fn set_selected_value(&self, selected_value: String) { + // Convert the selected value back to the normalized parameter value and set it. + if let Some(normalized_value) = self.param.string_to_normalized_value(&selected_value) { + let value = self.param.preview_plain(normalized_value); + if value != self.param.modulated_plain_value() { + self.setter.set_parameter(self.param, value); + } + } + } + + fn get_current_value(&self) -> String { + self.param.to_string() + } +} + +impl<'a, P: Param> Widget for ParamComboBox<'a, P> { + fn ui(self, ui: &mut Ui) -> Response { + // Store the current value to check for changes later + let mut current_value = self.get_current_value(); + let mut changed = false; // Flag to detect change + + let response = ComboBox::from_id_source(self.param.name().to_owned() + &self.id_name) + .selected_text(current_value.clone()) + .show_ui(ui, |ui| { + for option in &self.options { + // Update current_value and set changed flag if a new option is selected + if ui.selectable_value(&mut current_value, option.clone(), option).clicked() { + changed = true; + } + } + }) + .response + .on_hover_text("Select a parameter value"); + + // If the value has changed, call set_selected_value + if changed { + self.set_selected_value(current_value); + } + + response + } +} + + +/* +use nih_plug::prelude::{Param, ParamSetter}; +use nih_plug_egui::egui::{ComboBox, Response, Ui, Widget}; + +pub struct ParamComboBox<'a, P: Param> { + param: &'a P, + setter: &'a ParamSetter<'a>, + + options: Vec, // Options for the ComboBox +} + +impl<'a, P: Param> ParamComboBox<'a, P> { + pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>, options: Vec) -> Self { + Self { + param, + setter, + options, + } + } + + fn set_selected_value(&self, selected_value: String) { + // Convert the selected value back to the normalized parameter value and set it. + if let Some(normalized_value) = self.param.string_to_normalized_value(&selected_value) { + let value = self.param.preview_plain(normalized_value); + if value != self.param.modulated_plain_value() { + self.setter.set_parameter(self.param, value); + } + } + } + + fn get_current_value(&self) -> String { + self.param.to_string() + } +} + +impl<'a, P: Param> Widget for ParamComboBox<'a, P> { + fn ui(self, ui: &mut Ui) -> Response { + ComboBox::from_label(self.param.name()) + .selected_text(self.get_current_value()) + .show_ui(ui, |ui| { + for option in &self.options { + ui.selectable_value(&mut self.get_current_value(), option.clone(), option); + } + }) + .response + .on_hover_text("Select a parameter value") + } +} +*/ \ No newline at end of file diff --git a/src/actuate_enums.rs b/src/actuate_enums.rs index 4744606..9437dca 100644 --- a/src/actuate_enums.rs +++ b/src/actuate_enums.rs @@ -5,26 +5,6 @@ use std::fmt; use nih_plug::params::enums::Enum; use serde::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, Enum, Clone, Copy)] -pub enum GeneratorType { - Off, - Sine, - Tri, - Saw, - RSaw, - WSaw, - SSaw, - RASaw, - Ramp, - Square, - RSquare, - Pulse, - Noise, - Sampler, - Granulizer, - Additive, -} - // Gui for which filter to display on bottom #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub enum UIBottomSelection { diff --git a/src/actuate_gui.rs b/src/actuate_gui.rs index 9274f0c..a9271b3 100644 --- a/src/actuate_gui.rs +++ b/src/actuate_gui.rs @@ -7,12 +7,12 @@ use egui_file::{FileDialog, State}; use nih_plug::{context::gui::AsyncExecutor, editor::Editor}; use nih_plug_egui::{create_egui_editor, egui::{self, Color32, Pos2, Rect, RichText, Rounding, ScrollArea, Vec2}, widgets::ParamSlider}; +use crate::CustomWidgets::ComboBoxParam; +#[allow(unused_imports)] use crate::{ actuate_enums::{ - AMFilterRouting, FilterAlgorithms, GeneratorType, LFOSelect, ModulationDestination, ModulationSource, PresetType, UIBottomSelection}, actuate_structs::ActuatePresetV131, audio_module::{AudioModule, AudioModuleType, Oscillator::VoiceType}, Actuate, ActuateParams, CustomWidgets::{ - slim_checkbox, toggle_switch, ui_knob::{self, KnobLayout}, - BeizerButton::{self, ButtonLayout}, BoolButton, CustomParamSlider, - CustomVerticalSlider::ParamSlider as VerticalParamSlider}, A_BACKGROUND_COLOR_TOP, DARKER_GREY_UI_COLOR, DARKEST_BOTTOM_UI_COLOR, DARK_GREY_UI_COLOR, FONT, FONT_COLOR, HEIGHT, LIGHTER_GREY_UI_COLOR, MEDIUM_GREY_UI_COLOR, PRESET_BANK_SIZE, SMALLER_FONT, TEAL_GREEN, WIDTH, YELLOW_MUSTARD}; + AMFilterRouting, FilterAlgorithms, LFOSelect, ModulationDestination, ModulationSource, PresetType, UIBottomSelection}, actuate_structs::ActuatePresetV131, audio_module::{AudioModule, AudioModuleType}, Actuate, ActuateParams, CustomWidgets::{ + slim_checkbox, toggle_switch, ui_knob::{self, KnobLayout}, BeizerButton::{self, ButtonLayout}, BoolButton, CustomParamSlider, CustomVerticalSlider::ParamSlider as VerticalParamSlider}, A_BACKGROUND_COLOR_TOP, DARKER_GREY_UI_COLOR, DARKEST_BOTTOM_UI_COLOR, DARK_GREY_UI_COLOR, FONT, FONT_COLOR, HEIGHT, LIGHTER_GREY_UI_COLOR, MEDIUM_GREY_UI_COLOR, PRESET_BANK_SIZE, SMALLER_FONT, TEAL_GREEN, WIDTH, YELLOW_MUSTARD}; pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExecutor) -> Option> { let params: Arc = instance.params.clone(); @@ -20,7 +20,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe 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); + //let arc_preset_category: Arc> = Arc::clone(&instance.preset_category); let clear_voices: Arc = Arc::clone(&instance.clear_voices); let reload_entire_preset: Arc = Arc::clone(&instance.reload_entire_preset); let browse_preset_active: Arc = Arc::clone(&instance.browsing_presets); @@ -38,53 +38,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe let filter_select_outside: Arc> = Arc::new(Mutex::new(UIBottomSelection::Filter1)); let lfo_select_outside: Arc> = Arc::new(Mutex::new(LFOSelect::INFO)); - let mod_source_1_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationSource::None)); - let mod_source_2_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationSource::None)); - let mod_source_3_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationSource::None)); - let mod_source_4_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationSource::None)); - let mod_dest_1_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationDestination::None)); - let mod_dest_2_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationDestination::None)); - let mod_dest_3_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationDestination::None)); - let mod_dest_4_tracker_outside: Arc> = - Arc::new(Mutex::new(ModulationDestination::None)); - let gen_1_filter_tracker_outside: Arc> = - Arc::new(Mutex::new(AMFilterRouting::Filter1)); - let gen_2_filter_tracker_outside: Arc> = - Arc::new(Mutex::new(AMFilterRouting::Filter1)); - let gen_3_filter_tracker_outside: Arc> = - Arc::new(Mutex::new(AMFilterRouting::Filter1)); - let gen_1_type_tracker_outside: Arc> = - Arc::new(Mutex::new(GeneratorType::Off)); - let gen_2_type_tracker_outside: Arc> = - Arc::new(Mutex::new(GeneratorType::Off)); - let gen_3_type_tracker_outside: Arc> = - Arc::new(Mutex::new(GeneratorType::Off)); - - let preset_category_tracker_outside: Arc> = - Arc::new(Mutex::new(PresetType::Select)); - - let mod_source_override_1 = instance.mod_override_source_1.clone(); - let mod_source_override_2 = instance.mod_override_source_2.clone(); - let mod_source_override_3 = instance.mod_override_source_3.clone(); - let mod_source_override_4 = instance.mod_override_source_4.clone(); - let mod_dest_override_1 = instance.mod_override_dest_1.clone(); - let mod_dest_override_2 = instance.mod_override_dest_2.clone(); - let mod_dest_override_3 = instance.mod_override_dest_3.clone(); - let mod_dest_override_4 = instance.mod_override_dest_4.clone(); - let preset_category_override = instance.preset_category_override.clone(); - let gen_1_routing_override_set = instance.gen_1_routing_override.clone(); - let gen_2_routing_override_set = instance.gen_2_routing_override.clone(); - let gen_3_routing_override_set = instance.gen_3_routing_override.clone(); - let gen_1_type_override_set = instance.gen_1_type_override.clone(); - let gen_2_type_override_set = instance.gen_2_type_override.clone(); - let gen_3_type_override_set = instance.gen_3_type_override.clone(); let filter_acid = instance.filter_acid.clone(); let filter_analog = instance.filter_analog.clone(); @@ -195,21 +148,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe let current_preset_index = current_preset.load(Ordering::SeqCst); let filter_select = filter_select_outside.clone(); let lfo_select = lfo_select_outside.clone(); - let mod_source_1_tracker = mod_source_1_tracker_outside.clone(); - let mod_source_2_tracker = mod_source_2_tracker_outside.clone(); - let mod_source_3_tracker = mod_source_3_tracker_outside.clone(); - let mod_source_4_tracker = mod_source_4_tracker_outside.clone(); - let mod_dest_1_tracker = mod_dest_1_tracker_outside.clone(); - let mod_dest_2_tracker = mod_dest_2_tracker_outside.clone(); - let mod_dest_3_tracker = mod_dest_3_tracker_outside.clone(); - let mod_dest_4_tracker = mod_dest_4_tracker_outside.clone(); - let gen_1_filter_tracker = gen_1_filter_tracker_outside.clone(); - let gen_2_filter_tracker = gen_2_filter_tracker_outside.clone(); - let gen_3_filter_tracker = gen_3_filter_tracker_outside.clone(); - let gen_1_type_tracker = gen_1_type_tracker_outside.clone(); - let gen_2_type_tracker = gen_2_type_tracker_outside.clone(); - let gen_3_type_tracker = gen_3_type_tracker_outside.clone(); - let preset_category_tracker = preset_category_tracker_outside.clone(); let preset_lib_name_tracker = arc_preset_lib_name.clone(); // This lets the internal param track the current samples for when the plugin gets reopened/reloaded @@ -218,7 +156,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe // This would cause a deadlock and break Actuate :| // Maybe in future this will become nicer if params.am1_sample.lock().unwrap()[0].len() > 1 && - AM1.lock().unwrap().loaded_sample[0][0] == 0.0 && + AM1.lock().unwrap().loaded_sample[0].len() <= 1 && AM1.lock().unwrap().sample_lib[0][0][0] == 0.0 && (AM1.lock().unwrap().audio_module_type == AudioModuleType::Sampler || AM1.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) @@ -230,7 +168,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe AM1_Lock.regenerate_samples(); } if params.am2_sample.lock().unwrap()[0].len() > 1 && - AM2.lock().unwrap().loaded_sample[0][0] == 0.0 && + AM2.lock().unwrap().loaded_sample[0].len() <= 1 && AM2.lock().unwrap().sample_lib[0][0][0] == 0.0 && (AM2.lock().unwrap().audio_module_type == AudioModuleType::Sampler || AM2.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) @@ -242,7 +180,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe AM2_Lock.regenerate_samples(); } if params.am3_sample.lock().unwrap()[0].len() > 1 && - AM3.lock().unwrap().loaded_sample[0][0] == 0.0 && + AM3.lock().unwrap().loaded_sample[0].len() <= 1 && AM3.lock().unwrap().sample_lib[0][0][0] == 0.0 && (AM3.lock().unwrap().audio_module_type == AudioModuleType::Sampler || AM3.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) @@ -271,23 +209,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe *arc_preset_info.lock().unwrap() = temp_current_preset.preset_info; // GUI thread misses this without this call here for some reason - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( + Actuate::reload_entire_preset( setter, params.clone(), (current_preset_index + 1) as usize, @@ -296,9 +218,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe &mut AM2.lock().unwrap(), &mut AM3.lock().unwrap(),); - // This is the gui value only - the preset type itinstance is loaded in the preset already - *arc_preset_category.lock().unwrap() = *preset_category_override.lock().unwrap(); - // This is set for the process thread reload_entire_preset.store(true, Ordering::SeqCst); } @@ -319,23 +238,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe *arc_preset_info.lock().unwrap() = temp_current_preset.preset_info; // GUI thread misses this without this call here for some reason - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( + Actuate::reload_entire_preset( setter, params.clone(), (current_preset_index - 1) as usize, @@ -344,9 +247,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe &mut AM2.lock().unwrap(), &mut AM3.lock().unwrap(),); - // This is the gui value only - the preset type itinstance is loaded in the preset already - *arc_preset_category.lock().unwrap() = *preset_category_override.lock().unwrap(); - // This is set for the process thread reload_entire_preset.store(true, Ordering::SeqCst); } @@ -447,22 +347,22 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe ui.label(RichText::new("Actuate") .font(FONT) .color(FONT_COLOR)) - .on_hover_text("by Ardura!"); + .on_hover_text("v1.3.4 by Ardura!"); ui.add_space(2.0); ui.separator(); - let prev_preset_button = BoolButton::BoolButton::for_param(¶ms.param_prev_preset, setter, 1.5, 0.9, FONT) + let prev_preset_button = BoolButton::BoolButton::for_param(¶ms.param_prev_preset, setter, 1.0, 0.8, SMALLER_FONT) .with_background_color(DARK_GREY_UI_COLOR); ui.add(prev_preset_button); ui.label(RichText::new("Preset") .background_color(A_BACKGROUND_COLOR_TOP) .color(FONT_COLOR) - .size(16.0)); + .size(12.0)); ui.label(RichText::new(current_preset_index.to_string()) .background_color(A_BACKGROUND_COLOR_TOP) .color(FONT_COLOR) - .size(16.0)); - let next_preset_button = BoolButton::BoolButton::for_param(¶ms.param_next_preset, setter, 1.5, 0.9, FONT) + .size(12.0)); + let next_preset_button = BoolButton::BoolButton::for_param(¶ms.param_next_preset, setter, 1.0, 0.8, SMALLER_FONT) .with_background_color(DARK_GREY_UI_COLOR); ui.add(next_preset_button); @@ -472,6 +372,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe .background_color(A_BACKGROUND_COLOR_TOP) .color(FONT_COLOR) ); + ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::INFO, RichText::new("Preset Info").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); if browse.clicked() { browse_preset_active.store(true, Ordering::SeqCst); } @@ -607,23 +508,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe *lfo_select.lock().unwrap() = LFOSelect::INFO; // GUI thread misses this without this call here for some reason - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( + Actuate::reload_entire_preset( setter, params.clone(), row, @@ -637,7 +522,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe let temp_current_preset = arc_preset.lock().unwrap()[row].clone(); *arc_preset_name.lock().unwrap() = temp_current_preset.preset_name; *arc_preset_info.lock().unwrap() = temp_current_preset.preset_info; - *arc_preset_category.lock().unwrap() = *preset_category_override.lock().unwrap(); // This is set for the process thread reload_entire_preset.store(true, Ordering::SeqCst); @@ -742,23 +626,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe *lfo_select.lock().unwrap() = LFOSelect::INFO; // GUI thread misses this without this call here for some reason - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( + Actuate::reload_entire_preset( setter, params.clone(), *r_index, @@ -772,7 +640,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe let temp_current_preset = arc_preset.lock().unwrap()[*r_index].clone(); *arc_preset_name.lock().unwrap() = temp_current_preset.preset_name; *arc_preset_info.lock().unwrap() = temp_current_preset.preset_info; - *arc_preset_category.lock().unwrap() = *preset_category_override.lock().unwrap(); // This is set for the process thread reload_entire_preset.store(true, Ordering::SeqCst); @@ -856,21 +723,9 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe }); }); } - ui.separator(); - let use_fx_toggle = BoolButton::BoolButton::for_param(¶ms.use_fx, setter, 2.5, 1.0, FONT); + let use_fx_toggle = BoolButton::BoolButton::for_param(¶ms.use_fx, setter, 2.5, 1.0, SMALLER_FONT); ui.add(use_fx_toggle).on_hover_text("Enable or disable FX processing"); ui.separator(); - let max_voice_knob = ui_knob::ArcKnob::for_param( - ¶ms.voice_limit, - setter, - 11.0, - KnobLayout::HorizontalInline) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(YELLOW_MUSTARD) - .set_text_size(TEXT_SIZE) - .set_hover_text("The maximum number of voices that can be playing at once".to_string()); - ui.add(max_voice_knob); let master_knob = ui_knob::ArcKnob::for_param( ¶ms.master_level, setter, @@ -882,8 +737,211 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe .set_text_size(TEXT_SIZE) .set_hover_text("Master volume level for Actuate".to_string()); ui.add(master_knob); + // Studio One changes (compatible for all DAWs) + let import_bank_button = ui.button(RichText::new("Load Bank") + .font(SMALLER_FONT) + .background_color(DARK_GREY_UI_COLOR) + .color(TEAL_GREEN) + ); + if import_bank_button.clicked() { + import_bank_active.store(true, Ordering::SeqCst); + } + if import_bank_active.load(Ordering::SeqCst) { + // Move to info tab on preset change + *lfo_select.lock().unwrap() = LFOSelect::INFO; + + // hehe + let bank_dialock = bank_dialog_main.clone(); + let mut dialog = bank_dialock.lock().unwrap(); + dialog.open(); + let mut dvar = Some(dialog); + + if let Some(dialog) = &mut dvar { + if dialog.show(egui_ctx).selected() { + if let Some(file) = dialog.path() { + let default_name: String; + let opened_file = Some(file.to_path_buf()); + let unserialized: Vec; + (default_name, unserialized) = Actuate::load_preset_bank(opened_file); + let temppath = default_name.clone(); + let path = Path::new(&temppath); + if let Some(filename) = path.file_name() { + let mut locked_lib = arc_preset.lock().unwrap(); + + // Load our items into our library from the unserialized save file + for (item_index, item) in unserialized.iter().enumerate() { + // If our item exists then update it + if let Some(existing_item) = locked_lib.get_mut(item_index) { + *existing_item = item.clone(); + } else { + // item_index is out of bounds in locked_lib + // These get dropped as the preset size should be the same all around + } + } + + // Create missing samples on current preset + let mut AM1L = AM1.lock().unwrap(); + let mut AM2L = AM2.lock().unwrap(); + let mut AM3L = AM3.lock().unwrap(); + AM1L.regenerate_samples(); + AM2L.regenerate_samples(); + AM3L.regenerate_samples(); + + let temp_preset = &locked_lib[current_preset_index as usize]; + *arc_preset_name.lock().unwrap() = temp_preset.preset_name.clone(); + *arc_preset_info.lock().unwrap() = temp_preset.preset_info.clone(); + //*arc_preset_category.lock().unwrap() = temp_preset.preset_category.clone(); + + drop(locked_lib); + + Actuate::reload_entire_preset( + setter, + params.clone(), + current_preset_index as usize, + &arc_preset.lock().unwrap(), + &mut AM1L, + &mut AM2L, + &mut AM3L,); + import_bank_active.store(false, Ordering::SeqCst); + *preset_lib_name_tracker.lock().unwrap() = filename.to_string_lossy().to_string(); + } + } + } + + match dialog.state() { + State::Cancelled | State::Closed => { + import_bank_active.store(false, Ordering::SeqCst); + }, + _ => {} + } + } + } + // Studio One changes (compatible for all DAWs) + let export_bank_button = ui.button(RichText::new("Save Bank") + .font(SMALLER_FONT) + .background_color(DARK_GREY_UI_COLOR) + .color(TEAL_GREEN) + ); + if export_bank_button.clicked() { + export_bank_active.store(true, Ordering::SeqCst); + } + if export_bank_active.load(Ordering::SeqCst) { + // Name the preset bank + let bank_save_dialock = bank_save_dialog_main.clone(); + let mut save_dialog = bank_save_dialock.lock().unwrap(); + save_dialog.open(); + let mut dvar = Some(save_dialog); + + if let Some(s_dialog) = &mut dvar { + if s_dialog.show(egui_ctx).selected() { + if let Some(file) = s_dialog.path() { + let saved_file = Some(file.to_path_buf()); + let mut locked_lib = arc_preset.lock().unwrap(); + Actuate::save_preset_bank(&mut locked_lib, saved_file); + drop(locked_lib); + export_bank_active.store(false, Ordering::SeqCst); + } + } + + match s_dialog.state() { + State::Cancelled | State::Closed => { + export_bank_active.store(false, Ordering::SeqCst); + }, + _ => {} + } + } + } + // Studio One changes (compatible for all DAWs) + let import_preset_button = ui.button(RichText::new("Import Preset") + .font(SMALLER_FONT) + .background_color(DARK_GREY_UI_COLOR) + .color(TEAL_GREEN) + ); + if import_preset_button.clicked() { + import_preset_active.store(true, Ordering::SeqCst); + } + if import_preset_active.load(Ordering::SeqCst) { + let dialock = dialog_main.clone(); + let mut dialog = dialock.lock().unwrap(); + dialog.open(); + let mut dvar = Some(dialog); + + if let Some(dialog) = &mut dvar { + if dialog.show(egui_ctx).selected() { + if let Some(file) = dialog.path() { + let opened_file = Some(file.to_path_buf()); + let unserialized: Option; + (_, unserialized) = Actuate::import_preset(opened_file); + + if unserialized.is_some() { + let mut locked_lib = arc_preset.lock().unwrap(); + locked_lib[current_preset_index as usize] = + unserialized.unwrap(); + let temp_preset = + &locked_lib[current_preset_index as usize]; + *arc_preset_name.lock().unwrap() = temp_preset.preset_name.clone(); + *arc_preset_info.lock().unwrap() = temp_preset.preset_info.clone(); + //*arc_preset_category.lock().unwrap() = temp_preset.preset_category.clone(); + + import_preset_active.store(false, Ordering::SeqCst); + + drop(locked_lib); + + // GUI thread misses this without this call here for some reason + Actuate::reload_entire_preset( + setter, + params.clone(), + (current_preset_index) as usize, + &arc_preset.lock().unwrap(), + &mut AM1.lock().unwrap(), + &mut AM2.lock().unwrap(), + &mut AM3.lock().unwrap(),); + } + } + } + match dialog.state() { + State::Cancelled | State::Closed => { + import_preset_active.store(false, Ordering::SeqCst); + }, + _ => {} + } + } + + } + // Studio One changes (compatible for all DAWs) + let export_preset_button = ui.button(RichText::new("Export Preset") + .font(SMALLER_FONT) + .background_color(DARK_GREY_UI_COLOR) + .color(TEAL_GREEN) + ); + if export_preset_button.clicked() { + export_preset_active.store(true, Ordering::SeqCst); + } + if export_preset_active.load(Ordering::SeqCst) { + let save_dialock = save_dialog_main.clone(); + let mut save_dialog = save_dialock.lock().unwrap(); + save_dialog.open(); + let mut dvar = Some(save_dialog); + if let Some(s_dialog) = &mut dvar { + if s_dialog.show(egui_ctx).selected() { + if let Some(file) = s_dialog.path() { + let saved_file = Some(file.to_path_buf()); + let locked_lib = arc_preset.lock().unwrap(); + Actuate::export_preset(saved_file, locked_lib[current_preset_index as usize].clone()); + drop(locked_lib); + export_preset_active.store(false, Ordering::SeqCst); + } + } - ui.checkbox(&mut safety_clip_output.lock().unwrap(), "Safety Clip Output"); + match s_dialog.state() { + State::Cancelled | State::Closed => { + export_preset_active.store(false, Ordering::SeqCst); + }, + _ => {} + } + } + } + ui.checkbox(&mut safety_clip_output.lock().unwrap(), "Safety Clip").on_hover_text("Clip the output at 0dB to save your ears/speakers"); }); const KNOB_SIZE: f32 = 28.0; const TEXT_SIZE: f32 = 11.0; @@ -897,107 +955,38 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe ui.vertical(|ui|{ ui.add_space(12.0); ui.colored_label(TEAL_GREEN, "Type"); - egui::ComboBox::new("gen_1_combobox", "") - .selected_text(format!("{:?}", *gen_1_type_tracker.lock().unwrap())) - .width(86.0) - .height(336.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Off, "Off"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Sine, "Sine"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Tri, "Tri"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Saw, "Saw"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::RSaw, "Rsaw"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::WSaw, "WSaw"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::SSaw, "SSaw"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::RASaw, "RASaw"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Ramp, "Ramp"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Square, "Square"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::RSquare, "RSquare"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Pulse, "Pulse"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Noise, "Noise"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Sampler, "Sampler"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Granulizer, "Granulizer"); - ui.selectable_value(&mut *gen_1_type_tracker.lock().unwrap(), GeneratorType::Additive, "Additive"); - }).response.on_hover_text_at_pointer("The type of generator to use."); - let (new_type, sub_type) = match *gen_1_type_tracker.lock().unwrap() { - GeneratorType::Off => (AudioModuleType::Off, VoiceType::Sine), - GeneratorType::Sine => (AudioModuleType::Osc, VoiceType::Sine), - GeneratorType::Tri => (AudioModuleType::Osc, VoiceType::Tri), - GeneratorType::Saw => (AudioModuleType::Osc, VoiceType::Saw), - GeneratorType::RSaw => (AudioModuleType::Osc, VoiceType::RSaw), - GeneratorType::WSaw => (AudioModuleType::Osc, VoiceType::WSaw), - GeneratorType::SSaw => (AudioModuleType::Osc, VoiceType::SSaw), - GeneratorType::RASaw => (AudioModuleType::Osc, VoiceType::RASaw), - GeneratorType::Ramp => (AudioModuleType::Osc, VoiceType::Ramp), - GeneratorType::Square => (AudioModuleType::Osc, VoiceType::Square), - GeneratorType::RSquare => (AudioModuleType::Osc, VoiceType::RSquare), - GeneratorType::Pulse => (AudioModuleType::Osc, VoiceType::Pulse), - GeneratorType::Noise => (AudioModuleType::Osc, VoiceType::Noise), - GeneratorType::Sampler => (AudioModuleType::Sampler, VoiceType::Sine), - GeneratorType::Granulizer => (AudioModuleType::Granulizer, VoiceType::Sine), - GeneratorType::Additive => (AudioModuleType::Additive, VoiceType::Sine), - }; - if *gen_1_type_override_set.lock().unwrap() != GeneratorType::Off { - // This happens on plugin preset load - *gen_1_type_tracker.lock().unwrap() = *gen_1_type_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_1_type, new_type); - setter.set_parameter( ¶ms.osc_1_type, sub_type); - *gen_1_type_override_set.lock().unwrap() = GeneratorType::Off; - } else { - // Set the new value in our params FROM the GUI - if new_type.clone() != params.audio_module_1_type.value() || sub_type != params.osc_1_type.value() { - setter.set_parameter( ¶ms.audio_module_1_type, new_type); - setter.set_parameter( ¶ms.osc_1_type, sub_type); - } - } + let cb1 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_1_type, setter, vec![ + String::from("Off"), + String::from("Sine"), + String::from("Tri"), + String::from("Saw"), + String::from("RSaw"), + String::from("WSaw"), + String::from("SSaw"), + String::from("RASaw"), + String::from("Ramp"), + String::from("Square"), + String::from("RSquare"), + String::from("Pulse"), + String::from("Noise"), + String::from("Sampler"), + String::from("Granulizer"), + String::from("Additive"), + ], + "cb1".to_string()); + ui.add(cb1); ui.colored_label(TEAL_GREEN, "Filter Assign"); - egui::ComboBox::new("gen_1_routing_combobox", "") - .selected_text(format!("{:?}", *gen_1_filter_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_1_filter_tracker.lock().unwrap(), AMFilterRouting::Bypass, "Bypass"); - ui.selectable_value(&mut *gen_1_filter_tracker.lock().unwrap(), AMFilterRouting::Filter1, "Filter1"); - ui.selectable_value(&mut *gen_1_filter_tracker.lock().unwrap(), AMFilterRouting::Filter2, "Filter2"); - ui.selectable_value(&mut *gen_1_filter_tracker.lock().unwrap(), AMFilterRouting::Both, "Both"); - }).response.on_hover_text_at_pointer("Filter routing(s) for the generator"); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - // Set the new value FROM the override field - if *gen_1_routing_override_set.lock().unwrap() != AMFilterRouting::UNSETROUTING { - // This happens on plugin preset load - *gen_1_filter_tracker.lock().unwrap() = *gen_1_routing_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_1_routing, gen_1_filter_tracker.lock().unwrap().clone()); - *gen_1_routing_override_set.lock().unwrap() = AMFilterRouting::UNSETROUTING; - } else { - // Set the new value in our params FROM the GUI - if *gen_1_filter_tracker.lock().unwrap() != params.audio_module_1_routing.value() { - setter.set_parameter( ¶ms.audio_module_1_routing, gen_1_filter_tracker.lock().unwrap().clone()); - } - } + let fr1 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_1_routing, setter, vec![ + String::from("Bypass"), + String::from("Filter1"), + String::from("Filter2"), + String::from("Both"), + ], + "fr1".to_string()); + ui.add(fr1); }); - /* - let audio_module_1_knob = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_1_type, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE) - .set_hover_text("The type of generator to use".to_string()); - ui.add(audio_module_1_knob); - let audio_module_1_filter_routing = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_1_routing, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE).set_hover_text("Filter routing(s) for the generator".to_string()); - ui.add(audio_module_1_filter_routing); - */ + let audio_module_1_level_knob = ui_knob::ArcKnob::for_param( ¶ms.audio_module_1_level, setter, @@ -1017,108 +1006,38 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe ui.vertical(|ui|{ ui.add_space(12.0); ui.colored_label(TEAL_GREEN, "Type"); - egui::ComboBox::new("gen_2_combobox", "") - .selected_text(format!("{:?}", *gen_2_type_tracker.lock().unwrap())) - .width(86.0) - .height(336.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Off, "Off"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Sine, "Sine"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Tri, "Tri"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Saw, "Saw"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::RSaw, "Rsaw"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::WSaw, "WSaw"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::SSaw, "SSaw"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::RASaw, "RASaw"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Ramp, "Ramp"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Square, "Square"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::RSquare, "RSquare"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Pulse, "Pulse"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Noise, "Noise"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Sampler, "Sampler"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Granulizer, "Granulizer"); - ui.selectable_value(&mut *gen_2_type_tracker.lock().unwrap(), GeneratorType::Additive, "Additive"); - }).response.on_hover_text_at_pointer("The type of generator to use."); - let (new_type, sub_type) = match *gen_2_type_tracker.lock().unwrap() { - GeneratorType::Off => (AudioModuleType::Off, VoiceType::Sine), - GeneratorType::Sine => (AudioModuleType::Osc, VoiceType::Sine), - GeneratorType::Tri => (AudioModuleType::Osc, VoiceType::Tri), - GeneratorType::Saw => (AudioModuleType::Osc, VoiceType::Saw), - GeneratorType::RSaw => (AudioModuleType::Osc, VoiceType::RSaw), - GeneratorType::WSaw => (AudioModuleType::Osc, VoiceType::WSaw), - GeneratorType::SSaw => (AudioModuleType::Osc, VoiceType::SSaw), - GeneratorType::RASaw => (AudioModuleType::Osc, VoiceType::RASaw), - GeneratorType::Ramp => (AudioModuleType::Osc, VoiceType::Ramp), - GeneratorType::Square => (AudioModuleType::Osc, VoiceType::Square), - GeneratorType::RSquare => (AudioModuleType::Osc, VoiceType::RSquare), - GeneratorType::Pulse => (AudioModuleType::Osc, VoiceType::Pulse), - GeneratorType::Noise => (AudioModuleType::Osc, VoiceType::Noise), - GeneratorType::Sampler => (AudioModuleType::Sampler, VoiceType::Sine), - GeneratorType::Granulizer => (AudioModuleType::Granulizer, VoiceType::Sine), - GeneratorType::Additive => (AudioModuleType::Additive, VoiceType::Sine), - }; - if *gen_2_type_override_set.lock().unwrap() != GeneratorType::Off { - // This happens on plugin preset load - *gen_2_type_tracker.lock().unwrap() = *gen_2_type_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_2_type, new_type); - setter.set_parameter( ¶ms.osc_2_type, sub_type); - *gen_2_type_override_set.lock().unwrap() = GeneratorType::Off; - } else { - // Set the new value in our params FROM the GUI - if new_type.clone() != params.audio_module_2_type.value() || sub_type != params.osc_2_type.value() { - setter.set_parameter( ¶ms.audio_module_2_type, new_type); - setter.set_parameter( ¶ms.osc_2_type, sub_type); - } - } + let cb2 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_2_type, setter, vec![ + String::from("Off"), + String::from("Sine"), + String::from("Tri"), + String::from("Saw"), + String::from("RSaw"), + String::from("WSaw"), + String::from("SSaw"), + String::from("RASaw"), + String::from("Ramp"), + String::from("Square"), + String::from("RSquare"), + String::from("Pulse"), + String::from("Noise"), + String::from("Sampler"), + String::from("Granulizer"), + String::from("Additive"), + ], + "cb2".to_string()); + ui.add(cb2); ui.colored_label(TEAL_GREEN, "Filter Assign"); - egui::ComboBox::new("gen_2_routing_combobox", "") - .selected_text(format!("{:?}", *gen_2_filter_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_2_filter_tracker.lock().unwrap(), AMFilterRouting::Bypass, "Bypass"); - ui.selectable_value(&mut *gen_2_filter_tracker.lock().unwrap(), AMFilterRouting::Filter1, "Filter1"); - ui.selectable_value(&mut *gen_2_filter_tracker.lock().unwrap(), AMFilterRouting::Filter2, "Filter2"); - ui.selectable_value(&mut *gen_2_filter_tracker.lock().unwrap(), AMFilterRouting::Both, "Both"); - }).response.on_hover_text_at_pointer("Filter routing(s) for the generator"); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - // Set the new value FROM the override field - if *gen_2_routing_override_set.lock().unwrap() != AMFilterRouting::UNSETROUTING { - // This happens on plugin preset load - *gen_2_filter_tracker.lock().unwrap() = *gen_2_routing_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_2_routing, gen_2_filter_tracker.lock().unwrap().clone()); - *gen_2_routing_override_set.lock().unwrap() = AMFilterRouting::UNSETROUTING; - } else { - // Set the new value in our params FROM the GUI - if *gen_2_filter_tracker.lock().unwrap() != params.audio_module_2_routing.value() { - setter.set_parameter( ¶ms.audio_module_2_routing, gen_2_filter_tracker.lock().unwrap().clone()); - } - } + let fr2 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_2_routing, setter, vec![ + String::from("Bypass"), + String::from("Filter1"), + String::from("Filter2"), + String::from("Both"), + ], + "fr2".to_string()); + ui.add(fr2); }); - /* - let audio_module_2_knob = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_2_type, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE).set_hover_text("The type of generator to use".to_string()); - ui.add(audio_module_2_knob); - - let audio_module_2_filter_routing = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_2_routing, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE).set_hover_text("Filter routing(s) for the generator".to_string()); - ui.add(audio_module_2_filter_routing); - }); - */ + let audio_module_2_level_knob = ui_knob::ArcKnob::for_param( ¶ms.audio_module_2_level, setter, @@ -1137,106 +1056,37 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe ui.vertical(|ui|{ ui.add_space(12.0); ui.colored_label(TEAL_GREEN, "Type"); - egui::ComboBox::new("gen_3_combobox", "") - .selected_text(format!("{:?}", *gen_3_type_tracker.lock().unwrap())) - .width(86.0) - .height(336.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Off, "Off"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Sine, "Sine"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Tri, "Tri"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Saw, "Saw"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::RSaw, "Rsaw"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::WSaw, "WSaw"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::SSaw, "SSaw"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::RASaw, "RASaw"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Ramp, "Ramp"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Square, "Square"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::RSquare, "RSquare"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Pulse, "Pulse"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Noise, "Noise"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Sampler, "Sampler"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Granulizer, "Granulizer"); - ui.selectable_value(&mut *gen_3_type_tracker.lock().unwrap(), GeneratorType::Additive, "Additive"); - }).response.on_hover_text_at_pointer("The type of generator to use."); - let (new_type, sub_type) = match *gen_3_type_tracker.lock().unwrap() { - GeneratorType::Off => (AudioModuleType::Off, VoiceType::Sine), - GeneratorType::Sine => (AudioModuleType::Osc, VoiceType::Sine), - GeneratorType::Tri => (AudioModuleType::Osc, VoiceType::Tri), - GeneratorType::Saw => (AudioModuleType::Osc, VoiceType::Saw), - GeneratorType::RSaw => (AudioModuleType::Osc, VoiceType::RSaw), - GeneratorType::WSaw => (AudioModuleType::Osc, VoiceType::WSaw), - GeneratorType::SSaw => (AudioModuleType::Osc, VoiceType::SSaw), - GeneratorType::RASaw => (AudioModuleType::Osc, VoiceType::RASaw), - GeneratorType::Ramp => (AudioModuleType::Osc, VoiceType::Ramp), - GeneratorType::Square => (AudioModuleType::Osc, VoiceType::Square), - GeneratorType::RSquare => (AudioModuleType::Osc, VoiceType::RSquare), - GeneratorType::Pulse => (AudioModuleType::Osc, VoiceType::Pulse), - GeneratorType::Noise => (AudioModuleType::Osc, VoiceType::Noise), - GeneratorType::Sampler => (AudioModuleType::Sampler, VoiceType::Sine), - GeneratorType::Granulizer => (AudioModuleType::Granulizer, VoiceType::Sine), - GeneratorType::Additive => (AudioModuleType::Additive, VoiceType::Sine), - }; - if *gen_3_type_override_set.lock().unwrap() != GeneratorType::Off { - // This happens on plugin preset load - *gen_3_type_tracker.lock().unwrap() = *gen_3_type_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_3_type, new_type); - setter.set_parameter( ¶ms.osc_3_type, sub_type); - *gen_3_type_override_set.lock().unwrap() = GeneratorType::Off; - } else { - // Set the new value in our params FROM the GUI - if new_type.clone() != params.audio_module_3_type.value() || sub_type != params.osc_3_type.value() { - setter.set_parameter( ¶ms.audio_module_3_type, new_type); - setter.set_parameter( ¶ms.osc_3_type, sub_type); - } - } + let cb3 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_3_type, setter, vec![ + String::from("Off"), + String::from("Sine"), + String::from("Tri"), + String::from("Saw"), + String::from("RSaw"), + String::from("WSaw"), + String::from("SSaw"), + String::from("RASaw"), + String::from("Ramp"), + String::from("Square"), + String::from("RSquare"), + String::from("Pulse"), + String::from("Noise"), + String::from("Sampler"), + String::from("Granulizer"), + String::from("Additive"), + ], + "cb3".to_string()); + ui.add(cb3); ui.colored_label(TEAL_GREEN, "Filter Assign"); - egui::ComboBox::new("gen_3_routing_combobox", "") - .selected_text(format!("{:?}", *gen_3_filter_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *gen_3_filter_tracker.lock().unwrap(), AMFilterRouting::Bypass, "Bypass"); - ui.selectable_value(&mut *gen_3_filter_tracker.lock().unwrap(), AMFilterRouting::Filter1, "Filter1"); - ui.selectable_value(&mut *gen_3_filter_tracker.lock().unwrap(), AMFilterRouting::Filter2, "Filter2"); - ui.selectable_value(&mut *gen_3_filter_tracker.lock().unwrap(), AMFilterRouting::Both, "Both"); - }).response.on_hover_text_at_pointer("Filter routing(s) for the generator"); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - // Set the new value FROM the override field - if *gen_3_routing_override_set.lock().unwrap() != AMFilterRouting::UNSETROUTING { - // This happens on plugin preset load - *gen_3_filter_tracker.lock().unwrap() = *gen_3_routing_override_set.lock().unwrap(); - setter.set_parameter( ¶ms.audio_module_3_routing, gen_3_filter_tracker.lock().unwrap().clone()); - *gen_3_routing_override_set.lock().unwrap() = AMFilterRouting::UNSETROUTING; - } else { - // Set the new value in our params FROM the GUI - if *gen_3_filter_tracker.lock().unwrap() != params.audio_module_3_routing.value() { - setter.set_parameter( ¶ms.audio_module_3_routing, gen_3_filter_tracker.lock().unwrap().clone()); - } - } + let fr3 = ComboBoxParam::ParamComboBox::for_param(¶ms.audio_module_3_routing, setter, vec![ + String::from("Bypass"), + String::from("Filter1"), + String::from("Filter2"), + String::from("Both"), + ], + "fr3".to_string()); + ui.add(fr3); }); - /* - let audio_module_3_knob = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_3_type, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE).set_hover_text("The type of generator to use".to_string()); - ui.add(audio_module_3_knob); - let audio_module_3_filter_routing = ui_knob::ArcKnob::for_param( - ¶ms.audio_module_3_routing, - setter, - KNOB_SIZE, - KnobLayout::Vertical) - .preset_style(ui_knob::KnobStyle::Preset1) - .set_fill_color(DARK_GREY_UI_COLOR) - .set_line_color(TEAL_GREEN) - .set_text_size(TEXT_SIZE).set_hover_text("Filter routing(s) for the generator".to_string()); - ui.add(audio_module_3_filter_routing); - */ let audio_module_3_level_knob = ui_knob::ArcKnob::for_param( ¶ms.audio_module_3_level, setter, @@ -1270,14 +1120,13 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe ui.selectable_value(&mut *filter_select.lock().unwrap(), UIBottomSelection::Pitch2, RichText::new("Pitch 2").background_color(DARKEST_BOTTOM_UI_COLOR)); // Jank spacing stuff :) ui.add_space(304.0); - ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::INFO, RichText::new("INFO").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); + ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::Modulation, RichText::new("Modulation").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::LFO1, RichText::new("LFO 1").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::LFO2, RichText::new("LFO 2").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::LFO3, RichText::new("LFO 3").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::FM, RichText::new("FM").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); - ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::Misc, RichText::new("Misc").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); - ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::Modulation, RichText::new("Modulation").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::FX, RichText::new("FX").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); + ui.selectable_value(&mut *lfo_select.lock().unwrap(), LFOSelect::Misc, RichText::new("Misc").background_color(DARKEST_BOTTOM_UI_COLOR).font(SMALLER_FONT)); }); //////////////////////////////////////////////////////////// @@ -2724,6 +2573,18 @@ A4I: Averaged 4 Pole Integrator".to_string()); }, LFOSelect::Misc => { ui.vertical(|ui|{ + let max_voice_knob = ui_knob::ArcKnob::for_param( + ¶ms.voice_limit, + setter, + 11.0, + KnobLayout::HorizontalInline) + .preset_style(ui_knob::KnobStyle::Preset1) + .set_fill_color(DARK_GREY_UI_COLOR) + .set_line_color(YELLOW_MUSTARD) + .set_text_size(TEXT_SIZE) + .set_hover_text("The maximum number of voices that can be playing at once".to_string()); + ui.add(max_voice_knob); + ui.separator(); ui.horizontal(|ui|{ ui.label(RichText::new("Link Cutoff 2 to Cutoff 1") .font(FONT) @@ -2732,6 +2593,7 @@ A4I: Averaged 4 Pole Integrator".to_string()); let filter_cutoff_link = toggle_switch::ToggleSwitch::for_param(¶ms.filter_cutoff_link, setter); ui.add(filter_cutoff_link); }); + ui.separator(); ui.horizontal(|ui|{ ui.label(RichText::new("Stereo Behavior") .font(FONT) @@ -2897,62 +2759,38 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); .set_show_label(false); ui.add(mod_1_knob); ui.separator(); - egui::ComboBox::new("mod_source_supported", "") - .selected_text(format!("{:?}", *mod_source_1_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui| { - ui.selectable_value(&mut *mod_source_1_tracker.lock().unwrap(), ModulationSource::None, "None"); - ui.selectable_value(&mut *mod_source_1_tracker.lock().unwrap(), ModulationSource::Velocity, "Velocity"); - ui.selectable_value(&mut *mod_source_1_tracker.lock().unwrap(), ModulationSource::LFO1, "LFO 1"); - ui.selectable_value(&mut *mod_source_1_tracker.lock().unwrap(), ModulationSource::LFO2, "LFO 2"); - ui.selectable_value(&mut *mod_source_1_tracker.lock().unwrap(), ModulationSource::LFO3, "LFO 3"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_source_override_1.lock().unwrap() != ModulationSource::UnsetModulation { - // This happens on plugin preset load - *mod_source_1_tracker.lock().unwrap() = *mod_source_override_1.lock().unwrap(); - setter.set_parameter( ¶ms.mod_source_1, mod_source_1_tracker.lock().unwrap().clone()); - *mod_source_override_1.lock().unwrap() = ModulationSource::UnsetModulation; - } else { - if *mod_source_1_tracker.lock().unwrap() != params.mod_source_1.value() { - setter.set_parameter( ¶ms.mod_source_1, mod_source_1_tracker.lock().unwrap().clone()); - } - } + let ms1 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_source_1, setter, vec![ + String::from("None"), + String::from("Velocity"), + String::from("LFO1"), + String::from("LFO2"), + String::from("LFO3"), + ], + "ms1".to_string()); + ui.add(ms1); ui.label(RichText::new("Mods") .font(FONT)); - egui::ComboBox::new("mod_dest_1_ID", "") - .selected_text(format!("{:?}", *mod_dest_1_tracker.lock().unwrap())) - .width(100.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::None, "None"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Cutoff_1, "Cutoff 1"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Cutoff_2, "Cutoff 2"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Resonance_1, "Resonance 1"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Resonance_2, "Resonance 2"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::All_Gain, "All Gain"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc1_Gain, "Osc1 Gain"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc2_Gain, "Osc2 Gain"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc3_Gain, "Osc3 Gain"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::All_Detune, "All Detune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc1Detune, "Osc1 Detune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc2Detune, "Osc2 Detune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc3Detune, "Osc3 Detune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::All_UniDetune, "All UniDetune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc1UniDetune, "Osc1 UniDetune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc2UniDetune, "Osc2 UniDetune"); - ui.selectable_value(&mut *mod_dest_1_tracker.lock().unwrap(), ModulationDestination::Osc3UniDetune, "Osc3 UniDetune"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_dest_override_1.lock().unwrap() != ModulationDestination::UnsetModulation { - // This happens on plugin preset load - *mod_dest_1_tracker.lock().unwrap() = *mod_dest_override_1.lock().unwrap(); - setter.set_parameter( ¶ms.mod_destination_1, mod_dest_1_tracker.lock().unwrap().clone()); - *mod_dest_override_1.lock().unwrap() = ModulationDestination::UnsetModulation; - } else { - if *mod_dest_1_tracker.lock().unwrap() != params.mod_destination_1.value() { - setter.set_parameter( ¶ms.mod_destination_1, mod_dest_1_tracker.lock().unwrap().clone()); - } - } + let md1 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_destination_1, setter, vec![ + String::from("None"), + String::from("Cutoff_1"), + String::from("Cutoff_2"), + String::from("Resonance_1"), + String::from("Resonance_2"), + String::from("All_Gain"), + String::from("Osc1_Gain"), + String::from("Osc2_Gain"), + String::from("Osc3_Gain"), + String::from("All_Detune"), + String::from("Osc1Detune"), + String::from("Osc2Detune"), + String::from("Osc3Detune"), + String::from("All_UniDetune"), + String::from("Osc1UniDetune"), + String::from("Osc2UniDetune"), + String::from("Osc3UniDetune"), + ], + "md1".to_string()); + ui.add(md1); }); ui.separator(); @@ -2970,62 +2808,38 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); .set_show_label(false); ui.add(mod_2_knob); ui.separator(); - egui::ComboBox::new("mod_source_2_ID","") - .selected_text(format!("{:?}", *mod_source_2_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_source_2_tracker.lock().unwrap(), ModulationSource::None, "None"); - ui.selectable_value(&mut *mod_source_2_tracker.lock().unwrap(), ModulationSource::Velocity, "Velocity"); - ui.selectable_value(&mut *mod_source_2_tracker.lock().unwrap(), ModulationSource::LFO1, "LFO 1"); - ui.selectable_value(&mut *mod_source_2_tracker.lock().unwrap(), ModulationSource::LFO2, "LFO 2"); - ui.selectable_value(&mut *mod_source_2_tracker.lock().unwrap(), ModulationSource::LFO3, "LFO 3"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_source_override_2.lock().unwrap() != ModulationSource::UnsetModulation { - // This happens on plugin preset load - *mod_source_2_tracker.lock().unwrap() = *mod_source_override_2.lock().unwrap(); - setter.set_parameter( ¶ms.mod_source_2, mod_source_2_tracker.lock().unwrap().clone()); - *mod_source_override_2.lock().unwrap() = ModulationSource::UnsetModulation; - } else { - if *mod_source_2_tracker.lock().unwrap() != params.mod_source_2.value() { - setter.set_parameter( ¶ms.mod_source_2, mod_source_2_tracker.lock().unwrap().clone()); - } - } + let ms2 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_source_2, setter, vec![ + String::from("None"), + String::from("Velocity"), + String::from("LFO1"), + String::from("LFO2"), + String::from("LFO3"), + ], + "ms2".to_string()); + ui.add(ms2); ui.label(RichText::new("Mods") .font(FONT)); - egui::ComboBox::new("mod_dest_2_ID", "") - .selected_text(format!("{:?}", *mod_dest_2_tracker.lock().unwrap())) - .width(100.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::None, "None"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Cutoff_1, "Cutoff 1"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Cutoff_2, "Cutoff 2"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Resonance_1, "Resonance 1"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Resonance_2, "Resonance 2"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::All_Gain, "All Gain"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc1_Gain, "Osc1 Gain"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc2_Gain, "Osc2 Gain"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc3_Gain, "Osc3 Gain"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::All_Detune, "All Detune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc1Detune, "Osc1 Detune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc2Detune, "Osc2 Detune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc3Detune, "Osc3 Detune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::All_UniDetune, "All UniDetune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc1UniDetune, "Osc1 UniDetune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc2UniDetune, "Osc2 UniDetune"); - ui.selectable_value(&mut *mod_dest_2_tracker.lock().unwrap(), ModulationDestination::Osc3UniDetune, "Osc3 UniDetune"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_dest_override_2.lock().unwrap() != ModulationDestination::UnsetModulation { - // This happens on plugin preset load - *mod_dest_2_tracker.lock().unwrap() = *mod_dest_override_2.lock().unwrap(); - setter.set_parameter( ¶ms.mod_destination_2, mod_dest_2_tracker.lock().unwrap().clone()); - *mod_dest_override_2.lock().unwrap() = ModulationDestination::UnsetModulation; - } else { - if *mod_dest_2_tracker.lock().unwrap() != params.mod_destination_2.value() { - setter.set_parameter( ¶ms.mod_destination_2, mod_dest_2_tracker.lock().unwrap().clone()); - } - } + let md2 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_destination_2, setter, vec![ + String::from("None"), + String::from("Cutoff_1"), + String::from("Cutoff_2"), + String::from("Resonance_1"), + String::from("Resonance_2"), + String::from("All_Gain"), + String::from("Osc1_Gain"), + String::from("Osc2_Gain"), + String::from("Osc3_Gain"), + String::from("All_Detune"), + String::from("Osc1Detune"), + String::from("Osc2Detune"), + String::from("Osc3Detune"), + String::from("All_UniDetune"), + String::from("Osc1UniDetune"), + String::from("Osc2UniDetune"), + String::from("Osc3UniDetune"), + ], + "md2".to_string()); + ui.add(md2); }); ui.separator(); @@ -3043,62 +2857,38 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); .set_show_label(false); ui.add(mod_3_knob); ui.separator(); - egui::ComboBox::new("mod_source_3_ID","") - .selected_text(format!("{:?}", *mod_source_3_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_source_3_tracker.lock().unwrap(), ModulationSource::None, "None"); - ui.selectable_value(&mut *mod_source_3_tracker.lock().unwrap(), ModulationSource::Velocity, "Velocity"); - ui.selectable_value(&mut *mod_source_3_tracker.lock().unwrap(), ModulationSource::LFO1, "LFO 1"); - ui.selectable_value(&mut *mod_source_3_tracker.lock().unwrap(), ModulationSource::LFO2, "LFO 2"); - ui.selectable_value(&mut *mod_source_3_tracker.lock().unwrap(), ModulationSource::LFO3, "LFO 3"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_source_override_3.lock().unwrap() != ModulationSource::UnsetModulation { - // This happens on plugin preset load - *mod_source_3_tracker.lock().unwrap() = *mod_source_override_3.lock().unwrap(); - setter.set_parameter( ¶ms.mod_source_3, mod_source_3_tracker.lock().unwrap().clone()); - *mod_source_override_3.lock().unwrap() = ModulationSource::UnsetModulation; - } else { - if *mod_source_3_tracker.lock().unwrap() != params.mod_source_3.value() { - setter.set_parameter( ¶ms.mod_source_3, mod_source_3_tracker.lock().unwrap().clone()); - } - } + let ms3 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_source_3, setter, vec![ + String::from("None"), + String::from("Velocity"), + String::from("LFO1"), + String::from("LFO2"), + String::from("LFO3"), + ], + "ms3".to_string()); + ui.add(ms3); ui.label(RichText::new("Mods") .font(FONT)); - egui::ComboBox::new("mod_dest_3_ID", "") - .selected_text(format!("{:?}", *mod_dest_3_tracker.lock().unwrap())) - .width(100.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::None, "None"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Cutoff_1, "Cutoff 1"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Cutoff_2, "Cutoff 2"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Resonance_1, "Resonance 1"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Resonance_2, "Resonance 2"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::All_Gain, "All Gain"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc1_Gain, "Osc1 Gain"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc2_Gain, "Osc2 Gain"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc3_Gain, "Osc3 Gain"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::All_Detune, "All Detune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc1Detune, "Osc1 Detune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc2Detune, "Osc2 Detune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc3Detune, "Osc3 Detune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::All_UniDetune, "All UniDetune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc1UniDetune, "Osc1 UniDetune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc2UniDetune, "Osc2 UniDetune"); - ui.selectable_value(&mut *mod_dest_3_tracker.lock().unwrap(), ModulationDestination::Osc3UniDetune, "Osc3 UniDetune"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_dest_override_3.lock().unwrap() != ModulationDestination::UnsetModulation { - // This happens on plugin preset load - *mod_dest_3_tracker.lock().unwrap() = *mod_dest_override_3.lock().unwrap(); - setter.set_parameter( ¶ms.mod_destination_3, mod_dest_3_tracker.lock().unwrap().clone()); - *mod_dest_override_3.lock().unwrap() = ModulationDestination::UnsetModulation; - } else { - if *mod_dest_3_tracker.lock().unwrap() != params.mod_destination_3.value() { - setter.set_parameter( ¶ms.mod_destination_3, mod_dest_3_tracker.lock().unwrap().clone()); - } - } + let md3 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_destination_3, setter, vec![ + String::from("None"), + String::from("Cutoff_1"), + String::from("Cutoff_2"), + String::from("Resonance_1"), + String::from("Resonance_2"), + String::from("All_Gain"), + String::from("Osc1_Gain"), + String::from("Osc2_Gain"), + String::from("Osc3_Gain"), + String::from("All_Detune"), + String::from("Osc1Detune"), + String::from("Osc2Detune"), + String::from("Osc3Detune"), + String::from("All_UniDetune"), + String::from("Osc1UniDetune"), + String::from("Osc2UniDetune"), + String::from("Osc3UniDetune"), + ], + "md3".to_string()); + ui.add(md3); }); ui.separator(); @@ -3116,61 +2906,38 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); .set_show_label(false); ui.add(mod_4_knob); ui.separator(); - egui::ComboBox::new("mod_source_4_ID","") - .selected_text(format!("{:?}", *mod_source_4_tracker.lock().unwrap())) - .width(70.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_source_4_tracker.lock().unwrap(), ModulationSource::None, "None"); - ui.selectable_value(&mut *mod_source_4_tracker.lock().unwrap(), ModulationSource::Velocity, "Velocity"); - ui.selectable_value(&mut *mod_source_4_tracker.lock().unwrap(), ModulationSource::LFO1, "LFO 1"); - ui.selectable_value(&mut *mod_source_4_tracker.lock().unwrap(), ModulationSource::LFO2, "LFO 2"); - ui.selectable_value(&mut *mod_source_4_tracker.lock().unwrap(), ModulationSource::LFO3, "LFO 3"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_source_override_4.lock().unwrap() != ModulationSource::UnsetModulation { - // This happens on plugin preset load - *mod_source_4_tracker.lock().unwrap() = *mod_source_override_4.lock().unwrap(); - setter.set_parameter( ¶ms.mod_source_4, mod_source_4_tracker.lock().unwrap().clone()); - *mod_source_override_4.lock().unwrap() = ModulationSource::UnsetModulation; - } else { - if *mod_source_4_tracker.lock().unwrap() != params.mod_source_4.value() { - setter.set_parameter( ¶ms.mod_source_4, mod_source_4_tracker.lock().unwrap().clone()); - } - } + let ms4 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_source_4, setter, vec![ + String::from("None"), + String::from("Velocity"), + String::from("LFO1"), + String::from("LFO2"), + String::from("LFO3"), + ], + "ms4".to_string()); + ui.add(ms4); ui.label(RichText::new("Mods") - .font(FONT)); egui::ComboBox::new("mod_dest_4_ID", "") - .selected_text(format!("{:?}", *mod_dest_4_tracker.lock().unwrap())) - .width(100.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::None, "None"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Cutoff_1, "Cutoff 1"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Cutoff_2, "Cutoff 2"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Resonance_1, "Resonance 1"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Resonance_2, "Resonance 2"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::All_Gain, "All Gain"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc1_Gain, "Osc1 Gain"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc2_Gain, "Osc2 Gain"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc3_Gain, "Osc3 Gain"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::All_Detune, "All Detune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc1Detune, "Osc1 Detune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc2Detune, "Osc2 Detune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc3Detune, "Osc3 Detune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::All_UniDetune, "All UniDetune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc1UniDetune, "Osc1 UniDetune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc2UniDetune, "Osc2 UniDetune"); - ui.selectable_value(&mut *mod_dest_4_tracker.lock().unwrap(), ModulationDestination::Osc3UniDetune, "Osc3 UniDetune"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *mod_dest_override_4.lock().unwrap() != ModulationDestination::UnsetModulation { - // This happens on plugin preset load - *mod_dest_4_tracker.lock().unwrap() = *mod_dest_override_4.lock().unwrap(); - setter.set_parameter( ¶ms.mod_destination_4, mod_dest_4_tracker.lock().unwrap().clone()); - *mod_dest_override_4.lock().unwrap() = ModulationDestination::UnsetModulation; - } else { - if *mod_dest_4_tracker.lock().unwrap() != params.mod_destination_4.value() { - setter.set_parameter( ¶ms.mod_destination_4, mod_dest_4_tracker.lock().unwrap().clone()); - } - } + .font(FONT)); + let md4 = ComboBoxParam::ParamComboBox::for_param(¶ms.mod_destination_4, setter, vec![ + String::from("None"), + String::from("Cutoff_1"), + String::from("Cutoff_2"), + String::from("Resonance_1"), + String::from("Resonance_2"), + String::from("All_Gain"), + String::from("Osc1_Gain"), + String::from("Osc2_Gain"), + String::from("Osc3_Gain"), + String::from("All_Detune"), + String::from("Osc1Detune"), + String::from("Osc2Detune"), + String::from("Osc3Detune"), + String::from("All_UniDetune"), + String::from("Osc1UniDetune"), + String::from("Osc2UniDetune"), + String::from("Osc3UniDetune"), + ], + "md4".to_string()); + ui.add(md4); }); ui.separator(); }); @@ -3186,33 +2953,21 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); ui.label(RichText::new("Category:") .font(FONT) .size(12.0)); - egui::ComboBox::new("preset_category", "") - .selected_text(format!("{:?}", *preset_category_tracker.lock().unwrap())) - .width(150.0) - .show_ui(ui, |ui|{ - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Select, "Select"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Atmosphere, "Atmosphere"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Bass, "Bass"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::FX, "FX"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Keys, "Keys"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Lead, "Lead"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Pad, "Pad"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Percussion, "Percussion"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Pluck, "Pluck"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Synth, "Synth"); - ui.selectable_value(&mut *preset_category_tracker.lock().unwrap(), PresetType::Other, "Other"); - }); - // This was a workaround for updating combobox on preset load but otherwise updating preset through combobox selection - if *preset_category_override.lock().unwrap() != PresetType::Select { - // This happens on plugin preset load - *preset_category_tracker.lock().unwrap() = *preset_category_override.lock().unwrap(); - setter.set_parameter( ¶ms.preset_category, preset_category_tracker.lock().unwrap().clone()); - *preset_category_override.lock().unwrap() = PresetType::Select; - } else { - if *preset_category_tracker.lock().unwrap() != params.preset_category.value() { - setter.set_parameter( ¶ms.preset_category, preset_category_tracker.lock().unwrap().clone()); - } - } + + let preset_category_box = ComboBoxParam::ParamComboBox::for_param(¶ms.preset_category, setter, vec![ + String::from("Select"), + String::from("Atmosphere"), + String::from("Bass"), + String::from("Keys"), + String::from("Lead"), + String::from("Pad"), + String::from("Percussion"), + String::from("Pluck"), + String::from("Synth"), + String::from("Other"), + ], + "preset_category_box".to_string()); + ui.add(preset_category_box); }); ui.horizontal(|ui|{ @@ -3276,252 +3031,13 @@ For constant FM, turn Sustain to 100% and A,D,R to 0%".to_string()); }); ui.separator(); ui.horizontal(|ui| { - let update_current_preset = BoolButton::BoolButton::for_param(¶ms.param_update_current_preset, setter, 5.0, 1.2, SMALLER_FONT) + let update_current_preset = BoolButton::BoolButton::for_param(¶ms.param_update_current_preset, setter, 5.2, 1.5, FONT) .with_background_color(DARK_GREY_UI_COLOR); ui.add(update_current_preset); - // Studio One changes (compatible for all DAWs) - let import_preset_button = ui.button(RichText::new("Import Preset") - .font(FONT) - .background_color(DARK_GREY_UI_COLOR) - .color(TEAL_GREEN) - ); - if import_preset_button.clicked() { - import_preset_active.store(true, Ordering::SeqCst); - } - if import_preset_active.load(Ordering::SeqCst) { - let dialock = dialog_main.clone(); - let mut dialog = dialock.lock().unwrap(); - dialog.open(); - let mut dvar = Some(dialog); - - if let Some(dialog) = &mut dvar { - if dialog.show(egui_ctx).selected() { - if let Some(file) = dialog.path() { - let opened_file = Some(file.to_path_buf()); - let unserialized: Option; - (_, unserialized) = Actuate::import_preset(opened_file); - - if unserialized.is_some() { - let mut locked_lib = arc_preset.lock().unwrap(); - locked_lib[current_preset_index as usize] = - unserialized.unwrap(); - let temp_preset = - &locked_lib[current_preset_index as usize]; - *arc_preset_name.lock().unwrap() = temp_preset.preset_name.clone(); - *arc_preset_info.lock().unwrap() = temp_preset.preset_info.clone(); - *arc_preset_category.lock().unwrap() = temp_preset.preset_category.clone(); - - import_preset_active.store(false, Ordering::SeqCst); - - drop(locked_lib); - - // GUI thread misses this without this call here for some reason - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( - setter, - params.clone(), - (current_preset_index) as usize, - &arc_preset.lock().unwrap(), - &mut AM1.lock().unwrap(), - &mut AM2.lock().unwrap(), - &mut AM3.lock().unwrap(),); - } - } - } - match dialog.state() { - State::Cancelled | State::Closed => { - import_preset_active.store(false, Ordering::SeqCst); - }, - _ => {} - } - } - - } - // Studio One changes (compatible for all DAWs) - let export_preset_button = ui.button(RichText::new("Export Preset") - .font(FONT) - .background_color(DARK_GREY_UI_COLOR) - .color(TEAL_GREEN) - ); - if export_preset_button.clicked() { - export_preset_active.store(true, Ordering::SeqCst); - } - if export_preset_active.load(Ordering::SeqCst) { - let save_dialock = save_dialog_main.clone(); - let mut save_dialog = save_dialock.lock().unwrap(); - save_dialog.open(); - let mut dvar = Some(save_dialog); - if let Some(s_dialog) = &mut dvar { - if s_dialog.show(egui_ctx).selected() { - if let Some(file) = s_dialog.path() { - let saved_file = Some(file.to_path_buf()); - let locked_lib = arc_preset.lock().unwrap(); - Actuate::export_preset(saved_file, locked_lib[current_preset_index as usize].clone()); - drop(locked_lib); - export_preset_active.store(false, Ordering::SeqCst); - } - } - - match s_dialog.state() { - State::Cancelled | State::Closed => { - export_preset_active.store(false, Ordering::SeqCst); - }, - _ => {} - } - } - } ui.separator(); - let use_fx_toggle = BoolButton::BoolButton::for_param(¶ms.use_fx, setter, 2.8, 1.2, FONT); + let use_fx_toggle = BoolButton::BoolButton::for_param(¶ms.use_fx, setter, 2.8, 1.2, SMALLER_FONT); ui.add(use_fx_toggle); }); - ui.horizontal(|ui|{ - ui.add_space(90.0); - // Studio One changes (compatible for all DAWs) - let import_bank_button = ui.button(RichText::new("Load Bank") - .font(FONT) - .background_color(DARK_GREY_UI_COLOR) - .color(TEAL_GREEN) - ); - if import_bank_button.clicked() { - import_bank_active.store(true, Ordering::SeqCst); - } - if import_bank_active.load(Ordering::SeqCst) { - // Move to info tab on preset change - *lfo_select.lock().unwrap() = LFOSelect::INFO; - - // hehe - let bank_dialock = bank_dialog_main.clone(); - let mut dialog = bank_dialock.lock().unwrap(); - dialog.open(); - let mut dvar = Some(dialog); - - if let Some(dialog) = &mut dvar { - if dialog.show(egui_ctx).selected() { - if let Some(file) = dialog.path() { - let default_name: String; - let opened_file = Some(file.to_path_buf()); - let unserialized: Vec; - (default_name, unserialized) = Actuate::load_preset_bank(opened_file); - let temppath = default_name.clone(); - let path = Path::new(&temppath); - if let Some(filename) = path.file_name() { - let mut locked_lib = arc_preset.lock().unwrap(); - - // Load our items into our library from the unserialized save file - for (item_index, item) in unserialized.iter().enumerate() { - // If our item exists then update it - if let Some(existing_item) = locked_lib.get_mut(item_index) { - *existing_item = item.clone(); - } else { - // item_index is out of bounds in locked_lib - // These get dropped as the preset size should be the same all around - } - } - - // Create missing samples on current preset - let mut AM1L = AM1.lock().unwrap(); - let mut AM2L = AM2.lock().unwrap(); - let mut AM3L = AM3.lock().unwrap(); - AM1L.regenerate_samples(); - AM2L.regenerate_samples(); - AM3L.regenerate_samples(); - - let temp_preset = &locked_lib[current_preset_index as usize]; - *arc_preset_name.lock().unwrap() = temp_preset.preset_name.clone(); - *arc_preset_info.lock().unwrap() = temp_preset.preset_info.clone(); - *arc_preset_category.lock().unwrap() = temp_preset.preset_category.clone(); - - drop(locked_lib); - - ( - *mod_source_override_1.lock().unwrap(), - *mod_source_override_2.lock().unwrap(), - *mod_source_override_3.lock().unwrap(), - *mod_source_override_4.lock().unwrap(), - *mod_dest_override_1.lock().unwrap(), - *mod_dest_override_2.lock().unwrap(), - *mod_dest_override_3.lock().unwrap(), - *mod_dest_override_4.lock().unwrap(), - *preset_category_override.lock().unwrap(), - *gen_1_routing_override_set.lock().unwrap(), - *gen_2_routing_override_set.lock().unwrap(), - *gen_3_routing_override_set.lock().unwrap(), - *gen_1_type_override_set.lock().unwrap(), - *gen_2_type_override_set.lock().unwrap(), - *gen_3_type_override_set.lock().unwrap(), - ) = Actuate::reload_entire_preset( - setter, - params.clone(), - current_preset_index as usize, - &arc_preset.lock().unwrap(), - &mut AM1L, - &mut AM2L, - &mut AM3L,); - import_bank_active.store(false, Ordering::SeqCst); - *preset_lib_name_tracker.lock().unwrap() = filename.to_string_lossy().to_string(); - } - } - } - - match dialog.state() { - State::Cancelled | State::Closed => { - import_bank_active.store(false, Ordering::SeqCst); - }, - _ => {} - } - } - } - // Studio One changes (compatible for all DAWs) - let export_bank_button = ui.button(RichText::new("Save Bank") - .font(FONT) - .background_color(DARK_GREY_UI_COLOR) - .color(TEAL_GREEN) - ); - if export_bank_button.clicked() { - export_bank_active.store(true, Ordering::SeqCst); - } - if export_bank_active.load(Ordering::SeqCst) { - // Name the preset bank - let bank_save_dialock = bank_save_dialog_main.clone(); - let mut save_dialog = bank_save_dialock.lock().unwrap(); - save_dialog.open(); - let mut dvar = Some(save_dialog); - - if let Some(s_dialog) = &mut dvar { - if s_dialog.show(egui_ctx).selected() { - if let Some(file) = s_dialog.path() { - let saved_file = Some(file.to_path_buf()); - let mut locked_lib = arc_preset.lock().unwrap(); - Actuate::save_preset_bank(&mut locked_lib, saved_file); - drop(locked_lib); - export_bank_active.store(false, Ordering::SeqCst); - } - } - - match s_dialog.state() { - State::Cancelled | State::Closed => { - export_bank_active.store(false, Ordering::SeqCst); - }, - _ => {} - } - } - } - }); }, LFOSelect::FX => { ScrollArea::vertical() diff --git a/src/actuate_structs.rs b/src/actuate_structs.rs index 3f25de3..9eb5df1 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, StereoAlgorithm}, 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}}, fx::{delay::{DelaySnapValues, DelayType}, saturation::SaturationType, ArduraFilter, StateVariableFilter::ResonanceType}, LFOController}; /// Modulation struct for passing mods to audio modules #[derive(Serialize, Deserialize, Clone)] @@ -67,7 +67,6 @@ pub struct ActuatePresetV131 { pub mod1_grain_crossfade: i32, // Osc module knob storage - pub mod1_osc_type: VoiceType, pub mod1_osc_octave: i32, pub mod1_osc_semitones: i32, pub mod1_osc_detune: f32, @@ -102,7 +101,6 @@ pub struct ActuatePresetV131 { pub mod2_grain_crossfade: i32, // Osc module knob storage - pub mod2_osc_type: VoiceType, pub mod2_osc_octave: i32, pub mod2_osc_semitones: i32, pub mod2_osc_detune: f32, @@ -137,7 +135,6 @@ pub struct ActuatePresetV131 { pub mod3_grain_crossfade: i32, // Osc module knob storage - pub mod3_osc_type: VoiceType, pub mod3_osc_octave: i32, pub mod3_osc_semitones: i32, pub mod3_osc_detune: f32, diff --git a/src/audio_module.rs b/src/audio_module.rs index 2bc9a80..4d20631 100644 --- a/src/audio_module.rs +++ b/src/audio_module.rs @@ -23,7 +23,7 @@ This is intended to be a generic implementation that can be extended for other a use egui_file::{FileDialog, State}; use nih_plug::{ - params::enums::Enum, prelude::{NoteEvent, ParamSetter, Smoother, SmoothingStyle}, util + prelude::{Enum, NoteEvent, ParamSetter, Smoother, SmoothingStyle}, util::{self, db_to_gain} }; use nih_plug_egui::egui::{self, Pos2, Rect, RichText, Rounding, ScrollArea, Ui}; use pitch_shift::PitchShifter; @@ -38,20 +38,35 @@ pub(crate) mod frequency_modulation; pub(crate) mod AdditiveModule; use self::Oscillator::{DeterministicWhiteNoiseGenerator, OscState, RetriggerStyle, SmoothStyle}; use crate::{ - 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, WIDTH, YELLOW_MUSTARD + actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, StereoAlgorithm}, adv_scale_value, + fx::{A4I_Filter::A4iFilter, ArduraFilter::{ArduraFilter, ResponseType}, + StateVariableFilter::{ResonanceType, StateVariableFilter}, + V4Filter::V4FilterStruct, + VCFilter::{ResponseType as VCFResponseType, VCFilter}}, ActuateParams, CustomWidgets::{ui_knob::{self, KnobLayout}, CustomVerticalSlider}, PitchRouting, DARK_GREY_UI_COLOR, FONT_COLOR, LIGHTER_GREY_UI_COLOR, MEDIUM_GREY_UI_COLOR, SMALLER_FONT, WIDTH, YELLOW_MUSTARD }; use crate::{CustomWidgets::{BeizerButton::{self, ButtonLayout}, BoolButton}, DARKER_GREY_UI_COLOR}; use CustomVerticalSlider::ParamSlider as VerticalParamSlider; -use Oscillator::VoiceType; // When you create a new audio module, you should add it here #[derive(Debug, Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] pub enum AudioModuleType { Off, - Osc, Sampler, Granulizer, Additive, + Sine, // These Osc values are added as of the generator dropdown menu stuff + Tri, + Saw, + RSaw, + WSaw, + SSaw, + RASaw, + Ramp, + Square, + RSquare, + Pulse, + Noise, + UnsetAm, } #[derive(Clone)] @@ -65,6 +80,9 @@ struct VoiceVec { // into any threading issues trying to modify different vecs in the same function rather than 1 struct // Underscores are to get rid of the compiler warning thinking it's not used but it's stored for debugging or passed between structs // and still functional. + +// Allow dead code is for rust-analyzer getting false issues on things that are actually used +#[allow(dead_code)] #[derive(Clone)] pub struct SingleVoice { /// The note's key/note, in `0..128`. Only used for the voice terminated event. @@ -108,7 +126,119 @@ pub struct SingleVoice { _decay_time: f32, _release_time: f32, _retrigger: RetriggerStyle, - _voice_type: Oscillator::VoiceType, + _voice_type: AudioModuleType, + + // This is only used for unison detunes + _angle: f32, + + // Sampler/Granulizer Pos + sample_pos: usize, + loop_it: bool, + grain_start_pos: usize, + _granular_hold: i32, + _granular_gap: i32, + granular_hold_end: usize, + next_grain_pos: usize, + _end_position: usize, + _granular_crossfade: i32, + grain_attack: Smoother, + grain_release: Smoother, + grain_state: GrainState, + + // Additive + harmonic_phases: Vec, + + //// Polyfilter update!! + /////////////////////////////////////////////////////// + filter_l_1: StateVariableFilter, + filter_r_1: StateVariableFilter, + // TILT Filters + tilt_filter_l_1: ArduraFilter, + tilt_filter_r_1: ArduraFilter, + // VCF Filters + vcf_filter_l_1: VCFilter, + vcf_filter_r_1: VCFilter, + // Filter state variables + filter_state_1: OscState, + filter_atk_smoother_1: Smoother, + filter_dec_smoother_1: Smoother, + filter_rel_smoother_1: Smoother, + // SVF Filters + filter_l_2: StateVariableFilter, + filter_r_2: StateVariableFilter, + // TILT Filters + tilt_filter_l_2: ArduraFilter, + tilt_filter_r_2: ArduraFilter, + // VCF Filters + vcf_filter_l_2:VCFilter, + vcf_filter_r_2:VCFilter, + // Filter state variables + filter_state_2: OscState, + filter_atk_smoother_2: Smoother, + filter_dec_smoother_2: Smoother, + filter_rel_smoother_2: Smoother, + // V4 Filter + V4F_l_1: V4FilterStruct, + V4F_l_2: V4FilterStruct, + V4F_r_1: V4FilterStruct, + V4F_r_2: V4FilterStruct, + // A4I Filter + A4I_l_1: A4iFilter, + A4I_l_2: A4iFilter, + A4I_r_1: A4iFilter, + A4I_r_2: A4iFilter, + + cutoff_modulation: f32, + resonance_modulation: f32, + cutoff_modulation_2: f32, + resonance_modulation_2: f32, + + internal_unison_voices: Vec, +} + +// Allow dead code is for rust-analyzer getting false issues on things that are actually used +#[allow(dead_code)] +#[derive(Clone)] +pub struct SingleUnisonVoice { + /// The note's key/note, in `0..128`. Only used for the voice terminated event. + note: u8, + /// Velocity of our note + _velocity: f32, + /// Mod amount for velocity inputted to this AM + vel_mod_amount: f32, + /// The voice's current phase. + phase: f32, + /// The phase increment. This is based on the voice's frequency, derived from the note index. + phase_delta: f32, + /// Oscillator state for amplitude controlling + state: Oscillator::OscState, + // These are the attack and release smoothers + amp_current: f32, + osc_attack: Smoother, + osc_decay: Smoother, + osc_release: Smoother, + // Pitch modulation info + pitch_enabled: bool, + pitch_current: f32, + pitch_state: Oscillator::OscState, + pitch_attack: Smoother, + pitch_decay: Smoother, + pitch_release: Smoother, + // Pitch modulation info 2 + pitch_enabled_2: bool, + pitch_current_2: f32, + pitch_state_2: Oscillator::OscState, + pitch_attack_2: Smoother, + pitch_decay_2: Smoother, + pitch_release_2: Smoother, + // Final info for a note to work + _detune: f32, + _unison_detune_value: f32, + _attack_time: f32, + _decay_time: f32, + _release_time: f32, + _retrigger: RetriggerStyle, + _voice_type: AudioModuleType, // This is only used for unison detunes _angle: f32, @@ -129,6 +259,11 @@ pub struct SingleVoice { // Additive harmonic_phases: Vec, + + cutoff_modulation: f32, + resonance_modulation: f32, + cutoff_modulation_2: f32, + resonance_modulation_2: f32, } #[derive(Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] @@ -177,7 +312,6 @@ pub struct AudioModule { // Stored params from main lib here on a per-module basis // Osc module knob storage - pub osc_type: VoiceType, pub osc_octave: i32, pub osc_semitones: i32, pub osc_detune: f32, @@ -263,6 +397,62 @@ pub struct AudioModule { pub prev_ah13: f32, pub prev_ah14: f32, pub prev_ah15: f32, + + /// Polyfilter!!! + /// These are intermediate values that get passed to the SingleVoice + ///////////////////////////////////////////////////////////////////// + pub audio_module_routing: AMFilterRouting, + pub filter_routing: FilterRouting, + + pub filter_env_peak: f32, + pub filter_env_peak_2: f32, + pub filter_alg_type: FilterAlgorithms, + pub filter_alg_type_2: FilterAlgorithms, + + pub filter_cutoff: f32, + pub filter_cutoff_2: f32, + + pub filter_wet: f32, + pub filter_wet_2: 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: SmoothStyle, + pub filter_env_dec_curve: SmoothStyle, + pub filter_env_rel_curve: SmoothStyle, + pub filter_atk_smoother_1: Smoother, + pub filter_dec_smoother_1: Smoother, + pub filter_rel_smoother_1: Smoother, + + 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: SmoothStyle, + pub filter_env_dec_curve_2: SmoothStyle, + pub filter_env_rel_curve_2: SmoothStyle, + pub filter_atk_smoother_2: Smoother, + pub filter_dec_smoother_2: Smoother, + pub filter_rel_smoother_2: Smoother, + + pub filter_resonance: f32, + pub filter_resonance_2: f32, + pub filter_res_type: ResonanceType, + pub filter_res_type_2: ResonanceType, + + pub lp_amount: f32, + pub bp_amount: f32, + pub hp_amount: f32, + pub lp_amount_2: f32, + pub bp_amount_2: f32, + pub hp_amount_2: f32, + + pub tilt_filter_type: ResponseType, + pub tilt_filter_type_2: ResponseType, + pub vcf_filter_type: VCFResponseType, + pub vcf_filter_type_2: VCFResponseType, } // When you create a new audio module you need to add its default creation here as well @@ -272,7 +462,7 @@ impl Default for AudioModule { Self { // Audio modules will use these sample_rate: 44100.0, - audio_module_type: AudioModuleType::Osc, + audio_module_type: AudioModuleType::Sine, two_voice_stereo_flipper: true, // Granulizer/Sampler @@ -289,13 +479,12 @@ impl Default for AudioModule { grain_crossfade: 50, // Osc module knob storage - osc_type: VoiceType::Sine, osc_octave: 0, osc_semitones: 0, osc_detune: 0.0, osc_attack: 0.0001, osc_decay: 0.0001, - osc_sustain: 999.9, + osc_sustain: 1999.9, osc_release: 0.07, osc_mod_amount: 0.0, osc_retrigger: RetriggerStyle::Free, @@ -376,6 +565,61 @@ impl Default for AudioModule { prev_ah13: 0.0, prev_ah14: 0.0, prev_ah15: 0.0, + + // Polyfilter!!! + ////////////////////// + audio_module_routing: AMFilterRouting::UNSETROUTING, + filter_routing: FilterRouting::Parallel, + filter_cutoff: 20000.0, + filter_cutoff_2: 20000.0, + + filter_env_peak: 0.0, + filter_env_peak_2: 0.0, + filter_alg_type: FilterAlgorithms::SVF, + filter_alg_type_2: FilterAlgorithms::SVF, + + filter_wet: 1.0, + filter_wet_2: 1.0, + + filter_env_attack: 30.0, + filter_env_decay: 0.0, + filter_env_sustain: 1999.9, + filter_env_release: 30.0, + filter_env_atk_curve: SmoothStyle::Linear, + filter_env_dec_curve: SmoothStyle::Linear, + filter_env_rel_curve: SmoothStyle::Linear, + filter_atk_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + + filter_env_attack_2: 30.0, + filter_env_decay_2: 0.0, + filter_env_sustain_2: 1999.9, + filter_env_release_2: 30.0, + filter_env_atk_curve_2: SmoothStyle::Linear, + filter_env_dec_curve_2: SmoothStyle::Linear, + filter_env_rel_curve_2: SmoothStyle::Linear, + filter_atk_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + + + filter_resonance: 0.0, + filter_resonance_2: 0.0, + filter_res_type: ResonanceType::Default, + filter_res_type_2: ResonanceType::Default, + + lp_amount: 1.0, + bp_amount: 0.0, + hp_amount: 0.0, + lp_amount_2: 1.0, + bp_amount_2: 0.0, + hp_amount_2: 0.0, + + tilt_filter_type: ResponseType::Lowpass, + tilt_filter_type_2: ResponseType::Lowpass, + vcf_filter_type: VCFResponseType::Lowpass, + vcf_filter_type_2: VCFResponseType::Lowpass, } } } @@ -570,12 +814,26 @@ impl AudioModule { const DISABLED_SPACE: f32 = 104.0; match am_type.value() { + AudioModuleType::UnsetAm => { + ui.label("UNSET - Err"); + } AudioModuleType::Off => { // Blank space ui.label("Disabled"); ui.add_space(DISABLED_SPACE); } - AudioModuleType::Osc => { + AudioModuleType::Sine | + AudioModuleType::Tri | + AudioModuleType::Saw | + AudioModuleType::RSaw | + AudioModuleType::WSaw | + AudioModuleType::SSaw | + AudioModuleType::RASaw | + AudioModuleType::Ramp | + AudioModuleType::Square | + AudioModuleType::RSquare | + AudioModuleType::Pulse | + AudioModuleType::Noise => { const KNOB_SIZE: f32 = 22.0; const TEXT_SIZE: f32 = 10.0; // Oscillator @@ -583,6 +841,20 @@ impl AudioModule { ui.add_space(1.0); ui.horizontal(|ui| { ui.vertical(|ui| { + /*let osc_1_type_knob = ui_knob::ArcKnob::for_param( + _osc_voice, + setter, + KNOB_SIZE, + KnobLayout::Horizonal, + ) + .preset_style(ui_knob::KnobStyle::Preset1) + .set_fill_color(DARK_GREY_UI_COLOR) + .set_line_color(YELLOW_MUSTARD) + .set_text_size(TEXT_SIZE) + .set_hover_text("Oscillator wave form type".to_string()); + ui.add(osc_1_type_knob); + */ + let osc_1_retrigger_knob = ui_knob::ArcKnob::for_param( osc_retrigger, setter, @@ -1715,11 +1987,10 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) // Index proper params from knobs // This lets us have a copy for voices, and also track changes like restretch changing or ADR slopes - pub fn consume_params(&mut self, params: Arc, voice_index: usize) { + pub fn consume_params(&mut self, params: Arc, voice_index: usize) -> AudioModuleType { match voice_index { 1 => { self.audio_module_type = params.audio_module_1_type.value(); - self.osc_type = params.osc_1_type.value(); if self.osc_octave != params.osc_1_octave.value() { let oct_shift = self.osc_octave - params.osc_1_octave.value(); for voice in self.playing_voices.voices.iter_mut() { @@ -1814,10 +2085,68 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) self.ah13 = params.additive_amp_1_13.value(); self.ah14 = params.additive_amp_1_14.value(); self.ah15 = params.additive_amp_1_15.value(); + self.filter_routing = params.filter_routing.value(); + self.audio_module_routing = params.audio_module_1_routing.value(); + self.filter_cutoff = params.filter_cutoff.value(); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_wet = params.filter_wet.value(); + self.filter_wet_2 = params.filter_wet_2.value(); + self.filter_env_attack = params.filter_env_attack.value(); + self.filter_env_decay = params.filter_env_decay.value(); + self.filter_env_sustain = params.filter_env_sustain.value(); + self.filter_env_release = params.filter_env_release.value(); + self.filter_env_atk_curve = params.filter_env_atk_curve.value(); + self.filter_env_dec_curve = params.filter_env_dec_curve.value(); + self.filter_env_rel_curve = params.filter_env_rel_curve.value(); + // Intentionally only initializing attack since the other ones get initialized when we get there + self.filter_atk_smoother_1 = match self.filter_env_atk_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_attack, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_attack, + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_attack, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_attack, + )), + }; + self.filter_dec_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_env_attack_2 = params.filter_env_attack_2.value(); + self.filter_env_decay_2 = params.filter_env_decay_2.value(); + self.filter_env_sustain_2 = params.filter_env_sustain_2.value(); + self.filter_env_release_2 = params.filter_env_release_2.value(); + self.filter_env_atk_curve_2 = params.filter_env_atk_curve_2.value(); + self.filter_env_dec_curve_2 = params.filter_env_dec_curve_2.value(); + self.filter_env_rel_curve_2 = params.filter_env_rel_curve_2.value(); + self.filter_atk_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_dec_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_alg_type = params.filter_alg_type.value(); + self.filter_alg_type_2 = params.filter_alg_type_2.value(); + self.filter_env_peak = params.filter_env_peak.value(); + self.filter_env_peak_2 = params.filter_env_peak_2.value(); + self.filter_resonance = params.filter_resonance.value(); + self.filter_resonance_2 = params.filter_resonance_2.value(); + self.filter_res_type = params.filter_res_type.value(); + self.filter_res_type_2 = params.filter_res_type_2.value(); + self.lp_amount = params.filter_lp_amount.value(); + self.bp_amount = params.filter_bp_amount.value(); + self.hp_amount = params.filter_hp_amount.value(); + self.lp_amount_2 = params.filter_lp_amount_2.value(); + self.bp_amount_2 = params.filter_bp_amount_2.value(); + self.hp_amount_2 = params.filter_hp_amount_2.value(); + self.tilt_filter_type = params.tilt_filter_type.value(); + self.tilt_filter_type_2 = params.tilt_filter_type_2.value(); + self.vcf_filter_type = params.vcf_filter_type.value(); + self.vcf_filter_type_2 = params.vcf_filter_type_2.value(); } 2 => { self.audio_module_type = params.audio_module_2_type.value(); - self.osc_type = params.osc_2_type.value(); if self.osc_octave != params.osc_2_octave.value() { let oct_shift = self.osc_octave - params.osc_2_octave.value(); for voice in self.playing_voices.voices.iter_mut() { @@ -1912,10 +2241,64 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) self.ah13 = params.additive_amp_2_13.value(); self.ah14 = params.additive_amp_2_14.value(); self.ah15 = params.additive_amp_2_15.value(); + self.filter_routing = params.filter_routing.value(); + self.audio_module_routing = params.audio_module_2_routing.value(); + self.filter_cutoff = params.filter_cutoff.value(); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_wet = params.filter_wet.value(); + self.filter_wet_2 = params.filter_wet_2.value(); + self.filter_env_attack = params.filter_env_attack.value(); + self.filter_env_decay = params.filter_env_decay.value(); + self.filter_env_sustain = params.filter_env_sustain.value(); + self.filter_env_release = params.filter_env_release.value(); + self.filter_env_atk_curve = params.filter_env_atk_curve.value(); + self.filter_env_dec_curve = params.filter_env_dec_curve.value(); + self.filter_env_rel_curve = params.filter_env_rel_curve.value(); + // Intentionally only initializing attack since the other ones get initialized when we get there + self.filter_atk_smoother_1 = match self.filter_env_atk_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_attack, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_attack, + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_attack, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_attack, + )), + }; + self.filter_dec_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_env_attack_2 = params.filter_env_attack_2.value(); + self.filter_env_decay_2 = params.filter_env_decay_2.value(); + self.filter_env_sustain_2 = params.filter_env_sustain_2.value(); + self.filter_env_release_2 = params.filter_env_release_2.value(); + self.filter_env_atk_curve_2 = params.filter_env_atk_curve_2.value(); + self.filter_env_dec_curve_2 = params.filter_env_dec_curve_2.value(); + self.filter_env_rel_curve_2 = params.filter_env_rel_curve_2.value(); + self.filter_atk_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_dec_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_alg_type = params.filter_alg_type.value(); + self.filter_alg_type_2 = params.filter_alg_type_2.value(); + self.filter_env_peak = params.filter_env_peak.value(); + self.filter_env_peak_2 = params.filter_env_peak_2.value(); + self.lp_amount = params.filter_lp_amount.value(); + self.bp_amount = params.filter_bp_amount.value(); + self.hp_amount = params.filter_hp_amount.value(); + self.lp_amount_2 = params.filter_lp_amount_2.value(); + self.bp_amount_2 = params.filter_bp_amount_2.value(); + self.hp_amount_2 = params.filter_hp_amount_2.value(); + self.tilt_filter_type = params.tilt_filter_type.value(); + self.tilt_filter_type_2 = params.tilt_filter_type_2.value(); + self.vcf_filter_type = params.vcf_filter_type.value(); + self.vcf_filter_type_2 = params.vcf_filter_type_2.value(); } 3 => { self.audio_module_type = params.audio_module_3_type.value(); - self.osc_type = params.osc_3_type.value(); if self.osc_octave != params.osc_3_octave.value() { let oct_shift = self.osc_octave - params.osc_3_octave.value(); for voice in self.playing_voices.voices.iter_mut() { @@ -2010,9 +2393,65 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) self.ah13 = params.additive_amp_3_13.value(); self.ah14 = params.additive_amp_3_14.value(); self.ah15 = params.additive_amp_3_15.value(); + self.filter_routing = params.filter_routing.value(); + self.audio_module_routing = params.audio_module_3_routing.value(); + self.filter_cutoff = params.filter_cutoff.value(); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_wet = params.filter_wet.value(); + self.filter_wet_2 = params.filter_wet_2.value(); + self.filter_env_attack = params.filter_env_attack.value(); + self.filter_env_decay = params.filter_env_decay.value(); + self.filter_env_sustain = params.filter_env_sustain.value(); + self.filter_env_release = params.filter_env_release.value(); + self.filter_env_atk_curve = params.filter_env_atk_curve.value(); + self.filter_env_dec_curve = params.filter_env_dec_curve.value(); + self.filter_env_rel_curve = params.filter_env_rel_curve.value(); + // Intentionally only initializing attack since the other ones get initialized when we get there + self.filter_atk_smoother_1 = match self.filter_env_atk_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_attack, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_attack, + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_attack, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_attack, + )), + }; + self.filter_dec_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_1 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_cutoff_2 = params.filter_cutoff_2.value(); + self.filter_env_attack_2 = params.filter_env_attack_2.value(); + self.filter_env_decay_2 = params.filter_env_decay_2.value(); + self.filter_env_sustain_2 = params.filter_env_sustain_2.value(); + self.filter_env_release_2 = params.filter_env_release_2.value(); + self.filter_env_atk_curve_2 = params.filter_env_atk_curve_2.value(); + self.filter_env_dec_curve_2 = params.filter_env_dec_curve_2.value(); + self.filter_env_rel_curve_2 = params.filter_env_rel_curve_2.value(); + self.filter_atk_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_dec_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_rel_smoother_2 = Smoother::new(SmoothingStyle::Linear(300.0)); + self.filter_alg_type = params.filter_alg_type.value(); + self.filter_alg_type_2 = params.filter_alg_type_2.value(); + self.filter_env_peak = params.filter_env_peak.value(); + self.filter_env_peak_2 = params.filter_env_peak_2.value(); + self.lp_amount = params.filter_lp_amount.value(); + self.bp_amount = params.filter_bp_amount.value(); + self.hp_amount = params.filter_hp_amount.value(); + self.lp_amount_2 = params.filter_lp_amount_2.value(); + self.bp_amount_2 = params.filter_bp_amount_2.value(); + self.hp_amount_2 = params.filter_hp_amount_2.value(); + self.tilt_filter_type = params.tilt_filter_type.value(); + self.tilt_filter_type_2 = params.tilt_filter_type_2.value(); + self.vcf_filter_type = params.vcf_filter_type.value(); + self.vcf_filter_type_2 = params.vcf_filter_type_2.value(); } _ => {} } + self.audio_module_type } // I was looking at the PolyModSynth Example and decided on this @@ -2031,6 +2470,10 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) vel_gain_mod: f32, vel_lfo_gain_mod: f32, stereo_algorithm: StereoAlgorithm, + resonance_mod: f32, + cutoff_mod: f32, + resonance_mod_2: f32, + cutoff_mod_2: f32, ) -> (f32, f32, bool, bool) { // If the process is in here the file dialog is not open per lib.rs @@ -2068,7 +2511,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_attack.clamp(0.0001, 999.9), + self.pitch_env_attack.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => Smoother::new( @@ -2076,7 +2519,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) ), SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_attack.clamp(0.0001, 999.9) + self.pitch_env_attack.clamp(0.0001, 1999.9) )) } }; @@ -2087,7 +2530,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_decay.clamp(0.0001, 999.9), + self.pitch_env_decay.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => { @@ -2095,7 +2538,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_decay.clamp(0.0001, 999.9) + self.pitch_env_decay.clamp(0.0001, 1999.9) )) } }; @@ -2106,7 +2549,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_release.clamp(0.0001, 999.9), + self.pitch_env_release.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => Smoother::new( @@ -2114,7 +2557,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) ), SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_release.clamp(0.0001, 999.9) + self.pitch_env_release.clamp(0.0001, 1999.9) )) } }; @@ -2149,7 +2592,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_attack_2.clamp(0.0001, 999.9), + self.pitch_env_attack_2.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => Smoother::new( @@ -2157,7 +2600,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) ), SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_attack_2.clamp(0.0001, 999.9) + self.pitch_env_attack_2.clamp(0.0001, 1999.9) )) } }; @@ -2168,7 +2611,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_decay_2.clamp(0.0001, 999.9), + self.pitch_env_decay_2.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => Smoother::new( @@ -2176,7 +2619,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) ), SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_decay_2.clamp(0.0001, 999.9) + self.pitch_env_decay_2.clamp(0.0001, 1999.9) )) } }; @@ -2187,14 +2630,14 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } SmoothStyle::Logarithmic => { Smoother::new(SmoothingStyle::Logarithmic( - self.pitch_env_release_2.clamp(0.0001, 999.9), + self.pitch_env_release_2.clamp(0.0001, 1999.9), )) } SmoothStyle::Exponential => Smoother::new( SmoothingStyle::Exponential(self.pitch_env_release_2), ), SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.pitch_env_release_2.clamp(0.0001, 999.9), + self.pitch_env_release_2.clamp(0.0001, 1999.9), )), }; @@ -2272,13 +2715,6 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } RetriggerStyle::Random | RetriggerStyle::UniRandom => { match self.audio_module_type { - AudioModuleType::Osc | AudioModuleType::Additive => { - // Get a random phase to use - // Poly solution is to pass the phase to the struct - // instead of the osc alone - let mut rng = rand::thread_rng(); - new_phase = rng.gen_range(0.0..1.0); - } AudioModuleType::Sampler => { let mut rng = rand::thread_rng(); // Prevent panic when no sample loaded yet @@ -2292,7 +2728,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) new_phase = 0.0; } } - } + }, AudioModuleType::Granulizer => { let mut rng = rand::thread_rng(); // Prevent panic when no sample loaded yet @@ -2306,8 +2742,14 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) new_phase = 0.0; } } + }, + _ => { + // Get a random phase to use + // Poly solution is to pass the phase to the struct + // instead of the osc alone + let mut rng = rand::thread_rng(); + new_phase = rng.gen_range(0.0..1.0); } - _ => {} } } RetriggerStyle::Free => { @@ -2356,14 +2798,14 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) Smoother::new(SmoothingStyle::Linear(self.osc_attack)) } SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.osc_attack.clamp(0.0001, 999.9), + self.osc_attack.clamp(0.0001, 1999.9), )), SmoothStyle::Exponential => { Smoother::new(SmoothingStyle::Exponential(self.osc_attack)) } SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.osc_attack.clamp(0.0001, 999.9) + self.osc_attack.clamp(0.0001, 1999.9) )) } }; @@ -2373,14 +2815,14 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) Smoother::new(SmoothingStyle::Linear(self.osc_decay)) } SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.osc_decay.clamp(0.0001, 999.9), + self.osc_decay.clamp(0.0001, 1999.9), )), SmoothStyle::Exponential => { Smoother::new(SmoothingStyle::Exponential(self.osc_decay)) } SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.osc_decay.clamp(0.0001, 999.9) + self.osc_decay.clamp(0.0001, 1999.9) )) } }; @@ -2390,14 +2832,14 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) Smoother::new(SmoothingStyle::Linear(self.osc_release)) } SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.osc_release.clamp(0.0001, 999.9), + self.osc_release.clamp(0.0001, 1999.9), )), SmoothStyle::Exponential => { Smoother::new(SmoothingStyle::Exponential(self.osc_release)) } SmoothStyle::LogSteep => { Smoother::new(SmoothingStyle::LogSteep( - self.osc_release.clamp(0.0001, 999.9) + self.osc_release.clamp(0.0001, 1999.9) )) } }; @@ -2406,7 +2848,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) SmoothingStyle::Logarithmic(_) | SmoothingStyle::LogSteep(_) => { attack_smoother.reset(0.0001); attack_smoother - .set_target(self.sample_rate, velocity.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, velocity.clamp(0.0001, 1999.9)); } _ => { attack_smoother.reset(0.0); @@ -2473,7 +2915,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } // Osc Updates - let new_voice: SingleVoice = SingleVoice { + let mut new_voice: SingleVoice = SingleVoice { note: note, _velocity: velocity, vel_mod_amount: velocity_mod, @@ -2508,7 +2950,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _decay_time: self.osc_decay, _release_time: self.osc_release, _retrigger: self.osc_retrigger, - _voice_type: self.osc_type, + _voice_type: self.audio_module_type, _angle: 0.0, sample_pos: scaled_sample_pos, loop_it: self.loop_wavetable, @@ -2549,22 +2991,194 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) vector.push(0.0); vector }, + //// Polyfilter update!! + /////////////////////////////////////////////////////// + filter_l_1: StateVariableFilter::default().set_oversample(4), + filter_r_1: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_1: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_1: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_1: VCFilter::new(), + vcf_filter_r_1: VCFilter::new(), + // Filter state variables + filter_state_1: OscState::Attacking, + filter_atk_smoother_1: match self.filter_env_atk_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_attack, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_attack.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_attack, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_attack.clamp(0.0001, 1999.9), + )), + }, + filter_dec_smoother_1: match self.filter_env_dec_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_decay, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_decay.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_decay, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_decay.clamp(0.0001, 1999.9), + )), + }, + filter_rel_smoother_1: match self.filter_env_rel_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_release, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_release.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_release, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_release.clamp(0.0001, 1999.9), + )), + }, + // SVF Filters + filter_l_2: StateVariableFilter::default().set_oversample(4), + filter_r_2: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_2: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff_2, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_2: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff_2, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_2: VCFilter::new(), + vcf_filter_r_2: VCFilter::new(), + // Filter state variables + filter_state_2: OscState::Attacking, + filter_atk_smoother_2: match self.filter_env_atk_curve_2 { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_attack_2, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_attack_2.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_attack_2, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_attack_2.clamp(0.0001, 1999.9), + )), + }, + filter_dec_smoother_2: match self.filter_env_dec_curve_2 { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_decay_2, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_decay_2.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_decay_2, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_decay_2.clamp(0.0001, 1999.9), + )), + }, + filter_rel_smoother_2: match self.filter_env_rel_curve_2 { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_release_2, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_release_2.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_release_2, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_release_2.clamp(0.0001, 1999.9), + )), + }, + // V4 Filter + V4F_l_1: V4FilterStruct::default(), + V4F_l_2: V4FilterStruct::default(), + V4F_r_1: V4FilterStruct::default(), + V4F_r_2: V4FilterStruct::default(), + // A4I Filter + A4I_l_1: A4iFilter::new(self.filter_cutoff, self.filter_cutoff, self.filter_resonance), + A4I_l_2: A4iFilter::new(self.filter_cutoff_2, self.filter_cutoff_2, self.filter_resonance_2), + A4I_r_1: A4iFilter::new(self.filter_cutoff, self.filter_cutoff, self.filter_resonance), + A4I_r_2: A4iFilter::new(self.filter_cutoff_2, self.filter_cutoff_2, self.filter_resonance_2), + + cutoff_modulation: cutoff_mod, + cutoff_modulation_2: cutoff_mod_2, + resonance_modulation: 0.0, + resonance_modulation_2: 0.0, + + internal_unison_voices: Vec::new(), }; - // Add our voice struct to our voice tracking deque - self.playing_voices.voices.push_back(new_voice); + // POLYFILTER FILTER ATTACK UPDATES + // Reset our attack to start from the filter cutoff + new_voice.filter_atk_smoother_1.reset(self.filter_cutoff); + // Since we're in attack state at the start of our note we need to setup the attack going to the env peak + new_voice.filter_atk_smoother_1.set_target( + self.sample_rate, + (self.filter_cutoff + + ( + // This scales the peak env to be much gentler for the TILT filter + match self.filter_alg_type { + FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.filter_env_peak, + FilterAlgorithms::TILT => adv_scale_value( + self.filter_env_peak, + -19980.0, + 19980.0, + -5000.0, + 5000.0, + ), + } + )) + .clamp(20.0, 20000.0), + ); // Add unison voices to our voice tracking deque - if self.osc_unison > 1 && ( self.audio_module_type == AudioModuleType::Osc || self.audio_module_type == AudioModuleType::Sampler - || self.audio_module_type == AudioModuleType::Additive ) { + if self.osc_unison > 1 && ( + self.audio_module_type != AudioModuleType::Granulizer && + self.audio_module_type != AudioModuleType::UnsetAm) { + let unison_even_voices = if self.osc_unison % 2 == 0 { self.osc_unison } else { self.osc_unison - 1 }; + 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, stereo_algorithm); + // Fix our weird voice switching that "Actuate" just has + //if i%2 == 0 { + // voice_angle *= -1.0; + //} unison_angles[(i - 1) as usize] = voice_angle; } @@ -2572,7 +3186,19 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) let uni_phase = match self.osc_retrigger { RetriggerStyle::UniRandom => { match self.audio_module_type { - AudioModuleType::Osc | AudioModuleType::Additive => { + AudioModuleType::Additive | + AudioModuleType::Sine | + AudioModuleType::Tri | + AudioModuleType::Saw | + AudioModuleType::RSaw | + AudioModuleType::WSaw | + AudioModuleType::SSaw | + AudioModuleType::RASaw | + AudioModuleType::Ramp | + AudioModuleType::Square | + AudioModuleType::RSquare | + AudioModuleType::Pulse | + AudioModuleType::Noise => { let mut rng = rand::thread_rng(); rng.gen_range(0.0..1.0) }, @@ -2592,7 +3218,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) 0.0 } }, - AudioModuleType::Off => { + AudioModuleType::Off | AudioModuleType::UnsetAm => { 0.0 }, } @@ -2601,7 +3227,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _ => new_phase, }; - let new_unison_voice: SingleVoice = SingleVoice { + let new_unison_voice: SingleUnisonVoice = SingleUnisonVoice { note: note, _velocity: velocity, vel_mod_amount: uni_velocity_mod, @@ -2614,14 +3240,12 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) osc_decay: decay_smoother.clone(), osc_release: release_smoother.clone(), pitch_enabled: self.pitch_enable, - pitch_env_peak: self.pitch_env_peak, pitch_current: pitch_mod_current, pitch_state: OscState::Attacking, pitch_attack: pitch_attack_smoother.clone(), pitch_decay: pitch_decay_smoother.clone(), pitch_release: pitch_release_smoother.clone(), pitch_enabled_2: self.pitch_enable_2, - pitch_env_peak_2: self.pitch_env_peak_2, pitch_current_2: pitch_mod_current_2, pitch_state_2: OscState::Attacking, pitch_attack_2: pitch_attack_smoother_2.clone(), @@ -2630,22 +3254,34 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _detune: self.osc_detune, _unison_detune_value: self.osc_unison_detune, //frequency: unison_notes[unison_voice], - frequency: 0.0, + //frequency: 0.0, //frequency: detuned_note, _attack_time: self.osc_attack, _decay_time: self.osc_decay, _release_time: self.osc_release, _retrigger: self.osc_retrigger, - _voice_type: self.osc_type, + _voice_type: self.audio_module_type, _angle: unison_angles[unison_voice], sample_pos: match self.audio_module_type { - AudioModuleType::Osc | AudioModuleType::Additive => { + AudioModuleType::Additive | + AudioModuleType::Sine | + AudioModuleType::Tri | + AudioModuleType::Saw | + AudioModuleType::RSaw | + AudioModuleType::WSaw | + AudioModuleType::SSaw | + AudioModuleType::RASaw | + AudioModuleType::Ramp | + AudioModuleType::Square | + AudioModuleType::RSquare | + AudioModuleType::Pulse | + AudioModuleType::Noise => { 0 }, AudioModuleType::Granulizer | AudioModuleType::Sampler => { uni_phase as usize }, - AudioModuleType::Off => { + AudioModuleType::Off | AudioModuleType::UnsetAm => { 0 }, }, @@ -2681,12 +3317,19 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) vector.push(0.0); vector }, + cutoff_modulation: cutoff_mod, + cutoff_modulation_2: cutoff_mod_2, + resonance_modulation: 0.0, + resonance_modulation_2: 0.0, }; - self.unison_voices.voices.push_back(new_unison_voice); + new_voice.internal_unison_voices.push(new_unison_voice); } } + // Add our voice struct to our voice tracking deque + self.playing_voices.voices.push_back(new_voice); + // Remove the last voice when > voice_max if self.playing_voices.voices.len() > voice_max { self.playing_voices.voices.resize( @@ -2724,7 +3367,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _decay_time: self.osc_decay, _release_time: self.osc_release, _retrigger: self.osc_retrigger, - _voice_type: self.osc_type, + _voice_type: self.audio_module_type, _angle: 0.0, sample_pos: 0, loop_it: self.loop_wavetable, @@ -2739,78 +3382,99 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) grain_release: Smoother::new(SmoothingStyle::Linear(5.0)), grain_state: GrainState::Attacking, // Additive - harmonic_phases: Vec::new(), + harmonic_phases: { + let mut vector: Vec = Vec::with_capacity(16); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector + }, + //// Polyfilter update!! + /////////////////////////////////////////////////////// + filter_l_1: StateVariableFilter::default().set_oversample(4), + filter_r_1: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_1: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_1: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_1: VCFilter::new(), + vcf_filter_r_1: VCFilter::new(), + // Filter state variables + filter_state_1: OscState::Attacking, + filter_atk_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + // SVF Filters + filter_l_2: StateVariableFilter::default().set_oversample(4), + filter_r_2: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_2: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_2: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_2: VCFilter::new(), + vcf_filter_r_2: VCFilter::new(), + // Filter state variables + filter_state_2: OscState::Attacking, + filter_atk_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + // V4 Filter + V4F_l_1: V4FilterStruct::default(), + V4F_l_2: V4FilterStruct::default(), + V4F_r_1: V4FilterStruct::default(), + V4F_r_2: V4FilterStruct::default(), + // A4I Filter + A4I_l_1: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_l_2: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_r_1: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_r_2: A4iFilter::new(44100.0, 20000.0, 0.0), + cutoff_modulation: cutoff_mod, + cutoff_modulation_2: cutoff_mod_2, + resonance_modulation: 0.0, + resonance_modulation_2: 0.0, + + internal_unison_voices: Vec::new(), }, ); - - if self.osc_unison > 1 && ( self.audio_module_type == AudioModuleType::Osc || self.audio_module_type == AudioModuleType::Sampler ) - { - self.unison_voices.voices.resize( - voice_max as usize, - // Insert a dummy "Off" entry when resizing UP - SingleVoice { - note: 0, - _velocity: 0.0, - vel_mod_amount: 0.0, - phase: new_phase, - phase_delta: 0.0, - state: OscState::Off, - amp_current: 0.0, - osc_attack: Smoother::new(SmoothingStyle::None), - osc_decay: Smoother::new(SmoothingStyle::None), - osc_release: Smoother::new(SmoothingStyle::None), - pitch_enabled: self.pitch_enable, - pitch_env_peak: 0.0, - pitch_current: 0.0, - pitch_state: OscState::Off, - pitch_attack: Smoother::new(SmoothingStyle::None), - pitch_decay: Smoother::new(SmoothingStyle::None), - pitch_release: Smoother::new(SmoothingStyle::None), - pitch_enabled_2: self.pitch_enable_2, - pitch_env_peak_2: 0.0, - pitch_current_2: 0.0, - pitch_state_2: OscState::Off, - pitch_attack_2: Smoother::new(SmoothingStyle::None), - pitch_decay_2: Smoother::new(SmoothingStyle::None), - pitch_release_2: Smoother::new(SmoothingStyle::None), - _detune: 0.0, - _unison_detune_value: 0.0, - frequency: 0.0, - _attack_time: self.osc_attack, - _decay_time: self.osc_decay, - _release_time: self.osc_release, - _retrigger: self.osc_retrigger, - _voice_type: self.osc_type, - _angle: 0.0, - sample_pos: 0, - grain_start_pos: 0, - loop_it: self.loop_wavetable, - _granular_gap: 200, - _granular_hold: 200, - granular_hold_end: 200, - next_grain_pos: 400, - _end_position: scaled_end_pos, - _granular_crossfade: 50, - grain_attack: Smoother::new(SmoothingStyle::Linear(5.0)), - grain_release: Smoother::new(SmoothingStyle::Linear(5.0)), - grain_state: GrainState::Attacking, - // Additive - harmonic_phases: Vec::new(), - }, - ); - } } - // Remove any off notes self.playing_voices.voices.retain(|voice| { voice.state != OscState::Off && !(voice.grain_state == GrainState::Releasing && voice.grain_release.steps_left() == 0) }); - if self.audio_module_type == AudioModuleType::Osc || self.audio_module_type == AudioModuleType::Sampler { - self.unison_voices.voices.retain(|unison_voice| { - unison_voice.state != OscState::Off - }); - } } //////////////////////////////////////////////////////////// // MIDI EVENT NOTE OFF @@ -2841,7 +3505,21 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _ => shifted_note + semi_shift, }; - if self.audio_module_type == AudioModuleType::Osc || self.audio_module_type == AudioModuleType::Sampler || self.audio_module_type == AudioModuleType::Additive { + /* + if self.audio_module_type == AudioModuleType::Sine || + self.audio_module_type == AudioModuleType::Tri || + self.audio_module_type == AudioModuleType::Saw || + self.audio_module_type == AudioModuleType::RSaw || + self.audio_module_type == AudioModuleType::WSaw || + self.audio_module_type == AudioModuleType::SSaw || + self.audio_module_type == AudioModuleType::RASaw || + self.audio_module_type == AudioModuleType::Ramp || + self.audio_module_type == AudioModuleType::Square || + self.audio_module_type == AudioModuleType::RSquare || + self.audio_module_type == AudioModuleType::Pulse || + self.audio_module_type == AudioModuleType::Noise || + self.audio_module_type == AudioModuleType::Sampler || + self.audio_module_type == AudioModuleType::Additive { // Update the matching unison voices for unison_voice in self.unison_voices.voices.iter_mut() { if unison_voice.note == shifted_note @@ -2870,6 +3548,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } } } + */ // Iterate through our voice vecdeque to find the one to update for voice in self.playing_voices.voices.iter_mut() { @@ -2893,6 +3572,20 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) // Update our base voice state to releasing voice.state = OscState::Releasing; + for internal_unison_voice in voice.internal_unison_voices.iter_mut() { + internal_unison_voice.osc_release.reset(internal_unison_voice.amp_current); + match internal_unison_voice.osc_release.style { + SmoothingStyle::Logarithmic(_) + | SmoothingStyle::LogSteep(_) => { + internal_unison_voice.osc_release.set_target(self.sample_rate, 0.0001); + } + _ => { + internal_unison_voice.osc_release.set_target(self.sample_rate, 0.0); + } + } + internal_unison_voice.amp_current = internal_unison_voice.osc_release.next(); + internal_unison_voice.state = OscState::Releasing; + } } } } @@ -2944,7 +3637,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) _decay_time: self.osc_decay, _release_time: self.osc_release, _retrigger: self.osc_retrigger, - _voice_type: self.osc_type, + _voice_type: self.audio_module_type, _angle: 0.0, sample_pos: 0, loop_it: self.loop_wavetable, @@ -2959,7 +3652,91 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) grain_release: Smoother::new(SmoothingStyle::Linear(5.0)), grain_state: GrainState::Attacking, // Additive - harmonic_phases: Vec::new(), + harmonic_phases: { + let mut vector: Vec = Vec::with_capacity(16); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector + }, + //// Polyfilter update!! + /////////////////////////////////////////////////////// + filter_l_1: StateVariableFilter::default().set_oversample(4), + filter_r_1: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_1: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_1: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_1: VCFilter::new(), + vcf_filter_r_1: VCFilter::new(), + // Filter state variables + filter_state_1: OscState::Attacking, + filter_atk_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + // SVF Filters + filter_l_2: StateVariableFilter::default().set_oversample(4), + filter_r_2: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_2: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_2: ArduraFilter::new( + 44100.0, + 20000.0, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_2: VCFilter::new(), + vcf_filter_r_2: VCFilter::new(), + // Filter state variables + filter_state_2: OscState::Attacking, + filter_atk_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + // V4 Filter + V4F_l_1: V4FilterStruct::default(), + V4F_l_2: V4FilterStruct::default(), + V4F_r_1: V4FilterStruct::default(), + V4F_r_2: V4FilterStruct::default(), + // A4I Filter + A4I_l_1: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_l_2: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_r_1: A4iFilter::new(44100.0, 20000.0, 0.0), + A4I_r_2: A4iFilter::new(44100.0, 20000.0, 0.0), + cutoff_modulation: cutoff_mod, + cutoff_modulation_2: cutoff_mod_2, + resonance_modulation: 0.0, + resonance_modulation_2: 0.0, + + internal_unison_voices: Vec::new(), }; //} @@ -2970,11 +3747,6 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.state != OscState::Off && !(voice.grain_state == GrainState::Releasing && voice.grain_release.steps_left() == 0) }); - if self.audio_module_type != AudioModuleType::Off { - self.unison_voices.voices.retain(|unison_voice| { - unison_voice.state != OscState::Off - }); - } //////////////////////////////////////////////////////////// // Update our voices before output @@ -3075,9 +3847,10 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } for voice in self.playing_voices.voices.iter_mut() { - if self.audio_module_type == AudioModuleType::Osc - || self.audio_module_type == AudioModuleType::Sampler - || self.audio_module_type == AudioModuleType::Additive + + if self.audio_module_type != AudioModuleType::Granulizer + && self.audio_module_type != AudioModuleType::Off + && self.audio_module_type != AudioModuleType::UnsetAm { // Move our phase outside of the midi events // I couldn't find much on how to model this so I based it off previous note phase @@ -3092,7 +3865,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } // Move our pitch envelopes if this is an Osc - if self.audio_module_type == AudioModuleType::Osc && voice.pitch_enabled { + if voice.pitch_enabled { // Attack is over so use decay amount to reach sustain level - reusing current smoother if voice.pitch_attack.steps_left() == 0 && voice.pitch_state == OscState::Attacking @@ -3101,21 +3874,21 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.pitch_current = voice.pitch_attack.next(); // Now we will use decay smoother from here voice.pitch_decay.reset(voice.pitch_current); - let sustain_scaled = self.pitch_env_sustain / 999.9; + let sustain_scaled = self.pitch_env_sustain / 1999.9; voice .pitch_decay - .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); } // Move from Decaying to Sustain hold if voice.pitch_decay.steps_left() == 0 && voice.pitch_state == OscState::Decaying { - let sustain_scaled = self.pitch_env_sustain / 999.9; + let sustain_scaled = self.pitch_env_sustain / 1999.9; voice.pitch_current = sustain_scaled; voice .pitch_decay - .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); voice.pitch_state = OscState::Sustaining; } @@ -3130,7 +3903,10 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.pitch_current = 0.0; voice.pitch_state = OscState::Off; } - if (self.audio_module_type == AudioModuleType::Osc || self.audio_module_type == AudioModuleType::Additive) && voice.pitch_enabled_2 { + if (self.audio_module_type != AudioModuleType::Granulizer + && self.audio_module_type != AudioModuleType::Off + && self.audio_module_type != AudioModuleType::Sampler + && self.audio_module_type != AudioModuleType::UnsetAm) && voice.pitch_enabled_2 { // Attack is over so use decay amount to reach sustain level - reusing current smoother if voice.pitch_attack_2.steps_left() == 0 && voice.pitch_state_2 == OscState::Attacking @@ -3139,21 +3915,21 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.pitch_current_2 = voice.pitch_attack_2.next(); // Now we will use decay smoother from here voice.pitch_decay_2.reset(voice.pitch_current_2); - let sustain_scaled_2 = self.pitch_env_sustain_2 / 999.9; + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; voice .pitch_decay_2 - .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 1999.9)); } // Move from Decaying to Sustain hold if voice.pitch_decay_2.steps_left() == 0 && voice.pitch_state_2 == OscState::Decaying { - let sustain_scaled_2 = self.pitch_env_sustain_2 / 999.9; + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; voice.pitch_current_2 = sustain_scaled_2; voice .pitch_decay_2 - .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 1999.9)); voice.pitch_state_2 = OscState::Sustaining; } @@ -3176,13 +3952,13 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.amp_current = voice.osc_attack.next(); // Now we will use decay smoother from here voice.osc_decay.reset(voice.amp_current); - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; voice.osc_decay.set_target(self.sample_rate, sustain_scaled); } // Move from Decaying to Sustain hold if voice.osc_decay.steps_left() == 0 && voice.state == OscState::Decaying { - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; voice.amp_current = sustain_scaled; voice.osc_decay.set_target(self.sample_rate, sustain_scaled); voice.state = OscState::Sustaining; @@ -3192,6 +3968,124 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) if voice.state == OscState::Releasing && voice.osc_release.steps_left() == 0 { voice.state = OscState::Off; } + + // NEW UNISON STUFF + for internal_unison_voice in voice.internal_unison_voices.iter_mut() { + internal_unison_voice.phase += internal_unison_voice.phase_delta; + if internal_unison_voice.phase > 1.0 { + internal_unison_voice.phase -= 1.0; + } + // This happens on extreme pitch envelope values only and catches wild increments + // or pitches above nyquist that would alias into other pitches + if internal_unison_voice.phase > 1.0 { + internal_unison_voice.phase = internal_unison_voice.phase % 1.0; + } + + // Move our pitch envelopes if this is an Osc + if internal_unison_voice.pitch_enabled { + // Attack is over so use decay amount to reach sustain level - reusing current smoother + if internal_unison_voice.pitch_attack.steps_left() == 0 + && internal_unison_voice.pitch_state == OscState::Attacking + { + internal_unison_voice.pitch_state = OscState::Decaying; + internal_unison_voice.pitch_current = internal_unison_voice.pitch_attack.next(); + // Now we will use decay smoother from here + internal_unison_voice.pitch_decay.reset(internal_unison_voice.pitch_current); + let sustain_scaled = self.pitch_env_sustain / 1999.9; + internal_unison_voice + .pitch_decay + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); + } + + // Move from Decaying to Sustain hold + if internal_unison_voice.pitch_decay.steps_left() == 0 + && internal_unison_voice.pitch_state == OscState::Decaying + { + let sustain_scaled = self.pitch_env_sustain / 1999.9; + internal_unison_voice.pitch_current = sustain_scaled; + internal_unison_voice + .pitch_decay + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); + internal_unison_voice.pitch_state = OscState::Sustaining; + } + + // End of release + if internal_unison_voice.pitch_state == OscState::Releasing + && internal_unison_voice.pitch_release.steps_left() == 0 + { + internal_unison_voice.pitch_state = OscState::Off; + } + } else { + // Reassign here for safety + internal_unison_voice.pitch_current = 0.0; + internal_unison_voice.pitch_state = OscState::Off; + } + if (self.audio_module_type != AudioModuleType::Granulizer + && self.audio_module_type != AudioModuleType::Off + && self.audio_module_type != AudioModuleType::Sampler + && self.audio_module_type != AudioModuleType::UnsetAm) && internal_unison_voice.pitch_enabled_2 { + // Attack is over so use decay amount to reach sustain level - reusing current smoother + if internal_unison_voice.pitch_attack_2.steps_left() == 0 + && internal_unison_voice.pitch_state_2 == OscState::Attacking + { + internal_unison_voice.pitch_state_2 = OscState::Decaying; + internal_unison_voice.pitch_current_2 = internal_unison_voice.pitch_attack_2.next(); + // Now we will use decay smoother from here + internal_unison_voice.pitch_decay_2.reset(internal_unison_voice.pitch_current_2); + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; + internal_unison_voice + .pitch_decay_2 + .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 1999.9)); + } + + // Move from Decaying to Sustain hold + if internal_unison_voice.pitch_decay_2.steps_left() == 0 + && internal_unison_voice.pitch_state_2 == OscState::Decaying + { + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; + internal_unison_voice.pitch_current_2 = sustain_scaled_2; + internal_unison_voice + .pitch_decay_2 + .set_target(self.sample_rate, sustain_scaled_2.clamp(0.0001, 1999.9)); + internal_unison_voice.pitch_state_2 = OscState::Sustaining; + } + + // End of release + if internal_unison_voice.pitch_state_2 == OscState::Releasing + && internal_unison_voice.pitch_release_2.steps_left() == 0 + { + internal_unison_voice.pitch_state_2 = OscState::Off; + } + } else { + // Reassign here for safety + internal_unison_voice.pitch_current_2 = 0.0; + internal_unison_voice.pitch_state_2 = OscState::Off; + } + + // Move from attack to decay if needed + // Attack is over so use decay amount to reach sustain level - reusing current smoother + if internal_unison_voice.osc_attack.steps_left() == 0 && internal_unison_voice.state == OscState::Attacking { + internal_unison_voice.state = OscState::Decaying; + internal_unison_voice.amp_current = internal_unison_voice.osc_attack.next(); + // Now we will use decay smoother from here + internal_unison_voice.osc_decay.reset(internal_unison_voice.amp_current); + let sustain_scaled = self.osc_sustain / 1999.9; + internal_unison_voice.osc_decay.set_target(self.sample_rate, sustain_scaled); + } + + // Move from Decaying to Sustain hold + if internal_unison_voice.osc_decay.steps_left() == 0 && internal_unison_voice.state == OscState::Decaying { + let sustain_scaled = self.osc_sustain / 1999.9; + internal_unison_voice.amp_current = sustain_scaled; + internal_unison_voice.osc_decay.set_target(self.sample_rate, sustain_scaled); + internal_unison_voice.state = OscState::Sustaining; + } + + // End of release + if internal_unison_voice.state == OscState::Releasing && internal_unison_voice.osc_release.steps_left() == 0 { + internal_unison_voice.state = OscState::Off; + } + } } else if self.audio_module_type == AudioModuleType::Granulizer { // Move from attack to decay if needed // Attack is over so use decay amount to reach sustain level - reusing current smoother @@ -3200,13 +4094,13 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.amp_current = voice.osc_attack.next(); // Now we will use decay smoother from here voice.osc_decay.reset(voice.amp_current); - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; voice.osc_decay.set_target(self.sample_rate, sustain_scaled); } // Move from Decaying to Sustain hold if voice.osc_decay.steps_left() == 0 && voice.state == OscState::Decaying { - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; voice.amp_current = sustain_scaled; voice.osc_decay.set_target(self.sample_rate, sustain_scaled); voice.state = OscState::Sustaining; @@ -3307,10 +4201,94 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) )), grain_state: GrainState::Attacking, // Additive - harmonic_phases: Vec::new(), - }; - } - + harmonic_phases: { + let mut vector: Vec = Vec::with_capacity(16); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector.push(0.0); + vector + }, + //// Polyfilter update!! + /////////////////////////////////////////////////////// + filter_l_1: StateVariableFilter::default().set_oversample(4), + filter_r_1: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_1: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_1: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_1: VCFilter::new(), + vcf_filter_r_1: VCFilter::new(), + // Filter state variables + filter_state_1: OscState::Attacking, + filter_atk_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), + // SVF Filters + filter_l_2: StateVariableFilter::default().set_oversample(4), + filter_r_2: StateVariableFilter::default().set_oversample(4), + // TILT Filters + tilt_filter_l_2: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff_2, + 1.0, + ResponseType::Lowpass, + ), + tilt_filter_r_2: ArduraFilter::new( + self.sample_rate, + self.filter_cutoff_2, + 1.0, + ResponseType::Lowpass, + ), + // VCF Filters + vcf_filter_l_2: VCFilter::new(), + vcf_filter_r_2: VCFilter::new(), + // Filter state variables + filter_state_2: OscState::Attacking, + filter_atk_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_dec_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + filter_rel_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), + // V4 Filter + V4F_l_1: V4FilterStruct::default(), + V4F_l_2: V4FilterStruct::default(), + V4F_r_1: V4FilterStruct::default(), + V4F_r_2: V4FilterStruct::default(), + // A4I Filter + A4I_l_1: A4iFilter::new(self.sample_rate, self.filter_cutoff, 0.0), + A4I_l_2: A4iFilter::new(self.sample_rate, self.filter_cutoff_2, 0.0), + A4I_r_1: A4iFilter::new(self.sample_rate, self.filter_cutoff, 0.0), + A4I_r_2: A4iFilter::new(self.sample_rate, self.filter_cutoff_2, 0.0), + cutoff_modulation: cutoff_mod, + cutoff_modulation_2: cutoff_mod_2, + resonance_modulation: 0.0, + resonance_modulation_2: 0.0, + + internal_unison_voices: Vec::new(), + }; + } + // End of release if (voice.state == OscState::Releasing && voice.osc_release.steps_left() == 0) || (voice.grain_state == GrainState::Releasing @@ -3321,8 +4299,21 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } } + /* match self.audio_module_type { - AudioModuleType::Osc | AudioModuleType::Sampler | AudioModuleType::Additive => { + AudioModuleType::Sine | + AudioModuleType::Tri | + AudioModuleType::Saw | + AudioModuleType::RSaw | + AudioModuleType::WSaw | + AudioModuleType::SSaw | + AudioModuleType::RASaw | + AudioModuleType::Ramp | + AudioModuleType::Square | + AudioModuleType::RSquare | + AudioModuleType::Pulse | + AudioModuleType::Noise | + AudioModuleType::Additive => { // Update our matching unison voices for unison_voice in self.unison_voices.voices.iter_mut() { // Move our phase outside of the midi events @@ -3338,7 +4329,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } // Move our pitch envelopes if this is an Osc - if self.audio_module_type == AudioModuleType::Osc && unison_voice.pitch_enabled + if unison_voice.pitch_enabled { // Attack is over so use decay amount to reach sustain level - reusing current smoother if unison_voice.pitch_attack.steps_left() == 0 @@ -3348,21 +4339,21 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) unison_voice.pitch_current = unison_voice.pitch_attack.next(); // Now we will use decay smoother from here unison_voice.pitch_decay.reset(unison_voice.pitch_current); - let sustain_scaled = self.pitch_env_sustain / 999.9; + let sustain_scaled = self.pitch_env_sustain / 1999.9; unison_voice .pitch_decay - .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); } // Move from Decaying to Sustain hold if unison_voice.pitch_decay.steps_left() == 0 && unison_voice.pitch_state == OscState::Decaying { - let sustain_scaled = self.pitch_env_sustain / 999.9; + let sustain_scaled = self.pitch_env_sustain / 1999.9; unison_voice.pitch_current = sustain_scaled; unison_voice .pitch_decay - .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 999.9)); + .set_target(self.sample_rate, sustain_scaled.clamp(0.0001, 1999.9)); unison_voice.pitch_state = OscState::Sustaining; } @@ -3377,8 +4368,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) unison_voice.pitch_current = 0.0; unison_voice.pitch_state = OscState::Off; } - if self.audio_module_type == AudioModuleType::Osc - && unison_voice.pitch_enabled_2 + if unison_voice.pitch_enabled_2 { // Attack is over so use decay amount to reach sustain level - reusing current smoother if unison_voice.pitch_attack_2.steps_left() == 0 @@ -3390,10 +4380,10 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) unison_voice .pitch_decay_2 .reset(unison_voice.pitch_current_2); - let sustain_scaled_2 = self.pitch_env_sustain_2 / 999.9; + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; unison_voice.pitch_decay_2.set_target( self.sample_rate, - sustain_scaled_2.clamp(0.0001, 999.9), + sustain_scaled_2.clamp(0.0001, 1999.9), ); } @@ -3401,11 +4391,11 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) if unison_voice.pitch_decay_2.steps_left() == 0 && unison_voice.pitch_state_2 == OscState::Decaying { - let sustain_scaled_2 = self.pitch_env_sustain_2 / 999.9; + let sustain_scaled_2 = self.pitch_env_sustain_2 / 1999.9; unison_voice.pitch_current_2 = sustain_scaled_2; unison_voice.pitch_decay_2.set_target( self.sample_rate, - sustain_scaled_2.clamp(0.0001, 999.9), + sustain_scaled_2.clamp(0.0001, 1999.9), ); unison_voice.pitch_state_2 = OscState::Sustaining; } @@ -3431,7 +4421,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) unison_voice.amp_current = unison_voice.osc_attack.next(); // Now we will use decay smoother from here unison_voice.osc_decay.reset(unison_voice.amp_current); - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; unison_voice .osc_decay .set_target(self.sample_rate, sustain_scaled); @@ -3441,7 +4431,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) && unison_voice.state == OscState::Decaying { unison_voice.state = OscState::Sustaining; - let sustain_scaled = self.osc_sustain / 999.9; + let sustain_scaled = self.osc_sustain / 1999.9; unison_voice.amp_current = sustain_scaled; unison_voice .osc_decay @@ -3453,28 +4443,143 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) { unison_voice.state = OscState::Off; } + + ////////////////////////////////////////////////////////////////////////// + // POLYFILTER UPDATE + ////////////////////////////////////////////////////////////////////////// + + // Filter 1 Processing + /////////////////////////////////////////////////////////////// + if self.filter_wet > 0.0 { + // Filter state movement code + ////////////////////////////////////////// + // If a note is ending and we should enter releasing + if note_off { + let old_filter_state = unison_voice.filter_state_1; + unison_voice.filter_state_1 = OscState::Releasing; + unison_voice.filter_rel_smoother_1 = match self.filter_env_rel_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_release, + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_release.clamp(0.0001, 1999.9), + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_release, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_release.clamp(0.0001, 1999.9), + )), + }; + // Reset our filter release to be at sustain level to start + unison_voice.filter_rel_smoother_1.reset( + match old_filter_state { + OscState::Attacking => self.filter_atk_smoother_1.next(), + OscState::Decaying | OscState::Releasing => self.filter_dec_smoother_1.next(), + OscState::Sustaining => self.filter_dec_smoother_1.next(), + OscState::Off => self.filter_cutoff, + }, + ); + // Move release to the cutoff to end + unison_voice.filter_rel_smoother_1 + .set_target(self.sample_rate, self.filter_cutoff); + } + + // If our attack has finished + if unison_voice.filter_atk_smoother_1.steps_left() == 0 + && unison_voice.filter_state_1 == OscState::Attacking + { + unison_voice.filter_state_1 = OscState::Decaying; + unison_voice.filter_dec_smoother_1 = match self.filter_env_dec_curve { + SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( + self.filter_env_decay + )), + SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( + self.filter_env_decay, + )), + SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( + self.filter_env_decay, + )), + SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( + self.filter_env_decay, + )), + }; + // This makes our filter decay start at env peak point + unison_voice.filter_dec_smoother_1.reset( + unison_voice.filter_atk_smoother_1.next() + .clamp(20.0, 20000.0), + ); + // Set up the smoother for our filter movement to go from our decay point to our sustain point + unison_voice.filter_dec_smoother_1.set_target( + self.sample_rate, + ( + self.filter_cutoff + + // This scales the peak env to be much gentler for the TILT filter + match self.filter_alg_type { + FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.filter_env_peak, + FilterAlgorithms::TILT => adv_scale_value( + self.filter_env_peak, + -19980.0, + 19980.0, + -5000.0, + 5000.0, + ), + } + ).clamp(20.0, 20000.0) + * (self.filter_env_sustain / 1999.9), + ); + } + + // If our decay has finished move to sustain state + if unison_voice.filter_dec_smoother_1.steps_left() == 0 + && unison_voice.filter_state_1 == OscState::Decaying + { + unison_voice.filter_state_1 = OscState::Sustaining; + } + } } } _ => {} } + */ // Add our new grain to our voices if new_grain { self.playing_voices.voices.push_back(next_grain); } + // Define the outputs for filter routing or non-filter routing + let mut left_output_filter1: f32 = 0.0; + let mut right_output_filter1: f32 = 0.0; + let mut left_output_filter2: f32 = 0.0; + let mut right_output_filter2: f32 = 0.0; + let mut left_output: f32 = 0.0; + let mut right_output: f32 = 0.0; + //////////////////////////////////////////////////////////// // Create output //////////////////////////////////////////////////////////// let output_signal_l: f32; let output_signal_r: f32; (output_signal_l, output_signal_r) = match self.audio_module_type { - AudioModuleType::Osc => { - let mut summed_voices_l: f32 = 0.0; - let mut summed_voices_r: f32 = 0.0; + AudioModuleType::Sine | + AudioModuleType::Tri | + AudioModuleType::Saw | + AudioModuleType::RSaw | + AudioModuleType::WSaw | + AudioModuleType::SSaw | + AudioModuleType::RASaw | + AudioModuleType::Ramp | + AudioModuleType::Square | + AudioModuleType::RSquare | + AudioModuleType::Pulse | + AudioModuleType::Noise => { let mut stereo_voices_l: f32 = 0.0; let mut stereo_voices_r: f32 = 0.0; - let mut center_voices: f32 = 0.0; + ////////////////////////////////////////////////////////////////////////// + // POLYFILTER UPDATE + ////////////////////////////////////////////////////////////////////////// + for voice in self.playing_voices.voices.iter_mut() { // Move the pitch envelope stuff independently of the MIDI info if voice.pitch_enabled { @@ -3482,7 +4587,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) match voice.pitch_state { OscState::Attacking => voice.pitch_attack.next(), OscState::Decaying => voice.pitch_decay.next(), - OscState::Sustaining => self.pitch_env_sustain / 999.9, + OscState::Sustaining => self.pitch_env_sustain / 1999.9, OscState::Releasing => voice.pitch_release.next(), OscState::Off => 0.0, } @@ -3491,7 +4596,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.pitch_current_2 = match voice.pitch_state_2 { OscState::Attacking => voice.pitch_attack_2.next(), OscState::Decaying => voice.pitch_decay_2.next(), - OscState::Sustaining => self.pitch_env_sustain_2 / 999.9, + OscState::Sustaining => self.pitch_env_sustain_2 / 1999.9, OscState::Releasing => voice.pitch_release_2.next(), OscState::Off => 0.0, } @@ -3509,7 +4614,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod } OscState::Sustaining => { - (self.osc_sustain / 999.9) * vel_gain_mod * vel_lfo_gain_mod + (self.osc_sustain / 1999.9) * vel_gain_mod * vel_lfo_gain_mod } OscState::Releasing => { voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod @@ -3520,7 +4625,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) temp_osc_gain_multiplier = match voice.state { OscState::Attacking => voice.osc_attack.next() * vel_lfo_gain_mod, OscState::Decaying => voice.osc_decay.next() * vel_lfo_gain_mod, - OscState::Sustaining => (self.osc_sustain / 999.9) * vel_lfo_gain_mod, + OscState::Sustaining => (self.osc_sustain / 1999.9) * vel_lfo_gain_mod, OscState::Releasing => voice.osc_release.next() * vel_lfo_gain_mod, OscState::Off => 0.0, }; @@ -3548,210 +4653,492 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; } - if self.audio_module_type == AudioModuleType::Osc { - center_voices += match self.osc_type { - VoiceType::Sine => { - Oscillator::get_sine(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::Tri => { - Oscillator::get_tri(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::Saw => { - Oscillator::get_saw(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::RSaw => { - Oscillator::get_rsaw(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::WSaw => { - Oscillator::get_wsaw(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::RASaw => { - Oscillator::get_rasaw(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::SSaw => { - Oscillator::get_ssaw(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::Ramp => { - Oscillator::get_ramp(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::Square => { - Oscillator::get_square(voice.phase) * temp_osc_gain_multiplier - } - VoiceType::RSquare => { - Oscillator::get_rsquare(voice.phase) * temp_osc_gain_multiplier + let temp_center_voices = match self.audio_module_type { + AudioModuleType::Sine => { + Oscillator::get_sine(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Tri => { + Oscillator::get_tri(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Saw => { + Oscillator::get_saw(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RSaw => { + Oscillator::get_rsaw(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::WSaw => { + Oscillator::get_wsaw(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RASaw => { + Oscillator::get_rasaw(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::SSaw => { + Oscillator::get_ssaw(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Ramp => { + Oscillator::get_ramp(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Square => { + Oscillator::get_square(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RSquare => { + Oscillator::get_rsquare(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Pulse => { + Oscillator::get_pulse(voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Noise => { + self.noise_obj.generate_sample() * temp_osc_gain_multiplier + }, + AudioModuleType::Additive | AudioModuleType::Granulizer | AudioModuleType::Off | AudioModuleType::UnsetAm | AudioModuleType::Sampler => 0.0, + }; + for internal_unison_voice in voice.internal_unison_voices.iter_mut() { + // Move the pitch envelope stuff independently of the MIDI info + if internal_unison_voice.pitch_enabled { + internal_unison_voice.pitch_current = + match internal_unison_voice.pitch_state { + OscState::Attacking => internal_unison_voice.pitch_attack.next(), + OscState::Decaying => internal_unison_voice.pitch_decay.next(), + OscState::Sustaining => self.pitch_env_sustain / 1999.9, + OscState::Releasing => internal_unison_voice.pitch_release.next(), + OscState::Off => 0.0, } - VoiceType::Pulse => { - Oscillator::get_pulse(voice.phase) * temp_osc_gain_multiplier + } + if internal_unison_voice.pitch_enabled_2 { + internal_unison_voice.pitch_current_2 = match internal_unison_voice.pitch_state_2 { + OscState::Attacking => internal_unison_voice.pitch_attack_2.next(), + OscState::Decaying => internal_unison_voice.pitch_decay_2.next(), + OscState::Sustaining => self.pitch_env_sustain_2 / 1999.9, + OscState::Releasing => internal_unison_voice.pitch_release_2.next(), + OscState::Off => 0.0, } - VoiceType::Noise => { + } + + let temp_osc_gain_multiplier: f32; + // Get our current gain amount for use in match below + // Include gain scaling if mod is there + if vel_gain_mod != -2.0 { + temp_osc_gain_multiplier = match internal_unison_voice.state { + OscState::Attacking => { + internal_unison_voice.osc_attack.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Decaying => { + internal_unison_voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Sustaining => { + (self.osc_sustain / 1999.9) * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Releasing => { + internal_unison_voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Off => 0.0, + }; + } else { + temp_osc_gain_multiplier = match internal_unison_voice.state { + OscState::Attacking => internal_unison_voice.osc_attack.next() * vel_lfo_gain_mod, + OscState::Decaying => internal_unison_voice.osc_decay.next() * vel_lfo_gain_mod, + OscState::Sustaining => (self.osc_sustain / 1999.9) * vel_lfo_gain_mod, + OscState::Releasing => internal_unison_voice.osc_release.next() * vel_lfo_gain_mod, + OscState::Off => 0.0, + }; + } + + internal_unison_voice.amp_current = temp_osc_gain_multiplier; + + let nyquist = self.sample_rate / 2.0; + if internal_unison_voice.vel_mod_amount == 0.0 { + let base_note = internal_unison_voice.note as f32 + + internal_unison_voice._detune + + detune_mod + + internal_unison_voice.pitch_current + + internal_unison_voice.pitch_current_2; + internal_unison_voice.phase_delta = + util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; + } else { + let base_note = internal_unison_voice.note as f32 + + internal_unison_voice._detune + + detune_mod + + (internal_unison_voice.vel_mod_amount * internal_unison_voice._velocity) + + internal_unison_voice.pitch_current + + internal_unison_voice.pitch_current_2; + internal_unison_voice.phase_delta = + util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; + } + + let temp_unison_voice_out = match self.audio_module_type { + AudioModuleType::Sine => { + Oscillator::get_sine(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Tri => { + Oscillator::get_tri(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Saw => { + Oscillator::get_saw(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RSaw => { + Oscillator::get_rsaw(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::WSaw => { + Oscillator::get_wsaw(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RASaw => { + Oscillator::get_rasaw(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::SSaw => { + Oscillator::get_ssaw(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Ramp => { + Oscillator::get_ramp(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Square => { + Oscillator::get_square(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::RSquare => { + Oscillator::get_rsquare(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Pulse => { + Oscillator::get_pulse(internal_unison_voice.phase) * temp_osc_gain_multiplier + }, + AudioModuleType::Noise => { self.noise_obj.generate_sample() * temp_osc_gain_multiplier - } + }, + AudioModuleType::Additive | AudioModuleType::Granulizer | AudioModuleType::Off | AudioModuleType::UnsetAm | AudioModuleType::Sampler => 0.0, }; + // Create our stereo pan for unison + // Our angle comes back as radians + let pan = internal_unison_voice._angle; + + // Precompute sine and cosine of the angle + let cos_pan = pan.cos(); + let sin_pan = pan.sin(); + + // Calculate the amplitudes for the panned voice using vector operations + let scale = SQRT_2 / 2.0; + let temp_unison_voice_scaled = scale * temp_unison_voice_out; + + let left_amp = temp_unison_voice_scaled * (cos_pan + sin_pan); + let right_amp = temp_unison_voice_scaled * (cos_pan - sin_pan); + + // Add the voice to the sum of stereo voices + stereo_voices_l += left_amp / (self.osc_unison - 1).clamp(1, 9) as f32; + stereo_voices_r += right_amp / (self.osc_unison - 1).clamp(1, 9) as f32; } - } - // Stereo applies to unison voices - for unison_voice in self.unison_voices.voices.iter_mut() { - // Move the pitch envelope stuff independently of the MIDI info - if unison_voice.pitch_enabled { - unison_voice.pitch_current = - match unison_voice.pitch_state { - OscState::Attacking => unison_voice.pitch_attack.next(), - OscState::Decaying => unison_voice.pitch_decay.next(), - OscState::Sustaining => self.pitch_env_sustain / 999.9, - OscState::Releasing => unison_voice.pitch_release.next(), - OscState::Off => 0.0, + + ////////////////////////////////////////////////////////////////////////// + // POLYFILTER UPDATE + ////////////////////////////////////////////////////////////////////////// + + // Filter 1 Processing + /////////////////////////////////////////////////////////////// + let mut next_filter_step: f32 = 0.0; + let mut next_filter_step_2: f32 = 0.0; + if self.filter_wet > 0.0 { + // Filter state movement code + ////////////////////////////////////////// + // If a note is ending and we should enter releasing + if note_off { + let old_filter_state = voice.filter_state_1; + voice.filter_state_1 = OscState::Releasing; + // Reset our filter release to be at sustain level to start + voice.filter_rel_smoother_1.reset( + match old_filter_state { + OscState::Attacking => voice.filter_atk_smoother_1.next(), + OscState::Decaying | OscState::Releasing => voice.filter_dec_smoother_1.next(), + OscState::Sustaining => voice.filter_dec_smoother_1.next(), + OscState::Off => self.filter_cutoff, + }, + ); + // Move release to the cutoff to end + voice.filter_rel_smoother_1.set_target(self.sample_rate, self.filter_cutoff); } - } - if unison_voice.pitch_enabled_2 { - unison_voice.pitch_current_2 = match unison_voice.pitch_state_2 { - OscState::Attacking => unison_voice.pitch_attack_2.next(), - OscState::Decaying => unison_voice.pitch_decay_2.next(), - OscState::Sustaining => self.pitch_env_sustain_2 / 999.9, - OscState::Releasing => unison_voice.pitch_release_2.next(), - OscState::Off => 0.0, + + // If our attack has finished + if voice.filter_atk_smoother_1.steps_left() == 0 && voice.filter_state_1 == OscState::Attacking + { + voice.filter_state_1 = OscState::Decaying; + // This makes our filter decay start at env peak point + voice.filter_dec_smoother_1.reset( + voice.filter_atk_smoother_1.next().clamp(20.0, 20000.0), + ); + // Set up the smoother for our filter movement to go from our decay point to our sustain point + voice.filter_dec_smoother_1.set_target( + self.sample_rate, + ( + self.filter_cutoff + + // This scales the peak env to be much gentler for the TILT filter + match self.filter_alg_type { + FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.filter_env_peak, + FilterAlgorithms::TILT => adv_scale_value( + self.filter_env_peak, + -19980.0, + 19980.0, + -5000.0, + 5000.0, + ), + } + ).clamp(20.0, 20000.0) + * (self.filter_env_sustain / 1999.9), + ); } - } - let temp_osc_gain_multiplier: f32; - // Get our current gain amount for use in match below - // Include gain scaling if mod is there - if vel_gain_mod != -2.0 { - temp_osc_gain_multiplier = match unison_voice.state { + // If our decay has finished move to sustain state + if voice.filter_dec_smoother_1.steps_left() == 0 + && voice.filter_state_1 == OscState::Decaying + { + voice.filter_state_1 = OscState::Sustaining; + } + // use proper variable now that there are four filters and multiple states + // This double addition of voice.cutoff_modulation + cutoff_mod will stack the mod at the time of the voice movement with the current + next_filter_step = match voice.filter_state_1 { OscState::Attacking => { - unison_voice.osc_attack.next() * vel_gain_mod * vel_lfo_gain_mod + (voice.filter_atk_smoother_1.next() + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0) } OscState::Decaying => { - unison_voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod + (voice.filter_dec_smoother_1.next() + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0) } OscState::Sustaining => { - (self.osc_sustain / 999.9) * vel_gain_mod * vel_lfo_gain_mod + (voice.filter_dec_smoother_1.next() + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0) } OscState::Releasing => { - unison_voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod + if self.filter_env_release <= 0.0001 { + (voice.filter_dec_smoother_1.next() + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0) + } else { + (voice.filter_rel_smoother_1.next() + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0) + } } - OscState::Off => 0.0, + // I don't expect this to be used + _ => (self.filter_cutoff + voice.cutoff_modulation + cutoff_mod).clamp(20.0, 20000.0), }; - } else { - temp_osc_gain_multiplier = match unison_voice.state { + } + + if self.filter_wet_2 > 0.0 { + // Filter state movement code + ////////////////////////////////////////// + // If a note is ending and we should enter releasing + if note_off { + let old_filter_state = voice.filter_state_2; + voice.filter_state_2 = OscState::Releasing; + // Reset our filter release to be at sustain level to start + voice.filter_rel_smoother_2.reset( + match old_filter_state { + OscState::Attacking => voice.filter_atk_smoother_2.next(), + OscState::Decaying | OscState::Releasing => voice.filter_dec_smoother_2.next(), + OscState::Sustaining => voice.filter_dec_smoother_2.next(), + OscState::Off => self.filter_cutoff_2, + }, + ); + // Move release to the cutoff to end + voice.filter_rel_smoother_2.set_target(self.sample_rate, self.filter_cutoff_2); + } + + // If our attack has finished + if voice.filter_atk_smoother_2.steps_left() == 0 && voice.filter_state_2 == OscState::Attacking + { + voice.filter_state_2 = OscState::Decaying; + // This makes our filter decay start at env peak point + voice.filter_dec_smoother_2.reset( + voice.filter_atk_smoother_2.next().clamp(20.0, 20000.0), + ); + // Set up the smoother for our filter movement to go from our decay point to our sustain point + voice.filter_dec_smoother_2.set_target( + self.sample_rate, + ( + self.filter_cutoff_2 + + // This scales the peak env to be much gentler for the TILT filter + match self.filter_alg_type_2 { + FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.filter_env_peak_2, + FilterAlgorithms::TILT => adv_scale_value( + self.filter_env_peak_2, + -19980.0, + 19980.0, + -5000.0, + 5000.0, + ), + } + ).clamp(20.0, 20000.0) + * (self.filter_env_sustain_2 / 1999.9), + ); + } + + // If our decay has finished move to sustain state + if voice.filter_dec_smoother_2.steps_left() == 0 + && voice.filter_state_2 == OscState::Decaying + { + voice.filter_state_2 = OscState::Sustaining; + } + // use proper variable now that there are four filters and multiple states + next_filter_step_2 = match voice.filter_state_2 { OscState::Attacking => { - unison_voice.osc_attack.next() * vel_lfo_gain_mod + (voice.filter_atk_smoother_2.next() + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0) + } + OscState::Decaying => { + (voice.filter_dec_smoother_2.next() + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0) + } + OscState::Sustaining => { + (voice.filter_dec_smoother_2.next() + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0) } - OscState::Decaying => unison_voice.osc_decay.next() * vel_lfo_gain_mod, - OscState::Sustaining => (self.osc_sustain / 999.9) * vel_lfo_gain_mod, OscState::Releasing => { - unison_voice.osc_release.next() * vel_lfo_gain_mod + if self.filter_env_release_2 <= 0.0001 { + (voice.filter_dec_smoother_2.next() + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0) + } else { + (voice.filter_rel_smoother_2.next() + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0) + } } - OscState::Off => 0.0, + // I don't expect this to be used + _ => (self.filter_cutoff_2 + voice.cutoff_modulation_2 + cutoff_mod_2).clamp(20.0, 20000.0), }; } - unison_voice.amp_current = temp_osc_gain_multiplier; - - if unison_voice.vel_mod_amount == 0.0 { - let base_note = unison_voice.note as f32 - + unison_voice._unison_detune_value - + uni_detune_mod - + unison_voice.pitch_current - + unison_voice.pitch_current_2; - unison_voice.phase_delta = - util::f32_midi_note_to_freq(base_note) / self.sample_rate; - } else { - let base_note = unison_voice.note as f32 - + unison_voice._unison_detune_value - + uni_detune_mod - + (unison_voice.vel_mod_amount * unison_voice._velocity) - + unison_voice.pitch_current - + unison_voice.pitch_current_2; - unison_voice.phase_delta = - util::f32_midi_note_to_freq(base_note) / self.sample_rate; + ////////////////////////////////////////////////////////////////////////// + // POLYFILTER UPDATE + ////////////////////////////////////////////////////////////////////////// + match self.audio_module_routing { + AMFilterRouting::Bypass | AMFilterRouting::UNSETROUTING => { + left_output += temp_center_voices + stereo_voices_l; + right_output += temp_center_voices + stereo_voices_r; + }, + AMFilterRouting::Filter1 => { + left_output_filter1 = temp_center_voices + stereo_voices_l; + right_output_filter1 = temp_center_voices + stereo_voices_r; + }, + AMFilterRouting::Filter2 => { + left_output_filter2 = temp_center_voices + stereo_voices_l; + right_output_filter2 = temp_center_voices + stereo_voices_r; + }, + AMFilterRouting::Both => { + left_output_filter1 = temp_center_voices + stereo_voices_l; + right_output_filter1 = temp_center_voices + stereo_voices_r; + left_output_filter2 = temp_center_voices + stereo_voices_l; + right_output_filter2 = temp_center_voices + stereo_voices_r; + }, } - if self.osc_unison > 1 { - let mut temp_unison_voice: f32 = 0.0; - if self.audio_module_type == AudioModuleType::Osc { - temp_unison_voice = match self.osc_type { - VoiceType::Sine => { - Oscillator::get_sine(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Tri => { - Oscillator::get_tri(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Saw => { - Oscillator::get_saw(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::RSaw => { - Oscillator::get_rsaw(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::WSaw => { - Oscillator::get_wsaw(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::SSaw => { - Oscillator::get_ssaw(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::RASaw => { - Oscillator::get_rasaw(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Ramp => { - Oscillator::get_ramp(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Square => { - Oscillator::get_square(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::RSquare => { - Oscillator::get_rsquare(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Pulse => { - Oscillator::get_pulse(unison_voice.phase) - * temp_osc_gain_multiplier - } - VoiceType::Noise => { - self.noise_obj.generate_sample() * temp_osc_gain_multiplier - } - }; + if self.audio_module_routing != AMFilterRouting::Bypass { + match self.filter_routing { + FilterRouting::Parallel => { + let (filter1_processed_l,filter1_processed_r) = filter_process_1( + self.filter_alg_type.clone(), + self.filter_resonance, + self.sample_rate, + self.filter_res_type.clone(), + self.lp_amount, + self.bp_amount, + self.hp_amount, + self.filter_wet, + self.tilt_filter_type.clone(), + self.vcf_filter_type.clone(), + voice, + next_filter_step, + resonance_mod, + left_output_filter1, + right_output_filter1, + ); + let (filter2_processed_l,filter2_processed_r) = filter_process_2( + self.filter_alg_type_2.clone(), + self.filter_resonance_2, + self.sample_rate, + self.filter_res_type_2.clone(), + self.lp_amount_2, + self.bp_amount_2, + self.hp_amount_2, + self.filter_wet_2, + self.tilt_filter_type_2.clone(), + self.vcf_filter_type_2.clone(), + voice, + next_filter_step_2, + resonance_mod_2, + left_output_filter2, + right_output_filter2, + ); + left_output += filter1_processed_l + filter2_processed_l; + right_output += filter1_processed_r + filter2_processed_r; + } + FilterRouting::Series12 => { + let (filter1_processed_l,filter1_processed_r) = filter_process_1( + self.filter_alg_type.clone(), + self.filter_resonance, + self.sample_rate, + self.filter_res_type.clone(), + self.lp_amount, + self.bp_amount, + self.hp_amount, + self.filter_wet, + self.tilt_filter_type.clone(), + self.vcf_filter_type.clone(), + voice, + next_filter_step, + resonance_mod, + left_output_filter1, + right_output_filter1, + ); + let (filter2_processed_l,filter2_processed_r) = filter_process_2( + self.filter_alg_type_2.clone(), + self.filter_resonance_2, + self.sample_rate, + self.filter_res_type_2.clone(), + self.lp_amount_2, + self.bp_amount_2, + self.hp_amount_2, + self.filter_wet_2, + self.tilt_filter_type_2.clone(), + self.vcf_filter_type_2.clone(), + voice, + next_filter_step_2, + resonance_mod_2, + left_output_filter2 + filter1_processed_l, + right_output_filter2 + filter1_processed_r, + ); + left_output += filter2_processed_l; + right_output += filter2_processed_r; + } + FilterRouting::Series21 => { + let (filter2_processed_l,filter2_processed_r) = filter_process_2( + self.filter_alg_type_2.clone(), + self.filter_resonance_2, + self.sample_rate, + self.filter_res_type_2.clone(), + self.lp_amount_2, + self.bp_amount_2, + self.hp_amount_2, + self.filter_wet_2, + self.tilt_filter_type_2.clone(), + self.vcf_filter_type_2.clone(), + voice, + next_filter_step_2, + resonance_mod_2, + left_output_filter2, + right_output_filter2, + ); + let (filter1_processed_l,filter1_processed_r) = filter_process_1( + self.filter_alg_type.clone(), + self.filter_resonance, + self.sample_rate, + self.filter_res_type.clone(), + self.lp_amount, + self.bp_amount, + self.hp_amount, + self.filter_wet, + self.tilt_filter_type.clone(), + self.vcf_filter_type.clone(), + voice, + next_filter_step, + resonance_mod, + left_output_filter1 + filter2_processed_l, + right_output_filter1 + filter2_processed_r, + ); + left_output += filter1_processed_l; + right_output += filter1_processed_r; + } } - - // Create our stereo pan for unison - - // Our angle comes back as radians - let pan = unison_voice._angle; - - // Precompute sine and cosine of the angle - let cos_pan = pan.cos(); - let sin_pan = pan.sin(); - - // Calculate the amplitudes for the panned voice using vector operations - let scale = SQRT_2 / 2.0; - let temp_unison_voice_scaled = scale * temp_unison_voice; - - let left_amp = temp_unison_voice_scaled * (cos_pan + sin_pan); - let right_amp = temp_unison_voice_scaled * (cos_pan - sin_pan); - - // Add the voice to the sum of stereo voices - stereo_voices_l += left_amp; - stereo_voices_r += right_amp; } } - // Sum our voices for output - summed_voices_l += center_voices; - summed_voices_r += center_voices; - // Scaling of output based on stereo voices and unison - summed_voices_l += stereo_voices_l / (self.osc_unison - 1).clamp(1, 9) as f32; - summed_voices_r += stereo_voices_r / (self.osc_unison - 1).clamp(1, 9) as f32; // Blending when multi-voiced if self.osc_unison > 1 { - summed_voices_l = (summed_voices_l + summed_voices_r * 0.8)/2.0; - summed_voices_r = (summed_voices_r + summed_voices_l * 0.8)/2.0; + let l = left_output; + let r = right_output; + left_output = (l + r * 0.8)/2.0; + right_output = (r + l * 0.8)/2.0; } // Stereo Spreading code @@ -3766,14 +5153,16 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) 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; - summed_voices_r = mid + stereo; + let l = left_output; + let r = right_output; + let mid = (l + r) * 0.5; + let stereo = (r - l) * width_coeff; + left_output = mid - stereo; + right_output = mid + stereo; // Return output - (summed_voices_l, summed_voices_r) - } + (left_output, right_output) + }, AudioModuleType::Additive => { let mut summed_voices_l: f32 = 0.0; let mut summed_voices_r: f32 = 0.0; @@ -3787,7 +5176,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) match voice.pitch_state { OscState::Attacking => voice.pitch_attack.next(), OscState::Decaying => voice.pitch_decay.next(), - OscState::Sustaining => self.pitch_env_sustain / 999.9, + OscState::Sustaining => self.pitch_env_sustain / 1999.9, OscState::Releasing => voice.pitch_release.next(), OscState::Off => 0.0, } @@ -3796,7 +5185,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.pitch_current_2 = match voice.pitch_state_2 { OscState::Attacking => voice.pitch_attack_2.next(), OscState::Decaying => voice.pitch_decay_2.next(), - OscState::Sustaining => self.pitch_env_sustain_2 / 999.9, + OscState::Sustaining => self.pitch_env_sustain_2 / 1999.9, OscState::Releasing => voice.pitch_release_2.next(), OscState::Off => 0.0, } @@ -3814,7 +5203,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod } OscState::Sustaining => { - (self.osc_sustain / 999.9) * vel_gain_mod * vel_lfo_gain_mod + (self.osc_sustain / 1999.9) * vel_gain_mod * vel_lfo_gain_mod } OscState::Releasing => { voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod @@ -3825,7 +5214,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) temp_osc_gain_multiplier = match voice.state { OscState::Attacking => voice.osc_attack.next() * vel_lfo_gain_mod, OscState::Decaying => voice.osc_decay.next() * vel_lfo_gain_mod, - OscState::Sustaining => (self.osc_sustain / 999.9) * vel_lfo_gain_mod, + OscState::Sustaining => (self.osc_sustain / 1999.9) * vel_lfo_gain_mod, OscState::Releasing => voice.osc_release.next() * vel_lfo_gain_mod, OscState::Off => 0.0, }; @@ -3853,96 +5242,86 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; } - // TODO make this use the additive engine - center_voices += self.additive_module.next_sample(voice, self.sample_rate, detune_mod, false) * voice.amp_current; - } - // Stereo applies to unison voices - for unison_voice in self.unison_voices.voices.iter_mut() { - // Move the pitch envelope stuff independently of the MIDI info - if unison_voice.pitch_enabled { - unison_voice.pitch_current = - match unison_voice.pitch_state { - OscState::Attacking => unison_voice.pitch_attack.next(), - OscState::Decaying => unison_voice.pitch_decay.next(), - OscState::Sustaining => self.pitch_env_sustain / 999.9, - OscState::Releasing => unison_voice.pitch_release.next(), - OscState::Off => 0.0, + center_voices += self.additive_module.next_sample(voice, self.sample_rate, detune_mod) * voice.amp_current; + for internal_unison_voice in voice.internal_unison_voices.iter_mut() { + // Move the pitch envelope stuff independently of the MIDI info + if internal_unison_voice.pitch_enabled { + internal_unison_voice.pitch_current = + match internal_unison_voice.pitch_state { + OscState::Attacking => internal_unison_voice.pitch_attack.next(), + OscState::Decaying => internal_unison_voice.pitch_decay.next(), + OscState::Sustaining => self.pitch_env_sustain / 1999.9, + OscState::Releasing => internal_unison_voice.pitch_release.next(), + OscState::Off => 0.0, + } } - } - if unison_voice.pitch_enabled_2 { - unison_voice.pitch_current_2 = match unison_voice.pitch_state_2 { - OscState::Attacking => unison_voice.pitch_attack_2.next(), - OscState::Decaying => unison_voice.pitch_decay_2.next(), - OscState::Sustaining => self.pitch_env_sustain_2 / 999.9, - OscState::Releasing => unison_voice.pitch_release_2.next(), - OscState::Off => 0.0, + if internal_unison_voice.pitch_enabled_2 { + internal_unison_voice.pitch_current_2 = match internal_unison_voice.pitch_state_2 { + OscState::Attacking => internal_unison_voice.pitch_attack_2.next(), + OscState::Decaying => internal_unison_voice.pitch_decay_2.next(), + OscState::Sustaining => self.pitch_env_sustain_2 / 1999.9, + OscState::Releasing => internal_unison_voice.pitch_release_2.next(), + OscState::Off => 0.0, + } } - } - let temp_osc_gain_multiplier: f32; - // Get our current gain amount for use in match below - // Include gain scaling if mod is there - if vel_gain_mod != -2.0 { - temp_osc_gain_multiplier = match unison_voice.state { - OscState::Attacking => { - unison_voice.osc_attack.next() * vel_gain_mod * vel_lfo_gain_mod - } - OscState::Decaying => { - unison_voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod - } - OscState::Sustaining => { - (self.osc_sustain / 999.9) * vel_gain_mod * vel_lfo_gain_mod - } - OscState::Releasing => { - unison_voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod - } - OscState::Off => 0.0, - }; - } else { - temp_osc_gain_multiplier = match unison_voice.state { - OscState::Attacking => { - unison_voice.osc_attack.next() * vel_lfo_gain_mod - } - OscState::Decaying => unison_voice.osc_decay.next() * vel_lfo_gain_mod, - OscState::Sustaining => (self.osc_sustain / 999.9) * vel_lfo_gain_mod, - OscState::Releasing => { - unison_voice.osc_release.next() * vel_lfo_gain_mod - } - OscState::Off => 0.0, - }; - } + let temp_osc_gain_multiplier: f32; + // Get our current gain amount for use in match below + // Include gain scaling if mod is there + if vel_gain_mod != -2.0 { + temp_osc_gain_multiplier = match internal_unison_voice.state { + OscState::Attacking => { + internal_unison_voice.osc_attack.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Decaying => { + internal_unison_voice.osc_decay.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Sustaining => { + (self.osc_sustain / 1999.9) * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Releasing => { + internal_unison_voice.osc_release.next() * vel_gain_mod * vel_lfo_gain_mod + } + OscState::Off => 0.0, + }; + } else { + temp_osc_gain_multiplier = match internal_unison_voice.state { + OscState::Attacking => internal_unison_voice.osc_attack.next() * vel_lfo_gain_mod, + OscState::Decaying => internal_unison_voice.osc_decay.next() * vel_lfo_gain_mod, + OscState::Sustaining => (self.osc_sustain / 1999.9) * vel_lfo_gain_mod, + OscState::Releasing => internal_unison_voice.osc_release.next() * vel_lfo_gain_mod, + OscState::Off => 0.0, + }; + } - unison_voice.amp_current = temp_osc_gain_multiplier; + internal_unison_voice.amp_current = temp_osc_gain_multiplier; - if unison_voice.vel_mod_amount == 0.0 { - let base_note = unison_voice.note as f32 - + unison_voice._unison_detune_value - + uni_detune_mod - + unison_voice.pitch_current - + unison_voice.pitch_current_2; - unison_voice.phase_delta = - util::f32_midi_note_to_freq(base_note) / self.sample_rate; - } else { - let base_note = unison_voice.note as f32 - + unison_voice._unison_detune_value - + uni_detune_mod - + (unison_voice.vel_mod_amount * unison_voice._velocity) - + unison_voice.pitch_current - + unison_voice.pitch_current_2; - unison_voice.phase_delta = - util::f32_midi_note_to_freq(base_note) / self.sample_rate; - } + let nyquist = self.sample_rate / 2.0; + if internal_unison_voice.vel_mod_amount == 0.0 { + let base_note = internal_unison_voice.note as f32 + + internal_unison_voice._detune + + detune_mod + + internal_unison_voice.pitch_current + + internal_unison_voice.pitch_current_2; + internal_unison_voice.phase_delta = + util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; + } else { + let base_note = internal_unison_voice.note as f32 + + internal_unison_voice._detune + + detune_mod + + (internal_unison_voice.vel_mod_amount * internal_unison_voice._velocity) + + internal_unison_voice.pitch_current + + internal_unison_voice.pitch_current_2; + internal_unison_voice.phase_delta = + util::f32_midi_note_to_freq(base_note).min(nyquist) / self.sample_rate; + } - if self.osc_unison > 1 { - let temp_unison_voice: f32 = self.additive_module.next_sample(unison_voice, self.sample_rate, detune_mod, true) * unison_voice.amp_current; - - // TODO make the unison voice sum - //temp_unison_voice = 0.0; + let temp_unison_voice = self.additive_module.next_unison_sample(internal_unison_voice, self.sample_rate, uni_detune_mod) * internal_unison_voice.amp_current; // Create our stereo pan for unison // Our angle comes back as radians - let pan = unison_voice._angle; + let pan = internal_unison_voice._angle; // Precompute sine and cosine of the angle let cos_pan = pan.cos(); @@ -3960,6 +5339,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) stereo_voices_r += right_amp; } } + // Stereo applies to unison voices // Sum our voices for output summed_voices_l += center_voices; summed_voices_r += center_voices; @@ -3992,7 +5372,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) // Return output (summed_voices_l, summed_voices_r) - } + }, AudioModuleType::Sampler => { let mut summed_voices_l: f32 = 0.0; let mut summed_voices_r: f32 = 0.0; @@ -4005,7 +5385,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) let temp_osc_gain_multiplier: f32 = match voice.state { OscState::Attacking => voice.osc_attack.next(), OscState::Decaying => voice.osc_decay.next(), - OscState::Sustaining => self.osc_sustain / 999.9, + OscState::Sustaining => self.osc_sustain / 1999.9, OscState::Releasing => voice.osc_release.next(), OscState::Off => 0.0, }; @@ -4061,7 +5441,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) let temp_osc_gain_multiplier: f32 = match unison_voice.state { OscState::Attacking => unison_voice.osc_attack.next(), OscState::Decaying => unison_voice.osc_decay.next(), - OscState::Sustaining => self.osc_sustain / 999.9, + OscState::Sustaining => self.osc_sustain / 1999.9, OscState::Releasing => unison_voice.osc_release.next(), OscState::Off => 0.0, }; @@ -4144,11 +5524,11 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) summed_voices_r = mid + stereo; (summed_voices_l, summed_voices_r) - } - AudioModuleType::Off => { + }, + AudioModuleType::Off | AudioModuleType::UnsetAm => { // Do nothing, return 0.0 (0.0, 0.0) - } + }, AudioModuleType::Granulizer => { let mut summed_voices_l: f32 = 0.0; let mut summed_voices_r: f32 = 0.0; @@ -4157,7 +5537,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) let temp_osc_gain_multiplier: f32 = match voice.state { OscState::Attacking => voice.osc_attack.next(), OscState::Decaying => voice.osc_decay.next(), - OscState::Sustaining => self.osc_sustain / 999.9, + OscState::Sustaining => self.osc_sustain / 1999.9, OscState::Releasing => voice.osc_release.next(), OscState::Off => 0.0, }; @@ -4227,7 +5607,7 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } } (summed_voices_l, summed_voices_r) - } + }, }; // Send it back @@ -4336,84 +5716,94 @@ UniRandom: Every voice uses its own unique random phase every note".to_string()) } if self.restretch { - let middle_c: f32 = 256.0; - // Generate our sample library from our sample - for i in 0..127 { - let target_pitch_factor = util::f32_midi_note_to_freq(i as f32) / middle_c; - - // Calculate the number of samples in the shifted frame - let shifted_num_samples = - (self.loaded_sample[0].len() as f32 / target_pitch_factor).round() as usize; - - // Apply pitch shifting by interpolating between the original samples - let mut shifted_samples_l = Vec::with_capacity(shifted_num_samples); - let mut shifted_samples_r = Vec::with_capacity(shifted_num_samples); - - for j in 0..shifted_num_samples { - let original_index: usize; - let fractional_part: f32; - - original_index = (j as f32 * target_pitch_factor).floor() as usize; - fractional_part = j as f32 * target_pitch_factor - original_index as f32; - - if original_index < self.loaded_sample[0].len() - 1 { - // Linear interpolation between adjacent samples - let interpolated_sample_r; - let interpolated_sample_l = (1.0 - fractional_part) - * self.loaded_sample[0][original_index] - + fractional_part * self.loaded_sample[0][original_index + 1]; - if self.loaded_sample.len() > 1 { - interpolated_sample_r = (1.0 - fractional_part) - * self.loaded_sample[1][original_index] - + fractional_part * self.loaded_sample[1][original_index + 1]; - } else { - interpolated_sample_r = interpolated_sample_l; - } - - shifted_samples_l.push(interpolated_sample_l); - shifted_samples_r.push(interpolated_sample_r); - } else { - // If somehow through buffer shenanigans we are past our length we shouldn't do anything here - if original_index < self.loaded_sample[0].len() { - shifted_samples_l.push(self.loaded_sample[0][original_index]); - if self.loaded_sample.len() > 1 { - shifted_samples_r.push(self.loaded_sample[1][original_index]); + match self.audio_module_type { + AudioModuleType::Granulizer | AudioModuleType::Sampler => { + let middle_c: f32 = 256.0; + // Generate our sample library from our sample + for i in 0..127 { + let target_pitch_factor = util::f32_midi_note_to_freq(i as f32) / middle_c; + + // Calculate the number of samples in the shifted frame + let shifted_num_samples = + (self.loaded_sample[0].len() as f32 / target_pitch_factor).round() as usize; + + // Apply pitch shifting by interpolating between the original samples + let mut shifted_samples_l = Vec::with_capacity(shifted_num_samples); + let mut shifted_samples_r = Vec::with_capacity(shifted_num_samples); + + for j in 0..shifted_num_samples { + let original_index: usize; + let fractional_part: f32; + + original_index = (j as f32 * target_pitch_factor).floor() as usize; + fractional_part = j as f32 * target_pitch_factor - original_index as f32; + + if original_index < self.loaded_sample[0].len() - 1 { + // Linear interpolation between adjacent samples + let interpolated_sample_r; + let interpolated_sample_l = (1.0 - fractional_part) + * self.loaded_sample[0][original_index] + + fractional_part * self.loaded_sample[0][original_index + 1]; + if self.loaded_sample.len() > 1 { + interpolated_sample_r = (1.0 - fractional_part) + * self.loaded_sample[1][original_index] + + fractional_part * self.loaded_sample[1][original_index + 1]; + } else { + interpolated_sample_r = interpolated_sample_l; + } + + shifted_samples_l.push(interpolated_sample_l); + shifted_samples_r.push(interpolated_sample_r); } else { - shifted_samples_r.push(self.loaded_sample[0][original_index]); + // If somehow through buffer shenanigans we are past our length we shouldn't do anything here + if original_index < self.loaded_sample[0].len() { + shifted_samples_l.push(self.loaded_sample[0][original_index]); + if self.loaded_sample.len() > 1 { + shifted_samples_r.push(self.loaded_sample[1][original_index]); + } else { + shifted_samples_r.push(self.loaded_sample[0][original_index]); + } + } } } + + let mut NoteVector = Vec::with_capacity(2); + NoteVector.insert(0, shifted_samples_l); + NoteVector.insert(1, shifted_samples_r); + self.sample_lib.insert(i, NoteVector); } - } - - let mut NoteVector = Vec::with_capacity(2); - NoteVector.insert(0, shifted_samples_l); - NoteVector.insert(1, shifted_samples_r); - self.sample_lib.insert(i, NoteVector); + }, + _ => {}, } } // If we are just pitch shifting instead of restretching else { - let mut shifter = PitchShifter::new(50, self.sample_rate as usize); - for i in 0..127 { - let translated_i = (i as i32 - 60_i32) as f32; - let mut out_buffer_left = vec![0.0; self.loaded_sample[0].len()]; - let mut out_buffer_right = vec![0.0; self.loaded_sample[0].len()]; - - let loaded_left = self.loaded_sample[0].as_slice(); - let loaded_right; - if self.loaded_sample.len() > 1 { - loaded_right = self.loaded_sample[1].as_slice(); - } else { - loaded_right = self.loaded_sample[0].as_slice(); - } - - shifter.shift_pitch(3, translated_i, loaded_left, &mut out_buffer_left); - shifter.shift_pitch(3, translated_i, loaded_right, &mut out_buffer_right); - - let mut NoteVector = Vec::with_capacity(2); - NoteVector.insert(0, out_buffer_left); - NoteVector.insert(1, out_buffer_right); - self.sample_lib.insert(i, NoteVector); + match self.audio_module_type { + AudioModuleType::Granulizer | AudioModuleType::Sampler => { + let mut shifter = PitchShifter::new(50, self.sample_rate as usize); + for i in 0..127 { + let translated_i = (i as i32 - 60_i32) as f32; + let mut out_buffer_left = vec![0.0; self.loaded_sample[0].len()]; + let mut out_buffer_right = vec![0.0; self.loaded_sample[0].len()]; + + let loaded_left = self.loaded_sample[0].as_slice(); + let loaded_right; + if self.loaded_sample.len() > 1 { + loaded_right = self.loaded_sample[1].as_slice(); + } else { + loaded_right = self.loaded_sample[0].as_slice(); + } + + shifter.shift_pitch(3, translated_i, loaded_left, &mut out_buffer_left); + shifter.shift_pitch(3, translated_i, loaded_right, &mut out_buffer_right); + + let mut NoteVector = Vec::with_capacity(2); + NoteVector.insert(0, out_buffer_left); + NoteVector.insert(1, out_buffer_right); + self.sample_lib.insert(i, NoteVector); + } + }, + _ => {}, } } } @@ -4508,4 +5898,272 @@ fn check_inequality( a5 != b5 || a6 != b6 || a7 != b7 || a8 != b8 || a9 != b9 || a10 != b10 || a11 != b11 || a12 != b12 || a13 != b13 || a14 != b14 || a15 != b15 || a16 != b16 +} + + + +fn filter_process_1( + filter_alg_type: FilterAlgorithms, + filter_resonance: f32, + sample_rate: f32, + filter_res_type: ResonanceType, + lp_amount: f32, + bp_amount: f32, + hp_amount: f32, + filter_wet: f32, + tilt_filter_type: ResponseType, + vcf_filter_type: VCFResponseType, + voice: &mut SingleVoice, + next_filter_step: f32, + filter_resonance_mod: f32, + left_input_filter1: f32, + right_input_filter1: f32, +) -> (f32, f32) { + match filter_alg_type { + FilterAlgorithms::SVF => { + // Filtering before output + voice.filter_l_1.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + sample_rate, + filter_res_type.clone(), + ); + voice.filter_r_1.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + sample_rate, + filter_res_type.clone(), + ); + let low_l: f32; + let band_l: f32; + let high_l: f32; + let low_r: f32; + let band_r: f32; + let high_r: f32; + (low_l, band_l, high_l) = voice.filter_l_1.process(left_input_filter1); + (low_r, band_r, high_r) = voice.filter_r_1.process(right_input_filter1); + let left_output = (low_l * lp_amount + + band_l * bp_amount + + high_l * hp_amount) + * filter_wet + + left_input_filter1 * (1.0 - filter_wet); + let right_output = (low_r * lp_amount + + band_r * bp_amount + + high_r * hp_amount) + * filter_wet + + right_input_filter1 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::TILT => { + voice.tilt_filter_l_1.update( + sample_rate, + next_filter_step, + filter_resonance - filter_resonance_mod, + tilt_filter_type.clone(), + ); + voice.tilt_filter_r_1.update( + sample_rate, + next_filter_step, + filter_resonance - filter_resonance_mod, + tilt_filter_type.clone(), + ); + let tilt_out_l = voice.tilt_filter_l_1.process(left_input_filter1 * db_to_gain(-12.0)); + let tilt_out_r = voice.tilt_filter_r_1.process(right_input_filter1 * db_to_gain(-12.0)); + let left_output = tilt_out_l * filter_wet + + left_input_filter1 * (1.0 - filter_wet); + let right_output = tilt_out_r * filter_wet + + right_input_filter1 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::VCF => { + voice.vcf_filter_l_1.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + vcf_filter_type.clone(), + sample_rate, + ); + voice.vcf_filter_r_1.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + vcf_filter_type.clone(), + sample_rate, + ); + let vcf_out_l = voice.vcf_filter_l_1.process(left_input_filter1); + let vcf_out_r = voice.vcf_filter_r_1.process(right_input_filter1); + let left_output = vcf_out_l * filter_wet + + left_input_filter1 * (1.0 - filter_wet); + let right_output = vcf_out_r * filter_wet + + right_input_filter1 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::V4 => { + voice.V4F_l_1.update( + filter_resonance, + next_filter_step, + sample_rate + ); + voice.V4F_r_1.update( + filter_resonance, + next_filter_step, + sample_rate + ); + let v4f_out_l = voice.V4F_l_1.process(left_input_filter1); + let v4f_out_r = voice.V4F_r_1.process(right_input_filter1); + let left_output = v4f_out_l * filter_wet + + left_input_filter1 * (1.0 - filter_wet); + let right_output = v4f_out_r * filter_wet + + right_input_filter1 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::A4I => { + voice.A4I_l_1.update( + next_filter_step, + filter_resonance, + sample_rate); + voice.A4I_r_1.update( + next_filter_step, + filter_resonance, + sample_rate); + let a4i_out_l = voice.A4I_l_1.process(left_input_filter1); + let a4i_out_r = voice.A4I_r_1.process(right_input_filter1); + let left_output = a4i_out_l * filter_wet + + left_input_filter1 * (1.0 - filter_wet); + let right_output = a4i_out_r * filter_wet + + right_input_filter1 * (1.0 - filter_wet); + (left_output,right_output) + } + } +} + +fn filter_process_2( + filter_alg_type: FilterAlgorithms, + filter_resonance: f32, + sample_rate: f32, + filter_res_type: ResonanceType, + lp_amount: f32, + bp_amount: f32, + hp_amount: f32, + filter_wet: f32, + tilt_filter_type: ResponseType, + vcf_filter_type: VCFResponseType, + voice: &mut SingleVoice, + next_filter_step: f32, + filter_resonance_mod: f32, + left_input_filter2: f32, + right_input_filter2: f32, +) -> (f32, f32) { + match filter_alg_type { + FilterAlgorithms::SVF => { + // Filtering before output + voice.filter_l_2.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + sample_rate, + filter_res_type.clone(), + ); + voice.filter_r_2.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + sample_rate, + filter_res_type.clone(), + ); + let low_l: f32; + let band_l: f32; + let high_l: f32; + let low_r: f32; + let band_r: f32; + let high_r: f32; + (low_l, band_l, high_l) = voice.filter_l_2.process(left_input_filter2); + (low_r, band_r, high_r) = voice.filter_r_2.process(right_input_filter2); + let left_output = (low_l * lp_amount + + band_l * bp_amount + + high_l * hp_amount) + * filter_wet + + left_input_filter2 * (1.0 - filter_wet); + let right_output = (low_r * lp_amount + + band_r * bp_amount + + high_r * hp_amount) + * filter_wet + + right_input_filter2 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::TILT => { + voice.tilt_filter_l_2.update( + sample_rate, + next_filter_step, + filter_resonance - filter_resonance_mod, + tilt_filter_type.clone(), + ); + voice.tilt_filter_r_2.update( + sample_rate, + next_filter_step, + filter_resonance - filter_resonance_mod, + tilt_filter_type.clone(), + ); + let tilt_out_l = voice.tilt_filter_l_2.process(left_input_filter2 * db_to_gain(-12.0)); + let tilt_out_r = voice.tilt_filter_r_2.process(right_input_filter2 * db_to_gain(-12.0)); + let left_output = tilt_out_l * filter_wet + + left_input_filter2 * (1.0 - filter_wet); + let right_output = tilt_out_r * filter_wet + + right_input_filter2 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::VCF => { + voice.vcf_filter_l_2.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + vcf_filter_type.clone(), + sample_rate, + ); + voice.vcf_filter_r_2.update( + next_filter_step, + filter_resonance - filter_resonance_mod, + vcf_filter_type.clone(), + sample_rate, + ); + let vcf_out_l = voice.vcf_filter_l_2.process(left_input_filter2); + let vcf_out_r = voice.vcf_filter_r_2.process(right_input_filter2); + let left_output = vcf_out_l * filter_wet + + left_input_filter2 * (1.0 - filter_wet); + let right_output = vcf_out_r * filter_wet + + right_input_filter2 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::V4 => { + voice.V4F_l_2.update( + filter_resonance, + next_filter_step, + sample_rate + ); + voice.V4F_r_2.update( + filter_resonance, + next_filter_step, + sample_rate + ); + let v4f_out_l = voice.V4F_l_2.process(left_input_filter2); + let v4f_out_r = voice.V4F_r_2.process(right_input_filter2); + let left_output = v4f_out_l * filter_wet + + left_input_filter2 * (1.0 - filter_wet); + let right_output = v4f_out_r * filter_wet + + right_input_filter2 * (1.0 - filter_wet); + (left_output,right_output) + } + FilterAlgorithms::A4I => { + voice.A4I_l_2.update( + next_filter_step, + filter_resonance, + sample_rate); + voice.A4I_r_2.update( + next_filter_step, + filter_resonance, + sample_rate); + let a4i_out_l = voice.A4I_l_2.process(left_input_filter2); + let a4i_out_r = voice.A4I_r_2.process(right_input_filter2); + let left_output = a4i_out_l * filter_wet + + left_input_filter2 * (1.0 - filter_wet); + let right_output = a4i_out_r * filter_wet + + right_input_filter2 * (1.0 - filter_wet); + (left_output,right_output) + } + } } \ No newline at end of file diff --git a/src/audio_module/AdditiveModule.rs b/src/audio_module/AdditiveModule.rs index 8f90b88..1a3fb2c 100644 --- a/src/audio_module/AdditiveModule.rs +++ b/src/audio_module/AdditiveModule.rs @@ -1,7 +1,7 @@ use std::f32::consts::{FRAC_PI_2, PI, TAU}; use nih_plug::util; -use super::SingleVoice; +use super::{SingleUnisonVoice, SingleVoice}; #[derive(Clone, PartialEq)] pub struct AdditiveHarmonic { @@ -34,16 +34,38 @@ impl AdditiveOscillator { self.harmonics = harmonics; } - pub fn next_sample(&mut self, voice: &mut SingleVoice, sample_rate: f32, detune_mod: f32, unison_voice: bool) -> f32 { + pub fn next_sample(&mut self, voice: &mut SingleVoice, sample_rate: f32, detune_mod: f32) -> f32 { + let mut sample = 0.0; + let nyquist = sample_rate / 2.0; + + if voice.amp_current != 0.0 { + let base_note = voice.note as f32 + voice._detune + detune_mod + voice.pitch_current + voice.pitch_current_2; + let instant_frequency = util::f32_midi_note_to_freq(base_note).min(nyquist); + voice.phase_delta = instant_frequency / sample_rate; + + for (i, harmonic) in self.harmonics.iter_mut().enumerate() { + if harmonic.amplitude != 0.0 { + let harmonic_freq = if harmonic.index == 0 { + instant_frequency + } else { + (harmonic.index as f32 + 1.0) * instant_frequency + }; + let phase_increment = TAU * harmonic_freq / sample_rate; + voice.harmonic_phases[i] = (voice.harmonic_phases[i] + phase_increment) % TAU; + sample += fast_sine(voice.harmonic_phases[i]) * harmonic.amplitude; + } + } + } + + sample + } + + pub fn next_unison_sample(&mut self, voice: &mut SingleUnisonVoice, sample_rate: f32, detune_mod: f32) -> f32 { let mut sample = 0.0; let nyquist = sample_rate / 2.0; if voice.amp_current != 0.0 { - let base_note = if unison_voice { - voice.note as f32 + voice._unison_detune_value + detune_mod + voice.pitch_current + voice.pitch_current_2 - } else { - voice.note as f32 + voice._detune + detune_mod + voice.pitch_current + voice.pitch_current_2 - }; + let base_note = voice.note as f32 + voice._unison_detune_value + detune_mod + voice.pitch_current + voice.pitch_current_2; let instant_frequency = util::f32_midi_note_to_freq(base_note).min(nyquist); voice.phase_delta = instant_frequency / sample_rate; diff --git a/src/audio_module/Oscillator.rs b/src/audio_module/Oscillator.rs index 4f75d9c..ab5c643 100644 --- a/src/audio_module/Oscillator.rs +++ b/src/audio_module/Oscillator.rs @@ -493,22 +493,6 @@ const TRI_TABLE: [f32; 512] =[ 0.0,0.007827789,0.015655577,0.023483366,0.031311154,0.039138943,0.04696673,0.05479452,0.06262231,0.0704501,0.078277886,0.086105675,0.09393346,0.10176125,0.10958904,0.11741683,0.12524462,0.1330724,0.1409002,0.14872798,0.15655577,0.16438356,0.17221135,0.18003914,0.18786693,0.19569471,0.20352252,0.21135029,0.21917808,0.22700587,0.23483367,0.24266145,0.25048923,0.25831705,0.2661448,0.27397257,0.2818004,0.28962818,0.29745597,0.30528376,0.31311154,0.32093933,0.32876712,0.3365949,0.34442267,0.35225046,0.3600783,0.36790606,0.37573385,0.38356164,0.3913895,0.39921725,0.40704495,0.4148728,0.42270058,0.43052837,0.43835622,0.44618395,0.45401174,0.46183953,0.4696673,0.47749513,0.48532286,0.49315068,0.50097847,0.5088062,0.51663405,0.5244619,0.5322896,0.5401175,0.54794514,0.555773,0.5636008,0.57142854,0.57925636,0.5870841,0.59491193,0.60273975,0.6105675,0.6183953,0.6262231,0.6340509,0.64187866,0.6497065,0.65753424,0.665362,0.6731898,0.68101764,0.6888454,0.6966732,0.704501,0.71232873,0.72015655,0.72798437,0.7358121,0.7436398,0.75146765,0.75929546,0.7671233,0.7749511,0.782779,0.7906067,0.79843444,0.8062622,0.8140899,0.8219178,0.8297456,0.8375733,0.8454011,0.85322887,0.86105675,0.8688846,0.8767123,0.88454014,0.89236796,0.9001958,0.90802336,0.91585124,0.9236792,0.93150693,0.93933463,0.94716233,0.9549903,0.96281797,0.9706455,0.9784739,0.9863011,0.99413073,0.99804634,0.9902143,0.98238766,0.9745598,0.96673167,0.9589042,0.95107627,0.9432484,0.93542063,0.92759305,0.9197649,0.91193736,0.9041094,0.89628166,0.8884539,0.88062626,0.8727983,0.8649705,0.8571428,0.849315,0.8414872,0.83365947,0.8258315,0.81800383,0.8101761,0.80234826,0.7945205,0.7866927,0.77886486,0.7710371,0.7632092,0.75538146,0.74755377,0.739726,0.7318981,0.7240704,0.7162425,0.7084148,0.70058703,0.6927592,0.6849314,0.6771037,0.66927594,0.661448,0.6536203,0.6457925,0.63796467,0.63013697,0.6223091,0.6144814,0.6066536,0.5988257,0.59099793,0.58317024,0.5753424,0.5675146,0.5596869,0.551859,0.54403114,0.5362035,0.5283756,0.5205479,0.5127201,0.50489223,0.4970645,0.48923683,0.48140895,0.47358108,0.46575344,0.4579256,0.45009768,0.44227,0.43444216,0.42661443,0.41878662,0.41095874,0.40313104,0.39530334,0.38747552,0.3796476,0.3718199,0.36399207,0.35616425,0.34833655,0.34050867,0.33268097,0.32485315,0.31702542,0.30919757,0.30136988,0.29354206,0.28571418,0.27788648,0.27005866,0.26223078,0.25440308,0.24657522,0.23874752,0.23091967,0.22309197,0.21526413,0.20743643,0.19960856,0.19178072,0.18395302,0.17612517,0.16829732,0.16046962,0.15264176,0.14481406,0.13698623,0.12915851,0.121330656,0.11350296,0.10567511,0.09784725,0.090019554,0.082191706,0.07436385,0.06653615,0.0587083,0.050880603,0.043052748,0.035225052,0.027397199,0.019569498,0.011741647,0.003913794,-0.003913906,-0.011741757,-0.019569458,-0.02739716,-0.035225164,-0.043053016,-0.050880715,-0.058708414,-0.06653626,-0.07436397,-0.08219182,-0.09001952,-0.09784752,-0.10567522,-0.113503076,-0.121330775,-0.12915862,-0.13698633,-0.14481403,-0.15264188,-0.16046987,-0.16829757,-0.17612529,-0.18395314,-0.19178084,-0.19960867,-0.20743638,-0.21526408,-0.22309211,-0.23091994,-0.23874764,-0.24657536,-0.2544032,-0.2622309,-0.27005875,-0.27788645,-0.28571445,-0.29354215,-0.30137,-0.3091977,-0.31702554,-0.32485327,-0.33268094,-0.34050882,-0.3483368,-0.35616452,-0.3639922,-0.3718201,-0.37964773,-0.38747564,-0.39530328,-0.40313104,-0.410959,-0.41878688,-0.42661458,-0.43444228,-0.44227013,-0.45009783,-0.45792568,-0.46575338,-0.4735814,-0.4814091,-0.48923695,-0.49706462,-0.50489235,-0.51272017,-0.52054787,-0.5283757,-0.53620374,-0.54403144,-0.55185914,-0.55968684,-0.56751484,-0.57534254,-0.58317024,-0.59099793,-0.59882593,-0.60665363,-0.6144817,-0.6223094,-0.6301371,-0.63796467,-0.6457925,-0.65362006,-0.6614482,-0.6692762,-0.6771038,-0.6849316,-0.6927593,-0.7005869,-0.7084149,-0.7162427,-0.72407067,-0.7318983,-0.739726,-0.74755377,-0.75538176,-0.7632094,-0.7710373,-0.77886486,-0.78669286,-0.7945205,-0.8023485,-0.8101762,-0.818004,-0.8258316,-0.8336593,-0.8414871,-0.849315,-0.85714316,-0.86497074,-0.87279856,-0.88062626,-0.8884539,-0.8962819,-0.90410966,-0.91193765,-0.9197652,-0.92759305,-0.93542063,-0.9432488,-0.95107627,-0.9589042,-0.96673167,-0.9745598,-0.98238766,-0.9902143,-0.99804634,-0.99413073,-0.9863011,-0.9784739,-0.9706455,-0.96281797,-0.9549898,-0.94716233,-0.93933463,-0.93150693,-0.9236792,-0.91585124,-0.90802336,-0.90019554,-0.8923677,-0.88454014,-0.8767123,-0.86888427,-0.86105657,-0.85322887,-0.8454012,-0.8375732,-0.8297455,-0.8219175,-0.81408983,-0.80626214,-0.79843444,-0.79060674,-0.78277904,-0.774951,-0.7671229,-0.7592952,-0.7514675,-0.7436398,-0.7358121,-0.72798413,-0.72015655,-0.7123285,-0.7045008,-0.69667304,-0.6888454,-0.6810174,-0.6731897,-0.665362,-0.65753424,-0.6497063,-0.6418786,-0.6340509,-0.62622285,-0.6183952,-0.6105675,-0.60273975,-0.59491205,-0.5870841,-0.579256,-0.5714284,-0.56360066,-0.555773,-0.54794526,-0.54011726,-0.53228956,-0.52446157,-0.51663387,-0.5088061,-0.50097847,-0.4931504,-0.4853228,-0.47749504,-0.46966735,-0.46183938,-0.45401165,-0.44618395,-0.43835595,-0.43052825,-0.42270055,-0.41487285,-0.4070452,-0.39921713,-0.39138913,-0.38356146,-0.37573373,-0.367906,-0.36007833,-0.35225034,-0.34442267,-0.33659464,-0.32876694,-0.32093924,-0.31311154,-0.30528352,-0.29745582,-0.28962812,-0.28180042,-0.27397242,-0.26614472,-0.25831705,-0.25048903,-0.24266131,-0.23483361,-0.22700594,-0.21917824,-0.21135022,-0.2035222,-0.1956945,-0.18786684,-0.18003911,-0.17221141,-0.16438341,-0.15655571,-0.1487277,-0.1409,-0.1330723,-0.1252446,-0.1174166,-0.10958891,-0.10176121,-0.0939335,-0.086105496,-0.0782778,-0.070450105,-0.0626221,-0.054794393,-0.046966698,-0.039138995,-0.031311296,-0.023483293,-0.01565529,-0.007827589,0.00000011131013, ]; -#[derive(Enum, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)] -pub enum VoiceType { - Sine, - Tri, - Saw, - RSaw, - WSaw, - SSaw, - RASaw, - Ramp, - Square, - RSquare, - Pulse, - Noise, -} - #[derive(Enum, PartialEq, Eq, Debug, Copy, Clone)] pub enum OscState { Off, diff --git a/src/fx/A4I_Filter.rs b/src/fx/A4I_Filter.rs index 3f68af0..55a1190 100644 --- a/src/fx/A4I_Filter.rs +++ b/src/fx/A4I_Filter.rs @@ -4,6 +4,7 @@ use nih_plug::util; // Define the filter structure +#[derive(Clone)] pub struct A4iFilter { poles: [OnePoleLowPassFilter; 4], iter: usize, @@ -73,6 +74,7 @@ impl A4iFilter { } +#[derive(Clone)] pub struct OnePoleLowPassFilter { alpha: f32, prev_output: f32, diff --git a/src/fx/StateVariableFilter.rs b/src/fx/StateVariableFilter.rs index 7ada781..f7b8ee7 100644 --- a/src/fx/StateVariableFilter.rs +++ b/src/fx/StateVariableFilter.rs @@ -44,7 +44,7 @@ impl Default for StateVariableFilter { sample_rate: 44100.0, sample_rate_quad: 44100.0 * 4.0, sample_rate_half: 22050.0, - q: 0.0, + q: 0.1, frequency: 20000.0, double_pi_freq: 2.0 * PI * 20000.0, low_output: 0.0, @@ -144,13 +144,26 @@ impl StateVariableFilter { } }; + let rd_input = remove_denormals(input); + // Oversample by running multiple iterations for _ in 0..self.oversample { self.low_output += normalized_freq * self.band_output; - self.high_output = input - self.low_output - self.q * self.band_output; + self.high_output = rd_input - self.low_output - self.q * self.band_output; self.band_output += resonance * self.high_output; self.low_output += resonance * self.band_output; } + self.low_output = remove_denormals(self.low_output); + self.band_output = remove_denormals(self.band_output); + self.high_output = remove_denormals(self.high_output); (self.low_output, self.band_output, self.high_output) } } + +fn remove_denormals(x: f32) -> f32 { + if x.abs() < 1e-30 { + 0.0 + } else { + x + } +} diff --git a/src/fx/VCFilter.rs b/src/fx/VCFilter.rs index d69a160..c41b130 100644 --- a/src/fx/VCFilter.rs +++ b/src/fx/VCFilter.rs @@ -11,6 +11,7 @@ pub enum ResponseType { Highpass, } +#[derive(Clone)] pub struct VCFilter { // Parameters center_freq: f32, @@ -30,7 +31,7 @@ impl VCFilter { pub fn new() -> Self { VCFilter { center_freq: 1000.0, - resonance: 0.0, + resonance: 0.1, shape: ResponseType::Lowpass, f: 0.0, k: 0.0, diff --git a/src/lib.rs b/src/lib.rs index efcf8d5..367a2d2 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.3.3 +Version 1.3.4 ##################################### @@ -25,15 +25,14 @@ 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, GeneratorType, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel, StereoAlgorithm}; +use actuate_enums::{AMFilterRouting, FilterAlgorithms, FilterRouting, ModulationDestination, ModulationSource, PitchRouting, PresetType, ReverbModel, StereoAlgorithm}; use actuate_structs::{ActuatePresetV131, ModulationStruct}; -use flate2::{read::GzDecoder,write::GzEncoder,Compression}; -use nih_plug::{prelude::*, util::db_to_gain}; +use nih_plug::{prelude::*}; use nih_plug_egui::{ egui::{Color32, FontId}, EguiState }; use std::{ - fs::File, io::{Read, Write}, path::PathBuf, sync::{ + fs::File, io::{Read}, path::PathBuf, sync::{ atomic::{AtomicBool, AtomicU32, Ordering}, Arc, Mutex, } @@ -42,15 +41,17 @@ use std::{ // My Files/crates use audio_module::{ AudioModule, AudioModuleType, - Oscillator::{self, OscState, RetriggerStyle, SmoothStyle, VoiceType}, + Oscillator::{self, OscState, RetriggerStyle, SmoothStyle}, frequency_modulation, }; use fx::{ - 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, A4I_Filter::{self, A4iFilter}, ArduraFilter::{self, ResponseType}, StateVariableFilter::{ResonanceType,StateVariableFilter}, V4Filter::{self, V4FilterStruct}, 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 }; +// This is here in meantime until new Actuate versions past this one! +#[allow(unused_imports)] use old_preset_structs::{ - load_unserialized_old, load_unserialized_v114, load_unserialized_v122, load_unserialized_v123, load_unserialized_v125, load_unserialized_v126, load_unserialized_v130, ActuatePresetV123, ActuatePresetV125, ActuatePresetV126, ActuatePresetV130 + _load_unserialized_v130, ActuatePresetV130 }; mod actuate_gui; @@ -122,83 +123,23 @@ pub struct Actuate { audio_module_2: Arc>, audio_module_3: Arc>, - // SVF Filters - filter_l_1: StateVariableFilter, - filter_r_1: StateVariableFilter, - // TILT Filters - tilt_filter_l_1: ArduraFilter::ArduraFilter, - tilt_filter_r_1: ArduraFilter::ArduraFilter, - // VCF Filters - vcf_filter_l_1: fx::VCFilter::VCFilter, - vcf_filter_r_1: fx::VCFilter::VCFilter, - // Filter state variables - filter_state_1: OscState, - filter_atk_smoother_1: Smoother, - filter_dec_smoother_1: Smoother, - filter_rel_smoother_1: Smoother, - - // SVF Filters - filter_l_2: StateVariableFilter, - filter_r_2: StateVariableFilter, - // TILT Filters - tilt_filter_l_2: ArduraFilter::ArduraFilter, - tilt_filter_r_2: ArduraFilter::ArduraFilter, - // VCF Filters - vcf_filter_l_2: fx::VCFilter::VCFilter, - vcf_filter_r_2: fx::VCFilter::VCFilter, - // Filter state variables - filter_state_2: OscState, - filter_atk_smoother_2: Smoother, - filter_dec_smoother_2: Smoother, - filter_rel_smoother_2: Smoother, // LFOs! lfo_1: LFOController::LFOController, lfo_2: LFOController::LFOController, lfo_3: LFOController::LFOController, - // Modulation overrides for preset loading - mod_override_source_1: Arc>, - mod_override_source_2: Arc>, - mod_override_source_3: Arc>, - mod_override_source_4: Arc>, - mod_override_dest_1: Arc>, - mod_override_dest_2: Arc>, - mod_override_dest_3: Arc>, - mod_override_dest_4: Arc>, - preset_category_override: Arc>, - - // Other overrides for preset loading - gen_1_routing_override: Arc>, - gen_2_routing_override: Arc>, - gen_3_routing_override: Arc>, - gen_1_type_override: Arc>, - gen_2_type_override: Arc>, - gen_3_type_override: Arc>, - // Preset Lib Default preset_lib_name: Arc>, preset_name: Arc>, preset_info: Arc>, - preset_category: Arc>, + //preset_category: Arc>, preset_lib: Arc>>, // Used for DC Offset calculations dc_filter_l: StateVariableFilter, dc_filter_r: StateVariableFilter, - // V4 Filter - V4F_l_1: V4Filter::V4FilterStruct, - V4F_l_2: V4Filter::V4FilterStruct, - V4F_r_1: V4Filter::V4FilterStruct, - V4F_r_2: V4Filter::V4FilterStruct, - - // A4I Filter - A4I_l_1: A4I_Filter::A4iFilter, - A4I_l_2: A4I_Filter::A4iFilter, - A4I_r_1: A4I_Filter::A4iFilter, - A4I_r_2: A4I_Filter::A4iFilter, - fm_state: OscState, fm_atk_smoother_1: Smoother, fm_dec_smoother_1: Smoother, @@ -269,7 +210,7 @@ pub struct Actuate { impl Default for Actuate { fn default() -> Self { // These are persistent fields to trigger updates like Diopser - let update_something = Arc::new(AtomicBool::new(false)); + let update_something = Arc::new(AtomicBool::new(true)); let clear_voices = Arc::new(AtomicBool::new(false)); let reload_entire_preset = Arc::new(AtomicBool::new(false)); let file_dialog = Arc::new(AtomicBool::new(false)); @@ -291,7 +232,6 @@ impl Default for Actuate { Self { params: Arc::new(ActuateParams::new( update_something.clone(), - clear_voices.clone(), file_dialog.clone(), update_current_preset.clone(), )), @@ -323,99 +263,17 @@ impl Default for Actuate { audio_module_2: Arc::new(Mutex::new(AudioModule::default())), audio_module_3: Arc::new(Mutex::new(AudioModule::default())), - // SVF Filters - filter_l_2: StateVariableFilter::default().set_oversample(4), - filter_r_2: StateVariableFilter::default().set_oversample(4), - // TILT Filters - tilt_filter_l_2: ArduraFilter::ArduraFilter::new( - 44100.0, - 20000.0, - 1.0, - ResponseType::Lowpass, - ), - tilt_filter_r_2: ArduraFilter::ArduraFilter::new( - 44100.0, - 20000.0, - 1.0, - ResponseType::Lowpass, - ), - // VCF Filters - vcf_filter_l_1: fx::VCFilter::VCFilter::new(), - vcf_filter_r_1: fx::VCFilter::VCFilter::new(), - - // V4Filter - V4F_l_1: V4FilterStruct::default(), - V4F_r_1: V4FilterStruct::default(), - - // A4I Filter - A4I_l_1: A4iFilter::new(44100.0, 20000.0, 0.0), - A4I_r_1: A4iFilter::new(44100.0, 20000.0, 0.0), - - filter_state_2: OscState::Off, - filter_atk_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), - filter_dec_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), - filter_rel_smoother_2: Smoother::new(SmoothingStyle::Linear(300.0)), - - // SVF Filters - filter_l_1: StateVariableFilter::default().set_oversample(4), - filter_r_1: StateVariableFilter::default().set_oversample(4), - // TILT Filters - tilt_filter_l_1: ArduraFilter::ArduraFilter::new( - 44100.0, - 20000.0, - 1.0, - ResponseType::Lowpass, - ), - tilt_filter_r_1: ArduraFilter::ArduraFilter::new( - 44100.0, - 20000.0, - 1.0, - ResponseType::Lowpass, - ), - // VCF Filters - vcf_filter_l_2: fx::VCFilter::VCFilter::new(), - vcf_filter_r_2: fx::VCFilter::VCFilter::new(), - - // V4Filter - V4F_l_2: V4FilterStruct::default(), - V4F_r_2: V4FilterStruct::default(), - - // A4I Filter - A4I_l_2: A4iFilter::new(44100.0, 20000.0, 0.0), - A4I_r_2: A4iFilter::new(44100.0, 20000.0, 0.0), - - filter_state_1: OscState::Off, - filter_atk_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), - filter_dec_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), - filter_rel_smoother_1: Smoother::new(SmoothingStyle::Linear(300.0)), //LFOs lfo_1: LFOController::LFOController::new(2.0, 1.0, LFOController::Waveform::Sine, 0.0), lfo_2: LFOController::LFOController::new(2.0, 1.0, LFOController::Waveform::Sine, 0.0), lfo_3: LFOController::LFOController::new(2.0, 1.0, LFOController::Waveform::Sine, 0.0), - // Modulation Overrides - mod_override_source_1: Arc::new(Mutex::new(ModulationSource::UnsetModulation)), - mod_override_source_2: Arc::new(Mutex::new(ModulationSource::UnsetModulation)), - mod_override_source_3: Arc::new(Mutex::new(ModulationSource::UnsetModulation)), - mod_override_source_4: Arc::new(Mutex::new(ModulationSource::UnsetModulation)), - mod_override_dest_1: Arc::new(Mutex::new(ModulationDestination::UnsetModulation)), - mod_override_dest_2: Arc::new(Mutex::new(ModulationDestination::UnsetModulation)), - mod_override_dest_3: Arc::new(Mutex::new(ModulationDestination::UnsetModulation)), - mod_override_dest_4: Arc::new(Mutex::new(ModulationDestination::UnsetModulation)), - preset_category_override: Arc::new(Mutex::new(PresetType::Select)), - gen_1_routing_override: Arc::new(Mutex::new(AMFilterRouting::UNSETROUTING)), - gen_2_routing_override: Arc::new(Mutex::new(AMFilterRouting::UNSETROUTING)), - gen_3_routing_override: Arc::new(Mutex::new(AMFilterRouting::UNSETROUTING)), - gen_1_type_override: Arc::new(Mutex::new(GeneratorType::Off)), - gen_2_type_override: Arc::new(Mutex::new(GeneratorType::Off)), - gen_3_type_override: Arc::new(Mutex::new(GeneratorType::Off)), - // Preset Library DEFAULT preset_lib_name: Arc::new(Mutex::new(String::from("Default"))), preset_name: Arc::new(Mutex::new(String::new())), preset_info: Arc::new(Mutex::new(String::new())), - preset_category: Arc::new(Mutex::new(PresetType::Select)), + //preset_category: Arc::new(Mutex::new(PresetType::Select)), preset_lib: Arc::new(Mutex::new(vec![ DEFAULT_PRESET.clone(); PRESET_BANK_SIZE @@ -558,8 +416,6 @@ pub struct ActuateParams { pub filter_cutoff_link: BoolParam, // Controls for when audio_module_1_type is Osc - #[id = "osc_1_type"] - pub osc_1_type: EnumParam, #[id = "osc_1_octave"] pub osc_1_octave: IntParam, #[id = "osc_1_semitones"] @@ -590,8 +446,6 @@ pub struct ActuateParams { pub osc_1_stereo: FloatParam, // Controls for when audio_module_2_type is Osc - #[id = "osc_2_type"] - pub osc_2_type: EnumParam, #[id = "osc_2_octave"] pub osc_2_octave: IntParam, #[id = "osc_2_semitones"] @@ -622,8 +476,6 @@ pub struct ActuateParams { pub osc_2_stereo: FloatParam, // Controls for when audio_module_3_type is Osc - #[id = "osc_3_type"] - pub osc_3_type: EnumParam, #[id = "osc_3_octave"] pub osc_3_octave: IntParam, #[id = "osc_3_semitones"] @@ -1220,7 +1072,6 @@ pub struct ActuateParams { impl ActuateParams { fn new( update_something: Arc, - clear_voices: Arc, file_dialog: Arc, update_current_preset: Arc, ) -> Self { @@ -1237,18 +1088,21 @@ impl ActuateParams { .with_unit("%"), voice_limit: IntParam::new("Max Voices", 64, IntRange::Linear { min: 1, max: 512 }), - audio_module_1_type: EnumParam::new("Type", AudioModuleType::Osc).with_callback({ - let clear_voices = clear_voices.clone(); - Arc::new(move |_| clear_voices.store(true, Ordering::SeqCst)) - }), - audio_module_2_type: EnumParam::new("Type", AudioModuleType::Off).with_callback({ - let clear_voices = clear_voices.clone(); - Arc::new(move |_| clear_voices.store(true, Ordering::SeqCst)) - }), - audio_module_3_type: EnumParam::new("Type", AudioModuleType::Off).with_callback({ - let clear_voices = clear_voices.clone(); - Arc::new(move |_| clear_voices.store(true, Ordering::SeqCst)) - }), + audio_module_1_type: EnumParam::new("Type", AudioModuleType::Sine) + .with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + audio_module_2_type: EnumParam::new("Type", AudioModuleType::Sine) + .with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + audio_module_3_type: EnumParam::new("Type", AudioModuleType::Sine) + .with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), audio_module_1_level: FloatParam::new( "Level", @@ -1272,18 +1126,26 @@ impl ActuateParams { .with_value_to_string(formatters::v2s_f32_percentage(0)) .with_unit("%"), - audio_module_1_routing: EnumParam::new("Routing", AMFilterRouting::Filter1), - audio_module_2_routing: EnumParam::new("Routing", AMFilterRouting::Filter1), - audio_module_3_routing: EnumParam::new("Routing", AMFilterRouting::Filter1), - - filter_routing: EnumParam::new("Filter Routing", FilterRouting::Parallel), + audio_module_1_routing: EnumParam::new("Routing", AMFilterRouting::Filter1).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + audio_module_2_routing: EnumParam::new("Routing", AMFilterRouting::Filter1).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + audio_module_3_routing: EnumParam::new("Routing", AMFilterRouting::Filter1).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), - // Oscillators - //////////////////////////////////////////////////////////////////////////////////// - osc_1_type: EnumParam::new("Wave", VoiceType::Sine).with_callback({ + filter_routing: EnumParam::new("Filter Routing", FilterRouting::Parallel).with_callback({ let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), + + // Oscillators + //////////////////////////////////////////////////////////////////////////////////// osc_1_octave: IntParam::new("Octave", 0, IntRange::Linear { min: -2, max: 2 }) .with_callback({ let update_something = update_something.clone(); @@ -1413,10 +1275,6 @@ impl ActuateParams { Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - osc_2_type: EnumParam::new("Wave", VoiceType::Sine).with_callback({ - let update_something = update_something.clone(); - Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) - }), osc_2_octave: IntParam::new("Octave", 0, IntRange::Linear { min: -2, max: 2 }) .with_callback({ let update_something = update_something.clone(); @@ -1546,10 +1404,6 @@ impl ActuateParams { Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - osc_3_type: EnumParam::new("Wave", VoiceType::Sine).with_callback({ - let update_something = update_something.clone(); - Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) - }), osc_3_octave: IntParam::new("Octave", 0, IntRange::Linear { min: -2, max: 2 }) .with_callback({ let update_something = update_something.clone(); @@ -1906,9 +1760,18 @@ impl ActuateParams { let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - filter_alg_type: EnumParam::new("Filter Alg", FilterAlgorithms::SVF), - tilt_filter_type: EnumParam::new("Filter Type", ResponseType::Lowpass), - vcf_filter_type: EnumParam::new("Filter Type", VCResponseType::Lowpass), + filter_alg_type: EnumParam::new("Filter Alg", FilterAlgorithms::SVF).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + tilt_filter_type: EnumParam::new("Filter Type", ResponseType::Lowpass).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + vcf_filter_type: EnumParam::new("Filter Type", VCResponseType::Lowpass).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), filter_env_peak: FloatParam::new( "Env Mod", @@ -2063,9 +1926,18 @@ impl ActuateParams { let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - filter_alg_type_2: EnumParam::new("Filter Alg", FilterAlgorithms::SVF), - tilt_filter_type_2: EnumParam::new("Filter Type", ResponseType::Lowpass), - vcf_filter_type_2: EnumParam::new("Filter Type", VCResponseType::Lowpass), + filter_alg_type_2: EnumParam::new("Filter Alg", FilterAlgorithms::SVF).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + tilt_filter_type_2: EnumParam::new("Filter Type", ResponseType::Lowpass).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), + vcf_filter_type_2: EnumParam::new("Filter Type", VCResponseType::Lowpass).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), filter_env_peak_2: FloatParam::new( "Env Mod", @@ -2250,7 +2122,10 @@ impl ActuateParams { let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - pitch_enable: BoolParam::new("Pitch Enable", false), + pitch_enable: BoolParam::new("Pitch Enable", false).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), pitch_routing: EnumParam::new("Routing", PitchRouting::Osc1).with_callback({ let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) @@ -2345,7 +2220,10 @@ impl ActuateParams { let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) }), - pitch_enable_2: BoolParam::new("Pitch Enable", false), + pitch_enable_2: BoolParam::new("Pitch Enable", false).with_callback({ + let update_something = update_something.clone(); + Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) + }), pitch_routing_2: EnumParam::new("Routing", PitchRouting::Osc1).with_callback({ let update_something = update_something.clone(); Arc::new(move |_| update_something.store(true, Ordering::SeqCst)) @@ -3875,6 +3753,9 @@ impl Actuate { _ => {}, } } + let mut am1_lock = self.audio_module_1.lock().unwrap(); + let mut am2_lock = self.audio_module_2.lock().unwrap(); + let mut am3_lock = self.audio_module_3.lock().unwrap(); // Prevent processing if our file dialog is open!!! if self.file_dialog.load(Ordering::SeqCst) { @@ -3892,39 +3773,25 @@ impl Actuate { // but also allowing playing of the synth while stopped // midi choke doesn't seem to be working in FL if !context.transport().playing - && (self.audio_module_1.clone().lock().unwrap().get_playing() - || self.audio_module_2.clone().lock().unwrap().get_playing() - || self.audio_module_3.clone().lock().unwrap().get_playing()) + && (am1_lock.get_playing() || am2_lock.get_playing() || am3_lock.get_playing()) { // Create clones here - let AM1 = self.audio_module_1.clone(); - let AM2 = self.audio_module_2.clone(); - let AM3 = self.audio_module_3.clone(); + //let AM1 = self.audio_module_1.clone(); + //let AM2 = self.audio_module_2.clone(); + //let AM3 = self.audio_module_3.clone(); // For some reason this format works vs doing lock and storing it earlier - AM1.lock().unwrap().set_playing(false); - AM2.lock().unwrap().set_playing(false); - AM3.lock().unwrap().set_playing(false); - AM1.lock().unwrap().clear_voices(); - AM2.lock().unwrap().clear_voices(); - AM3.lock().unwrap().clear_voices(); + am1_lock.set_playing(false); + am2_lock.set_playing(false); + am3_lock.set_playing(false); + am1_lock.clear_voices(); + am2_lock.clear_voices(); + am3_lock.clear_voices(); } if context.transport().playing { - self.audio_module_1 - .clone() - .lock() - .unwrap() - .set_playing(true); - self.audio_module_2 - .clone() - .lock() - .unwrap() - .set_playing(true); - self.audio_module_3 - .clone() - .lock() - .unwrap() - .set_playing(true); + am1_lock.set_playing(true); + am2_lock.set_playing(true); + am3_lock.set_playing(true); } let midi_event: Option> = context.next_event(); @@ -3946,31 +3813,21 @@ impl Actuate { // Trigger passing variables to the audio modules when the GUI input changes if self.update_something.load(Ordering::SeqCst) { - self.audio_module_1 - .lock() - .unwrap() - .consume_params(self.params.clone(), 1); - self.audio_module_2 - .lock() - .unwrap() - .consume_params(self.params.clone(), 2); - self.audio_module_3 - .lock() - .unwrap() - .consume_params(self.params.clone(), 3); + am1_lock.consume_params(self.params.clone(), 1); + am2_lock.consume_params(self.params.clone(), 2); + am3_lock.consume_params(self.params.clone(), 3); // Fix Auto restretch/repitch behavior if self.prev_restretch_1.load(Ordering::SeqCst) != self.params.restretch_1.value() { self.prev_restretch_1.store(self.params.restretch_1.value(), Ordering::SeqCst); - self.audio_module_1.lock().unwrap().regenerate_samples(); + am1_lock.regenerate_samples(); } if self.prev_restretch_2.load(Ordering::SeqCst) != self.params.restretch_2.value() { self.prev_restretch_2.store(self.params.restretch_2.value(), Ordering::SeqCst); - - self.audio_module_2.lock().unwrap().regenerate_samples(); + am2_lock.regenerate_samples(); } if self.prev_restretch_3.load(Ordering::SeqCst) != self.params.restretch_3.value() { self.prev_restretch_3.store(self.params.restretch_3.value(), Ordering::SeqCst); - self.audio_module_3.lock().unwrap().regenerate_samples(); + am3_lock.regenerate_samples(); } self.update_something.store(false, Ordering::SeqCst); @@ -4896,7 +4753,8 @@ impl Actuate { let mut fm_wave_2: f32 = 0.0; // Since File Dialog can be set by any of these we need to check each time if !self.file_dialog.load(Ordering::SeqCst) - && self.params.audio_module_1_type.value() != AudioModuleType::Off + //&& self.params.audio_module_1_type.value() != AudioModuleType::Off + && am1_lock.audio_module_type != AudioModuleType::Off { // We send our sample_id position, params, current midi event, module index, current voice max, and whether any params have changed ( @@ -4904,7 +4762,7 @@ impl Actuate { wave1_r, reset_filter_controller1, note_off_filter_controller1, - ) = self.audio_module_1.lock().unwrap().process( + ) = am1_lock.process( sample_id, midi_event.clone(), sent_voice_max, @@ -4920,23 +4778,44 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_1, temp_mod_lfo_gain_1, - self.params.stereo_algorithm.value() + self.params.stereo_algorithm.value(), + modulations_1.temp_mod_resonance_1 + + modulations_2.temp_mod_resonance_1 + + modulations_3.temp_mod_resonance_1 + + modulations_4.temp_mod_resonance_1, + modulations_1.temp_mod_cutoff_1 + + modulations_2.temp_mod_cutoff_1 + + modulations_3.temp_mod_cutoff_1 + + modulations_4.temp_mod_cutoff_1, + modulations_1.temp_mod_resonance_2 + + modulations_2.temp_mod_resonance_2 + + modulations_3.temp_mod_resonance_2 + + modulations_4.temp_mod_resonance_2, + modulations_1.temp_mod_cutoff_2 + + modulations_2.temp_mod_cutoff_2 + + modulations_3.temp_mod_cutoff_2 + + modulations_4.temp_mod_cutoff_2, ); // Sum to MONO fm_wave_1 = (wave1_l + wave1_r)/2.0; // I know this isn't a perfect 3rd, but 0.01 is acceptable headroom - wave1_l *= self.params.audio_module_1_level.value() * 0.33; - wave1_r *= self.params.audio_module_1_level.value() * 0.33; + let levelAmp1 = self.params.audio_module_1_level.value(); + wave1_l *= levelAmp1 * 0.33; + wave1_r *= levelAmp1 * 0.33; } + + // Since File Dialog can be set by any of these we need to check each time if !self.file_dialog.load(Ordering::SeqCst) - && self.params.audio_module_2_type.value() != AudioModuleType::Off + //&& self.params.audio_module_1_type.value() != AudioModuleType::Off + && am2_lock.audio_module_type != AudioModuleType::Off { + // We send our sample_id position, params, current midi event, module index, current voice max, and whether any params have changed ( wave2_l, wave2_r, reset_filter_controller2, note_off_filter_controller2, - ) = self.audio_module_2.lock().unwrap().process( + ) = am2_lock.process( sample_id, midi_event.clone(), sent_voice_max, @@ -4952,23 +4831,44 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_2, temp_mod_lfo_gain_2, - self.params.stereo_algorithm.value() + self.params.stereo_algorithm.value(), + modulations_1.temp_mod_resonance_1 + + modulations_2.temp_mod_resonance_1 + + modulations_3.temp_mod_resonance_1 + + modulations_4.temp_mod_resonance_1, + modulations_1.temp_mod_cutoff_1 + + modulations_2.temp_mod_cutoff_1 + + modulations_3.temp_mod_cutoff_1 + + modulations_4.temp_mod_cutoff_1, + modulations_1.temp_mod_resonance_2 + + modulations_2.temp_mod_resonance_2 + + modulations_3.temp_mod_resonance_2 + + modulations_4.temp_mod_resonance_2, + modulations_1.temp_mod_cutoff_2 + + modulations_2.temp_mod_cutoff_2 + + modulations_3.temp_mod_cutoff_2 + + modulations_4.temp_mod_cutoff_2, ); // Sum to MONO fm_wave_2 = (wave2_l + wave2_r)/2.0; // I know this isn't a perfect 3rd, but 0.01 is acceptable headroom - wave2_l *= self.params.audio_module_2_level.value() * 0.33; - wave2_r *= self.params.audio_module_2_level.value() * 0.33; + let levelAmp2 = self.params.audio_module_2_level.value(); + wave2_l *= levelAmp2 * 0.33; + wave2_r *= levelAmp2 * 0.33; } + + // Since File Dialog can be set by any of these we need to check each time if !self.file_dialog.load(Ordering::SeqCst) - && self.params.audio_module_3_type.value() != AudioModuleType::Off + //&& self.params.audio_module_1_type.value() != AudioModuleType::Off + && am3_lock.audio_module_type != AudioModuleType::Off { + // We send our sample_id position, params, current midi event, module index, current voice max, and whether any params have changed ( wave3_l, wave3_r, reset_filter_controller3, note_off_filter_controller3, - ) = self.audio_module_3.lock().unwrap().process( + ) = am3_lock.process( sample_id, midi_event.clone(), sent_voice_max, @@ -4984,11 +4884,28 @@ impl Actuate { temp_mod_uni_vel_sum, temp_mod_gain_3, temp_mod_lfo_gain_3, - self.params.stereo_algorithm.value() + self.params.stereo_algorithm.value(), + modulations_1.temp_mod_resonance_1 + + modulations_2.temp_mod_resonance_1 + + modulations_3.temp_mod_resonance_1 + + modulations_4.temp_mod_resonance_1, + modulations_1.temp_mod_cutoff_1 + + modulations_2.temp_mod_cutoff_1 + + modulations_3.temp_mod_cutoff_1 + + modulations_4.temp_mod_cutoff_1, + modulations_1.temp_mod_resonance_2 + + modulations_2.temp_mod_resonance_2 + + modulations_3.temp_mod_resonance_2 + + modulations_4.temp_mod_resonance_2, + modulations_1.temp_mod_cutoff_2 + + modulations_2.temp_mod_cutoff_2 + + modulations_3.temp_mod_cutoff_2 + + modulations_4.temp_mod_cutoff_2, ); // 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; - wave3_r *= self.params.audio_module_3_level.value() * 0.33; + let levelAmp3 = self.params.audio_module_3_level.value(); + wave3_l *= levelAmp3 * 0.33; + wave3_r *= levelAmp3 * 0.33; } // FM Calculations @@ -5239,230 +5156,12 @@ impl Actuate { lfo_3_current = self.lfo_3.next_sample(self.sample_rate); } - // Define the outputs for filter routing or non-filter routing - let mut left_output_filter1: f32 = 0.0; - let mut right_output_filter1: f32 = 0.0; - let mut left_output_filter2: f32 = 0.0; - let mut right_output_filter2: f32 = 0.0; - let mut left_output: f32 = 0.0; - let mut right_output: f32 = 0.0; - - match self.params.audio_module_1_routing.value() { - AMFilterRouting::Bypass | AMFilterRouting::UNSETROUTING => { - left_output += wave1_l; - right_output += wave1_r; - }, - AMFilterRouting::Filter1 => { - left_output_filter1 += wave1_l; - right_output_filter1 += wave1_r; - }, - AMFilterRouting::Filter2 => { - left_output_filter2 += wave1_l; - right_output_filter2 += wave1_r; - }, - AMFilterRouting::Both => { - left_output_filter1 += wave1_l; - right_output_filter1 += wave1_r; - left_output_filter2 += wave1_l; - right_output_filter2 += wave1_r; - }, - } - //#[allow(unused_assignments)] - match self.params.audio_module_2_routing.value() { - AMFilterRouting::Bypass | AMFilterRouting::UNSETROUTING => { - left_output += wave2_l; - right_output += wave2_r; - }, - AMFilterRouting::Filter1 => { - left_output_filter1 += wave2_l; - right_output_filter1 += wave2_r; - }, - AMFilterRouting::Filter2 => { - left_output_filter2 += wave2_l; - right_output_filter2 += wave2_r; - }, - AMFilterRouting::Both => { - left_output_filter1 += wave2_l; - right_output_filter1 += wave2_r; - left_output_filter2 += wave2_l; - right_output_filter2 += wave2_r; - }, - } - //#[allow(unused_assignments)] - match self.params.audio_module_3_routing.value() { - AMFilterRouting::Bypass | AMFilterRouting::UNSETROUTING => { - left_output += wave3_l; - right_output += wave3_r; - }, - AMFilterRouting::Filter1 => { - left_output_filter1 += wave3_l; - right_output_filter1 += wave3_r; - }, - AMFilterRouting::Filter2 => { - left_output_filter2 += wave3_l; - right_output_filter2 += wave3_r; - }, - AMFilterRouting::Both => { - left_output_filter1 += wave3_l; - right_output_filter1 += wave3_r; - left_output_filter2 += wave3_l; - right_output_filter2 += wave3_r; - }, - } + // Define the outputs + let mut left_output: f32; + let mut right_output: f32; - let mut filter1_processed_l: f32 = 0.0; - let mut filter1_processed_r: f32 = 0.0; - let mut filter2_processed_l: f32 = 0.0; - let mut filter2_processed_r: f32 = 0.0; - - // I ended up doing a passthrough/sum of modulations so they can stack if that's what user desires - // without breaking things when they are unset - match self.params.filter_routing.value() { - FilterRouting::Parallel => { - self.filter_process_1( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - left_output_filter1, - right_output_filter1, - &mut filter1_processed_l, - &mut filter1_processed_r, - modulations_1.temp_mod_cutoff_1 - + modulations_2.temp_mod_cutoff_1 - + modulations_3.temp_mod_cutoff_1 - + modulations_4.temp_mod_cutoff_1, - //+ vel_cutoff_1, - modulations_1.temp_mod_resonance_1 - + modulations_2.temp_mod_resonance_1 - + modulations_3.temp_mod_resonance_1 - + modulations_4.temp_mod_resonance_1, - //+ vel_resonance_1, - ); - self.filter_process_2( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - left_output_filter2, - right_output_filter2, - &mut filter2_processed_l, - &mut filter2_processed_r, - modulations_1.temp_mod_cutoff_2 - + modulations_2.temp_mod_cutoff_2 - + modulations_3.temp_mod_cutoff_2 - + modulations_4.temp_mod_cutoff_2, - //+ vel_cutoff_2, - modulations_1.temp_mod_resonance_2 - + modulations_2.temp_mod_resonance_2 - + modulations_3.temp_mod_resonance_2 - + modulations_4.temp_mod_resonance_2, - //+ vel_resonance_2, - ); - left_output += filter1_processed_l + filter2_processed_l; - right_output += filter1_processed_r + filter2_processed_r; - } - FilterRouting::Series12 => { - self.filter_process_1( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - left_output_filter1, - right_output_filter1, - &mut filter1_processed_l, - &mut filter1_processed_r, - modulations_1.temp_mod_cutoff_1 - + modulations_2.temp_mod_cutoff_1 - + modulations_3.temp_mod_cutoff_1 - + modulations_4.temp_mod_cutoff_1, - //+ vel_cutoff_1, - modulations_1.temp_mod_resonance_1 - + modulations_2.temp_mod_resonance_1 - + modulations_3.temp_mod_resonance_1 - + modulations_4.temp_mod_resonance_1, - //+ vel_resonance_1, - ); - self.filter_process_2( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - filter1_processed_l, - filter1_processed_r, - &mut filter2_processed_l, - &mut filter2_processed_r, - modulations_1.temp_mod_cutoff_2 - + modulations_2.temp_mod_cutoff_2 - + modulations_3.temp_mod_cutoff_2 - + modulations_4.temp_mod_cutoff_2, - //+ vel_cutoff_2, - modulations_1.temp_mod_resonance_2 - + modulations_2.temp_mod_resonance_2 - + modulations_3.temp_mod_resonance_2 - + modulations_4.temp_mod_resonance_2, - //+ vel_resonance_2, - ); - left_output += filter2_processed_l; - right_output += filter2_processed_r; - } - FilterRouting::Series21 => { - self.filter_process_2( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - left_output_filter2, - right_output_filter2, - &mut filter2_processed_l, - &mut filter2_processed_r, - modulations_1.temp_mod_cutoff_2 - + modulations_2.temp_mod_cutoff_2 - + modulations_3.temp_mod_cutoff_2 - + modulations_4.temp_mod_cutoff_2, - //+ vel_cutoff_2, - modulations_1.temp_mod_resonance_2 - + modulations_2.temp_mod_resonance_2 - + modulations_3.temp_mod_resonance_2 - + modulations_4.temp_mod_resonance_2, - //+ vel_resonance_2, - ); - self.filter_process_1( - note_off_filter_controller1, - note_off_filter_controller2, - note_off_filter_controller3, - reset_filter_controller1, - reset_filter_controller2, - reset_filter_controller3, - filter2_processed_l, - filter2_processed_r, - &mut filter1_processed_l, - &mut filter1_processed_r, - modulations_1.temp_mod_cutoff_1 - + modulations_2.temp_mod_cutoff_1 - + modulations_3.temp_mod_cutoff_1 - + modulations_4.temp_mod_cutoff_1, - //+ vel_cutoff_1, - modulations_1.temp_mod_resonance_1 - + modulations_2.temp_mod_resonance_1 - + modulations_3.temp_mod_resonance_1 - + modulations_4.temp_mod_resonance_1, - //+ vel_resonance_1, - ); - left_output += filter1_processed_l; - right_output += filter1_processed_r; - } - } + left_output = (wave1_l + wave2_l + wave3_l)*0.33; + right_output = (wave1_r + wave2_r + wave3_r)*0.33; // FX //////////////////////////////////////////////////////////////////////////////////////// @@ -5724,19 +5423,11 @@ impl Actuate { preset.mod2_sample_lib.clear(); preset.mod3_sample_lib.clear(); - // Serialize to MessagePack bytes - let serialized_data = rmp_serde::to_vec::(&preset); - - if let Err(err) = serialized_data { - eprintln!("Error serializing data: {}", err); - return; - } - - // Compress the serialized data using different GzEncoder - let compressed_data = Self::compress_bytes(&serialized_data.unwrap()); + // Serialize to json + let serialized_data = serde_json::to_string(&preset); // Now you can write the compressed data to the file - if let Err(err) = std::fs::write(&location, &compressed_data) { + if let Err(err) = std::fs::write(&location, serialized_data.unwrap()) { eprintln!("Error writing compressed data to file: {}", err); return; } @@ -5757,49 +5448,20 @@ impl Actuate { .to_string(); // Read the compressed data from the file - let mut compressed_data = Vec::new(); + let mut file_data = String::new(); if let Err(err) = std::fs::File::open(&return_name) - .and_then(|mut file| file.read_to_end(&mut compressed_data)) + .and_then(|mut file| file.read_to_string(&mut file_data)) { eprintln!("Error reading compressed data from file: {}", err); return (err.to_string(), Option::None); } - // Decompress the data - let decompressed_data = Self::decompress_bytes(&compressed_data); - if let Err(err) = decompressed_data { - eprintln!("Error decompressing data: {}", err); - return (err.to_string(), Option::None); - } - - // Deserialize the MessagePack data - let file_string_data = decompressed_data.unwrap(); - // Deserialize into preset struct - return default empty lib if error - let mut unserialized: ActuatePresetV131 = rmp_serde::from_slice(&file_string_data) - .unwrap_or(ERROR_PRESET.clone()); + let unserialized: ActuatePresetV131 = serde_json::from_slice(file_data.as_bytes()).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_v130(file_string_data.clone()); - if unserialized.preset_name.contains("Error") { - 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") { - unserialized = load_unserialized_v123(file_string_data.clone()); - if unserialized.preset_name.contains("Error") { - unserialized = load_unserialized_v122(file_string_data.clone()); - if unserialized.preset_name.contains("Error") { - unserialized = load_unserialized_v114(file_string_data.clone()); - if unserialized.preset_name.contains("Error") { - unserialized = load_unserialized_old(file_string_data.clone()); - } - } - } - } - } - } + //unserialized = load_unserialized_v130(file_data.clone()); } return (return_name, Some(unserialized)); @@ -5815,26 +5477,16 @@ impl Actuate { return_name = loading_bank.to_str().unwrap_or("Invalid Path").to_string(); // Read the compressed data from the file - let mut compressed_data = Vec::new(); + let mut file_data = String::new(); if let Err(err) = std::fs::File::open(&return_name) - .and_then(|mut file| file.read_to_end(&mut compressed_data)) + .and_then(|mut file| file.read_to_string(&mut file_data)) { eprintln!("Error reading compressed data from file: {}", err); return (err.to_string(), Vec::new()); } - // Decompress the data - let decompressed_data = Self::decompress_bytes(&compressed_data); - if let Err(err) = decompressed_data { - eprintln!("Error decompressing data: {}", err); - return (err.to_string(), Vec::new()); - } - - // Deserialize the MessagePack data - 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 = serde_json::from_slice(&file_data.as_bytes()) .unwrap_or(vec![ ERROR_PRESET.clone(); PRESET_BANK_SIZE @@ -5842,6 +5494,8 @@ impl Actuate { // Attempt loading 1.3.0 bank if error if unserialized[0].preset_name.contains("Error") { + /* + // Deserialize into preset struct - return default empty lib if error let unserialized: Vec = rmp_serde::from_slice(&file_string_data) .unwrap_or(vec![ @@ -5853,54 +5507,9 @@ impl Actuate { for v130_preset in unserialized.iter() { converted.push(old_preset_structs::convert_preset_v130(v130_preset.clone())); } - // Attempt loading 1.2.6 bank if error - if unserialized[0].preset_name.contains("Error") { - // 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.5 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.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); - } - return (return_name, converted); - } return (return_name, converted); + */ } - return (return_name, unserialized); } return (String::from("Error"), Vec::new()); @@ -5915,22 +5524,6 @@ impl Actuate { AMod1: &mut AudioModule, AMod2: &mut AudioModule, AMod3: &mut AudioModule, - ) -> ( - ModulationSource, - ModulationSource, - ModulationSource, - ModulationSource, - ModulationDestination, - ModulationDestination, - ModulationDestination, - ModulationDestination, - PresetType, - AMFilterRouting, - AMFilterRouting, - AMFilterRouting, - GeneratorType, - GeneratorType, - GeneratorType, ) { // Try to load preset into our params if possible let loaded_preset = &arc_preset[current_preset_index as usize]; @@ -5950,7 +5543,6 @@ impl Actuate { setter.set_parameter(¶ms.loop_sample_1, loaded_preset.mod1_loop_wavetable); setter.set_parameter(¶ms.single_cycle_1, loaded_preset.mod1_single_cycle); setter.set_parameter(¶ms.restretch_1, loaded_preset.mod1_restretch); - setter.set_parameter(¶ms.osc_1_type, loaded_preset.mod1_osc_type); setter.set_parameter(¶ms.osc_1_octave, loaded_preset.mod1_osc_octave); setter.set_parameter(¶ms.osc_1_semitones, loaded_preset.mod1_osc_semitones); setter.set_parameter(¶ms.osc_1_detune, loaded_preset.mod1_osc_detune); @@ -5992,7 +5584,6 @@ impl Actuate { setter.set_parameter(¶ms.loop_sample_2, loaded_preset.mod2_loop_wavetable); setter.set_parameter(¶ms.single_cycle_2, loaded_preset.mod2_single_cycle); setter.set_parameter(¶ms.restretch_2, loaded_preset.mod2_restretch); - setter.set_parameter(¶ms.osc_2_type, loaded_preset.mod2_osc_type); setter.set_parameter(¶ms.osc_2_octave, loaded_preset.mod2_osc_octave); setter.set_parameter(¶ms.osc_2_semitones, loaded_preset.mod2_osc_semitones); setter.set_parameter(¶ms.osc_2_detune, loaded_preset.mod2_osc_detune); @@ -6034,7 +5625,6 @@ impl Actuate { setter.set_parameter(¶ms.loop_sample_3, loaded_preset.mod3_loop_wavetable); setter.set_parameter(¶ms.single_cycle_3, loaded_preset.mod3_single_cycle); setter.set_parameter(¶ms.restretch_3, loaded_preset.mod3_restretch); - setter.set_parameter(¶ms.osc_3_type, loaded_preset.mod3_osc_type); setter.set_parameter(¶ms.osc_3_octave, loaded_preset.mod3_osc_octave); setter.set_parameter(¶ms.osc_3_semitones, loaded_preset.mod3_osc_semitones); setter.set_parameter(¶ms.osc_3_detune, loaded_preset.mod3_osc_detune); @@ -6095,107 +5685,6 @@ impl Actuate { setter.set_parameter(¶ms.mod_amount_knob_4, loaded_preset.mod_amount_4); setter.set_parameter(¶ms.mod_destination_4, loaded_preset.mod_dest_4.clone()); setter.set_parameter(¶ms.mod_source_4, loaded_preset.mod_source_4.clone()); - let mod_source_1_override = loaded_preset.mod_source_1.clone(); - let mod_source_2_override = loaded_preset.mod_source_2.clone(); - let mod_source_3_override = loaded_preset.mod_source_3.clone(); - let mod_source_4_override = loaded_preset.mod_source_4.clone(); - let mod_dest_1_override = loaded_preset.mod_dest_1.clone(); - let mod_dest_2_override = loaded_preset.mod_dest_2.clone(); - let mod_dest_3_override = loaded_preset.mod_dest_3.clone(); - let mod_dest_4_override = loaded_preset.mod_dest_4.clone(); - let gen_1_routing_override = loaded_preset.mod1_audio_module_routing.clone(); - let gen_2_routing_override = loaded_preset.mod2_audio_module_routing.clone(); - let gen_3_routing_override = loaded_preset.mod3_audio_module_routing.clone(); - let gen_1_type_override = match loaded_preset.mod1_audio_module_type { - AudioModuleType::Off => { - GeneratorType::Off - }, - AudioModuleType::Osc => { - match loaded_preset.mod1_osc_type { - VoiceType::Sine => GeneratorType::Sine, - VoiceType::Tri => GeneratorType::Tri, - VoiceType::Saw => GeneratorType::Saw, - VoiceType::RSaw => GeneratorType::RSaw, - VoiceType::WSaw => GeneratorType::WSaw, - VoiceType::SSaw => GeneratorType::SSaw, - VoiceType::RASaw => GeneratorType::RASaw, - VoiceType::Ramp => GeneratorType::Ramp, - VoiceType::Square => GeneratorType::Square, - VoiceType::RSquare => GeneratorType::RSquare, - VoiceType::Pulse => GeneratorType::Pulse, - VoiceType::Noise => GeneratorType::Noise, - } - }, - AudioModuleType::Sampler => { - GeneratorType::Sampler - }, - AudioModuleType::Granulizer => { - GeneratorType::Granulizer - }, - AudioModuleType::Additive => { - GeneratorType::Additive - } - }; - let gen_2_type_override = match loaded_preset.mod2_audio_module_type { - AudioModuleType::Off => { - GeneratorType::Off - }, - AudioModuleType::Osc => { - match loaded_preset.mod2_osc_type { - VoiceType::Sine => GeneratorType::Sine, - VoiceType::Tri => GeneratorType::Tri, - VoiceType::Saw => GeneratorType::Saw, - VoiceType::RSaw => GeneratorType::RSaw, - VoiceType::WSaw => GeneratorType::WSaw, - VoiceType::SSaw => GeneratorType::SSaw, - VoiceType::RASaw => GeneratorType::RASaw, - VoiceType::Ramp => GeneratorType::Ramp, - VoiceType::Square => GeneratorType::Square, - VoiceType::RSquare => GeneratorType::RSquare, - VoiceType::Pulse => GeneratorType::Pulse, - VoiceType::Noise => GeneratorType::Noise, - } - }, - AudioModuleType::Sampler => { - GeneratorType::Sampler - }, - AudioModuleType::Granulizer => { - GeneratorType::Granulizer - }, - AudioModuleType::Additive => { - GeneratorType::Additive - } - }; - let gen_3_type_override = match loaded_preset.mod3_audio_module_type { - AudioModuleType::Off => { - GeneratorType::Off - }, - AudioModuleType::Osc => { - match loaded_preset.mod3_osc_type { - VoiceType::Sine => GeneratorType::Sine, - VoiceType::Tri => GeneratorType::Tri, - VoiceType::Saw => GeneratorType::Saw, - VoiceType::RSaw => GeneratorType::RSaw, - VoiceType::WSaw => GeneratorType::WSaw, - VoiceType::SSaw => GeneratorType::SSaw, - VoiceType::RASaw => GeneratorType::RASaw, - VoiceType::Ramp => GeneratorType::Ramp, - VoiceType::Square => GeneratorType::Square, - VoiceType::RSquare => GeneratorType::RSquare, - VoiceType::Pulse => GeneratorType::Pulse, - VoiceType::Noise => GeneratorType::Noise, - } - }, - AudioModuleType::Sampler => { - GeneratorType::Sampler - }, - AudioModuleType::Granulizer => { - GeneratorType::Granulizer - }, - AudioModuleType::Additive => { - GeneratorType::Additive - } - }; setter.set_parameter(¶ms.use_fx, loaded_preset.use_fx); setter.set_parameter(¶ms.pre_use_eq, loaded_preset.pre_use_eq); @@ -6330,6 +5819,7 @@ impl Actuate { ); setter.set_parameter(¶ms.filter_routing, loaded_preset.filter_routing.clone()); + /* #[allow(unreachable_patterns)] let preset_category_override = match loaded_preset.preset_category { PresetType::Bass @@ -6352,6 +5842,7 @@ impl Actuate { // This should be unreachable since unserialize will fail before we get here anyways actually _ => PresetType::Select, }; + */ // 1.2.1 Pitch update setter.set_parameter(¶ms.pitch_enable, loaded_preset.pitch_enable); @@ -6535,24 +6026,6 @@ impl Actuate { }, _ => {}, } - - ( - mod_source_1_override, - mod_source_2_override, - mod_source_3_override, - mod_source_4_override, - mod_dest_1_override, - mod_dest_2_override, - mod_dest_3_override, - mod_dest_4_override, - preset_category_override, - gen_1_routing_override, - gen_2_routing_override, - gen_3_routing_override, - gen_1_type_override, - gen_2_type_override, - gen_3_type_override, - ) } fn save_preset_bank(preset_store: &mut Vec, saving_bank: Option) { @@ -6578,19 +6051,15 @@ impl Actuate { } // Serialize to MessagePack bytes - let serialized_data = - rmp_serde::to_vec::<&Vec>(&preset_store.as_ref()); + let serialized_data = serde_json::to_string(&preset_store); if let Err(err) = serialized_data { eprintln!("Error serializing data: {}", err); return; } - // Compress the serialized data using different GzEncoder - let compressed_data = Self::compress_bytes(&serialized_data.unwrap()); - // Now you can write the compressed data to the file - if let Err(err) = std::fs::write(&location, &compressed_data) { + if let Err(err) = std::fs::write(&location, &serialized_data.unwrap()) { eprintln!("Error writing compressed data to file: {}", err); return; } @@ -6600,20 +6069,6 @@ impl Actuate { } } - // Functions to compress bytes and decompress using gz - fn compress_bytes(data: &[u8]) -> Vec { - let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); - encoder.write_all(data).unwrap(); - encoder.finish().unwrap() - } - - fn decompress_bytes(compressed_data: &[u8]) -> Result, std::io::Error> { - let mut decoder = GzDecoder::new(compressed_data); - let mut decompressed_data = Vec::new(); - decoder.read_to_end(&mut decompressed_data)?; - Ok(decompressed_data) - } - // Update our current preset fn update_current_preset(&mut self) { let arc_lib = Arc::clone(&self.preset_lib); @@ -6667,7 +6122,6 @@ impl Actuate { mod1_grain_hold: AM1.grain_hold, // Osc module knob storage - mod1_osc_type: AM1.osc_type, mod1_osc_octave: AM1.osc_octave, mod1_osc_semitones: AM1.osc_semitones, mod1_osc_detune: AM1.osc_detune, @@ -6702,7 +6156,6 @@ impl Actuate { mod2_grain_hold: AM2.grain_hold, // Osc module knob storage - mod2_osc_type: AM2.osc_type, mod2_osc_octave: AM2.osc_octave, mod2_osc_semitones: AM2.osc_semitones, mod2_osc_detune: AM2.osc_detune, @@ -6737,7 +6190,6 @@ impl Actuate { mod3_grain_hold: AM3.grain_hold, // Osc module knob storage - mod3_osc_type: AM3.osc_type, mod3_osc_octave: AM3.osc_octave, mod3_osc_semitones: AM3.osc_semitones, mod3_osc_detune: AM3.osc_detune, @@ -6972,599 +6424,7 @@ impl Actuate { additive_amp_3_15: self.params.additive_amp_3_15.value(), }; } - - fn filter_process_1( - &mut self, - note_off_filter_controller1: bool, - note_off_filter_controller2: bool, - note_off_filter_controller3: bool, - reset_filter_controller1: bool, - reset_filter_controller2: bool, - reset_filter_controller3: bool, - left_input_filter1: f32, - right_input_filter1: f32, - left_output: &mut f32, - right_output: &mut f32, - filter_cutoff_mod: f32, - filter_resonance_mod: f32, - ) { - // Filter 1 Processing - /////////////////////////////////////////////////////////////// - if self.params.filter_wet.value() > 0.0 && !self.file_dialog.load(Ordering::SeqCst) { - // Filter state movement code - ////////////////////////////////////////// - // If a note is ending and we should enter releasing - if note_off_filter_controller1 - || note_off_filter_controller2 - || note_off_filter_controller3 - { - let old_filter_state = self.filter_state_1; - self.filter_state_1 = OscState::Releasing; - self.filter_rel_smoother_1 = match self.params.filter_env_rel_curve.value() { - SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( - self.params.filter_env_release.value(), - )), - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_release.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_release.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_release.value(), - )), - }; - // Reset our filter release to be at sustain level to start - self.filter_rel_smoother_1.reset( - //(//self.params.filter_cutoff.value() - //+ - match old_filter_state { - OscState::Attacking => self.filter_atk_smoother_1.next(), - OscState::Decaying | OscState::Releasing => self.filter_dec_smoother_1.next(), - OscState::Sustaining => self.filter_dec_smoother_1.next(), - OscState::Off => self.params.filter_cutoff.value(), - } - /* - // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - }*/ - //) - //* (self.params.filter_env_sustain.value() / 1999.9) - , - ); - // Move release to the cutoff to end - self.filter_rel_smoother_1 - .set_target(self.sample_rate, self.params.filter_cutoff.value()); - } - // Try to trigger our filter mods on note on! This is sequential/single because we just need a trigger at a point in time - if reset_filter_controller1 || reset_filter_controller2 || reset_filter_controller3 { - // Set our filter in attack state - self.filter_state_1 = OscState::Attacking; - // Consume our params for smoothing - self.filter_atk_smoother_1 = match self.params.filter_env_atk_curve.value() { - SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( - self.params.filter_env_attack.value(), - )), - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_attack.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_attack.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_attack.value(), - )), - }; - // Reset our attack to start from the filter cutoff - self.filter_atk_smoother_1 - .reset(self.params.filter_cutoff.value()); - // Since we're in attack state at the start of our note we need to setup the attack going to the env peak - self.filter_atk_smoother_1.set_target( - self.sample_rate, - (self.params.filter_cutoff.value() - + ( - // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - )) - .clamp(20.0, 20000.0), - ); - } - // If our attack has finished - if self.filter_atk_smoother_1.steps_left() == 0 - && self.filter_state_1 == OscState::Attacking - { - self.filter_state_1 = OscState::Decaying; - self.filter_dec_smoother_1 = match self.params.filter_env_dec_curve.value() { - SmoothStyle::Linear => { - Smoother::new(SmoothingStyle::Linear(self.params.filter_env_decay.value())) - } - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_decay.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_decay.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_decay.value(), - )), - }; - // This makes our filter decay start at env peak point - self.filter_dec_smoother_1.reset( - /* - (self.params.filter_cutoff.value() - + ( - // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - ) - ) - */ - self.filter_atk_smoother_1.next() - .clamp(20.0, 20000.0), - ); - // Set up the smoother for our filter movement to go from our decay point to our sustain point - self.filter_dec_smoother_1.set_target( - self.sample_rate, - ( - self.params.filter_cutoff.value() - + // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - ) - * (self.params.filter_env_sustain.value() / 1999.9), - ); - } - // If our decay has finished move to sustain state - if self.filter_dec_smoother_1.steps_left() == 0 - && self.filter_state_1 == OscState::Decaying - { - self.filter_state_1 = OscState::Sustaining; - } - // use proper variable now that there are four filters and multiple states - let next_filter_step = match self.filter_state_1 { - OscState::Attacking => { - (self.filter_atk_smoother_1.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Decaying => { - (self.filter_dec_smoother_1.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Sustaining => { - (self.filter_dec_smoother_1.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Releasing => { - (self.filter_rel_smoother_1.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - // I don't expect this to be used - _ => (self.params.filter_cutoff.value() + filter_cutoff_mod).clamp(20.0, 20000.0), - }; - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF => { - // Filtering before output - self.filter_l_1.update( - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.sample_rate, - self.params.filter_res_type.value(), - ); - self.filter_r_1.update( - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.sample_rate, - self.params.filter_res_type.value(), - ); - let low_l: f32; - let band_l: f32; - let high_l: f32; - let low_r: f32; - let band_r: f32; - let high_r: f32; - (low_l, band_l, high_l) = self.filter_l_1.process(left_input_filter1); - (low_r, band_r, high_r) = self.filter_r_1.process(right_input_filter1); - *left_output += (low_l * self.params.filter_lp_amount.value() - + band_l * self.params.filter_bp_amount.value() - + high_l * self.params.filter_hp_amount.value()) - * self.params.filter_wet.value() - + left_input_filter1 * (1.0 - self.params.filter_wet.value()); - *right_output += (low_r * self.params.filter_lp_amount.value() - + band_r * self.params.filter_bp_amount.value() - + high_r * self.params.filter_hp_amount.value()) - * self.params.filter_wet.value() - + right_input_filter1 * (1.0 - self.params.filter_wet.value()); - } - FilterAlgorithms::TILT => { - self.tilt_filter_l_1.update( - self.sample_rate, - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.params.tilt_filter_type.value(), - ); - self.tilt_filter_r_1.update( - self.sample_rate, - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.params.tilt_filter_type.value(), - ); - let tilt_out_l = self.tilt_filter_l_1.process(left_input_filter1 * db_to_gain(-12.0)); - let tilt_out_r = self.tilt_filter_r_1.process(right_input_filter1 * db_to_gain(-12.0)); - *left_output += tilt_out_l * self.params.filter_wet.value() - + left_input_filter1 * (1.0 - self.params.filter_wet.value()); - *right_output += tilt_out_r * self.params.filter_wet.value() - + right_input_filter1 * (1.0 - self.params.filter_wet.value()); - } - FilterAlgorithms::VCF => { - self.vcf_filter_l_1.update( - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.params.vcf_filter_type.value(), - self.sample_rate, - ); - self.vcf_filter_r_1.update( - next_filter_step, - self.params.filter_resonance.value() - filter_resonance_mod, - self.params.vcf_filter_type.value(), - self.sample_rate, - ); - let vcf_out_l = self.vcf_filter_l_1.process(left_input_filter1); - let vcf_out_r = self.vcf_filter_r_1.process(right_input_filter1); - *left_output += vcf_out_l * self.params.filter_wet.value() - + left_input_filter1 * (1.0 - self.params.filter_wet.value()); - *right_output += vcf_out_r * self.params.filter_wet.value() - + right_input_filter1 * (1.0 - self.params.filter_wet.value()); - } - FilterAlgorithms::V4 => { - self.V4F_l_1.update( - self.params.filter_resonance.value(), - next_filter_step, - self.sample_rate - ); - self.V4F_r_1.update( - self.params.filter_resonance.value(), - next_filter_step, - self.sample_rate - ); - let v4f_out_l = self.V4F_l_1.process(left_input_filter1); - let v4f_out_r = self.V4F_r_1.process(right_input_filter1); - *left_output += v4f_out_l * self.params.filter_wet.value() + left_input_filter1 * (1.0 - self.params.filter_wet.value()); - *right_output += v4f_out_r * self.params.filter_wet.value() + right_input_filter1 * (1.0 - self.params.filter_wet.value()); - } - FilterAlgorithms::A4I => { - self.A4I_l_1.update(next_filter_step, self.params.filter_resonance.value(), self.sample_rate); - self.A4I_r_1.update(next_filter_step, self.params.filter_resonance.value(), self.sample_rate); - let a4i_out_l = self.A4I_l_1.process(left_input_filter1); - let a4i_out_r = self.A4I_r_1.process(right_input_filter1); - *left_output += a4i_out_l * self.params.filter_wet.value() + left_input_filter1 * (1.0 - self.params.filter_wet.value()); - *right_output += a4i_out_r * self.params.filter_wet.value() + right_input_filter1 * (1.0 - self.params.filter_wet.value()); - } - } - } - } - - fn filter_process_2( - &mut self, - note_off_filter_controller1: bool, - note_off_filter_controller2: bool, - note_off_filter_controller3: bool, - reset_filter_controller1: bool, - reset_filter_controller2: bool, - reset_filter_controller3: bool, - left_input_filter2: f32, - right_input_filter2: f32, - left_output: &mut f32, - right_output: &mut f32, - filter_cutoff_mod: f32, - filter_resonance_mod: f32, - ) { - // Filter 2 Processing - /////////////////////////////////////////////////////////////// - if self.params.filter_wet_2.value() > 0.0 && !self.file_dialog.load(Ordering::SeqCst) { - // Filter state movement code - ////////////////////////////////////////// - // If a note is ending and we should enter releasing - if note_off_filter_controller1 - || note_off_filter_controller2 - || note_off_filter_controller3 - { - let old_filter_state = self.filter_state_2; - self.filter_state_2 = OscState::Releasing; - self.filter_rel_smoother_2 = match self.params.filter_env_rel_curve_2.value() { - SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( - self.params.filter_env_release_2.value(), - )), - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_release_2.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_release_2.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_release_2.value(), - )), - }; - // Reset our filter release to be at sustain level to start - self.filter_rel_smoother_2.reset( - /*self.params.filter_cutoff_2.value() - * (self.params.filter_env_sustain_2.value() / 1999.9) - + // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type_2.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak_2.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak_2.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - }, - */ - //self.filter_dec_smoother_2.next(), - match old_filter_state { - OscState::Attacking => self.filter_atk_smoother_2.next(), - OscState::Decaying | OscState::Releasing => self.filter_dec_smoother_2.next(), - OscState::Sustaining => self.filter_dec_smoother_2.next(), - OscState::Off => self.params.filter_cutoff_2.value(), - } - ); - // Move release to the cutoff to end - self.filter_rel_smoother_2 - .set_target(self.sample_rate, self.params.filter_cutoff_2.value()); - } - // Try to trigger our filter mods on note on! This is sequential/single because we just need a trigger at a point in time - if reset_filter_controller1 || reset_filter_controller2 || reset_filter_controller3 { - // Set our filter in attack state - self.filter_state_2 = OscState::Attacking; - // Consume our params for smoothing - self.filter_atk_smoother_2 = match self.params.filter_env_atk_curve_2.value() { - SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( - self.params.filter_env_attack_2.value(), - )), - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_attack_2.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_attack_2.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_attack_2.value(), - )), - }; - // Reset our attack to start from the filter cutoff - self.filter_atk_smoother_2 - .reset(self.params.filter_cutoff_2.value()); - // Since we're in attack state at the start of our note we need to setup the attack going to the env peak - self.filter_atk_smoother_2.set_target( - self.sample_rate, - (self.params.filter_cutoff_2.value() - + ( - // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type_2.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak_2.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak_2.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - )) - .clamp(20.0, 20000.0), - ); - } - // If our attack has finished - if self.filter_atk_smoother_2.steps_left() == 0 - && self.filter_state_2 == OscState::Attacking - { - self.filter_state_2 = OscState::Decaying; - self.filter_dec_smoother_2 = match self.params.filter_env_dec_curve_2.value() { - SmoothStyle::Linear => Smoother::new(SmoothingStyle::Linear( - self.params.filter_env_decay_2.value(), - )), - SmoothStyle::Logarithmic => Smoother::new(SmoothingStyle::Logarithmic( - self.params.filter_env_decay_2.value(), - )), - SmoothStyle::Exponential => Smoother::new(SmoothingStyle::Exponential( - self.params.filter_env_decay_2.value(), - )), - SmoothStyle::LogSteep => Smoother::new(SmoothingStyle::LogSteep( - self.params.filter_env_decay_2.value(), - )), - }; - // This makes our filter decay start at env peak point - self.filter_dec_smoother_2.reset( - /*(self.params.filter_cutoff_2.value() - + ( - // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type_2.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak_2.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak_2.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - ))*/ - self.filter_atk_smoother_2.next() - .clamp(20.0, 20000.0), - ); - // Set up the smoother for our filter movement to go from our decay point to our sustain point - self.filter_dec_smoother_2.set_target( - self.sample_rate, - (self.params.filter_cutoff_2.value() - + // This scales the peak env to be much gentler for the TILT filter - match self.params.filter_alg_type_2.value() { - FilterAlgorithms::SVF | FilterAlgorithms::VCF | FilterAlgorithms::V4 | FilterAlgorithms::A4I => self.params.filter_env_peak_2.value(), - FilterAlgorithms::TILT => adv_scale_value( - self.params.filter_env_peak_2.value(), - -19980.0, - 19980.0, - -5000.0, - 5000.0, - ), - } - ) - * (self.params.filter_env_sustain_2.value() / 1999.9) - ); - } - // If our decay has finished move to sustain state - if self.filter_dec_smoother_2.steps_left() == 0 - && self.filter_state_2 == OscState::Decaying - { - self.filter_state_2 = OscState::Sustaining; - } - // use proper variable now that there are four filters and multiple states - let next_filter_step = match self.filter_state_2 { - OscState::Attacking => { - (self.filter_atk_smoother_2.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Decaying => { - (self.filter_dec_smoother_2.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Sustaining => { - (self.filter_dec_smoother_2.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - OscState::Releasing => { - (self.filter_rel_smoother_2.next() + filter_cutoff_mod).clamp(20.0, 20000.0) - } - // I don't expect this to be used - _ => self.params.filter_cutoff_2.value() + filter_cutoff_mod, - }; - match self.params.filter_alg_type.value() { - FilterAlgorithms::SVF => { - // Filtering before output - self.filter_l_2.update( - next_filter_step, - self.params.filter_resonance_2.value(), - self.sample_rate, - self.params.filter_res_type_2.value(), - ); - self.filter_r_2.update( - next_filter_step, - self.params.filter_resonance_2.value() + filter_resonance_mod, - self.sample_rate, - self.params.filter_res_type_2.value(), - ); - let low_l: f32; - let band_l: f32; - let high_l: f32; - let low_r: f32; - let band_r: f32; - let high_r: f32; - (low_l, band_l, high_l) = self.filter_l_2.process(left_input_filter2); - (low_r, band_r, high_r) = self.filter_r_2.process(right_input_filter2); - *left_output += (low_l * self.params.filter_lp_amount_2.value() - + band_l * self.params.filter_bp_amount_2.value() - + high_l * self.params.filter_hp_amount_2.value()) - * self.params.filter_wet_2.value() - + *left_output * (1.0 - self.params.filter_wet_2.value()); - *right_output += (low_r * self.params.filter_lp_amount_2.value() - + band_r * self.params.filter_bp_amount_2.value() - + high_r * self.params.filter_hp_amount_2.value()) - * self.params.filter_wet_2.value() - + *right_output * (1.0 - self.params.filter_wet_2.value()); - } - FilterAlgorithms::TILT => { - self.tilt_filter_l_2.update( - self.sample_rate, - next_filter_step, - self.params.filter_resonance_2.value(), - self.params.tilt_filter_type_2.value(), - ); - self.tilt_filter_r_2.update( - self.sample_rate, - next_filter_step, - self.params.filter_resonance_2.value(), - self.params.tilt_filter_type_2.value(), - ); - let tilt_out_l = self.tilt_filter_l_2.process(left_input_filter2 * db_to_gain(-12.0)); - let tilt_out_r = self.tilt_filter_r_2.process(right_input_filter2 * db_to_gain(-12.0)); - *left_output += tilt_out_l * self.params.filter_wet_2.value() - + left_input_filter2 * (1.0 - self.params.filter_wet_2.value()); - *right_output += tilt_out_r * self.params.filter_wet_2.value() - + right_input_filter2 * (1.0 - self.params.filter_wet_2.value()); - } - FilterAlgorithms::VCF => { - self.vcf_filter_l_2.update( - next_filter_step, - self.params.filter_resonance_2.value(), - self.params.vcf_filter_type_2.value(), - self.sample_rate, - ); - self.vcf_filter_r_2.update( - next_filter_step, - self.params.filter_resonance_2.value(), - self.params.vcf_filter_type_2.value(), - self.sample_rate, - ); - let vcf_out_l = self.vcf_filter_l_2.process(left_input_filter2); - let vcf_out_r = self.vcf_filter_r_2.process(right_input_filter2); - *left_output += vcf_out_l * self.params.filter_wet_2.value() - + left_input_filter2 * (1.0 - self.params.filter_wet_2.value()); - *right_output += vcf_out_r * self.params.filter_wet_2.value() - + right_input_filter2 * (1.0 - self.params.filter_wet_2.value()); - } - FilterAlgorithms::V4 => { - self.V4F_l_2.update( - self.params.filter_resonance.value(), - next_filter_step, - self.sample_rate - ); - self.V4F_r_2.update( - self.params.filter_resonance.value(), - next_filter_step, - self.sample_rate - ); - let v4f_out_l = self.V4F_l_2.process(left_input_filter2); - let v4f_out_r = self.V4F_r_2.process(right_input_filter2); - *left_output += v4f_out_l * self.params.filter_wet.value() + left_input_filter2 * (1.0 - self.params.filter_wet.value()); - *right_output += v4f_out_r * self.params.filter_wet.value() + right_input_filter2 * (1.0 - self.params.filter_wet.value()); - } - FilterAlgorithms::A4I => { - self.A4I_l_2.update(next_filter_step, self.params.filter_resonance.value(), self.sample_rate); - self.A4I_r_2.update(next_filter_step, self.params.filter_resonance.value(), self.sample_rate); - let a4i_out_l = self.A4I_l_2.process(left_input_filter2); - let a4i_out_r = self.A4I_r_2.process(right_input_filter2); - *left_output += a4i_out_l * self.params.filter_wet.value() + left_input_filter2 * (1.0 - self.params.filter_wet.value()); - *right_output += a4i_out_r * self.params.filter_wet.value() + right_input_filter2 * (1.0 - self.params.filter_wet.value()); - } - } - } - } -} +} impl ClapPlugin for Actuate { const CLAP_ID: &'static str = "com.ardura.actuate"; @@ -7605,843 +6465,6 @@ fn adv_scale_value(input: f32, in_min: f32, in_max: f32, out_min: f32, out_max: lazy_static::lazy_static!( - static ref ERROR_PRESETV123: ActuatePresetV123 = ActuatePresetV123 { - 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: 1999.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: 1999.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: 1999.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: 1999.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: 1999.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, - - // 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_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, - }; - - static ref ERROR_PRESETV125: ActuatePresetV125 = ActuatePresetV125 { - 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: 1999.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: 1999.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: 1999.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: 1999.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: 1999.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, - - // 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, - }; - - 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: 1999.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: 1999.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: 1999.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: 1999.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: 1999.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, - }; - static ref ERROR_PRESETV130: ActuatePresetV130 = ActuatePresetV130 { preset_name: String::from("Error Loading"), preset_info: String::from("Corrupt or incompatible versions"), @@ -8465,7 +6488,7 @@ lazy_static::lazy_static!( tag_soft: false, tag_stab: false, tag_warm: false, - mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_type: AudioModuleType::Sine, mod1_audio_module_level: 1.0, mod1_audio_module_routing: AMFilterRouting::Filter1, mod1_loaded_sample: vec![vec![0.0, 0.0]], @@ -8479,7 +6502,6 @@ lazy_static::lazy_static!( 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, @@ -8509,7 +6531,6 @@ lazy_static::lazy_static!( 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, @@ -8539,7 +6560,6 @@ lazy_static::lazy_static!( 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, @@ -8763,7 +6783,7 @@ lazy_static::lazy_static!( tag_soft: false, tag_stab: false, tag_warm: false, - mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_type: AudioModuleType::Sine, mod1_audio_module_level: 1.0, mod1_audio_module_routing: AMFilterRouting::Filter1, mod1_loaded_sample: vec![vec![0.0, 0.0]], @@ -8777,7 +6797,6 @@ lazy_static::lazy_static!( 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, @@ -8807,7 +6826,6 @@ lazy_static::lazy_static!( 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, @@ -8837,7 +6855,6 @@ lazy_static::lazy_static!( 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, @@ -9110,7 +7127,7 @@ lazy_static::lazy_static!( tag_soft: false, tag_stab: false, tag_warm: false, - mod1_audio_module_type: AudioModuleType::Osc, + mod1_audio_module_type: AudioModuleType::Sine, mod1_audio_module_level: 1.0, mod1_audio_module_routing: AMFilterRouting::Filter1, mod1_loaded_sample: vec![vec![0.0, 0.0]], @@ -9124,7 +7141,6 @@ lazy_static::lazy_static!( 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, @@ -9154,7 +7170,6 @@ lazy_static::lazy_static!( 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, @@ -9184,7 +7199,6 @@ lazy_static::lazy_static!( 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, diff --git a/src/old_preset_structs.rs b/src/old_preset_structs.rs index 5b62667..333430c 100644 --- a/src/old_preset_structs.rs +++ b/src/old_preset_structs.rs @@ -1,7 +1,7 @@ use crate::{ actuate_enums::StereoAlgorithm, audio_module::{ AudioModuleType, - Oscillator::{self, RetriggerStyle, SmoothStyle, VoiceType}, + Oscillator::{self, RetriggerStyle, SmoothStyle}, }, fx::{ delay::{DelaySnapValues, DelayType}, saturation::SaturationType, @@ -16,868 +16,7 @@ use serde::{Deserialize, Serialize}; /// This is the structure that represents a storable preset value #[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetOld { - // Information - preset_name: String, - preset_info: String, - preset_category: PresetType, - // Preset tag information - made into bools to make my life easier - tag_acid: bool, - tag_analog: bool, - tag_bright: bool, - tag_chord: bool, - tag_crisp: bool, - tag_deep: bool, - tag_delicate: bool, - tag_hard: bool, - tag_harsh: bool, - tag_lush: bool, - tag_mellow: bool, - tag_resonant: bool, - tag_rich: bool, - tag_sharp: bool, - tag_silky: bool, - tag_smooth: bool, - tag_soft: bool, - tag_stab: bool, - tag_warm: bool, - - // Modules 1 - /////////////////////////////////////////////////////////// - mod1_audio_module_type: AudioModuleType, - mod1_audio_module_level: f32, - // Granulizer/Sampler - mod1_loaded_sample: Vec>, - mod1_sample_lib: Vec>>, - mod1_loop_wavetable: bool, - mod1_single_cycle: bool, - mod1_restretch: bool, - mod1_prev_restretch: bool, - mod1_grain_hold: i32, - mod1_grain_gap: i32, - mod1_start_position: f32, - mod1_end_position: f32, - mod1_grain_crossfade: i32, - - // Osc module knob storage - mod1_osc_type: VoiceType, - mod1_osc_octave: i32, - mod1_osc_semitones: i32, - mod1_osc_detune: f32, - mod1_osc_attack: f32, - mod1_osc_decay: f32, - mod1_osc_sustain: f32, - mod1_osc_release: f32, - mod1_osc_retrigger: RetriggerStyle, - mod1_osc_atk_curve: SmoothStyle, - mod1_osc_dec_curve: SmoothStyle, - mod1_osc_rel_curve: SmoothStyle, - mod1_osc_unison: i32, - mod1_osc_unison_detune: f32, - mod1_osc_stereo: f32, - - // Modules 2 - /////////////////////////////////////////////////////////// - mod2_audio_module_type: AudioModuleType, - mod2_audio_module_level: f32, - // Granulizer/Sampler - mod2_loaded_sample: Vec>, - mod2_sample_lib: Vec>>, - mod2_loop_wavetable: bool, - mod2_single_cycle: bool, - mod2_restretch: bool, - mod2_prev_restretch: bool, - mod2_grain_hold: i32, - mod2_grain_gap: i32, - mod2_start_position: f32, - mod2_end_position: f32, - mod2_grain_crossfade: i32, - - // Osc module knob storage - mod2_osc_type: VoiceType, - mod2_osc_octave: i32, - mod2_osc_semitones: i32, - mod2_osc_detune: f32, - mod2_osc_attack: f32, - mod2_osc_decay: f32, - mod2_osc_sustain: f32, - mod2_osc_release: f32, - mod2_osc_retrigger: RetriggerStyle, - mod2_osc_atk_curve: SmoothStyle, - mod2_osc_dec_curve: SmoothStyle, - mod2_osc_rel_curve: SmoothStyle, - mod2_osc_unison: i32, - mod2_osc_unison_detune: f32, - mod2_osc_stereo: f32, - - // Modules 3 - /////////////////////////////////////////////////////////// - mod3_audio_module_type: AudioModuleType, - mod3_audio_module_level: f32, - // Granulizer/Sampler - mod3_loaded_sample: Vec>, - mod3_sample_lib: Vec>>, - mod3_loop_wavetable: bool, - mod3_single_cycle: bool, - mod3_restretch: bool, - mod3_prev_restretch: bool, - mod3_grain_hold: i32, - mod3_grain_gap: i32, - mod3_start_position: f32, - mod3_end_position: f32, - mod3_grain_crossfade: i32, - - // Osc module knob storage - mod3_osc_type: VoiceType, - mod3_osc_octave: i32, - mod3_osc_semitones: i32, - mod3_osc_detune: f32, - mod3_osc_attack: f32, - mod3_osc_decay: f32, - mod3_osc_sustain: f32, - mod3_osc_release: f32, - mod3_osc_retrigger: RetriggerStyle, - mod3_osc_atk_curve: SmoothStyle, - mod3_osc_dec_curve: SmoothStyle, - mod3_osc_rel_curve: SmoothStyle, - mod3_osc_unison: i32, - mod3_osc_unison_detune: f32, - mod3_osc_stereo: f32, - - // Filters - filter_wet: f32, - filter_cutoff: f32, - filter_resonance: f32, - filter_res_type: ResonanceType, - filter_lp_amount: f32, - filter_hp_amount: f32, - filter_bp_amount: f32, - filter_env_peak: f32, - filter_env_attack: f32, - filter_env_decay: f32, - filter_env_sustain: f32, - filter_env_release: f32, - filter_env_atk_curve: Oscillator::SmoothStyle, - filter_env_dec_curve: Oscillator::SmoothStyle, - filter_env_rel_curve: Oscillator::SmoothStyle, - filter_alg_type: FilterAlgorithms, - tilt_filter_type: ArduraFilter::ResponseType, - - filter_wet_2: f32, - filter_cutoff_2: f32, - filter_resonance_2: f32, - filter_res_type_2: ResonanceType, - filter_lp_amount_2: f32, - filter_hp_amount_2: f32, - filter_bp_amount_2: f32, - filter_env_peak_2: f32, - filter_env_attack_2: f32, - filter_env_decay_2: f32, - filter_env_sustain_2: f32, - filter_env_release_2: f32, - filter_env_atk_curve_2: Oscillator::SmoothStyle, - filter_env_dec_curve_2: Oscillator::SmoothStyle, - filter_env_rel_curve_2: Oscillator::SmoothStyle, - filter_alg_type_2: FilterAlgorithms, - tilt_filter_type_2: ArduraFilter::ResponseType, - - filter_routing: FilterRouting, - // MISSING IN OLDER STRUCTS - /////////////////////////////////////////////////////////////////////////// - // filter_cutoff_link: bool, - /////////////////////////////////////////////////////////////////////////// - - // LFOs - lfo1_enable: bool, - lfo2_enable: bool, - lfo3_enable: bool, - - lfo1_freq: f32, - lfo1_retrigger: LFOController::LFORetrigger, - lfo1_sync: bool, - lfo1_snap: LFOController::LFOSnapValues, - lfo1_waveform: LFOController::Waveform, - lfo1_phase: f32, - - lfo2_freq: f32, - lfo2_retrigger: LFOController::LFORetrigger, - lfo2_sync: bool, - lfo2_snap: LFOController::LFOSnapValues, - lfo2_waveform: LFOController::Waveform, - lfo2_phase: f32, - - lfo3_freq: f32, - lfo3_retrigger: LFOController::LFORetrigger, - lfo3_sync: bool, - lfo3_snap: LFOController::LFOSnapValues, - lfo3_waveform: LFOController::Waveform, - lfo3_phase: f32, - - // Modulation - mod_source_1: ModulationSource, - mod_source_2: ModulationSource, - mod_source_3: ModulationSource, - mod_source_4: ModulationSource, - mod_dest_1: ModulationDestination, - mod_dest_2: ModulationDestination, - mod_dest_3: ModulationDestination, - mod_dest_4: ModulationDestination, - mod_amount_1: f32, - mod_amount_2: f32, - mod_amount_3: f32, - mod_amount_4: f32, - - // EQ - pre_use_eq: bool, - pre_low_freq: f32, - pre_mid_freq: f32, - pre_high_freq: f32, - pre_low_gain: f32, - pre_mid_gain: f32, - pre_high_gain: f32, - - // FX - use_fx: bool, - - use_compressor: bool, - comp_amt: f32, - comp_atk: f32, - comp_rel: f32, - comp_drive: f32, - - use_abass: bool, - abass_amount: f32, - - use_saturation: bool, - sat_amount: f32, - sat_type: SaturationType, - - use_delay: bool, - delay_amount: f32, - delay_time: DelaySnapValues, - delay_decay: f32, - delay_type: DelayType, - - use_reverb: bool, - reverb_amount: f32, - reverb_size: f32, - reverb_feedback: f32, - - use_phaser: bool, - phaser_amount: f32, - phaser_depth: f32, - phaser_rate: f32, - phaser_feedback: f32, - - use_buffermod: bool, - buffermod_amount: f32, - buffermod_depth: f32, - buffermod_rate: f32, - buffermod_spread: f32, - buffermod_timing: f32, - - use_flanger: bool, - flanger_amount: f32, - flanger_depth: f32, - flanger_rate: f32, - flanger_feedback: f32, - - use_limiter: bool, - limiter_threshold: f32, - limiter_knee: f32, -} - -/// This is the structure that represents a storable preset value -#[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV114 { - // Information - preset_name: String, - preset_info: String, - preset_category: PresetType, - // Preset tag information - made into bools to make my life easier - tag_acid: bool, - tag_analog: bool, - tag_bright: bool, - tag_chord: bool, - tag_crisp: bool, - tag_deep: bool, - tag_delicate: bool, - tag_hard: bool, - tag_harsh: bool, - tag_lush: bool, - tag_mellow: bool, - tag_resonant: bool, - tag_rich: bool, - tag_sharp: bool, - tag_silky: bool, - tag_smooth: bool, - tag_soft: bool, - tag_stab: bool, - tag_warm: bool, - - // Modules 1 - /////////////////////////////////////////////////////////// - mod1_audio_module_type: AudioModuleType, - mod1_audio_module_level: f32, - // Granulizer/Sampler - mod1_loaded_sample: Vec>, - mod1_sample_lib: Vec>>, - mod1_loop_wavetable: bool, - mod1_single_cycle: bool, - mod1_restretch: bool, - mod1_prev_restretch: bool, - mod1_grain_hold: i32, - mod1_grain_gap: i32, - mod1_start_position: f32, - mod1_end_position: f32, - mod1_grain_crossfade: i32, - - // Osc module knob storage - mod1_osc_type: VoiceType, - mod1_osc_octave: i32, - mod1_osc_semitones: i32, - mod1_osc_detune: f32, - mod1_osc_attack: f32, - mod1_osc_decay: f32, - mod1_osc_sustain: f32, - mod1_osc_release: f32, - mod1_osc_retrigger: RetriggerStyle, - mod1_osc_atk_curve: SmoothStyle, - mod1_osc_dec_curve: SmoothStyle, - mod1_osc_rel_curve: SmoothStyle, - mod1_osc_unison: i32, - mod1_osc_unison_detune: f32, - mod1_osc_stereo: f32, - - // Modules 2 - /////////////////////////////////////////////////////////// - mod2_audio_module_type: AudioModuleType, - mod2_audio_module_level: f32, - // Granulizer/Sampler - mod2_loaded_sample: Vec>, - mod2_sample_lib: Vec>>, - mod2_loop_wavetable: bool, - mod2_single_cycle: bool, - mod2_restretch: bool, - mod2_prev_restretch: bool, - mod2_grain_hold: i32, - mod2_grain_gap: i32, - mod2_start_position: f32, - mod2_end_position: f32, - mod2_grain_crossfade: i32, - - // Osc module knob storage - mod2_osc_type: VoiceType, - mod2_osc_octave: i32, - mod2_osc_semitones: i32, - mod2_osc_detune: f32, - mod2_osc_attack: f32, - mod2_osc_decay: f32, - mod2_osc_sustain: f32, - mod2_osc_release: f32, - mod2_osc_retrigger: RetriggerStyle, - mod2_osc_atk_curve: SmoothStyle, - mod2_osc_dec_curve: SmoothStyle, - mod2_osc_rel_curve: SmoothStyle, - mod2_osc_unison: i32, - mod2_osc_unison_detune: f32, - mod2_osc_stereo: f32, - - // Modules 3 - /////////////////////////////////////////////////////////// - mod3_audio_module_type: AudioModuleType, - mod3_audio_module_level: f32, - // Granulizer/Sampler - mod3_loaded_sample: Vec>, - mod3_sample_lib: Vec>>, - mod3_loop_wavetable: bool, - mod3_single_cycle: bool, - mod3_restretch: bool, - mod3_prev_restretch: bool, - mod3_grain_hold: i32, - mod3_grain_gap: i32, - mod3_start_position: f32, - mod3_end_position: f32, - mod3_grain_crossfade: i32, - - // Osc module knob storage - mod3_osc_type: VoiceType, - mod3_osc_octave: i32, - mod3_osc_semitones: i32, - mod3_osc_detune: f32, - mod3_osc_attack: f32, - mod3_osc_decay: f32, - mod3_osc_sustain: f32, - mod3_osc_release: f32, - mod3_osc_retrigger: RetriggerStyle, - mod3_osc_atk_curve: SmoothStyle, - mod3_osc_dec_curve: SmoothStyle, - mod3_osc_rel_curve: SmoothStyle, - mod3_osc_unison: i32, - mod3_osc_unison_detune: f32, - mod3_osc_stereo: f32, - - // Filters - filter_wet: f32, - filter_cutoff: f32, - filter_resonance: f32, - filter_res_type: ResonanceType, - filter_lp_amount: f32, - filter_hp_amount: f32, - filter_bp_amount: f32, - filter_env_peak: f32, - filter_env_attack: f32, - filter_env_decay: f32, - filter_env_sustain: f32, - filter_env_release: f32, - filter_env_atk_curve: Oscillator::SmoothStyle, - filter_env_dec_curve: Oscillator::SmoothStyle, - filter_env_rel_curve: Oscillator::SmoothStyle, - filter_alg_type: FilterAlgorithms, - tilt_filter_type: ArduraFilter::ResponseType, - - filter_wet_2: f32, - filter_cutoff_2: f32, - filter_resonance_2: f32, - filter_res_type_2: ResonanceType, - filter_lp_amount_2: f32, - filter_hp_amount_2: f32, - filter_bp_amount_2: f32, - filter_env_peak_2: f32, - filter_env_attack_2: f32, - filter_env_decay_2: f32, - filter_env_sustain_2: f32, - filter_env_release_2: f32, - filter_env_atk_curve_2: Oscillator::SmoothStyle, - filter_env_dec_curve_2: Oscillator::SmoothStyle, - filter_env_rel_curve_2: Oscillator::SmoothStyle, - filter_alg_type_2: FilterAlgorithms, - tilt_filter_type_2: ArduraFilter::ResponseType, - - filter_routing: FilterRouting, - filter_cutoff_link: bool, - - /////////////////////////////////////////////////////////////////////////// - // MISSING IN OLDER STRUCTS - // PITCH STUFF - // - // pitch_enable: false, - // pitch_env_peak: 0.0, - // 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_release: 0.0, - // pitch_env_sustain: 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: bool, - lfo2_enable: bool, - lfo3_enable: bool, - - lfo1_freq: f32, - lfo1_retrigger: LFOController::LFORetrigger, - lfo1_sync: bool, - lfo1_snap: LFOController::LFOSnapValues, - lfo1_waveform: LFOController::Waveform, - lfo1_phase: f32, - - lfo2_freq: f32, - lfo2_retrigger: LFOController::LFORetrigger, - lfo2_sync: bool, - lfo2_snap: LFOController::LFOSnapValues, - lfo2_waveform: LFOController::Waveform, - lfo2_phase: f32, - - lfo3_freq: f32, - lfo3_retrigger: LFOController::LFORetrigger, - lfo3_sync: bool, - lfo3_snap: LFOController::LFOSnapValues, - lfo3_waveform: LFOController::Waveform, - lfo3_phase: f32, - - // Modulation - mod_source_1: ModulationSource, - mod_source_2: ModulationSource, - mod_source_3: ModulationSource, - mod_source_4: ModulationSource, - mod_dest_1: ModulationDestination, - mod_dest_2: ModulationDestination, - mod_dest_3: ModulationDestination, - mod_dest_4: ModulationDestination, - mod_amount_1: f32, - mod_amount_2: f32, - mod_amount_3: f32, - mod_amount_4: f32, - - // EQ - pre_use_eq: bool, - pre_low_freq: f32, - pre_mid_freq: f32, - pre_high_freq: f32, - pre_low_gain: f32, - pre_mid_gain: f32, - pre_high_gain: f32, - - // FX - use_fx: bool, - - use_compressor: bool, - comp_amt: f32, - comp_atk: f32, - comp_rel: f32, - comp_drive: f32, - - use_abass: bool, - abass_amount: f32, - - use_saturation: bool, - sat_amount: f32, - sat_type: SaturationType, - - use_delay: bool, - delay_amount: f32, - delay_time: DelaySnapValues, - delay_decay: f32, - delay_type: DelayType, - - use_reverb: bool, - reverb_amount: f32, - reverb_size: f32, - reverb_feedback: f32, - - use_phaser: bool, - phaser_amount: f32, - phaser_depth: f32, - phaser_rate: f32, - phaser_feedback: f32, - - use_buffermod: bool, - buffermod_amount: f32, - buffermod_depth: f32, - buffermod_rate: f32, - buffermod_spread: f32, - buffermod_timing: f32, - - use_flanger: bool, - flanger_amount: f32, - flanger_depth: f32, - flanger_rate: f32, - flanger_feedback: f32, - - use_limiter: bool, - limiter_threshold: f32, - limiter_knee: f32, -} - -/// This is the structure that represents a storable preset value -#[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV122 { - // Information - preset_name: String, - preset_info: String, - preset_category: PresetType, - // Preset tag information - made into bools to make my life easier - tag_acid: bool, - tag_analog: bool, - tag_bright: bool, - tag_chord: bool, - tag_crisp: bool, - tag_deep: bool, - tag_delicate: bool, - tag_hard: bool, - tag_harsh: bool, - tag_lush: bool, - tag_mellow: bool, - tag_resonant: bool, - tag_rich: bool, - tag_sharp: bool, - tag_silky: bool, - tag_smooth: bool, - tag_soft: bool, - tag_stab: bool, - tag_warm: bool, - - // Modules 1 - /////////////////////////////////////////////////////////// - mod1_audio_module_type: AudioModuleType, - mod1_audio_module_level: f32, - // Granulizer/Sampler - mod1_loaded_sample: Vec>, - mod1_sample_lib: Vec>>, - mod1_loop_wavetable: bool, - mod1_single_cycle: bool, - mod1_restretch: bool, - mod1_prev_restretch: bool, - mod1_grain_hold: i32, - mod1_grain_gap: i32, - mod1_start_position: f32, - mod1_end_position: f32, - mod1_grain_crossfade: i32, - - // Osc module knob storage - mod1_osc_type: VoiceType, - mod1_osc_octave: i32, - mod1_osc_semitones: i32, - mod1_osc_detune: f32, - mod1_osc_attack: f32, - mod1_osc_decay: f32, - mod1_osc_sustain: f32, - mod1_osc_release: f32, - mod1_osc_retrigger: RetriggerStyle, - mod1_osc_atk_curve: SmoothStyle, - mod1_osc_dec_curve: SmoothStyle, - mod1_osc_rel_curve: SmoothStyle, - mod1_osc_unison: i32, - mod1_osc_unison_detune: f32, - mod1_osc_stereo: f32, - - // Modules 2 - /////////////////////////////////////////////////////////// - mod2_audio_module_type: AudioModuleType, - mod2_audio_module_level: f32, - // Granulizer/Sampler - mod2_loaded_sample: Vec>, - mod2_sample_lib: Vec>>, - mod2_loop_wavetable: bool, - mod2_single_cycle: bool, - mod2_restretch: bool, - mod2_prev_restretch: bool, - mod2_grain_hold: i32, - mod2_grain_gap: i32, - mod2_start_position: f32, - mod2_end_position: f32, - mod2_grain_crossfade: i32, - - // Osc module knob storage - mod2_osc_type: VoiceType, - mod2_osc_octave: i32, - mod2_osc_semitones: i32, - mod2_osc_detune: f32, - mod2_osc_attack: f32, - mod2_osc_decay: f32, - mod2_osc_sustain: f32, - mod2_osc_release: f32, - mod2_osc_retrigger: RetriggerStyle, - mod2_osc_atk_curve: SmoothStyle, - mod2_osc_dec_curve: SmoothStyle, - mod2_osc_rel_curve: SmoothStyle, - mod2_osc_unison: i32, - mod2_osc_unison_detune: f32, - mod2_osc_stereo: f32, - - // Modules 3 - /////////////////////////////////////////////////////////// - mod3_audio_module_type: AudioModuleType, - mod3_audio_module_level: f32, - // Granulizer/Sampler - mod3_loaded_sample: Vec>, - mod3_sample_lib: Vec>>, - mod3_loop_wavetable: bool, - mod3_single_cycle: bool, - mod3_restretch: bool, - mod3_prev_restretch: bool, - mod3_grain_hold: i32, - mod3_grain_gap: i32, - mod3_start_position: f32, - mod3_end_position: f32, - mod3_grain_crossfade: i32, - - // Osc module knob storage - mod3_osc_type: VoiceType, - mod3_osc_octave: i32, - mod3_osc_semitones: i32, - mod3_osc_detune: f32, - mod3_osc_attack: f32, - mod3_osc_decay: f32, - mod3_osc_sustain: f32, - mod3_osc_release: f32, - mod3_osc_retrigger: RetriggerStyle, - mod3_osc_atk_curve: SmoothStyle, - mod3_osc_dec_curve: SmoothStyle, - mod3_osc_rel_curve: SmoothStyle, - mod3_osc_unison: i32, - mod3_osc_unison_detune: f32, - mod3_osc_stereo: f32, - - // Filters - filter_wet: f32, - filter_cutoff: f32, - filter_resonance: f32, - filter_res_type: ResonanceType, - filter_lp_amount: f32, - filter_hp_amount: f32, - filter_bp_amount: f32, - filter_env_peak: f32, - filter_env_attack: f32, - filter_env_decay: f32, - filter_env_sustain: f32, - filter_env_release: f32, - filter_env_atk_curve: Oscillator::SmoothStyle, - filter_env_dec_curve: Oscillator::SmoothStyle, - filter_env_rel_curve: Oscillator::SmoothStyle, - filter_alg_type: FilterAlgorithms, - tilt_filter_type: ArduraFilter::ResponseType, - - filter_wet_2: f32, - filter_cutoff_2: f32, - filter_resonance_2: f32, - filter_res_type_2: ResonanceType, - filter_lp_amount_2: f32, - filter_hp_amount_2: f32, - filter_bp_amount_2: f32, - filter_env_peak_2: f32, - filter_env_attack_2: f32, - filter_env_decay_2: f32, - filter_env_sustain_2: f32, - filter_env_release_2: f32, - filter_env_atk_curve_2: Oscillator::SmoothStyle, - filter_env_dec_curve_2: Oscillator::SmoothStyle, - filter_env_rel_curve_2: Oscillator::SmoothStyle, - filter_alg_type_2: FilterAlgorithms, - tilt_filter_type_2: ArduraFilter::ResponseType, - - filter_routing: FilterRouting, - filter_cutoff_link: bool, - - // Pitch Env - pitch_enable: bool, - pitch_routing: PitchRouting, - pitch_env_peak: f32, - pitch_env_attack: f32, - pitch_env_decay: f32, - pitch_env_sustain: f32, - pitch_env_release: f32, - pitch_env_atk_curve: Oscillator::SmoothStyle, - pitch_env_dec_curve: Oscillator::SmoothStyle, - pitch_env_rel_curve: Oscillator::SmoothStyle, - - pitch_enable_2: bool, - pitch_routing_2: PitchRouting, - pitch_env_peak_2: f32, - pitch_env_attack_2: f32, - pitch_env_decay_2: f32, - pitch_env_sustain_2: f32, - pitch_env_release_2: f32, - pitch_env_atk_curve_2: Oscillator::SmoothStyle, - pitch_env_dec_curve_2: Oscillator::SmoothStyle, - pitch_env_rel_curve_2: Oscillator::SmoothStyle, - - // LFOs - lfo1_enable: bool, - lfo2_enable: bool, - lfo3_enable: bool, - - lfo1_freq: f32, - lfo1_retrigger: LFOController::LFORetrigger, - lfo1_sync: bool, - lfo1_snap: LFOController::LFOSnapValues, - lfo1_waveform: LFOController::Waveform, - lfo1_phase: f32, - - lfo2_freq: f32, - lfo2_retrigger: LFOController::LFORetrigger, - lfo2_sync: bool, - lfo2_snap: LFOController::LFOSnapValues, - lfo2_waveform: LFOController::Waveform, - lfo2_phase: f32, - - lfo3_freq: f32, - lfo3_retrigger: LFOController::LFORetrigger, - lfo3_sync: bool, - lfo3_snap: LFOController::LFOSnapValues, - lfo3_waveform: LFOController::Waveform, - lfo3_phase: f32, - - // Modulation - mod_source_1: ModulationSource, - mod_source_2: ModulationSource, - mod_source_3: ModulationSource, - mod_source_4: ModulationSource, - mod_dest_1: ModulationDestination, - mod_dest_2: ModulationDestination, - mod_dest_3: ModulationDestination, - mod_dest_4: ModulationDestination, - mod_amount_1: f32, - mod_amount_2: f32, - mod_amount_3: f32, - mod_amount_4: f32, - - // EQ - pre_use_eq: bool, - pre_low_freq: f32, - pre_mid_freq: f32, - pre_high_freq: f32, - pre_low_gain: f32, - pre_mid_gain: f32, - pre_high_gain: f32, - - // FX - use_fx: bool, - - use_compressor: bool, - comp_amt: f32, - comp_atk: f32, - comp_rel: f32, - comp_drive: f32, - - use_abass: bool, - abass_amount: f32, - - use_saturation: bool, - sat_amount: f32, - sat_type: SaturationType, - - use_delay: bool, - delay_amount: f32, - delay_time: DelaySnapValues, - delay_decay: f32, - delay_type: DelayType, - - use_reverb: bool, - reverb_amount: f32, - reverb_size: f32, - reverb_feedback: f32, - - use_phaser: bool, - phaser_amount: f32, - phaser_depth: f32, - phaser_rate: f32, - phaser_feedback: f32, - - use_buffermod: bool, - buffermod_amount: f32, - buffermod_depth: f32, - buffermod_rate: f32, - buffermod_spread: f32, - buffermod_timing: f32, - - use_flanger: bool, - flanger_amount: f32, - flanger_depth: f32, - flanger_rate: f32, - flanger_feedback: f32, - - use_limiter: bool, - limiter_threshold: f32, - limiter_knee: f32, -} - -#[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV125 { +pub struct ActuatePresetV130 { // Information pub preset_name: String, pub preset_info: String, @@ -922,7 +61,6 @@ pub struct ActuatePresetV125 { pub mod1_grain_crossfade: i32, // Osc module knob storage - pub mod1_osc_type: VoiceType, pub mod1_osc_octave: i32, pub mod1_osc_semitones: i32, pub mod1_osc_detune: f32, @@ -957,7 +95,6 @@ pub struct ActuatePresetV125 { pub mod2_grain_crossfade: i32, // Osc module knob storage - pub mod2_osc_type: VoiceType, pub mod2_osc_octave: i32, pub mod2_osc_semitones: i32, pub mod2_osc_detune: f32, @@ -992,7 +129,6 @@ pub struct ActuatePresetV125 { pub mod3_grain_crossfade: i32, // Osc module knob storage - pub mod3_osc_type: VoiceType, pub mod3_osc_octave: i32, pub mod3_osc_semitones: i32, pub mod3_osc_detune: f32, @@ -1111,6 +247,22 @@ pub struct ActuatePresetV125 { pub mod_amount_3: f32, pub mod_amount_4: f32, + // 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, + + // Stereo + pub stereo_algorithm: StereoAlgorithm, + // EQ pub pre_use_eq: bool, pub pre_low_freq: f32, @@ -1154,6 +306,11 @@ pub struct ActuatePresetV125 { 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, @@ -1172,4855 +329,307 @@ pub struct ActuatePresetV125 { pub limiter_knee: f32, } -/// This is the structure that represents a storable preset value -#[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV123 { - // 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, +// 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_v130(file_data: Vec) -> ActuatePresetV131 { + let old_unserialized: ActuatePresetV130 = + serde_json::from_slice(&file_data).unwrap_or(ActuatePresetV130 { + 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::Sine, + 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_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, - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - 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, - - pub filter_routing: FilterRouting, - pub filter_cutoff_link: bool, - - // 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, - - 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, - - // LFOs - pub lfo1_enable: bool, - pub lfo2_enable: bool, - pub lfo3_enable: bool, - - 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, + 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_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, - 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, + 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_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, - 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, + // 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, - // 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, - - // 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, - - // FX - pub use_fx: bool, - pub use_compressor: bool, - pub comp_amt: f32, - pub comp_atk: f32, - pub comp_rel: f32, - pub comp_drive: f32, - pub use_abass: bool, - pub abass_amount: f32, - pub use_saturation: bool, - pub sat_amount: f32, - pub sat_type: SaturationType, - pub use_delay: bool, - pub delay_amount: f32, - pub delay_time: DelaySnapValues, - pub delay_decay: f32, - pub delay_type: DelayType, - pub use_reverb: bool, - //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 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - 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, - - pub filter_routing: FilterRouting, - pub filter_cutoff_link: bool, - - // 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, - - 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, - - // LFOs - pub lfo1_enable: bool, - pub lfo2_enable: bool, - pub lfo3_enable: bool, - - 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, - - 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, - - 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, - - // 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, - - // 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, - - // 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, - - // FX - pub use_fx: bool, - - pub use_compressor: bool, - pub comp_amt: f32, - pub comp_atk: f32, - pub comp_rel: f32, - pub comp_drive: f32, - - pub use_abass: bool, - pub abass_amount: f32, - - pub use_saturation: bool, - pub sat_amount: f32, - pub sat_type: SaturationType, - - 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 is the structure that represents a storable preset value -#[derive(Serialize, Deserialize, Clone)] -pub struct ActuatePresetV130 { - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - // 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, - - 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, - - pub filter_routing: FilterRouting, - pub filter_cutoff_link: bool, - - // 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, - - 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, - - // LFOs - pub lfo1_enable: bool, - pub lfo2_enable: bool, - pub lfo3_enable: bool, - - 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, - - 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, - - 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, - - // 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, - - // 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, - - // Stereo - pub stereo_algorithm: StereoAlgorithm, - - // 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, - - // FX - pub use_fx: bool, - - pub use_compressor: bool, - pub comp_amt: f32, - pub comp_atk: f32, - pub comp_rel: f32, - pub comp_drive: f32, - - pub use_abass: bool, - pub abass_amount: f32, - - pub use_saturation: bool, - pub sat_amount: f32, - pub sat_type: SaturationType, - - 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_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, - 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_v130(file_data: Vec) -> ActuatePresetV131 { - let old_unserialized: ActuatePresetV130 = - rmp_serde::from_slice(&file_data).unwrap_or(ActuatePresetV130 { - 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, - - 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, - - // 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, - - // 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, - - 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_model: ReverbModel::Default, - 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, - - //V130 Fields - chorus_amount: 0.5, - chorus_range: 0.5, - chorus_speed: 0.5, - use_chorus: false, - stereo_algorithm: StereoAlgorithm::Original, - }); - convert_preset_v130(old_unserialized) -} - -// 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) -> ActuatePresetV131 { - 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, - 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, - - 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, - - // 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, - - // 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, - - 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_model: ReverbModel::Default, - 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_v126(old_unserialized) -} - -// 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) -> ActuatePresetV131 { - 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, - - 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, - - // 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_model: ReverbModel::Default, - 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_v125(old_unserialized) -} - -// 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) -> ActuatePresetV131 { - 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, - 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, - - 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, - - // 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_model: ReverbModel::Default, - 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_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_v114(file_data: Vec) -> ActuatePresetV131 { - 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, - 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_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) -> ActuatePresetV131 { - 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) -> ActuatePresetV131 { - 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_v130(preset: ActuatePresetV130) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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, - - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format -} - -// This will get cloned each time we change preset styles in actuate -pub fn convert_preset_v126(preset: ActuatePresetV126) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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, - - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format -} - -// This will get cloned each time we change preset styles in actuate -pub fn convert_preset_v125(preset: ActuatePresetV125) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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: 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, - // 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, - - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format -} - -// This will get cloned each time we change preset styles in actuate -pub fn convert_preset_v123(preset: ActuatePresetV123) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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: 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, - // 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: crate::ReverbModel::Default, - 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, - - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format -} - -// This will get cloned each time we change preset styles in actuate -fn convert_preset_v122(preset: ActuatePresetV122) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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: crate::AMFilterRouting::Filter1, - 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: crate::AMFilterRouting::Filter1, - 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: crate::AMFilterRouting::Filter1, - 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: 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, - // 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: crate::ReverbModel::Default, - 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, - - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format -} - -// This will get cloned each time we change preset styles in actuate -fn convert_preset_v114(preset: ActuatePresetV114) -> ActuatePresetV131 { - let new_format: ActuatePresetV131 = ActuatePresetV131 { - 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: crate::AMFilterRouting::Filter1, - 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: crate::AMFilterRouting::Filter1, - 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: crate::AMFilterRouting::Filter1, - 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: false, - pitch_routing: PitchRouting::Osc1, - pitch_env_peak: 0.0, - 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_release: 0.0, - pitch_env_sustain: 0.0, - 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, - /////////////////////////////////////////////////////////////////// - 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: 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, - // 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: crate::ReverbModel::Default, - 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, + 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, - // v 1.3.1 Additive fields - additive_amp_1_0: 0.0, - additive_amp_1_1: 0.0, - additive_amp_1_2: 0.0, - additive_amp_1_3: 0.0, - additive_amp_1_4: 0.0, - additive_amp_1_5: 0.0, - additive_amp_1_6: 0.0, - additive_amp_1_7: 0.0, - additive_amp_1_8: 0.0, - additive_amp_1_9: 0.0, - additive_amp_1_10: 0.0, - additive_amp_1_11: 0.0, - additive_amp_1_12: 0.0, - additive_amp_1_13: 0.0, - additive_amp_1_14: 0.0, - additive_amp_1_15: 0.0, - additive_amp_2_0: 0.0, - additive_amp_2_1: 0.0, - additive_amp_2_2: 0.0, - additive_amp_2_3: 0.0, - additive_amp_2_4: 0.0, - additive_amp_2_5: 0.0, - additive_amp_2_6: 0.0, - additive_amp_2_7: 0.0, - additive_amp_2_8: 0.0, - additive_amp_2_9: 0.0, - additive_amp_2_10: 0.0, - additive_amp_2_11: 0.0, - additive_amp_2_12: 0.0, - additive_amp_2_13: 0.0, - additive_amp_2_14: 0.0, - additive_amp_2_15: 0.0, - additive_amp_3_0: 0.0, - additive_amp_3_1: 0.0, - additive_amp_3_2: 0.0, - additive_amp_3_3: 0.0, - additive_amp_3_4: 0.0, - additive_amp_3_5: 0.0, - additive_amp_3_6: 0.0, - additive_amp_3_7: 0.0, - additive_amp_3_8: 0.0, - additive_amp_3_9: 0.0, - additive_amp_3_10: 0.0, - additive_amp_3_11: 0.0, - additive_amp_3_12: 0.0, - additive_amp_3_13: 0.0, - additive_amp_3_14: 0.0, - additive_amp_3_15: 0.0, - }; - new_format + 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, + + // 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, + + 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_model: ReverbModel::Default, + 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, + + //V130 Fields + chorus_amount: 0.5, + chorus_range: 0.5, + chorus_speed: 0.5, + use_chorus: false, + stereo_algorithm: StereoAlgorithm::Original, + }); + _convert_preset_v130(old_unserialized) } // This will get cloned each time we change preset styles in actuate -fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { +pub fn _convert_preset_v130(preset: ActuatePresetV130) -> ActuatePresetV131 { let new_format: ActuatePresetV131 = ActuatePresetV131 { preset_name: preset.preset_name, preset_info: preset.preset_info, @@ -6047,7 +656,7 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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: crate::AMFilterRouting::Filter1, + 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, @@ -6059,7 +668,6 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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, @@ -6077,7 +685,7 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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: crate::AMFilterRouting::Filter1, + 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, @@ -6089,7 +697,6 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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, @@ -6107,7 +714,7 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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: crate::AMFilterRouting::Filter1, + 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, @@ -6119,7 +726,6 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { 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, @@ -6171,29 +777,29 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { filter_routing: preset.filter_routing, /////////////////////////////////////////////////////////////////// // Added in 1.1.4 - filter_cutoff_link: false, + filter_cutoff_link: preset.filter_cutoff_link, /////////////////////////////////////////////////////////////////// // Added in pitch update 1.2.1 - pitch_enable: false, - pitch_routing: PitchRouting::Osc1, - pitch_env_peak: 0.0, - 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_release: 0.0, - pitch_env_sustain: 0.0, - 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, + 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, @@ -6229,17 +835,17 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { mod_amount_3: preset.mod_amount_3, mod_amount_4: preset.mod_amount_4, // 1.2.6 - 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, + 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, @@ -6265,7 +871,7 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { delay_decay: preset.delay_decay, delay_type: preset.delay_type, use_reverb: preset.use_reverb, - reverb_model: crate::ReverbModel::Default, + reverb_model: preset.reverb_model, reverb_amount: preset.reverb_amount, reverb_size: preset.reverb_size, reverb_feedback: preset.reverb_feedback, @@ -6348,4 +954,3 @@ fn convert_preset(preset: ActuatePresetOld) -> ActuatePresetV131 { }; new_format } -