@@ -6,7 +6,7 @@ use std::{collections::HashMap, ffi::OsStr, ops::RangeInclusive, path::{Path, Pa
66use nih_plug:: { context:: gui:: AsyncExecutor , editor:: Editor , nih_log} ;
77use nih_plug_egui:: { create_egui_editor, egui:: { self , Color32 , Pos2 , Rect , RichText , CornerRadius , ScrollArea , Vec2 } , widgets:: ParamSlider } ;
88use walkdir:: WalkDir ;
9- use crate :: actuate_load_save_dialog:: FileDialog ;
9+ use crate :: actuate_load_save_dialog:: { DialogMode , FileDialog } ;
1010
1111use 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