mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
Use glib dynamic librar loading functions
This commit is contained in:
parent
7f0ad243e7
commit
9509628da1
3 changed files with 49 additions and 177 deletions
|
@ -305,18 +305,20 @@ if(NOT enable-pkgconfig)
|
|||
|
||||
FIND_LIBRARY( GLIB_LIB NAMES glib glib-2.0 PATH GLIB_LIBRARY_DIR NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY( GTHREAD_LIB NAMES gthread gthread-2.0 PATH GTHREAD_LIBRARY_DIR NO_DEFAULT_PATH )
|
||||
FIND_LIBRARY( GMODULE_LIB NAMES gmodule gmodule-2.0 PATH GMODULE_LIBRARY_DIR NO_DEFAULT_PATH )
|
||||
FIND_PATH( GLIBH_DIR glib.h PATH GLIB_INCLUDE_DIR NO_DEFAULT_PATH )
|
||||
FIND_PATH( GLIBCONF_DIR glibconfig.h PATH GLIBCONF_INCLUDE_DIR NO_DEFAULT_PATH )
|
||||
|
||||
IF( GLIB_LIB MATCHES "GLIB_LIB-NOTFOUND" OR
|
||||
GTHREAD_LIB MATCHES "GTHREAD_LIB-NOTFOUND" OR
|
||||
GMODULE_LIB MATCHES "GMODULE_LIB-NOTFOUND" OR
|
||||
GLIBH_DIR MATCHES "GLIBH_DIR-NOTFOUND" OR
|
||||
GLIBCONF_DIR MATCHES "GLIBCONF_DIR-NOTFOUND")
|
||||
message( WARNING "Not sure if I found GLIB, continuing anyway.")
|
||||
ENDIF()
|
||||
|
||||
SET( GLIB_INCLUDE_DIRS ${GLIBH_DIR} ${GLIBCONF_DIR} )
|
||||
SET( GLIB_LIBRARIES ${GLIB_LIB} ${GTHREAD_LIB} )
|
||||
SET( GLIB_LIBRARIES ${GLIB_LIB} ${GTHREAD_LIB} ${GMODULE_LIB} )
|
||||
|
||||
message( STATUS "GLIB_INCLUDE_DIRS: " ${GLIB_INCLUDE_DIRS} )
|
||||
message( STATUS "GLIB_LIBRARIES: " ${GLIB_LIBRARIES} )
|
||||
|
@ -326,7 +328,7 @@ else(NOT enable-pkgconfig)
|
|||
find_package ( PkgConfig REQUIRED )
|
||||
|
||||
# Mandatory libraries: glib and gthread
|
||||
pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 )
|
||||
pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 gmodule-2.0>=2.6.5 )
|
||||
|
||||
include ( UnsetPkgConfig )
|
||||
|
||||
|
|
|
@ -29,11 +29,9 @@
|
|||
|
||||
#include "fluid_ladspa.h"
|
||||
#include "fluid_sys.h"
|
||||
#include <dlfcn.h>
|
||||
#include <math.h>
|
||||
#include <ladspa.h>
|
||||
|
||||
#define FLUID_LADSPA_MAX_LIBS 100
|
||||
#define FLUID_LADSPA_MAX_EFFECTS 100
|
||||
#define FLUID_LADSPA_MAX_NODES 100
|
||||
#define FLUID_LADSPA_MAX_PATH_LENGTH 512
|
||||
|
@ -60,14 +58,6 @@ typedef enum _fluid_ladspa_node_type_t {
|
|||
|
||||
} fluid_ladspa_node_type_t;
|
||||
|
||||
typedef struct _fluid_ladspa_lib_t
|
||||
{
|
||||
char *filename;
|
||||
void *dlib;
|
||||
LADSPA_Descriptor_Function descriptor;
|
||||
|
||||
} fluid_ladspa_lib_t;
|
||||
|
||||
typedef struct _fluid_ladspa_node_t
|
||||
{
|
||||
char *name;
|
||||
|
@ -91,6 +81,9 @@ typedef struct _fluid_ladspa_effect_t
|
|||
{
|
||||
char *name;
|
||||
|
||||
/* Pointer to the library that this effect was loaded from */
|
||||
fluid_module_t *lib;
|
||||
|
||||
/* The descriptor defines the plugin implementation, the
|
||||
* handle points to an instance of that plugin */
|
||||
const LADSPA_Descriptor *desc;
|
||||
|
@ -114,9 +107,6 @@ struct _fluid_ladspa_fx_t
|
|||
/* The buffer size for all audio buffers */
|
||||
int buffer_size;
|
||||
|
||||
fluid_ladspa_lib_t *libs[FLUID_LADSPA_MAX_LIBS];
|
||||
int num_libs;
|
||||
|
||||
fluid_ladspa_node_t *nodes[FLUID_LADSPA_MAX_NODES];
|
||||
int num_nodes;
|
||||
|
||||
|
@ -157,7 +147,7 @@ static fluid_ladspa_node_t *get_node(fluid_ladspa_fx_t *fx, const char *name);
|
|||
|
||||
/* Effect helpers */
|
||||
static fluid_ladspa_effect_t *
|
||||
new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const fluid_ladspa_lib_t *lib, const char *plugin_name);
|
||||
new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const char *lib_name, const char *plugin_name);
|
||||
static void delete_fluid_ladspa_effect(fluid_ladspa_effect_t *effect);
|
||||
static void activate_effect(fluid_ladspa_effect_t *effect);
|
||||
static void deactivate_effect(fluid_ladspa_effect_t *effect);
|
||||
|
@ -169,13 +159,8 @@ static void connect_node_to_port(fluid_ladspa_node_t *node, fluid_ladspa_dir_t d
|
|||
fluid_ladspa_effect_t *effect, int port_idx);
|
||||
static int create_control_port_nodes(fluid_ladspa_fx_t *fx, fluid_ladspa_effect_t *effect);
|
||||
|
||||
/* LADSPA library and plugin helpers */
|
||||
static fluid_ladspa_lib_t *new_fluid_ladspa_lib(fluid_ladspa_fx_t *fx, const char *filename);
|
||||
static void delete_fluid_ladspa_lib(fluid_ladspa_lib_t *lib);
|
||||
static fluid_ladspa_lib_t *get_ladspa_library(fluid_ladspa_fx_t *fx, const char *filename);
|
||||
static int load_plugin_library(fluid_ladspa_lib_t *lib);
|
||||
static void unload_plugin_library(fluid_ladspa_lib_t *lib);
|
||||
static const LADSPA_Descriptor *get_plugin_descriptor(const fluid_ladspa_lib_t *lib, const char *name);
|
||||
/* Plugin helpers */
|
||||
static const LADSPA_Descriptor *get_plugin_descriptor(fluid_module_t *lib, const char *name);
|
||||
|
||||
/* Sanity checks */
|
||||
static int check_all_ports_connected(fluid_ladspa_effect_t *effect, const char **name);
|
||||
|
@ -648,14 +633,6 @@ static void clear_ladspa(fluid_ladspa_fx_t *fx)
|
|||
}
|
||||
fx->num_effects = 0;
|
||||
|
||||
/* Unload and free all libraries */
|
||||
for (i = 0; i < fx->num_libs; i++)
|
||||
{
|
||||
unload_plugin_library(fx->libs[i]);
|
||||
delete_fluid_ladspa_lib(fx->libs[i]);
|
||||
}
|
||||
fx->num_libs = 0;
|
||||
|
||||
/* Delete all nodes (but not the host audio nodes) */
|
||||
for (i = 0; i < fx->num_nodes; i++)
|
||||
{
|
||||
|
@ -846,7 +823,6 @@ int fluid_ladspa_effect_set_control(fluid_ladspa_fx_t *fx, const char *effect_na
|
|||
int fluid_ladspa_add_effect(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *lib_name, const char *plugin_name)
|
||||
{
|
||||
fluid_ladspa_lib_t *lib;
|
||||
fluid_ladspa_effect_t *effect;
|
||||
|
||||
LADSPA_API_ENTER(fx);
|
||||
|
@ -861,13 +837,7 @@ int fluid_ladspa_add_effect(fluid_ladspa_fx_t *fx, const char *effect_name,
|
|||
LADSPA_API_RETURN(fx, FLUID_FAILED);
|
||||
}
|
||||
|
||||
lib = get_ladspa_library(fx, lib_name);
|
||||
if (lib == NULL)
|
||||
{
|
||||
LADSPA_API_RETURN(fx, FLUID_FAILED);
|
||||
}
|
||||
|
||||
effect = new_fluid_ladspa_effect(fx, lib, plugin_name);
|
||||
effect = new_fluid_ladspa_effect(fx, lib_name, plugin_name);
|
||||
if (effect == NULL)
|
||||
{
|
||||
LADSPA_API_RETURN(fx, FLUID_FAILED);
|
||||
|
@ -1121,19 +1091,27 @@ static int get_effect_port_idx(const fluid_ladspa_effect_t *effect, const char *
|
|||
*
|
||||
* If name is optional if the library contains only one plugin.
|
||||
*
|
||||
* @param lib pointer to fluid_ladspa_lib_t instance
|
||||
* @param lib pointer to the dynamically loaded library
|
||||
* @param name name (LADSPA Label) of the plugin
|
||||
* @return pointer to LADSPA_Descriptor, NULL on error or if not found
|
||||
*/
|
||||
static const LADSPA_Descriptor *get_plugin_descriptor(const fluid_ladspa_lib_t *lib, const char *name)
|
||||
static const LADSPA_Descriptor *get_plugin_descriptor(fluid_module_t *lib, const char *name)
|
||||
{
|
||||
const LADSPA_Descriptor *desc;
|
||||
const LADSPA_Descriptor *last_desc = NULL;
|
||||
int i = 0;
|
||||
LADSPA_Descriptor_Function ladspa_descriptor;
|
||||
int i;
|
||||
|
||||
if (!fluid_module_symbol(lib, "ladspa_descriptor", (void *)&ladspa_descriptor))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Unable to find ladspa_descriptor in '%s'. "
|
||||
"Is this really a LADSPA plugin?", fluid_module_name(lib));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; /* endless */; i++)
|
||||
{
|
||||
desc = lib->descriptor(i);
|
||||
desc = ladspa_descriptor(i);
|
||||
if (desc == NULL)
|
||||
break;
|
||||
|
||||
|
@ -1166,12 +1144,12 @@ static const LADSPA_Descriptor *get_plugin_descriptor(const fluid_ladspa_lib_t *
|
|||
* Plugins are identified by their "Label" in the plugin descriptor structure.
|
||||
*
|
||||
* @param fx LADSPA fx instance
|
||||
* @param lib pointer to fluid_ladspa_lib_t
|
||||
* @param name (optional) string name of the plugin (the LADSPA Label)
|
||||
* @param lib_name file path of the plugin library
|
||||
* @param plugin_name (optional) string name of the plugin (the LADSPA Label)
|
||||
* @return pointer to the new ladspa_plugin_t structure or NULL on error
|
||||
*/
|
||||
static fluid_ladspa_effect_t *
|
||||
new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const fluid_ladspa_lib_t *lib, const char *plugin_name)
|
||||
new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const char *lib_name, const char *plugin_name)
|
||||
{
|
||||
fluid_ladspa_effect_t *effect;
|
||||
|
||||
|
@ -1183,7 +1161,16 @@ new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const fluid_ladspa_lib_t *lib, co
|
|||
}
|
||||
FLUID_MEMSET(effect, 0, sizeof(fluid_ladspa_effect_t));
|
||||
|
||||
effect->desc = get_plugin_descriptor(lib, plugin_name);
|
||||
effect->lib = fluid_module_open(lib_name);
|
||||
if (effect->lib == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Unable to load LADSPA library '%s': %s", lib_name,
|
||||
fluid_module_error());
|
||||
delete_fluid_ladspa_effect(effect);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
effect->desc = get_plugin_descriptor(effect->lib, plugin_name);
|
||||
if (effect->desc == NULL)
|
||||
{
|
||||
delete_fluid_ladspa_effect(effect);
|
||||
|
@ -1194,7 +1181,7 @@ new_fluid_ladspa_effect(fluid_ladspa_fx_t *fx, const fluid_ladspa_lib_t *lib, co
|
|||
if (effect->handle == NULL)
|
||||
{
|
||||
delete_fluid_ladspa_effect(effect);
|
||||
FLUID_LOG(FLUID_ERR, "Unable to instantiate plugin '%s' from '%s'", plugin_name, lib->filename);
|
||||
FLUID_LOG(FLUID_ERR, "Unable to instantiate plugin '%s' from '%s'", plugin_name, lib_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1221,6 +1208,8 @@ static void delete_fluid_ladspa_effect(fluid_ladspa_effect_t *effect)
|
|||
effect->desc->cleanup(effect->handle);
|
||||
}
|
||||
|
||||
fluid_module_close(effect->lib);
|
||||
|
||||
FLUID_FREE(effect->name);
|
||||
FLUID_FREE(effect);
|
||||
}
|
||||
|
@ -1325,135 +1314,6 @@ static void delete_fluid_ladspa_node(fluid_ladspa_node_t *node)
|
|||
FLUID_FREE(node);
|
||||
}
|
||||
|
||||
static fluid_ladspa_lib_t *get_ladspa_library(fluid_ladspa_fx_t *fx, const char *filename)
|
||||
{
|
||||
int i;
|
||||
fluid_ladspa_lib_t *lib;
|
||||
|
||||
/* check if we have loaded this lib before and return it if found */
|
||||
for (i = 0; i < fx->num_libs; i++)
|
||||
{
|
||||
if (FLUID_STRCMP(fx->libs[i]->filename, filename) == 0)
|
||||
{
|
||||
return fx->libs[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (fx->num_libs >= FLUID_LADSPA_MAX_LIBS)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Maximum number of LADSPA libraries reached");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lib = new_fluid_ladspa_lib(fx, filename);
|
||||
if (lib == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (load_plugin_library(lib) != FLUID_OK)
|
||||
{
|
||||
delete_fluid_ladspa_lib(lib);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fx->libs[fx->num_libs++] = lib;
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
static fluid_ladspa_lib_t *new_fluid_ladspa_lib(fluid_ladspa_fx_t *fx, const char *filename)
|
||||
{
|
||||
fluid_ladspa_lib_t *lib;
|
||||
|
||||
lib = FLUID_NEW(fluid_ladspa_lib_t);
|
||||
if (lib == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
FLUID_MEMSET(lib, 0, sizeof(fluid_ladspa_lib_t));
|
||||
|
||||
lib->filename = FLUID_STRDUP(filename);
|
||||
if (lib->filename == NULL)
|
||||
{
|
||||
delete_fluid_ladspa_lib(lib);
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
static void delete_fluid_ladspa_lib(fluid_ladspa_lib_t *lib)
|
||||
{
|
||||
fluid_return_if_fail(lib != NULL);
|
||||
|
||||
FLUID_FREE(lib->filename);
|
||||
FLUID_FREE(lib);
|
||||
}
|
||||
|
||||
static int load_plugin_library(fluid_ladspa_lib_t *lib)
|
||||
{
|
||||
char filepath[FLUID_LADSPA_MAX_PATH_LENGTH];
|
||||
char *error;
|
||||
char *ladspa_path;
|
||||
|
||||
/* If the library name does not contain a slash, then try to load from
|
||||
* LADSPA_PATH */
|
||||
if (FLUID_STRCHR(lib->filename, '/') == NULL)
|
||||
{
|
||||
ladspa_path = getenv("LADSPA_PATH");
|
||||
if (ladspa_path == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Unable to load LADSPA library '%s'. Use slashes in the "
|
||||
"LADSPA library filename or set the LADSPA_PATH variable.",
|
||||
lib->filename);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
FLUID_SNPRINTF(filepath, FLUID_LADSPA_MAX_PATH_LENGTH, "%s/%s", ladspa_path, lib->filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
FLUID_SNPRINTF(filepath, FLUID_LADSPA_MAX_PATH_LENGTH, "%s", lib->filename);
|
||||
}
|
||||
|
||||
dlerror();
|
||||
lib->dlib = dlopen(filepath, RTLD_NOW);
|
||||
error = dlerror();
|
||||
if (lib->dlib == NULL || error)
|
||||
{
|
||||
if (error == NULL)
|
||||
{
|
||||
error = "Unknown error";
|
||||
}
|
||||
FLUID_LOG(FLUID_ERR, "Unable to load LADSPA library '%s': %d", filepath, error);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
lib->descriptor = (LADSPA_Descriptor_Function)dlsym(lib->dlib, "ladspa_descriptor");
|
||||
error = dlerror();
|
||||
if (lib->descriptor == NULL || error)
|
||||
{
|
||||
if (error == NULL)
|
||||
{
|
||||
error = "Unknown error";
|
||||
}
|
||||
dlclose(lib->dlib);
|
||||
FLUID_LOG(FLUID_ERR, "Unable to find ladspa_descriptor in '%': %s", filepath, error);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
static void unload_plugin_library(fluid_ladspa_lib_t *lib)
|
||||
{
|
||||
dlclose(lib->dlib);
|
||||
lib->dlib = NULL;
|
||||
lib->descriptor = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a ladspa_effect_t instance by it's name.
|
||||
*
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define _FLUID_SYS_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include "fluidsynth_priv.h"
|
||||
|
||||
|
||||
|
@ -318,6 +319,15 @@ void delete_fluid_thread(fluid_thread_t* thread);
|
|||
void fluid_thread_self_set_prio (int prio_level);
|
||||
int fluid_thread_join(fluid_thread_t* thread);
|
||||
|
||||
/* Dynamic Module Loading */
|
||||
typedef GModule fluid_module_t;
|
||||
|
||||
#define fluid_module_open(_name) g_module_open((_name), G_MODULE_BIND_LOCAL)
|
||||
#define fluid_module_close(_mod) g_module_close(_mod)
|
||||
#define fluid_module_error() g_module_error()
|
||||
#define fluid_module_name(_mod) g_module_name(_mod)
|
||||
#define fluid_module_symbol(_mod, _name, _ptr) g_module_symbol((_mod), (_name), (_ptr))
|
||||
|
||||
/* Sockets and I/O */
|
||||
|
||||
fluid_istream_t fluid_get_stdin (void);
|
||||
|
|
Loading…
Reference in a new issue