Skip to content

Commit cd339e4

Browse files
committed
1.4.3 Small Update
1 parent 3a9113d commit cd339e4

5 files changed

Lines changed: 192 additions & 249 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Actuate (Latest is v1.4.2)
1+
# Actuate (Latest is v1.4.3)
22

33
A Subtractive and Additive Synthesizer, Sampler, and Granulizer built in Rust + Nih-Plug
44
Written by Ardura

src/actuate_gui.rs

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{collections::HashMap, ffi::OsStr, ops::RangeInclusive, path::{Path, Pa
66
use nih_plug::{context::gui::AsyncExecutor, editor::Editor, nih_log};
77
use nih_plug_egui::{create_egui_editor, egui::{self, Color32, Pos2, Rect, RichText, CornerRadius, ScrollArea, Vec2}, widgets::ParamSlider};
88
use walkdir::WalkDir;
9-
use crate::actuate_load_save_dialog::FileDialog;
9+
use crate::actuate_load_save_dialog::{DialogMode, FileDialog};
1010

1111
use crate::{actuate_enums::PresetBrowserEntry, release_downloader::ReleaseDownloader, CustomWidgets::ComboBoxParam};
1212
#[allow(unused_imports)]
@@ -100,7 +100,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
100100
let params: Arc<ActuateParams> = instance.params.clone();
101101
let arc_preset: Arc<Mutex<ActuatePresetV131>> = Arc::clone(&instance.current_loaded_params);
102102
let clear_voices: Arc<AtomicBool> = Arc::clone(&instance.clear_voices);
103-
let reload_entire_preset: Arc<AtomicBool> = Arc::clone(&instance.reload_entire_preset);
104103
let browse_preset_active: Arc<AtomicBool> = Arc::clone(&instance.browsing_presets);
105104
let import_preset_active: Arc<AtomicBool> = Arc::clone(&instance.importing_presets);
106105
let export_preset_active: Arc<AtomicBool> = Arc::clone(&instance.exporting_presets);
@@ -171,30 +170,30 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
171170

172171
// Open
173172
let dialog_main_open: Arc<Mutex<FileDialog>> = Arc::new(Mutex::new(if (default_dir).exists() {
174-
FileDialog::new(default_dir.clone(), false)
173+
FileDialog::new(default_dir.clone(), DialogMode::OpenPreset)
175174
} else {
176-
FileDialog::new(home_dir.clone(), false)
175+
FileDialog::new(home_dir.clone(), DialogMode::OpenPreset)
177176
}));
178177

179178
// Save
180179
let dialog_main_save: Arc<Mutex<FileDialog>> = Arc::new(Mutex::new(if (default_dir).exists() {
181-
FileDialog::new(default_dir.clone(), true)
180+
FileDialog::new(default_dir.clone(), DialogMode::ExportPreset)
182181
} else {
183-
FileDialog::new(home_dir.clone(), true)
182+
FileDialog::new(home_dir.clone(), DialogMode::ExportPreset)
184183
}));
185184

186185
// Export Last Sound
187186
let dialog_export_last_sound: Arc<Mutex<FileDialog>> = Arc::new(Mutex::new(if (default_dir).exists() {
188-
FileDialog::new(default_dir.clone(), true)
187+
FileDialog::new(default_dir.clone(), DialogMode::ExportSample)
189188
} else {
190-
FileDialog::new(home_dir.clone(), true)
189+
FileDialog::new(home_dir.clone(), DialogMode::ExportSample)
191190
}));
192191

193192
// Open Samples
194193
let dialog_main_open_samples: Arc<Mutex<FileDialog>> = Arc::new(Mutex::new(if (default_dir).exists() {
195-
FileDialog::new(default_dir.clone(), false)
194+
FileDialog::new(default_dir.clone(), DialogMode::OpenSample)
196195
} else {
197-
FileDialog::new(home_dir.clone(), false)
196+
FileDialog::new(home_dir.clone(), DialogMode::OpenSample)
198197
}));
199198

200199
// Do our GUI stuff. Store this to later get parent window handle from it
@@ -206,106 +205,113 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
206205
egui::CentralPanel::default()
207206
.show(egui_ctx, |ui| {
208207
if download_in_progress.load(Ordering::Relaxed) {
209-
recalculate_banks(&dir_files_map, &str_files_map, &lite_db, Path::new(&default_dir));
210208
download_in_progress.store(false, Ordering::Relaxed);
209+
recalculate_banks(&dir_files_map, &str_files_map, &lite_db, Path::new(&default_dir));
211210
}
212211

213-
214-
//let current_preset_index = current_preset.load(Ordering::SeqCst);
215212
let filter_select = filter_select_outside.clone();
216213
let lfo_select = lfo_select_outside.clone();
217214
let clone_dir = default_dir.clone();
218215

216+
let am1_type: AudioModuleType = AM1.lock().unwrap().audio_module_type.clone();
217+
let am2_type: AudioModuleType = AM2.lock().unwrap().audio_module_type.clone();
218+
let am3_type: AudioModuleType = AM3.lock().unwrap().audio_module_type.clone();
219+
220+
let am1_loaded_sample_len = AM1.lock().unwrap().loaded_sample[0].len();
221+
let am2_loaded_sample_len = AM2.lock().unwrap().loaded_sample[0].len();
222+
let am3_loaded_sample_len = AM3.lock().unwrap().loaded_sample[0].len();
223+
224+
// This scenario is: DAW reopens and loaded_sample has content but sample_lib needs to be regenerated!
219225
// This happens on some plugin loads and crashes your DAW :(
220226
// These if statements are ordered this way to catch this scenario first and prevent crashing DAW
221-
if AM1.lock().unwrap().sample_lib.len() == 0 &&
222-
(AM1.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
223-
AM1.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) {
227+
if (AM1.lock().unwrap().sample_lib.len() == 0 || am1_loaded_sample_len == 2) &&
228+
(am1_type == AudioModuleType::Sampler || am1_type == AudioModuleType::Granulizer) {
224229
let mut AM1_Lock = AM1.lock().unwrap();
225230

226231
AM1_Lock.loaded_sample = params.am1_sample.lock().unwrap().to_vec();
227232

228233
AM1_Lock.regenerate_samples();
234+
setter.set_parameter(&params.load_sample_1, false);
235+
}
229236
// This lets the internal param track the current samples for when the plugin gets reopened/reloaded
230237
// It runs if there is peristent sample data but not sample data in the audio module
231238
// This is not very pretty looking but I couldn't allocate separately locked Audio Modules since somewhere
232239
// This would cause a deadlock and break Actuate :|
233240
// Maybe in future this will become nicer
234-
} else if params.am1_sample.lock().unwrap()[0].len() > 1 &&
235-
AM1.lock().unwrap().loaded_sample[0].len() <= 2 &&
236-
(AM1.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
237-
AM1.lock().unwrap().audio_module_type == AudioModuleType::Granulizer)
241+
if params.am1_sample.lock().unwrap()[0].len() > 1 &&
242+
am1_loaded_sample_len <= 2 &&
243+
(am1_type == AudioModuleType::Sampler || am1_type == AudioModuleType::Granulizer)
238244
{
239-
// This if is separate since previously when it was included in th eabove it could
245+
// This if is separate since previously when it was included in the above it could
240246
// panic on length issues handled by [AM1.lock().unwrap().loaded_sample[0].len() <= 2]
241-
if AM1.lock().unwrap().sample_lib[0][0][0] == 0.0 {
247+
if AM1.lock().unwrap().sample_lib[0][0].len() != 127 {
242248
let mut AM1_Lock = AM1.lock().unwrap();
243249

244250
AM1_Lock.loaded_sample = params.am1_sample.lock().unwrap().to_vec();
245-
246-
AM1_Lock.regenerate_samples();
251+
AM1_Lock.sample_lib.clear();
252+
// Samples get regenerated next frame
247253
}
248254
}
249255

250256
// This happens on some plugin loads and crashes your DAW :(
251257
// These if statements are ordered this way to catch this scenario first and prevent crashing DAW
252-
if AM2.lock().unwrap().sample_lib.len() == 0 &&
253-
(AM2.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
254-
AM2.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) {
258+
if (AM2.lock().unwrap().sample_lib.len() == 0 || am2_loaded_sample_len == 2) &&
259+
(am2_type == AudioModuleType::Sampler || am2_type == AudioModuleType::Granulizer) {
255260
let mut AM2_Lock = AM2.lock().unwrap();
256261

257262
AM2_Lock.loaded_sample = params.am2_sample.lock().unwrap().to_vec();
258263

259264
AM2_Lock.regenerate_samples();
265+
setter.set_parameter(&params.load_sample_2, false);
266+
}
260267
// This lets the internal param track the current samples for when the plugin gets reopened/reloaded
261268
// It runs if there is peristent sample data but not sample data in the audio module
262269
// This is not very pretty looking but I couldn't allocate separately locked Audio Modules since somewhere
263270
// This would cause a deadlock and break Actuate :|
264271
// Maybe in future this will become nicer
265-
} else if params.am2_sample.lock().unwrap()[0].len() > 1 &&
266-
AM2.lock().unwrap().loaded_sample[0].len() <= 2 &&
267-
(AM2.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
268-
AM2.lock().unwrap().audio_module_type == AudioModuleType::Granulizer)
272+
if params.am2_sample.lock().unwrap()[0].len() > 1 &&
273+
am2_loaded_sample_len <= 2 &&
274+
(am2_type == AudioModuleType::Sampler || am2_type == AudioModuleType::Granulizer)
269275
{
270-
// This if is separate since previously when it was included in th eabove it could
276+
// This if is separate since previously when it was included in the above it could
271277
// panic on length issues handled by [AM1.lock().unwrap().loaded_sample[0].len() <= 2]
272-
if AM2.lock().unwrap().sample_lib[0][0][0] == 0.0 {
278+
if AM2.lock().unwrap().sample_lib[0][0].len() != 127 {
273279
let mut AM2_Lock = AM2.lock().unwrap();
274280

275281
AM2_Lock.loaded_sample = params.am2_sample.lock().unwrap().to_vec();
276-
277-
AM2_Lock.regenerate_samples();
282+
AM2_Lock.sample_lib.clear();
283+
// Samples get regenerated next frame
278284
}
279285
}
280286

281287
// This happens on some plugin loads and crashes your DAW :(
282288
// These if statements are ordered this way to catch this scenario first and prevent crashing DAW
283-
if AM3.lock().unwrap().sample_lib.len() == 0 &&
284-
(AM3.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
285-
AM3.lock().unwrap().audio_module_type == AudioModuleType::Granulizer) {
289+
if (AM3.lock().unwrap().sample_lib.len() == 0 || am3_loaded_sample_len == 2) &&
290+
(am3_type == AudioModuleType::Sampler || am3_type == AudioModuleType::Granulizer) {
286291
let mut AM3_Lock = AM3.lock().unwrap();
287292

288293
AM3_Lock.loaded_sample = params.am3_sample.lock().unwrap().to_vec();
289294

290295
AM3_Lock.regenerate_samples();
296+
setter.set_parameter(&params.load_sample_3, false);
297+
}
291298
// This lets the internal param track the current samples for when the plugin gets reopened/reloaded
292299
// It runs if there is peristent sample data but not sample data in the audio module
293300
// This is not very pretty looking but I couldn't allocate separately locked Audio Modules since somewhere
294301
// This would cause a deadlock and break Actuate :|
295302
// Maybe in future this will become nicer
296-
} else if params.am3_sample.lock().unwrap()[0].len() > 1 &&
297-
AM3.lock().unwrap().loaded_sample[0].len() <= 2 &&
298-
(AM3.lock().unwrap().audio_module_type == AudioModuleType::Sampler ||
299-
AM3.lock().unwrap().audio_module_type == AudioModuleType::Granulizer)
303+
if params.am3_sample.lock().unwrap()[0].len() > 1 &&
304+
am3_loaded_sample_len <= 2 &&
305+
(am3_type == AudioModuleType::Sampler || am3_type == AudioModuleType::Granulizer)
300306
{
301-
// This if is separate since previously when it was included in th eabove it could
307+
// This if is separate since previously when it was included in the above it could
302308
// panic on length issues handled by [AM1.lock().unwrap().loaded_sample[0].len() <= 2]
303-
if AM3.lock().unwrap().sample_lib[0][0][0] == 0.0 {
309+
if AM3.lock().unwrap().sample_lib[0][0].len() != 127 {
304310
let mut AM3_Lock = AM3.lock().unwrap();
305311

306312
AM3_Lock.loaded_sample = params.am3_sample.lock().unwrap().to_vec();
307-
308-
AM3_Lock.regenerate_samples();
313+
AM3_Lock.sample_lib.clear();
314+
// Samples get regenerated next frame
309315
}
310316
}
311317

@@ -406,7 +412,7 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
406412
ui.label(RichText::new("Actuate")
407413
.font(FONT)
408414
.color(FONT_COLOR))
409-
.on_hover_text("v1.4.1 by Ardura!");
415+
.on_hover_text("v1.4.3 by Ardura!");
410416
ui.add_space(2.0);
411417
ui.separator();
412418

@@ -549,7 +555,9 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
549555
}
550556
}
551557
ui.colored_label(YELLOW_MUSTARD, "Preset Banks");
552-
for (directory, _) in dir_files_map.lock().unwrap().iter() {
558+
let mut sorted_dirs: Vec<PathBuf> = dir_files_map.lock().unwrap().keys().cloned().collect();
559+
sorted_dirs.sort();
560+
for directory in sorted_dirs {
553561
let name = directory.file_name().unwrap().to_str().unwrap().to_string();
554562
ui.selectable_value(&mut *bank_current_value.write().unwrap(), name.clone(),
555563
RichText::new(name)
@@ -624,7 +632,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
624632
if unserialized.is_some() {
625633
let mut locked_lib = arc_preset.lock().unwrap();
626634
*locked_lib = unserialized.unwrap();
627-
//let temp_preset = &locked_lib;
628635
*params.preset_name_p.lock().unwrap() = locked_lib.preset_name.clone();
629636
*params.preset_info_p.lock().unwrap() = locked_lib.preset_info.clone();
630637
setter.set_parameter(&params.preset_category, locked_lib.preset_category);
@@ -639,8 +646,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
639646
&mut AM1.lock().unwrap(),
640647
&mut AM2.lock().unwrap(),
641648
&mut AM3.lock().unwrap(),);
642-
// This is set for the process thread
643-
reload_entire_preset.store(true, Ordering::SeqCst);
644649
}
645650
}
646651
// Tags
@@ -782,8 +787,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
782787
&mut AM1.lock().unwrap(),
783788
&mut AM2.lock().unwrap(),
784789
&mut AM3.lock().unwrap(),);
785-
// This is set for the process thread
786-
reload_entire_preset.store(true, Ordering::SeqCst);
787790
}
788791
}
789792
// Tags
@@ -936,8 +939,6 @@ pub(crate) fn make_actuate_gui(instance: &mut Actuate, _async_executor: AsyncExe
936939
&mut AM1.lock().unwrap(),
937940
&mut AM2.lock().unwrap(),
938941
&mut AM3.lock().unwrap(),);
939-
// This is set for the process thread
940-
reload_entire_preset.store(true, Ordering::SeqCst);
941942
}
942943
import_preset_active.store(false, Ordering::Relaxed);
943944
}

0 commit comments

Comments
 (0)