diff options
Diffstat (limited to 'src/wavedata.c')
-rw-r--r-- | src/wavedata.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/wavedata.c b/src/wavedata.c new file mode 100644 index 0000000..8f7e359 --- /dev/null +++ b/src/wavedata.c @@ -0,0 +1,141 @@ +/* + Oscillator wave data generation. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <string.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include <config.h> +#include "wavedata.h" + +#ifndef WAVEDATA_SUBDIR +#warning *** No wavedata subdir given, using default 'blip_files' +#define WAVEDATA_SUBDIR "blip_files" +#endif + +int +wavedata_load(Wavedata* w, + const char* wdat_descriptor_name, + unsigned long sample_rate) +{ + const char* subdir = WAVEDATA_SUBDIR; + char* ladspa_path; + const char* start; + const char* end; + int extra; + size_t subdirlen = strlen(WAVEDATA_SUBDIR); + size_t length; + size_t pathlen; + char* path; + char* filename; + DIR* dp; + struct dirent* ep; + struct stat sb; + void* handle; + int (*desc_func)(Wavedata*, unsigned long); + int retval = -1; + + /* Get LADPSA_PATH, if available */ + ladspa_path = getenv("LV2_PATH"); + if (!ladspa_path) { + ladspa_path = "/usr/lib/ladspa:/usr/local/lib/ladspa"; + } + + start = ladspa_path; + while (*start != '\0') { + while (*start == ':') { + start++; + } + end = start; + while (*end != ':' && *end != '\0') { + end++; + } + if (end - start > 0) { + extra = (*(end - 1) == '/') ? 0 : 1; + path = (char*)malloc(end - start + extra + subdirlen + 1 + 1); + if (path) { + strncpy(path, start, end - start); + if (extra == 1) { + path[end - start] = '/'; + } + + path[end - start + extra] = '\0'; + + if (subdirlen > 0) { + strncat(path, subdir, subdirlen); + path[end - start + extra + subdirlen] = '/'; + path[end - start + extra + subdirlen + 1] = '\0'; + } else { + path[end - start + extra + subdirlen] = '\0'; + } + + dp = opendir(path); + if (dp) { + pathlen = strlen(path); + while ((ep = readdir(dp))) { + /* Stat file to get type */ + length = pathlen + strlen(ep->d_name); + filename = (char*)malloc(length + 1); + if (filename) { + strncpy(filename, path, pathlen); + + filename[pathlen] = '\0'; + filename = strncat(filename, ep->d_name, strlen(ep->d_name)); + filename[length] = '\0'; + + if (!stat(filename, &sb)) { + /* We only want regular files */ + if (S_ISREG(sb.st_mode)) { + /* Whew. Now see if we've got the right dll */ + handle = dlopen(filename, RTLD_NOW); + + if (handle) { + desc_func = dlsym(handle, wdat_descriptor_name); + + if (desc_func) { + free(filename); + free(path); + retval = desc_func(w, sample_rate); + w->data_handle = handle; + return retval; + } + } + } + } + free(filename); + } + } + closedir(dp); + } + free(path); + } + } + start = end; + } + return retval; +} + +void +wavedata_unload(Wavedata* w) +{ + dlclose(w->data_handle); +} |