[Demudi-commits] r666 - in dssi/branches/upstream/current: . jack-dssi-host

Free Ekanayaka free-guest at costa.debian.org
Tue Feb 7 11:45:56 UTC 2006


Author: free-guest
Date: 2006-02-07 11:45:43 +0000 (Tue, 07 Feb 2006)
New Revision: 666

Removed:
   dssi/branches/upstream/current/Makefile
   dssi/branches/upstream/current/dssi.pc
   dssi/branches/upstream/current/examples/
   dssi/branches/upstream/current/jack-dssi-host/Makefile
Modified:
   dssi/branches/upstream/current/jack-dssi-host/jack-dssi-host.c
Log:
Load /tmp/tmp.BWcGOQ/dssi-0.9.1 into dssi/branches/upstream/current.


Deleted: dssi/branches/upstream/current/Makefile
===================================================================
--- dssi/branches/upstream/current/Makefile	2006-02-07 11:34:41 UTC (rev 665)
+++ dssi/branches/upstream/current/Makefile	2006-02-07 11:45:43 UTC (rev 666)
@@ -1,38 +0,0 @@
-
-PREFIX ?= /usr/local
-PKGCONFIG_INSTALL_DIR = $(PREFIX)/lib/pkgconfig
-
-FLUID ?= $(PWD)/../fluidsynth-1.0.3
-
-export PREFIX FLUID
-
-all:	doc/RFC.html doc/why-use.html
-	@$(MAKE) -C jack-dssi-host
-	@$(MAKE) -C examples
-	@$(MAKE) -C tests
-	@test -d $(FLUID)/src && $(MAKE) -C fluidsynth-dssi || echo "WARNING: Fluidsynth sources not found in $(FLUID), not building fluidsynth-dssi"
-
-clean:
-	@$(MAKE) -C jack-dssi-host clean
-	@$(MAKE) -C examples clean
-	@$(MAKE) -C tests clean
-	@$(MAKE) -C fluidsynth-dssi clean
-
-distclean:
-	@$(MAKE) -C jack-dssi-host distclean
-	@$(MAKE) -C examples distclean
-	@$(MAKE) -C tests distclean
-	@$(MAKE) -C fluidsynth-dssi distclean
-	rm -f *~ doc/*~ dssi/*~
-
-install: all
-	mkdir -p $(PREFIX)/include
-	mkdir -p $(PKGCONFIG_INSTALL_DIR)
-	cp dssi/dssi.h $(PREFIX)/include/
-	sed s:.PREFIX.:$(PREFIX): dssi.pc >$(PKGCONFIG_INSTALL_DIR)/dssi.pc
-	@$(MAKE) -C jack-dssi-host install
-	@$(MAKE) -C examples install
-	@test -d $(FLUID)/src && $(MAKE) -C fluidsynth-dssi install || echo "Not installing fluidsynth-dssi"
-
-doc/%.html:	doc/%.txt
-	perl ./scripts/txt2html.pl $< | perl ./scripts/tableofcontents.pl > $@

Deleted: dssi/branches/upstream/current/dssi.pc
===================================================================
--- dssi/branches/upstream/current/dssi.pc	2006-02-07 11:34:41 UTC (rev 665)
+++ dssi/branches/upstream/current/dssi.pc	2006-02-07 11:45:43 UTC (rev 666)
@@ -1,11 +0,0 @@
-prefix=.PREFIX.
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-
-Name: dssi
-Version: 0.9
-Description: A plugin API for software instruments
-Libs: 
-Cflags: -I${includedir}
-

Deleted: dssi/branches/upstream/current/jack-dssi-host/Makefile
===================================================================
--- dssi/branches/upstream/current/jack-dssi-host/Makefile	2006-02-07 11:34:41 UTC (rev 665)
+++ dssi/branches/upstream/current/jack-dssi-host/Makefile	2006-02-07 11:45:43 UTC (rev 666)
@@ -1,33 +0,0 @@
-
-PREFIX ?= /usr/local
-
-TARGETS = \
-	jack-dssi-host
-
-all: $(TARGETS)
-
-install: all
-	mkdir -p $(PREFIX)/bin
-	cp jack-dssi-host $(PREFIX)/bin/
-
-CFLAGS = -Wall -g3 -I../dssi $(shell pkg-config liblo --cflags)
-CXXFLAGS = $(CFLAGS)
-
-LDLIBS = -ljack -lasound -lpthread $(shell pkg-config liblo --libs)
-
-MB_O = ../message_buffer/message_buffer.o
-
-jack-dssi-host:	jack-dssi-host.o $(MB_O)
-
-jack-dssi-host.o:	../dssi/dssi.h jack-dssi-host.h
-
-%.so: %.o ../dssi/dssi.h $(MB_O)
-	gcc -nostartfiles -shared -lc -lm -o $*.so $*.o ../message_buffer/message_buffer.o
-
-clean:
-	rm -f *.o *.moc.*
-
-distclean:	clean
-	rm -f *~ $(TARGETS)
-
-

Modified: dssi/branches/upstream/current/jack-dssi-host/jack-dssi-host.c
===================================================================
--- dssi/branches/upstream/current/jack-dssi-host/jack-dssi-host.c	2006-02-07 11:34:41 UTC (rev 665)
+++ dssi/branches/upstream/current/jack-dssi-host/jack-dssi-host.c	2006-02-07 11:45:43 UTC (rev 666)
@@ -29,12 +29,23 @@
  * all copies or substantial portions of the software.
  */
 
