1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2020 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/plugin/ags_ladspa_manager.h>
21
22 #include <ags/plugin/ags_base_plugin.h>
23
24 #if defined(AGS_W32API)
25 #include <windows.h>
26 #else
27 #include <dlfcn.h>
28 #endif
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35
36 #include <string.h>
37 #include <strings.h>
38
39 #include <ladspa.h>
40
41 #include <ags/config.h>
42
43 void ags_ladspa_manager_class_init(AgsLadspaManagerClass *ladspa_manager);
44 void ags_ladspa_manager_init (AgsLadspaManager *ladspa_manager);
45 void ags_ladspa_manager_dispose(GObject *gobject);
46 void ags_ladspa_manager_finalize(GObject *gobject);
47
48 /**
49 * SECTION:ags_ladspa_manager
50 * @short_description: Singleton pattern to organize LADSPA
51 * @title: AgsLadspaManager
52 * @section_id:
53 * @include: ags/plugin/ags_ladspa_manager.h
54 *
55 * The #AgsLadspaManager loads/unloads LADSPA plugins.
56 */
57 enum{
58 ADD,
59 CREATE,
60 LAST_SIGNAL,
61 };
62
63 static gpointer ags_ladspa_manager_parent_class = NULL;
64
65 AgsLadspaManager *ags_ladspa_manager = NULL;
66 gchar **ags_ladspa_default_path = NULL;
67
68 GType
ags_ladspa_manager_get_type(void)69 ags_ladspa_manager_get_type (void)
70 {
71 static volatile gsize g_define_type_id__volatile = 0;
72
73 if(g_once_init_enter (&g_define_type_id__volatile)){
74 GType ags_type_ladspa_manager = 0;
75
76 static const GTypeInfo ags_ladspa_manager_info = {
77 sizeof (AgsLadspaManagerClass),
78 NULL, /* base_init */
79 NULL, /* base_finalize */
80 (GClassInitFunc) ags_ladspa_manager_class_init,
81 NULL, /* class_finalize */
82 NULL, /* class_data */
83 sizeof (AgsLadspaManager),
84 0, /* n_preallocs */
85 (GInstanceInitFunc) ags_ladspa_manager_init,
86 };
87
88 ags_type_ladspa_manager = g_type_register_static(G_TYPE_OBJECT,
89 "AgsLadspaManager",
90 &ags_ladspa_manager_info,
91 0);
92
93 g_once_init_leave(&g_define_type_id__volatile, ags_type_ladspa_manager);
94 }
95
96 return g_define_type_id__volatile;
97 }
98
99 void
ags_ladspa_manager_class_init(AgsLadspaManagerClass * ladspa_manager)100 ags_ladspa_manager_class_init(AgsLadspaManagerClass *ladspa_manager)
101 {
102 GObjectClass *gobject;
103
104 ags_ladspa_manager_parent_class = g_type_class_peek_parent(ladspa_manager);
105
106 /* GObjectClass */
107 gobject = (GObjectClass *) ladspa_manager;
108
109 gobject->dispose = ags_ladspa_manager_dispose;
110 gobject->finalize = ags_ladspa_manager_finalize;
111 }
112
113 void
ags_ladspa_manager_init(AgsLadspaManager * ladspa_manager)114 ags_ladspa_manager_init(AgsLadspaManager *ladspa_manager)
115 {
116 /* ladspa manager mutex */
117 g_rec_mutex_init(&(ladspa_manager->obj_mutex));
118
119 /* ladspa plugin and path */
120 ladspa_manager->ladspa_plugin = NULL;
121
122 if(ags_ladspa_default_path == NULL){
123 gchar *ladspa_env;
124
125 if((ladspa_env = getenv("LADSPA_PATH")) != NULL){
126 gchar *iter, *next;
127 guint i;
128
129 ags_ladspa_default_path = (gchar **) malloc(sizeof(gchar *));
130
131 iter = ladspa_env;
132 i = 0;
133
134 while((next = strchr(iter, G_SEARCHPATH_SEPARATOR)) != NULL){
135 ags_ladspa_default_path = (gchar **) realloc(ags_ladspa_default_path,
136 (i + 2) * sizeof(gchar *));
137 ags_ladspa_default_path[i] = g_strndup(iter,
138 next - iter);
139
140 iter = next + 1;
141 i++;
142 }
143
144 if(*iter != '\0'){
145 ags_ladspa_default_path = (gchar **) realloc(ags_ladspa_default_path,
146 (i + 2) * sizeof(gchar *));
147 ags_ladspa_default_path[i] = g_strdup(iter);
148
149 i++;
150 }
151
152 ags_ladspa_default_path[i] = NULL;
153 }else{
154 #if defined(AGS_W32API)
155 AgsApplicationContext *application_context;
156
157 gchar *app_dir;
158 gchar *path;
159
160 guint i;
161
162 i = 0;
163
164 application_context = ags_application_context_get_instance();
165
166 app_dir = NULL;
167
168 if(strlen(application_context->argv[0]) > strlen("\\gsequencer.exe")){
169 app_dir = g_strndup(application_context->argv[0],
170 strlen(application_context->argv[0]) - strlen("\\gsequencer.exe"));
171 }
172
173 ags_ladspa_default_path = (gchar **) malloc(2 * sizeof(gchar *));
174
175 path = g_strdup_printf("%s\\ladspa",
176 g_get_current_dir());
177
178 if(g_file_test(path,
179 G_FILE_TEST_IS_DIR)){
180 ags_ladspa_default_path[i++] = path;
181 }else{
182 g_free(path);
183
184 if(g_path_is_absolute(app_dir)){
185 ags_ladspa_default_path[i++] = g_strdup_printf("%s\\ladspa",
186 app_dir);
187 }else{
188 ags_ladspa_default_path[i++] = g_strdup_printf("%s\\%s\\ladspa",
189 g_get_current_dir(),
190 app_dir);
191 }
192 }
193
194 ags_ladspa_default_path[i++] = NULL;
195
196 g_free(app_dir);
197 #else
198 gchar *home_dir;
199 guint i;
200
201 #ifdef AGS_MAC_BUNDLE
202 if((home_dir = getenv("HOME")) != NULL){
203 ags_ladspa_default_path = (gchar **) malloc(7 * sizeof(gchar *));
204 }else{
205 ags_ladspa_default_path = (gchar **) malloc(6 * sizeof(gchar *));
206 }
207 #else
208 if((home_dir = getenv("HOME")) != NULL){
209 ags_ladspa_default_path = (gchar **) malloc(6 * sizeof(gchar *));
210 }else{
211 ags_ladspa_default_path = (gchar **) malloc(5 * sizeof(gchar *));
212 }
213 #endif
214
215 i = 0;
216
217 #ifdef AGS_MAC_BUNDLE
218 ags_ladspa_default_path[i++] = g_strdup_printf("%s/ladspa",
219 getenv("GSEQUENCER_PLUGIN_DIR"));
220 #endif
221
222 ags_ladspa_default_path[i++] = g_strdup("/usr/lib64/ladspa");
223 ags_ladspa_default_path[i++] = g_strdup("/usr/local/lib64/ladspa");
224 ags_ladspa_default_path[i++] = g_strdup("/usr/lib/ladspa");
225 ags_ladspa_default_path[i++] = g_strdup("/usr/local/lib/ladspa");
226
227 if(home_dir != NULL){
228 ags_ladspa_default_path[i++] = g_strdup_printf("%s/.ladspa",
229 home_dir);
230 }
231
232 ags_ladspa_default_path[i++] = NULL;
233 #endif
234 }
235 }
236 }
237
238 void
ags_ladspa_manager_dispose(GObject * gobject)239 ags_ladspa_manager_dispose(GObject *gobject)
240 {
241 AgsLadspaManager *ladspa_manager;
242
243 ladspa_manager = AGS_LADSPA_MANAGER(gobject);
244
245 if(ladspa_manager->ladspa_plugin != NULL){
246 g_list_free_full(ladspa_manager->ladspa_plugin,
247 (GDestroyNotify) g_object_unref);
248
249 ladspa_manager->ladspa_plugin = NULL;
250 }
251
252 /* call parent */
253 G_OBJECT_CLASS(ags_ladspa_manager_parent_class)->dispose(gobject);
254 }
255
256 void
ags_ladspa_manager_finalize(GObject * gobject)257 ags_ladspa_manager_finalize(GObject *gobject)
258 {
259 AgsLadspaManager *ladspa_manager;
260
261 GList *ladspa_plugin;
262
263 ladspa_manager = AGS_LADSPA_MANAGER(gobject);
264
265 ladspa_plugin = ladspa_manager->ladspa_plugin;
266
267 g_list_free_full(ladspa_plugin,
268 (GDestroyNotify) g_object_unref);
269
270 if(ladspa_manager == ags_ladspa_manager){
271 ags_ladspa_manager = NULL;
272 }
273
274 /* call parent */
275 G_OBJECT_CLASS(ags_ladspa_manager_parent_class)->finalize(gobject);
276 }
277
278 /**
279 * ags_ladspa_manager_get_default_path:
280 *
281 * Get ladspa manager default plugin path.
282 *
283 * Returns: (element-type utf8) (array zero-terminated=1) (transfer none): the plugin default search path as a string vector
284 *
285 * Since: 3.0.0
286 */
287 gchar**
ags_ladspa_manager_get_default_path()288 ags_ladspa_manager_get_default_path()
289 {
290 return(ags_ladspa_default_path);
291 }
292
293 /**
294 * ags_ladspa_manager_set_default_path:
295 * @default_path: (element-type utf8) (array zero-terminated=1) (transfer full): the string vector array to use as default path
296 *
297 * Set ladspa manager default plugin path.
298 *
299 * Since: 3.0.0
300 */
301 void
ags_ladspa_manager_set_default_path(gchar ** default_path)302 ags_ladspa_manager_set_default_path(gchar** default_path)
303 {
304 ags_ladspa_default_path = default_path;
305 }
306
307 /**
308 * ags_ladspa_manager_get_filenames:
309 * @ladspa_manager: the #AgsLadspaManager
310 *
311 * Retrieve all filenames
312 *
313 * Returns: (element-type utf8) (array zero-terminated=1) (transfer full): a %NULL-terminated array of filenames
314 *
315 * Since: 3.0.0
316 */
317 gchar**
ags_ladspa_manager_get_filenames(AgsLadspaManager * ladspa_manager)318 ags_ladspa_manager_get_filenames(AgsLadspaManager *ladspa_manager)
319 {
320 GList *start_ladspa_plugin, *ladspa_plugin;
321
322 gchar **filenames;
323
324 guint i;
325 gboolean contains_filename;
326
327 GRecMutex *ladspa_manager_mutex;
328 GRecMutex *base_plugin_mutex;
329
330 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager)){
331 return(NULL);
332 }
333
334 /* get ladspa manager mutex */
335 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
336
337 /* collect */
338 g_rec_mutex_lock(ladspa_manager_mutex);
339
340 ladspa_plugin =
341 start_ladspa_plugin = g_list_copy(ladspa_manager->ladspa_plugin);
342
343 g_rec_mutex_unlock(ladspa_manager_mutex);
344
345 filenames = NULL;
346
347 for(i = 0; ladspa_plugin != NULL;){
348 gchar *filename;
349
350 /* get base plugin mutex */
351 base_plugin_mutex = AGS_BASE_PLUGIN_GET_OBJ_MUTEX(ladspa_plugin->data);
352
353 /* duplicate filename */
354 g_rec_mutex_lock(base_plugin_mutex);
355
356 filename = g_strdup(AGS_BASE_PLUGIN(ladspa_plugin->data)->filename);
357
358 g_rec_mutex_unlock(base_plugin_mutex);
359
360 if(filenames == NULL){
361 filenames = (gchar **) malloc(2 * sizeof(gchar *));
362
363 /* set filename */
364 filenames[i] = filename;
365
366 /* terminate */
367 filenames[i + 1] = NULL;
368
369 i++;
370 }else{
371 #ifdef HAVE_GLIB_2_44
372 contains_filename = g_strv_contains(filenames,
373 AGS_BASE_PLUGIN(ladspa_plugin->data)->filename);
374 #else
375 contains_filename = ags_strv_contains(filenames,
376 AGS_BASE_PLUGIN(ladspa_plugin->data)->filename);
377 #endif
378
379 if(!contains_filename){
380 filenames = (gchar **) realloc(filenames,
381 (i + 2) * sizeof(gchar *));
382 filenames[i] = filename;
383 filenames[i + 1] = NULL;
384
385 i++;
386 }else{
387 g_free(filename);
388 }
389 }
390
391 ladspa_plugin = ladspa_plugin->next;
392 }
393
394 g_list_free(start_ladspa_plugin);
395
396 return(filenames);
397 }
398
399 /**
400 * ags_ladspa_manager_find_ladspa_plugin:
401 * @ladspa_manager: the #AgsLadspaManager
402 * @filename: the filename of the plugin
403 * @effect: the effect's name
404 *
405 * Lookup filename in loaded plugins.
406 *
407 * Returns: (transfer none): the #AgsLadspaPlugin
408 *
409 * Since: 3.0.0
410 */
411 AgsLadspaPlugin*
ags_ladspa_manager_find_ladspa_plugin(AgsLadspaManager * ladspa_manager,gchar * filename,gchar * effect)412 ags_ladspa_manager_find_ladspa_plugin(AgsLadspaManager *ladspa_manager,
413 gchar *filename, gchar *effect)
414 {
415 AgsLadspaPlugin *ladspa_plugin;
416
417 GList *start_list, *list;
418
419 gboolean success;
420
421 GRecMutex *ladspa_manager_mutex;
422 GRecMutex *base_plugin_mutex;
423
424 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager)){
425 return(NULL);
426 }
427
428 /* get ladspa manager mutex */
429 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
430
431 /* collect */
432 g_rec_mutex_lock(ladspa_manager_mutex);
433
434 list =
435 start_list = g_list_copy(ladspa_manager->ladspa_plugin);
436
437 g_rec_mutex_unlock(ladspa_manager_mutex);
438
439 success = FALSE;
440
441 while(list != NULL){
442 ladspa_plugin = AGS_LADSPA_PLUGIN(list->data);
443
444 /* get base plugin mutex */
445 base_plugin_mutex = AGS_BASE_PLUGIN_GET_OBJ_MUTEX(ladspa_plugin);
446
447 /* check filename and effect */
448 g_rec_mutex_lock(base_plugin_mutex);
449
450 success = (!g_strcmp0(AGS_BASE_PLUGIN(ladspa_plugin)->filename,
451 filename) &&
452 !g_strcmp0(AGS_BASE_PLUGIN(ladspa_plugin)->effect,
453 effect)) ? TRUE: FALSE;
454
455 g_rec_mutex_unlock(base_plugin_mutex);
456
457 if(success){
458 break;
459 }
460
461 list = list->next;
462 }
463
464 g_list_free(start_list);
465
466 if(!success){
467 ladspa_plugin = NULL;
468 }
469
470 return(ladspa_plugin);
471 }
472
473 /**
474 * ags_ladspa_manager_find_ladspa_plugin_with_fallback:
475 * @ladspa_manager: the #AgsLadspaManager
476 * @filename: the filename of the plugin
477 * @effect: the effect's name
478 *
479 * Lookup filename in loaded plugins.
480 *
481 * Returns: (transfer none): the #AgsLadspaPlugin
482 *
483 * Since: 3.5.10
484 */
485 AgsLadspaPlugin*
ags_ladspa_manager_find_ladspa_plugin_with_fallback(AgsLadspaManager * ladspa_manager,gchar * filename,gchar * effect)486 ags_ladspa_manager_find_ladspa_plugin_with_fallback(AgsLadspaManager *ladspa_manager,
487 gchar *filename, gchar *effect)
488 {
489 AgsLadspaPlugin *ladspa_plugin;
490
491 GList *start_list, *list;
492
493 gchar *filename_suffix;
494
495 gboolean success;
496
497 GRecMutex *ladspa_manager_mutex;
498 GRecMutex *base_plugin_mutex;
499
500 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager) ||
501 filename == NULL ||
502 effect == NULL){
503 return(NULL);
504 }
505
506 /* get ladspa manager mutex */
507 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
508
509 ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(ladspa_manager,
510 filename, effect);
511
512 if(ladspa_plugin == NULL){
513 filename_suffix = strrchr(filename, "/");
514
515 /* collect */
516 g_rec_mutex_lock(ladspa_manager_mutex);
517
518 list =
519 start_list = g_list_copy(ladspa_manager->ladspa_plugin);
520
521 g_rec_mutex_unlock(ladspa_manager_mutex);
522
523 success = FALSE;
524
525 while(list != NULL){
526 ladspa_plugin = AGS_LADSPA_PLUGIN(list->data);
527
528 /* get base plugin mutex */
529 base_plugin_mutex = AGS_BASE_PLUGIN_GET_OBJ_MUTEX(ladspa_plugin);
530
531 /* check filename and effect */
532 g_rec_mutex_lock(base_plugin_mutex);
533
534 success = (g_str_has_suffix(AGS_BASE_PLUGIN(ladspa_plugin)->filename,
535 filename_suffix) &&
536 !g_strcmp0(AGS_BASE_PLUGIN(ladspa_plugin)->effect,
537 effect)) ? TRUE: FALSE;
538
539 g_rec_mutex_unlock(base_plugin_mutex);
540
541 if(success){
542 break;
543 }
544
545 list = list->next;
546 }
547
548 g_list_free(start_list);
549
550 if(!success){
551 ladspa_plugin = NULL;
552 }
553 }
554
555 return(ladspa_plugin);
556 }
557
558 /**
559 * ags_ladspa_manager_load_blacklist:
560 * @ladspa_manager: the #AgsLadspaManager
561 * @blacklist_filename: the filename as string
562 *
563 * Load blacklisted plugin filenames.
564 *
565 * Since: 3.0.0
566 */
567 void
ags_ladspa_manager_load_blacklist(AgsLadspaManager * ladspa_manager,gchar * blacklist_filename)568 ags_ladspa_manager_load_blacklist(AgsLadspaManager *ladspa_manager,
569 gchar *blacklist_filename)
570 {
571 GRecMutex *ladspa_manager_mutex;
572
573 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager) ||
574 blacklist_filename == NULL){
575 return;
576 }
577
578 /* get ladspa manager mutex */
579 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
580
581 /* fill in */
582 g_rec_mutex_lock(ladspa_manager_mutex);
583
584 if(g_file_test(blacklist_filename,
585 (G_FILE_TEST_EXISTS |
586 G_FILE_TEST_IS_REGULAR))){
587 FILE *file;
588
589 gchar *str;
590
591 file = fopen(blacklist_filename,
592 "r");
593
594 #ifndef AGS_W32API
595 while(getline(&str, NULL, file) != -1){
596 ladspa_manager->ladspa_plugin_blacklist = g_list_prepend(ladspa_manager->ladspa_plugin_blacklist,
597 str);
598 }
599 #endif
600 }
601
602 g_rec_mutex_unlock(ladspa_manager_mutex);
603 }
604
605 /**
606 * ags_ladspa_manager_load_file:
607 * @ladspa_manager: the #AgsLadspaManager
608 * @ladspa_path: the LADSPA path
609 * @filename: the filename of the plugin
610 *
611 * Load @filename specified plugin.
612 *
613 * Since: 3.0.0
614 */
615 void
ags_ladspa_manager_load_file(AgsLadspaManager * ladspa_manager,gchar * ladspa_path,gchar * filename)616 ags_ladspa_manager_load_file(AgsLadspaManager *ladspa_manager,
617 gchar *ladspa_path,
618 gchar *filename)
619 {
620 AgsLadspaPlugin *ladspa_plugin;
621
622 gchar *path;
623 gchar *effect;
624
625 void *plugin_so;
626 LADSPA_Descriptor_Function ladspa_descriptor;
627 LADSPA_Descriptor *plugin_descriptor;
628 unsigned long i;
629 gboolean success;
630
631 GRecMutex *ladspa_manager_mutex;
632
633 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager) ||
634 ladspa_path == NULL ||
635 filename == NULL){
636 return;
637 }
638
639 /* get ladspa manager mutex */
640 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
641
642 /* load */
643 g_rec_mutex_lock(ladspa_manager_mutex);
644
645 path = g_strdup_printf("%s%c%s",
646 ladspa_path,
647 G_DIR_SEPARATOR,
648 filename);
649
650 g_message("ags_ladspa_manager.c loading - %s", path);
651
652 #ifdef AGS_W32API
653 plugin_so = LoadLibrary(path);
654 #else
655 plugin_so = dlopen(path,
656 RTLD_NOW);
657 #endif
658
659 if(plugin_so == NULL){
660 g_warning("ags_ladspa_manager.c - failed to load static object file");
661
662 #ifndef AGS_W32API
663 dlerror();
664 #endif
665
666 g_rec_mutex_unlock(ladspa_manager_mutex);
667
668 return;
669 }
670
671 success = FALSE;
672
673 #ifdef AGS_W32API
674 ladspa_descriptor = (LADSPA_Descriptor_Function) GetProcAddress((void *) plugin_so,
675 "ladspa_descriptor");
676
677 success = (!ladspa_descriptor) ? FALSE: TRUE;
678 #else
679 ladspa_descriptor = (LADSPA_Descriptor_Function) dlsym((void *) plugin_so,
680 "ladspa_descriptor");
681
682 success = (dlerror() == NULL) ? TRUE: FALSE;
683 #endif
684
685 if(success && ladspa_descriptor){
686 for(i = 0; (plugin_descriptor = ladspa_descriptor(i)) != NULL; i++){
687 if(ags_base_plugin_find_effect(ladspa_manager->ladspa_plugin,
688 path,
689 plugin_descriptor->Name) == NULL){
690 ladspa_plugin = ags_ladspa_plugin_new(path,
691 plugin_descriptor->Name,
692 i);
693 ags_base_plugin_load_plugin((AgsBasePlugin *) ladspa_plugin);
694 ladspa_manager->ladspa_plugin = g_list_prepend(ladspa_manager->ladspa_plugin,
695 ladspa_plugin);
696 }
697 }
698 }
699
700 g_rec_mutex_unlock(ladspa_manager_mutex);
701
702 g_free(path);
703 }
704
705 /**
706 * ags_ladspa_manager_load_default_directory:
707 * @ladspa_manager: the #AgsLadspaManager
708 *
709 * Loads all available plugins.
710 *
711 * Since: 3.0.0
712 */
713 void
ags_ladspa_manager_load_default_directory(AgsLadspaManager * ladspa_manager)714 ags_ladspa_manager_load_default_directory(AgsLadspaManager *ladspa_manager)
715 {
716 AgsLadspaPlugin *ladspa_plugin;
717
718 GDir *dir;
719
720 gchar **ladspa_path;
721 gchar *filename;
722
723 GError *error;
724
725 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager)){
726 return;
727 }
728
729 ladspa_path = ags_ladspa_default_path;
730
731 while(*ladspa_path != NULL){
732 if(!g_file_test(*ladspa_path,
733 G_FILE_TEST_EXISTS)){
734 ladspa_path++;
735
736 continue;
737 }
738
739 error = NULL;
740 dir = g_dir_open(*ladspa_path,
741 0,
742 &error);
743
744 if(error != NULL){
745 g_warning("%s", error->message);
746
747 ladspa_path++;
748
749 g_error_free(error);
750
751 continue;
752 }
753
754 while((filename = g_dir_read_name(dir)) != NULL){
755 if(g_str_has_suffix(filename,
756 AGS_LIBRARY_SUFFIX) &&
757 !g_list_find_custom(ladspa_manager->ladspa_plugin_blacklist,
758 filename,
759 strcmp)){
760 ags_ladspa_manager_load_file(ladspa_manager,
761 *ladspa_path,
762 filename);
763 }
764 }
765
766 ladspa_path++;
767 }
768 }
769
770 /**
771 * ags_ladspa_manager_get_ladspa_plugin:
772 * @ladspa_manager: the #AgsLadspaManager
773 *
774 * Get ladspa plugin.
775 *
776 * Returns: (transfer full): the #GList-struct containing #AgsLadspaPlugin
777 *
778 * Since: 3.5.15
779 */
780 GList*
ags_ladspa_manager_get_ladspa_plugin(AgsLadspaManager * ladspa_manager)781 ags_ladspa_manager_get_ladspa_plugin(AgsLadspaManager *ladspa_manager)
782 {
783 GList *ladspa_plugin;
784
785 GRecMutex *ladspa_manager_mutex;
786
787 if(!AGS_IS_LADSPA_MANAGER(ladspa_manager)){
788 return(NULL);
789 }
790
791 /* get ladspa manager mutex */
792 ladspa_manager_mutex = AGS_LADSPA_MANAGER_GET_OBJ_MUTEX(ladspa_manager);
793
794 g_rec_mutex_lock(ladspa_manager_mutex);
795
796 ladspa_plugin = g_list_copy_deep(ladspa_manager->ladspa_plugin,
797 (GCopyFunc) g_object_ref,
798 NULL);
799
800 g_rec_mutex_unlock(ladspa_manager_mutex);
801
802 return(ladspa_plugin);
803 }
804
805 /**
806 * ags_ladspa_manager_get_instance:
807 *
808 * Get instance.
809 *
810 * Returns: (transfer none): the #AgsLadspaManager
811 *
812 * Since: 3.0.0
813 */
814 AgsLadspaManager*
ags_ladspa_manager_get_instance()815 ags_ladspa_manager_get_instance()
816 {
817 static GMutex mutex;
818
819 g_mutex_lock(&mutex);
820
821 if(ags_ladspa_manager == NULL){
822 ags_ladspa_manager = ags_ladspa_manager_new();
823 }
824
825 g_mutex_unlock(&mutex);
826
827 return(ags_ladspa_manager);
828 }
829
830 /**
831 * ags_ladspa_manager_new:
832 *
833 * Create a new instance of #AgsLadspaManager
834 *
835 * Returns: the new #AgsLadspaManager
836 *
837 * Since: 3.0.0
838 */
839 AgsLadspaManager*
ags_ladspa_manager_new()840 ags_ladspa_manager_new()
841 {
842 AgsLadspaManager *ladspa_manager;
843
844 ladspa_manager = (AgsLadspaManager *) g_object_new(AGS_TYPE_LADSPA_MANAGER,
845 NULL);
846
847 return(ladspa_manager);
848 }
849