Update of /cvsroot/pure-data/externals/postlude/dssi/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3190/src
Modified Files: dssi~.c dssi~.h Added Files: jload.c jsearch.c jutils.h Log Message: Added jutils for improved search and load facilities
--- NEW FILE: jsearch.c --- /* search.c
Free software by Richard W.E. Furse. Do with as you will. No warranty. */
/* patched by Jarno Seppänen, jams@cs.tut.fi, for plugin~ */
/* patched by Jamie Bullock, jamie@postlude.co.uk, for dssi~ */
/*****************************************************************************/
#include <dirent.h> #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h>
/*****************************************************************************/
#include "dssi.h" #include "jutils.h"
/*****************************************************************************/
/* Search just the one directory. */ static void LADSPADirectoryPluginSearch (const char * pcDirectory, LADSPAPluginSearchCallbackFunction fCallbackFunction, void* user_data) { char * pcFilename; DIR * psDirectory; DSSI_Descriptor_Function fDescriptorFunction; long lDirLength; long iNeedSlash; struct dirent * psDirectoryEntry; void * pvPluginHandle; int is_DSSI;
lDirLength = strlen(pcDirectory); if (!lDirLength) return; if (pcDirectory[lDirLength - 1] == '/') iNeedSlash = 0; else iNeedSlash = 1;
psDirectory = opendir(pcDirectory); if (!psDirectory) return;
while (1) {
psDirectoryEntry = readdir(psDirectory); if (!psDirectoryEntry) { closedir(psDirectory); return; }
pcFilename = malloc(lDirLength + strlen(psDirectoryEntry->d_name) + 1 + iNeedSlash); strcpy(pcFilename, pcDirectory); if (iNeedSlash) strcat(pcFilename, "/"); strcat(pcFilename, psDirectoryEntry->d_name);
pvPluginHandle = dlopen(pcFilename, RTLD_LAZY); if (pvPluginHandle) { /* This is a file and the file is a shared library! */
dlerror(); if(fDescriptorFunction = (DSSI_Descriptor_Function)dlsym(pvPluginHandle, "ladspa_descriptor")) is_DSSI = 0;
else if(fDescriptorFunction = (DSSI_Descriptor_Function)dlsym(pvPluginHandle, "dssi_descriptor")) is_DSSI = 1;
if (dlerror() == NULL && fDescriptorFunction) { /* We've successfully found a ladspa_descriptor function. Pass it to the callback function. */ fCallbackFunction(pcFilename, pvPluginHandle, fDescriptorFunction, user_data, is_DSSI); dlclose (pvPluginHandle); } else { /* It was a library, but not a LADSPA one. Unload it. */ dlclose(pcFilename); } } } }
/*****************************************************************************/
void LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction, void* user_data) {
char * pcBuffer; const char * pcEnd; const char * pcLADSPAPath; char *pluginPath; const char * pcStart;
pcLADSPAPath = NULL;
if(getenv("LADSPA_PATH") && getenv("DSSI_PATH")){ pluginPath = malloc(sizeof(char) * (strlen(getenv("LADSPA_PATH")) + 1) + sizeof(char) * strlen(getenv("DSSI_PATH"))); sprintf(pluginPath, "%s:%s", getenv("LADSPA_PATH"), getenv("DSSI_PATH")); pcLADSPAPath = pluginPath; free(pluginPath); } if (pcLADSPAPath == NULL) { fprintf(stderr, "Warning: no LADSPA_PATH and DSSI_PATH, assuming /usr/lib/ladspa:/usr/local/lib/ladspa:/usr/lib/dssi:/usr/local/lib/dssi\n"); pcLADSPAPath = "/usr/lib/ladspa:/usr/local/lib/ladspa:/usr/lib/dssi:/usr/local/lib/dssi"; }
pcStart = pcLADSPAPath; while (*pcStart != '\0') { pcEnd = pcStart; while (*pcEnd != ':' && *pcEnd != '\0') pcEnd++;
pcBuffer = malloc(1 + pcEnd - pcStart); if (pcEnd > pcStart) strncpy(pcBuffer, pcStart, pcEnd - pcStart); pcBuffer[pcEnd - pcStart] = '\0';
LADSPADirectoryPluginSearch(pcBuffer, fCallbackFunction, user_data);
pcStart = pcEnd; if (*pcStart == ':') pcStart++; } }
/*****************************************************************************/
/* EOF */
--- NEW FILE: jload.c --- /* load.c
Free software by Richard W.E. Furse. Do with as you will. No warranty. */
/* patched by Jarno Seppänen, jams@cs.tut.fi, for plugin~ */
/* patched by Jamie Bullock, jamie@postlude.co.uk, for dssi~ */
/*****************************************************************************/
#include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
/*****************************************************************************/
#include "ladspa.h" #include "jutils.h"
/*****************************************************************************/
/* This function provides a wrapping of dlopen(). When the filename is not an absolute path (i.e. does not begin with / character), this routine will search the LADSPA_PATH for the file. */ static void * dlopenLADSPA(const char * pcFilename, int iFlag) {
char * pcBuffer; const char * pcEnd; const char * pcLADSPAPath; const char * pcStart; int iEndsInSO; int iNeedSlash; size_t iFilenameLength; void * pvResult; char *pluginPath;
iFilenameLength = strlen(pcFilename); pvResult = NULL;
/* First we just try calling dlopen(). This works if the user knows about dlopen() and has placed the file on the LD_LIBRARY path or has used an absolute directory. */ pvResult = dlopen(pcFilename, iFlag); if (pvResult != NULL) return pvResult;
/* If the filename is not absolute then we wish to check along the LADSPA_PATH path to see if we can find the file there. */ if (pcFilename[0] != '/') {
pcLADSPAPath = NULL; if(getenv("LADSPA_PATH") && getenv("DSSI_PATH")){ pluginPath = malloc(sizeof(char) * (strlen(getenv("LADSPA_PATH")) + 1) + sizeof(char) * strlen(getenv("DSSI_PATH"))); sprintf(pluginPath, "%s:%s", getenv("LADSPA_PATH"), getenv("DSSI_PATH")); pcLADSPAPath = pluginPath; free(pluginPath); } if (pcLADSPAPath == NULL) { fprintf(stderr, "Warning: no LADSPA_PATH and DSSI_PATH, assuming /usr/lib/ladspa:/usr/local/lib/ladspa:/usr/lib/dssi:/usr/local/lib/dssi\n"); pcLADSPAPath = "/usr/lib/ladspa:/usr/local/lib/ladspa:/usr/lib/dssi:/usr/local/lib/dssi"; }
if (pcLADSPAPath) {
pcStart = pcLADSPAPath; while (*pcStart != '\0') { pcEnd = pcStart; while (*pcEnd != ':' && *pcEnd != '\0') pcEnd++; pcBuffer = malloc(iFilenameLength + 2 + (pcEnd - pcStart)); if (pcEnd > pcStart) strncpy(pcBuffer, pcStart, pcEnd - pcStart); iNeedSlash = 0; if (pcEnd > pcStart) if (*(pcEnd - 1) != '/') { iNeedSlash = 1; pcBuffer[pcEnd - pcStart] = '/'; } strcpy(pcBuffer + iNeedSlash + (pcEnd - pcStart), pcFilename); pvResult = dlopen(pcBuffer, iFlag); free (pcBuffer); if (pvResult != NULL){ return pvResult; } pcStart = pcEnd; if (*pcStart == ':') pcStart++; } } else { fputs ("warning: You haven't specified the LADSPA_PATH environment variable and didn't specify an absolute path to the plug-in.\n" "Please set the LADSPA_PATH variable to point to your LADSPA plug-in directories (eg. "export LADSPA_PATH=/usr/local/lib/ladspa").\n", stderr); } }
/* As a last ditch effort, check if filename does not end with ".so". In this case, add this suffix and recurse. */ iEndsInSO = 0; if (iFilenameLength > 3) iEndsInSO = (strcmp(pcFilename + iFilenameLength - 3, ".so") == 0); if (!iEndsInSO) { pcBuffer = malloc(iFilenameLength + 4); strcpy(pcBuffer, pcFilename); strcat(pcBuffer, ".so"); pvResult = dlopenLADSPA(pcBuffer, iFlag); }
if (pvResult != NULL) return pvResult;
/* If nothing has worked, then at least we can make sure we set the correct error message - and this should correspond to a call to dlopen() with the actual filename requested. The dlopen() manual page does not specify whether the first or last error message will be kept when multiple calls are made to dlopen(). We've covered the former case - now we can handle the latter by calling dlopen() again here. */ return dlopen(pcFilename, iFlag); }
/*****************************************************************************/
void * loadLADSPAPluginLibrary(const char * pcPluginFilename) {
void * pvPluginHandle;
pvPluginHandle = dlopenLADSPA(pcPluginFilename, RTLD_NOW); if (!pvPluginHandle) { fprintf(stderr, "Failed to load plugin "%s": %s\n", pcPluginFilename, dlerror()); #if 0 exit(1); #else return NULL; #endif }
return pvPluginHandle; }
/*****************************************************************************/
void unloadLADSPAPluginLibrary(void * pvLADSPAPluginLibrary) { dlclose(pvLADSPAPluginLibrary); }
/*****************************************************************************/
const LADSPA_Descriptor * findLADSPAPluginDescriptor(void * pvLADSPAPluginLibrary, const char * pcPluginLibraryFilename, const char * pcPluginLabel) {
const LADSPA_Descriptor * psDescriptor; LADSPA_Descriptor_Function pfDescriptorFunction; unsigned long lPluginIndex;
dlerror(); pfDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(pvLADSPAPluginLibrary, "ladspa_descriptor"); if (!pfDescriptorFunction) { const char * pcError = dlerror(); if (pcError) fprintf(stderr, "Unable to find ladspa_descriptor() function in plugin " "library file "%s": %s.\n" "Are you sure this is a LADSPA plugin file?\n", pcPluginLibraryFilename, pcError); #if 0 exit(1); #else return NULL; #endif }
for (lPluginIndex = 0;; lPluginIndex++) { psDescriptor = pfDescriptorFunction(lPluginIndex); if (psDescriptor == NULL) { fprintf(stderr, "Unable to find label "%s" in plugin library file "%s".\n", pcPluginLabel, pcPluginLibraryFilename); #if 0 exit(1); #else return NULL; #endif } if (strcmp(psDescriptor->Label, pcPluginLabel) == 0) return psDescriptor; } }
/*****************************************************************************/
/* EOF */
Index: dssi~.c =================================================================== RCS file: /cvsroot/pure-data/externals/postlude/dssi/src/dssi~.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dssi~.c 22 Feb 2006 12:34:12 -0000 1.6 --- dssi~.c 11 Mar 2006 20:32:51 -0000 1.7 *************** *** 9,12 **** --- 9,14 ---- * Hexter (GPL license): Copyright (C) 2004 Sean Bolton and others. * + * plugin~ (GPL license): Copyright (C) 2000 Jarno SeppÀnen, remIXed 2005 + * * * This program is free software; you can redistribute it and/or *************** *** 28,32 ****
[...1669 lines suppressed...] ! class_addmethod(dssi_tilde_class, (t_method)dssi_config, ! gensym("config"), A_GIMME, 0); class_sethelpsymbol(dssi_tilde_class, gensym("help-dssi")); CLASS_MAINSIGNALIN(dssi_tilde_class, t_dssi_tilde,f); --- 2108,2122 ---- void dssi_tilde_setup(void) { ! dssi_tilde_class = class_new(gensym("dssi~"), (t_newmethod)dssi_tilde_new,(t_method)dssi_tilde_free, sizeof(t_dssi_tilde), 0, A_GIMME, 0); ! class_addlist(dssi_tilde_class, dssi_tilde_list); class_addbang(dssi_tilde_class, dssi_bang); ! class_addmethod(dssi_tilde_class, ! (t_method)dssi_tilde_dsp, gensym("dsp"), 0); ! class_addmethod(dssi_tilde_class, (t_method)dssi_tilde_dssi_methods, ! gensym("dssi"), A_GIMME, 0); ! class_addmethod (dssi_tilde_class,(t_method)dssi_tilde_control, gensym ("control"),A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod (dssi_tilde_class,(t_method)dssi_tilde_info,gensym ("info"),0); ! class_addmethod (dssi_tilde_class,(t_method)dssi_tilde_list_plugins,gensym ("listplugins"),0); ! class_addmethod (dssi_tilde_class,(t_method)dssi_tilde_reset,gensym ("reset"), A_DEFFLOAT, 0); class_sethelpsymbol(dssi_tilde_class, gensym("help-dssi")); CLASS_MAINSIGNALIN(dssi_tilde_class, t_dssi_tilde,f);
Index: dssi~.h =================================================================== RCS file: /cvsroot/pure-data/externals/postlude/dssi/src/dssi~.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dssi~.h 22 Feb 2006 12:34:12 -0000 1.4 --- dssi~.h 11 Mar 2006 20:32:51 -0000 1.5 *************** *** 42,46 ****
! #define VERSION 0.83 #define EVENT_BUFSIZE 1024 #define OSC_BASE_MAX 1024 --- 42,46 ----
! #define VERSION 0.89 #define EVENT_BUFSIZE 1024 #define OSC_BASE_MAX 1024 *************** *** 53,58 ****
#define LOADGUI 1 /* FIX: depracate this */ ! #define DEBUG 0 #ifdef DEBUG #define CHECKSUM_PATCH_FILES_ON_LOAD 1 #endif --- 53,177 ----
#define LOADGUI 1 /* FIX: depracate this */ ! #define DEBUG 1 #ifdef DEBUG #define CHECKSUM_PATCH_FILES_ON_LOAD 1 #endif + + #ifndef MIN + #define MIN(a,b) ((a)<(b)?(a):(b)) + #endif + + + /*From dx7_voice.h by Sean Bolton */ + + typedef struct _dx7_patch_t { + uint8_t data[128]; + } dx7_patch_t; + + typedef struct _dssi_instance { + + long currentBank; + long currentProgram; + int pendingBankLSB; + int pendingBankMSB; + int pendingProgramChange; + + int plugin_ProgramCount; + DSSI_Program_Descriptor *pluginPrograms; + + lo_address uiTarget; /*osc stuff */ + int ui_hidden; + int ui_show; + int uiNeedsProgramUpdate; + char *ui_osc_control_path; + char *ui_osc_configure_path; + char *ui_osc_program_path; + char *ui_osc_show_path; + char *ui_osc_hide_path; + char *ui_osc_quit_path; + + int *plugin_PortControlInNumbers; /*not sure if this should go here?*/ + + char *osc_url_path; + pid_t gui_pid; + + } t_dssi_instance; + + struct dssi_configure_pair { + t_int instance; + char *key, + *value; + struct dssi_configure_pair *next; + }; + + typedef struct dssi_configure_pair t_dssi_configure_pair; + + typedef struct _port_info { + t_atom type, + data_type, + name, + lower_bound, + upper_bound, + p_default; + } t_port_info; + + typedef struct _dssi_tilde { + t_object x_obj; + t_int is_DSSI; + const char *dll_arg, /*arg given by user - either path or dll name*/ + *plugin_label; + char *dll_path; /*absolute path to plugin */ + void *dll_handle; + char *dir; /* project dircetory */ + LADSPA_Handle *instanceHandles; /*was handle*/ + t_dssi_instance *instances; + int n_instances; + unsigned long *instanceEventCounts; + snd_seq_event_t **instanceEventBuffers; + + snd_seq_event_t midiEventBuf[EVENT_BUFSIZE]; + /*static snd_seq_event_t **instanceEventBuffers;*/ + int bufWriteIndex, bufReadIndex; + pthread_mutex_t midiEventBufferMutex; + /*static pthread_mutex_t listHandlerMutex = PTHREAD_MUTEX_INITIALIZER;*/ + + DSSI_Descriptor_Function desc_func; + DSSI_Descriptor *descriptor; + + t_port_info *port_info; + + t_int ports_in, ports_out, ports_controlIn, ports_controlOut; + t_int plugin_ins;/* total audio input ports for plugin*/ + t_int plugin_outs;/* total audio output ports plugin*/ + t_int plugin_controlIns;/* total control input ports*/ + t_int plugin_controlOuts;/* total control output ports */ + + unsigned long *plugin_ControlInPortNumbers; /*Array of input port numbers for the plugin */ + + t_float **plugin_InputBuffers, **plugin_OutputBuffers; /* arrays of arrays for buffering audio for each audio port */ + t_float *plugin_ControlDataInput, *plugin_ControlDataOutput; /*arrays for control data for each port (1 item per 'run')*/ + lo_server_thread osc_thread; + char *osc_url_base; + char *dll_name; + + t_int time_ref; /*logical time reference */ + t_int sr; + t_float sr_inv; + t_int blksize; + t_float f; + + t_float **outlets, **inlets; + t_outlet *control_outlet; + + t_dssi_configure_pair *configure_buffer_head; + + } t_dssi_tilde; + + static char *dssi_tilde_send_configure(t_dssi_tilde *x, char *key, + char *value, t_int instance); + static int osc_message_handler(const char *path, const char *types, + lo_arg **argv, int argc, void *data, void *user_data); + static LADSPA_Data get_port_default(t_dssi_tilde *x, int port); + static void MIDIbuf(int type, int chan, int param, int val, t_dssi_tilde *x); + +
--- NEW FILE: jutils.h --- /* utils.h
Free software by Richard W.E. Furse. Do with as you will. No warranty. */
/* patched by Jarno Seppänen, jams@cs.tut.fi, for plugin~ */
/* patched by Jamie Bullock, jamie@postlude.co.uk, for dssi~ */
#ifndef LADSPA_SDK_LOAD_PLUGIN_LIB #define LADSPA_SDK_LOAD_PLUGIN_LIB
/*****************************************************************************/
#include "dssi.h"
/*****************************************************************************/
/* Functions in load.c: */
/* This function call takes a plugin library filename, searches for the library along the LADSPA_PATH, loads it with dlopen() and returns a plugin handle for use with findPluginDescriptor() or unloadLADSPAPluginLibrary(). Errors are handled by writing a message to stderr and calling exit(1). It is alright (although inefficient) to call this more than once for the same file. */ void * loadLADSPAPluginLibrary(const char * pcPluginFilename);
/* This function unloads a LADSPA plugin library. */ void unloadLADSPAPluginLibrary(void * pvLADSPAPluginLibrary);
/* This function locates a LADSPA plugin within a plugin library loaded with loadLADSPAPluginLibrary(). Errors are handled by writing a message to stderr and calling exit(1). Note that the plugin library filename is only included to help provide informative error messages. */ const LADSPA_Descriptor * findLADSPAPluginDescriptor(void * pvLADSPAPluginLibrary, const char * pcPluginLibraryFilename, const char * pcPluginLabel);
/*****************************************************************************/
/* Functions in search.c: */
/* Callback function for use with LADSPAPluginSearch(). The callback function passes the filename (full path), a plugin handle (dlopen() style) and a LADSPA_DescriptorFunction (from which LADSPA_Descriptors can be acquired). */ typedef void LADSPAPluginSearchCallbackFunction (const char * pcFullFilename, void * pvPluginHandle, DSSI_Descriptor_Function fDescriptorFunction, void* user_data, int is_DSSI);
/* Search through the $(LADSPA_PATH) (or a default path) for any LADSPA plugin libraries. Each plugin library is tested using dlopen() and dlsym(,"ladspa_descriptor"). After loading each library, the callback function is called to process it. This function leaves items passed to the callback function open. */ void LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction, void* user_data);
/*****************************************************************************/
#endif
/* EOF */