+#define _BSD_SOURCE    1
+#define _SVID_SOURCE   1
+#define _ISOC99_SOURCE 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <ladspa.h>
 #include "dssi.h"
 #include <alsa/asoundlib.h>
 #include <alsa/seq.h>
 #include <jack/jack.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
 #include <dlfcn.h>
 #include <unistd.h>
 #include <math.h>
@@ -53,7 +64,9 @@
 
 #include "../message_buffer/message_buffer.h"
 
+#ifdef MIDI_ALSA
 static snd_seq_t *alsaClient;
+#endif
 
 static jack_client_t *jackClient;
 static jack_port_t **inputPorts, **outputPorts;
@@ -92,6 +105,8 @@
 
 int exiting = 0;
 static int verbose = 0;
+static int autoconnect = 1;
+static int load_guis = 1;
 const char *myName = NULL;
 
 #define EVENT_BUFFER_SIZE 1024
@@ -112,7 +127,8 @@
 void
 signalHandler(int sig)
 {
-    fprintf(stderr, "%s: signal caught, trying to clean up and exit\n", myName);
+    fprintf(stderr, "%s: signal %d caught, trying to clean up and exit\n",
+	    myName, sig);
     exiting = 1;
 }
 
@@ -124,6 +140,7 @@
 
     pthread_mutex_lock(&midiEventBufferMutex);
 
+#ifdef MIDI_ALSA
     do {
 	if (snd_seq_event_input(alsaClient, &ev) > 0) {
 
@@ -159,6 +176,7 @@
 	}
 	
     } while (snd_seq_event_input_pending(alsaClient, 0) > 0);
+#endif
 
     pthread_mutex_unlock(&midiEventBufferMutex);
 }
@@ -185,6 +203,7 @@
     if (!LADSPA_IS_HINT_BOUNDED_BELOW(d)) {
 	if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
 	    /* unbounded: might as well leave the value alone. */
+            return;
 	} else {
 	    /* bounded above only. just shift the range. */
 	    value = ub - 127.0f + value;
@@ -195,7 +214,7 @@
 	    value = lb + value;
 	} else {
 	    /* bounded both ends.  more interesting. */
-	    if (LADSPA_IS_HINT_LOGARITHMIC(d)) {
+            if (LADSPA_IS_HINT_LOGARITHMIC(d) && lb > 0.0f && ub > 0.0f) {
 		const float llb = logf(lb);
 		const float lub = logf(ub);
 
@@ -205,6 +224,9 @@
 	    }
 	}
     }
+    if (LADSPA_IS_HINT_INTEGER(d)) {
+        value = lrintf(value);
+    }
 
     if (verbose) {
 	printf("%s: %s MIDI controller %d=%d -> control in %ld=%f\n", myName,
@@ -220,7 +242,7 @@
 audio_callback(jack_nframes_t nframes, void *arg)
 {
     int i;
-    int outCount;
+    int outCount, inCount;
     d3h_instance_t *instance;
     struct timeval tv, evtv, diff;
     long framediff;
@@ -379,6 +401,14 @@
         }
     }
 
+    for (inCount = 0; inCount < insTotal; ++inCount) {
+
+	jack_default_audio_sample_t *buffer =
+	    jack_port_get_buffer(inputPorts[inCount], nframes);
+	
+	memcpy(pluginInputBuffers[inCount], buffer, nframes * sizeof(LADSPA_Data));
+    }
+
     /* call run_synth() or run_multiple_synths() for all instances */
 
     i = 0;
@@ -408,13 +438,20 @@
                  instanceEventBuffers + i,
                  instanceEventCounts + i);
             i += instances[i].plugin->instances;
-        } else {
+        } else if (instances[i].plugin->descriptor->run_synth) {
             instances[i].plugin->descriptor->run_synth(instanceHandles[i],
                                                        nframes,
                                                        instanceEventBuffers[i],
                                                        instanceEventCounts[i]);
             i++;
-        }
+        } else if (instances[i].plugin->descriptor->LADSPA_Plugin->run) {
+	    instances[i].plugin->descriptor->LADSPA_Plugin->run(instanceHandles[i],
+								nframes);
+	    i++;
+	} else {
+	    fprintf(stderr, "DSSI plugin %d has no run_multiple_synths, run_synth or run method!\n", i);
+	    i++;
+	}
     }
 
     assert(sizeof(LADSPA_Data) == sizeof(jack_default_audio_sample_t));
@@ -435,7 +472,7 @@
 {
     static char *defaultDssiPath = 0;
     const char *dssiPath = getenv("DSSI_PATH");
-    char *path, *element, *message;
+    char *path, *origPath, *element, *message;
     void *handle = 0;
 
     /* If the dllName is an absolute path */
@@ -446,7 +483,7 @@
 	    return dirname(path);
 	} else {
 	    if (!quiet) {
-		fprintf(stderr, "Cannot find DSSI plugin at '%s'\n", dllName);
+		fprintf(stderr, "Cannot find DSSI or LADSPA plugin at '%s'\n", dllName);
 	    }
 	    return NULL;
 	}
@@ -469,10 +506,13 @@
     }
 
     path = strdup(dssiPath);
+    origPath = path;
     *dll = 0;
 
     while ((element = strtok(path, ":")) != 0) {
 
+	char *filePath;
+
 	path = 0;
 
 	if (element[0] != '/') {
@@ -486,7 +526,7 @@
 	    fprintf(stderr, "%s: Looking for library \"%s\" in %s... ", myName, dllName, element);
 	}
 
-	char *filePath = (char *)malloc(strlen(element) + strlen(dllName) + 2);
+	filePath = (char *)malloc(strlen(element) + strlen(dllName) + 2);
 	sprintf(filePath, "%s/%s", element, dllName);
 
 	if ((handle = dlopen(filePath, RTLD_NOW))) {  /* real-time programs should not use RTLD_LAZY */
@@ -496,6 +536,7 @@
 	    *dll = handle;
             free(filePath);
             path = strdup(element);
+            free(origPath);
 	    return path;
 	}
 
@@ -511,6 +552,7 @@
         free(filePath);
     }
 
+    free(origPath);
     return 0;
 }
 
@@ -545,7 +587,8 @@
     }
 
     if (*dllBase == '/') {
-	subpath = strdup(dllBase);
+        subpath = dllBase;
+        dllBase = strdup(strrchr(subpath, '/') + 1);
     } else {
 	subpath = (char *)malloc(strlen(directory) + strlen(dllBase) + 2);
 	sprintf(subpath, "%s/%s", directory, dllBase);
@@ -571,12 +614,18 @@
 		if (verbose) {
 		    fprintf(stderr, "checking %s against %s\n", entry->d_name, dllBase);
 		}
-		if (strncmp(entry->d_name, dllBase, strlen(dllBase))) continue;
+                if (strlen(entry->d_name) <= strlen(dllBase) ||
+                    strncmp(entry->d_name, dllBase, strlen(dllBase)) ||
+                    entry->d_name[strlen(dllBase)] != '_')
+                    continue;
 	    } else {
 		if (verbose) {
 		    fprintf(stderr, "checking %s against %s\n", entry->d_name, label);
 		}
-		if (strncmp(entry->d_name, label, strlen(label))) continue;
+                if (strlen(entry->d_name) <= strlen(label) ||
+                    strncmp(entry->d_name, label, strlen(label)) ||
+                    entry->d_name[strlen(label)] != '_')
+                    continue;
 	    }
 	    
 	    filename = (char *)malloc(strlen(subpath) + strlen(entry->d_name) + 2);
@@ -597,7 +646,7 @@
 		}
 		
 		if (fork() == 0) {
-		    execlp(filename, filename, oscUrl, dllName, label, instanceTag, 0);
+		    execlp(filename, filename, oscUrl, dllName, label, instanceTag, NULL);
 		    perror("exec failed");
 		    exit(1);
 		}
@@ -687,6 +736,7 @@
     char *url;
     int i, reps, j;
     int in, out, controlIn, controlOut;
+    char clientName[33];
 
     setsid();
     sigemptyset (&_signals);
@@ -729,8 +779,10 @@
     /* Parse args and report usage */
 
     if (argc < 2) {
-	fprintf(stderr, "\nUsage: %s [-v] [-p <projdir>] [-<i>] <libname>[%c<label>] [...]\n", argv[0], LABEL_SEP);
+	fprintf(stderr, "\nUsage: %s [-v] [-a] [-n] [-p <projdir>] [-<i>] <libname>[%c<label>] [...]\n", argv[0], LABEL_SEP);
 	fprintf(stderr, "\n  -v        Verbose mode\n");
+	fprintf(stderr, "  -a        Don't autoconnect outputs to JACK physical outputs\n");
+	fprintf(stderr, "  -n        Don't automatically start plugin GUIs\n");
 	fprintf(stderr, "  <projdir> Project directory to pass to plugin and UI\n");
 	fprintf(stderr, "  <i>       Number of instances of each plugin to run (max %d total, default 1)\n", D3H_MAX_INSTANCES);
 	fprintf(stderr, "  <libname> DSSI plugin library .so to load (searched for in $DSSI_PATH)\n");
@@ -755,6 +807,14 @@
 	    verbose = 1;
 	    continue;
 	}
+	if (!strcmp(argv[i], "-a")) {
+	    autoconnect = 0;
+	    continue;
+	}
+	if (!strcmp(argv[i], "-n")) {
+	    load_guis = 0;
+	    continue;
+	}
 
 	if (!strcmp(argv[i], "-p")) {
 	    if (i < argc - 1) {
@@ -836,10 +896,17 @@
                 
                 dll->descfn = (DSSI_Descriptor_Function)dlsym(pluginObject,
                                                               "dssi_descriptor");
-                if (!dll->descfn) {
-                    fprintf(stderr, "\n%s: Error: \"%s\" is not a DSSI plugin library\n", myName, dllName);
-                    return 1;
-                } 
+                if (dll->descfn) {
+                    dll->is_DSSI_dll = 1;
+                } else {
+                    dll->descfn = (DSSI_Descriptor_Function)dlsym(pluginObject,
+                                                                  "ladspa_descriptor");
+                    if (!dll->descfn) {
+                        fprintf(stderr, "\n%s: Error: \"%s\" is not a DSSI or LADSPA plugin library\n", myName, dllName);
+                        return 1;
+                    }
+                    dll->is_DSSI_dll = 0;
+                }
 
                 dll->next = dlls;
                 dlls = dll;
@@ -848,11 +915,33 @@
 
             /* get the plugin descriptor */
             j = 0;
-            while ((plugin->descriptor = dll->descfn(j++))) {
-                if (!plugin->label ||
-                    !strcmp(plugin->descriptor->LADSPA_Plugin->Label,
-                            plugin->label))
-                    break;
+            if (dll->is_DSSI_dll) {
+                const DSSI_Descriptor *desc;
+
+                while ((desc = dll->descfn(j++))) {
+                    if (!plugin->label ||
+                        !strcmp(desc->LADSPA_Plugin->Label, plugin->label)) {
+                        plugin->descriptor = desc;
+                        break;
+                    }
+                }
+            } else { /* LADSPA plugin; create and use a dummy DSSI descriptor */
+                LADSPA_Descriptor *desc;
+
+                plugin->descriptor = (const DSSI_Descriptor *)calloc(1, sizeof(DSSI_Descriptor));
+                ((DSSI_Descriptor *)plugin->descriptor)->DSSI_API_Version = 1;
+
+                while ((desc = (LADSPA_Descriptor *)dll->descfn(j++))) {
+                    if (!plugin->label ||
+                        !strcmp(desc->Label, plugin->label)) {
+                        ((DSSI_Descriptor *)plugin->descriptor)->LADSPA_Plugin = desc;
+                        break;
+                    }
+                }
+                if (!plugin->descriptor->LADSPA_Plugin) {
+                    free((void *)plugin->descriptor);
+                    plugin->descriptor = NULL;
+                }
             }
             if (!plugin->descriptor) {
                 fprintf(stderr, "\n%s: Error: Plugin label \"%s\" not found in library \"%s\"\n",
@@ -913,7 +1002,6 @@
                     tmp = tmp + strlen(tmp);
                 }
                 sprintf(tmp, "/%s/chan%02d", plugin->label, instance->channel);
-                instance->firstControlIn = controlInsTotal;
                 instance->pluginProgramCount = 0;
                 instance->pluginPrograms = NULL;
                 instance->currentBank = 0;
@@ -922,10 +1010,12 @@
                 instance->pendingBankMSB = -1;
                 instance->pendingProgramChange = -1;
                 instance->uiTarget = NULL;
+		instance->uiSource = NULL;
                 instance->ui_initial_show_sent = 0;
                 instance->uiNeedsProgramUpdate = 0;
                 instance->ui_osc_control_path = NULL;
                 instance->ui_osc_program_path = NULL;
+                instance->ui_osc_quit_path = NULL;
                 instance->ui_osc_show_path = NULL;
 
                 insTotal += plugin->ins;
@@ -969,10 +1059,9 @@
 
     /* Create buffers and JACK client and ports */
 
-    char clientName[33];
     if (instance_count > 1) strcpy(clientName, "jack-dssi-host");
     else {
-	strncpy(clientName, plugin->descriptor->LADSPA_Plugin->Name, 32);
+	strncpy(clientName, instances[0].plugin->descriptor->LADSPA_Plugin->Name, 32);
 	clientName[32] = '\0';
     }
 
@@ -1110,7 +1199,7 @@
 
     /* Connect and activate plugins */
 
-    for (in = 0; in < insTotal; in++) {
+    for (in = 0; in < controlInsTotal; in++) {
         pluginPortUpdated[in] = 0;
     }
 
@@ -1119,6 +1208,7 @@
     for (i = 0; i < instance_count; i++) {   /* i is instance number */
         instance = &instances[i];
 
+        instance->firstControlIn = controlIn;
         for (j = 0; j < MIDI_CONTROLLER_COUNT; j++) {
             instance->controllerMap[j] = -1;
         }
@@ -1212,6 +1302,7 @@
 
     /* Create ALSA MIDI port */
 
+#ifdef MIDI_ALSA
     if (snd_seq_open(&alsaClient, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
 	fprintf(stderr, "\n%s: Error: Failed to open ALSA sequencer interface\n",
 		myName);
@@ -1231,27 +1322,30 @@
     npfd = snd_seq_poll_descriptors_count(alsaClient, POLLIN);
     pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
     snd_seq_poll_descriptors(alsaClient, pfd, npfd, POLLIN);
+#endif /* MIDI_ALSA */
 
     mb_init("host: ");
 
+    /* activate JACK and connect ports */
     if (jack_activate(jackClient)) {
         fprintf (stderr, "cannot activate jack client");
         exit(1);
     }
 
-    /* activate JACK and connect ports */
-    /* !FIX! this to more intelligently connect ports: */
-    ports = jack_get_ports(jackClient, NULL, NULL,
-                           JackPortIsPhysical|JackPortIsInput);
-    if (ports && ports[0]) {
-        for (i = 0, j = 0; i < outsTotal; ++i) {
-            if (jack_connect(jackClient, jack_port_name(outputPorts[i]),
-                             ports[j])) {
-                fprintf (stderr, "cannot connect output port %d\n", i);
+    if (autoconnect) {
+        /* !FIX! this to more intelligently connect ports: */
+        ports = jack_get_ports(jackClient, NULL, NULL,
+                               JackPortIsPhysical|JackPortIsInput);
+        if (ports && ports[0]) {
+            for (i = 0, j = 0; i < outsTotal; ++i) {
+                if (jack_connect(jackClient, jack_port_name(outputPorts[i]),
+                                 ports[j])) {
+                    fprintf (stderr, "cannot connect output port %d\n", i);
+                }
+                if (!ports[++j]) j = 0;
             }
-            if (!ports[++j]) j = 0;
+            free(ports);
         }
-        free(ports);
     }
 
     signal(SIGINT, signalHandler);
@@ -1263,14 +1357,17 @@
     /* Attempt to locate and start up a GUI for the plugin -- but
      * continue even if we can't */
     /* -FIX- Ack! So many windows all at once! */
-    for (i = 0; i < instance_count; i++) {
-        char tag[12];
-        plugin = instances[i].plugin;
-        snprintf(osc_path_tmp, 1024, "%s/%s", url, instances[i].friendly_name);
-        snprintf(tag, 12, "channel %d", instances[i].channel);
-	printf("\n%s: OSC URL is:\n%s\n\n", myName, osc_path_tmp);
-        startGUI(plugin->dll->directory, plugin->dll->name,
-                 plugin->descriptor->LADSPA_Plugin->Label, osc_path_tmp, tag);
+    if (load_guis) {
+        for (i = 0; i < instance_count; i++) {
+            char tag[12];
+            plugin = instances[i].plugin;
+            snprintf(osc_path_tmp, 1024, "%s/%s", url, instances[i].friendly_name);
+            snprintf(tag, 12, "channel %d", instances[i].channel);
+            printf("\n%s: OSC URL is:\n%s\n\n", myName, osc_path_tmp);
+	    fflush(stdout);
+            startGUI(plugin->dll->directory, plugin->dll->name,
+                    plugin->descriptor->LADSPA_Plugin->Label, osc_path_tmp, tag);
+        }
     }
 
     MB_MESSAGE("Ready\n");
@@ -1279,9 +1376,11 @@
 
     while (!exiting) {
 
+#ifdef MIDI_ALSA
 	if (poll(pfd, npfd, 100) > 0) {
 	    midi_callback();
 	}
+#endif /* MIDI_ALSA */
 
 	/* Race conditions here, because the programs and ports are
 	   updated from the audio thread.  We at least try to minimise
@@ -1301,9 +1400,9 @@
 
 	for (i = 0; i < controlInsTotal; ++i) {
 	    if (pluginPortUpdated[i]) {
-                instance = pluginControlInInstances[i];
 		int port = pluginControlInPortNumbers[i];
 		float value = pluginControlIns[i];
+                instance = pluginControlInInstances[i];
 		pluginPortUpdated[i] = 0;
 		if (instance->uiTarget) {
 		    lo_send(instance->uiTarget, instance->ui_osc_control_path, "if", port, value);
@@ -1314,22 +1413,36 @@
 
     jack_client_close(jackClient);
 
-    while (i < instance_count) {
-	/* no -- see comment in osc_exiting_handler */
-	/* if (!instances[i].inactive) { */
-	    if (instances[i].plugin->descriptor->LADSPA_Plugin->deactivate) {
-		instances[i].plugin->descriptor->LADSPA_Plugin->deactivate
-		    (instanceHandles[i]);
-	    }
-	/* } */
-        if (instances[i].plugin->descriptor->LADSPA_Plugin &&
-	    instances[i].plugin->descriptor->LADSPA_Plugin->cleanup) {
-            instances[i].plugin->descriptor->LADSPA_Plugin->cleanup
+    /* cleanup plugins */
+    for (i = 0; i < instance_count; i++) {
+        instance = &instances[i];
+
+        if (instance->uiTarget) {
+            lo_send(instance->uiTarget, instance->ui_osc_quit_path, "");
+            lo_address_free(instance->uiTarget);
+            instance->uiTarget = NULL;
+        }
+
+        if (instance->uiSource) {
+            lo_address_free(instance->uiSource);
+            instance->uiSource = NULL;
+        }
+
+        if (instance->plugin->descriptor->LADSPA_Plugin->deactivate) {
+            instance->plugin->descriptor->LADSPA_Plugin->deactivate
 		(instanceHandles[i]);
 	}
-	++i;
+
+        if (instance->plugin->descriptor->LADSPA_Plugin->cleanup) {
+            instance->plugin->descriptor->LADSPA_Plugin->cleanup
+		(instanceHandles[i]);
+	}
     }
 
+    sleep(1);
+    sigemptyset (&_signals);
+    sigaddset(&_signals, SIGHUP);
+    pthread_sigmask(SIG_BLOCK, &_signals, 0);
     kill(0, SIGHUP);
 
     return 0;
@@ -1383,12 +1496,23 @@
 	    return upper;
 	}
 	if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
-	    if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) {
-		return lower * 0.75f + upper * 0.25f;
-	    } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) {
-		return lower * 0.5f + upper * 0.5f;
-	    } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) {
-		return lower * 0.25f + upper * 0.75f;
+            if (LADSPA_IS_HINT_LOGARITHMIC(hint.HintDescriptor) &&
+                lower > 0.0f && upper > 0.0f) {
+                if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) {
+                    return expf(logf(lower) * 0.75f + logf(upper) * 0.25f);
+                } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) {
+                    return expf(logf(lower) * 0.5f + logf(upper) * 0.5f);
+                } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) {
+                    return expf(logf(lower) * 0.25f + logf(upper) * 0.75f);
+                }
+            } else {
+                if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) {
+                    return lower * 0.75f + upper * 0.25f;
+                } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) {
+                    return lower * 0.5f + upper * 0.5f;
+                } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) {
+                    return lower * 0.25f + upper * 0.75f;
+                }
 	    }
 	}
     }
@@ -1593,12 +1717,13 @@
 }
 
 int
-osc_update_handler(d3h_instance_t *instance, lo_arg **argv)
+osc_update_handler(d3h_instance_t *instance, lo_arg **argv, lo_address source)
 {
     const char *url = (char *)&argv[0]->s;
     const char *path;
     unsigned int i;
     char *host, *port;
+    const char *chost, *cport;
 
     if (verbose) {
 	printf("%s: OSC: got update request from <%s>\n", myName, url);
@@ -1611,6 +1736,11 @@
     free(host);
     free(port);
 
+    if (instance->uiSource) lo_address_free(instance->uiSource);
+    chost = lo_address_get_hostname(source);
+    cport = lo_address_get_port(source);
+    instance->uiSource = lo_address_new(chost, cport);
+
     path = lo_url_get_path(url);
 
     if (instance->ui_osc_control_path) free(instance->ui_osc_control_path);
@@ -1625,6 +1755,10 @@
     instance->ui_osc_program_path = (char *)malloc(strlen(path) + 10);
     sprintf(instance->ui_osc_program_path, "%s/program", path);
 
+    if (instance->ui_osc_quit_path) free(instance->ui_osc_quit_path);
+    instance->ui_osc_quit_path = (char *)malloc(strlen(path) + 10);
+    sprintf(instance->ui_osc_quit_path, "%s/quit", path);
+
     if (instance->ui_osc_show_path) free(instance->ui_osc_show_path);
     instance->ui_osc_show_path = (char *)malloc(strlen(path) + 10);
     sprintf(instance->ui_osc_show_path, "%s/show", path);
@@ -1682,6 +1816,16 @@
 	       instance->number);
     }
 
+    if (instance->uiTarget) {
+        lo_address_free(instance->uiTarget);
+        instance->uiTarget = NULL;
+    }
+
+    if (instance->uiSource) {
+        lo_address_free(instance->uiSource);
+        instance->uiSource = NULL;
+    }
+
     if (instance->plugin) {
 
 	/*!!! No, this isn't safe -- plugins deactivated in this way
@@ -1732,13 +1876,18 @@
     int i;
     d3h_instance_t *instance = NULL;
     const char *method;
+    unsigned int flen = 0;
+    lo_message message;
+    lo_address source;
+    int send_to_ui = 0;
 
     if (strncmp(path, "/dssi/", 6))
         return osc_debug_handler(path, types, argv, argc, data, user_data);
 
     for (i = 0; i < instance_count; i++) {
-        if (!strncmp(path + 6, instances[i].friendly_name,
-                     strlen(instances[i].friendly_name))) {
+	flen = strlen(instances[i].friendly_name);
+        if (!strncmp(path + 6, instances[i].friendly_name, flen) &&
+	    *(path + 6 + flen) == '/') { /* avoid matching prefix only */
             instance = &instances[i];
             break;
         }
@@ -1751,17 +1900,41 @@
     if (instance->inactive) 
 	return 0;
     */
-    method = path + 6 + strlen(instance->friendly_name);
+    method = path + 6 + flen;
     if (*method != '/' || *(method + 1) == 0)
         return osc_debug_handler(path, types, argv, argc, data, user_data);
     method++;
 
+    message = (lo_message)data;
+    source = lo_message_get_source(message);
+
+    if (instance->uiSource && instance->uiTarget) {
+	if (strcmp(lo_address_get_hostname(source),
+		   lo_address_get_hostname(instance->uiSource)) ||
+	    strcmp(lo_address_get_port(source),
+		   lo_address_get_port(instance->uiSource))) {
+	    /* This didn't come from our known UI for this plugin,
+	       so send an update to that as well */
+	    send_to_ui = 1;
+	}
+    }
+
     if (!strcmp(method, "configure") && argc == 2 && !strcmp(types, "ss")) {
 
+	if (send_to_ui) {
+	    lo_send(instance->uiTarget, instance->ui_osc_configure_path, "ss",
+		    &argv[0]->s, &argv[1]->s);
+	}
+
         return osc_configure_handler(instance, argv);
 
     } else if (!strcmp(method, "control") && argc == 2 && !strcmp(types, "if")) {
 
+	if (send_to_ui) {
+	    lo_send(instance->uiTarget, instance->ui_osc_control_path, "if",
+		    argv[0]->i, argv[1]->f);
+	}
+
         return osc_control_handler(instance, argv);
 
     } else if (!strcmp(method, "midi") && argc == 1 && !strcmp(types, "m")) {
@@ -1770,11 +1943,16 @@
 
     } else if (!strcmp(method, "program") && argc == 2 && !strcmp(types, "ii")) {
 
+	if (send_to_ui) {
+	    lo_send(instance->uiTarget, instance->ui_osc_program_path, "ii",
+		    argv[0]->i, argv[1]->i);
+	}
+	
         return osc_program_handler(instance, argv);
 
     } else if (!strcmp(method, "update") && argc == 1 && !strcmp(types, "s")) {
 
-        return osc_update_handler(instance, argv);
+        return osc_update_handler(instance, argv, source);
 
     } else if (!strcmp(method, "exiting") && argc == 0) {
 




More information about the Demudi-commits mailing list