Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > f967f5f6a1d8dc0ff357a43370aaad92 > files > 6

armstrong-0.2.6-11.fc13.src.rpm

# HG changeset patch -- Bitbucket.org
# Project Armstrong
# URL http://bitbucket.org/paniq/armstrong/overview/
# User mental@rydia.net
# Date 1240039816 14400
# Node ID bcb8dd70b78f42d968c0d7ca4259f9bb37b8e89c
# Parent 22d3f5482d250064f44790af032e9314386c1a31
Support multiple instances of DSSI plugins that require run_multiple_synths()

--- a/src/plugins/dssidapter/dssidapter.cpp
+++ b/src/plugins/dssidapter/dssidapter.cpp
@@ -26,6 +27,7 @@
 #include "zzub/plugin.h"
 
 #include <vector>
+#include <algorithm>
 #include <string>
 #include <assert.h>
 #include <alsa/asoundlib.h>
@@ -49,7 +51,7 @@ extern "C"
 }
 #include "../ladspadapter/paramtools.h"
 
-const char *myName = "zzub DSSI adaptor";
+const char *myName = "zzub DSSI adapter";
 
 typedef ladspa_param dssi_param;
 
@@ -75,6 +77,7 @@ struct dssi_info : zzub::info
 
 };
 
+static std::vector<dssidapter *> active_instances;
 std::vector<dssi_info *> infos;
 
 #include "osc_functions.h"
@@ -182,6 +185,11 @@ dssidapter::~dssidapter()
      if (uiTarget && ui_osc_quit_path) {
 	  lo_send(uiTarget, ui_osc_quit_path, "");
      }
+     std::vector<dssidapter *>::iterator found;
+     found = std::find(active_instances.begin(), active_instances.end(), this);
+     if (found != active_instances.end()) {
+	  active_instances.erase(found);
+     }
      if (handle)
      {
 	  if (desc->LADSPA_Plugin->deactivate)
@@ -219,6 +227,7 @@ dssidapter::dssidapter(const dssi_info *
      data_values = 0;
      myinfo = _dssi_info;
      track_count = 1;
+     output_backlog = 0;
 
      if (myinfo->global_parameters.size())
      {
@@ -371,11 +380,14 @@ void dssidapter::init(archive *arc)
      _host->set_event_handler(_metaplugin, this);
      handle = desc->LADSPA_Plugin->instantiate(desc->LADSPA_Plugin, _master_info->samples_per_second);
      if (!desc->run_synth && !desc->run_multiple_synths) {
-	  printf("%s: Warning: no run_synth() method and no run_multiple_synth() method\n", myName);
+	  printf("%s: Warning: no run_synth() method and no run_multiple_synths() method\n", myName);
      }
      if (myinfo->m_audioouts.size() < 1) {
 	  printf("%s: Warning: no audio outputs\n", myName);
      }
+     if (myinfo->m_audioins.size() > 0 && !desc->run_synth && desc->run_multiple_synths) {
+	  printf("%s: Warning: audio input not supported with run_multiple_synths()\n", myName);
+     }
      std::vector<dssi_param>::const_iterator i;
      int index = 0;
      for (i = myinfo->m_metaparams.begin(); i != myinfo->m_metaparams.end(); ++i)
@@ -449,6 +461,8 @@ void dssidapter::init(archive *arc)
      if (desc->LADSPA_Plugin->activate)
 	  desc->LADSPA_Plugin->activate(handle);
 
+     active_instances.push_back(this);
+
      eventcount = 0;
 }
 
@@ -631,7 +645,9 @@ bool dssidapter::process_stereo(float **
 	  if (verbose) printf("dssidapter: process_stereo() returning false\n");
 	  return false;
      }
-     if (myinfo->m_audioins.size() == 1) {
+     if (!desc->run_synth && desc->run_multiple_synths) {
+	  // skip inputs since we can't readily support inputs and run_multiple_synths()
+     } else if (myinfo->m_audioins.size() == 1) {
 	  for (int i = 0; i < numsamples; i++) {
 	       inputs[0][i] = (pin[0][i] + pin[1][i]) * 0.5f;
 	  }
@@ -646,12 +662,42 @@ bool dssidapter::process_stereo(float **
      if (desc->run_synth) {
 	  desc->run_synth(handle, numsamples, events, eventcount);
      } else if (desc->run_multiple_synths) {
-	  desc->run_multiple_synths(1, &handle, numsamples, &events, &eventcount);
+	  if (output_backlog == 0) {
+	       // no additional allocations necessary for <= 16 active instances
+	       static std::vector<LADSPA_Handle> handles(16);
+	       static std::vector<snd_seq_event_t *> event_vectors(16);
+	       static std::vector<unsigned long> event_counts(16);
+
+	       // n.b. clear does not deallocate memory
+	       handles.clear();
+	       event_vectors.clear();
+	       event_counts.clear();
+
+	       // ensure minimal allocation if allocation is required
+	       handles.reserve(active_instances.size());
+	       event_vectors.reserve(active_instances.size());
+	       event_counts.reserve(active_instances.size());
+
+	       std::vector<dssidapter *>::iterator iter;
+	       for (iter = active_instances.begin(); iter != active_instances.end(); ++iter) {
+		    dssidapter *instance = *iter;
+		    handles.push_back(instance->handle);
+		    event_vectors.push_back(instance->events);
+		    event_counts.push_back(instance->eventcount);
+		    instance->eventcount = 0;
+		    instance->output_backlog = numsamples;
+	       }
+
+	       desc->run_multiple_synths(active_instances.size(), &handles[0], numsamples, &event_vectors[0], &event_counts[0]);
+	  } else {
+	       // what if output_backlog < numsamples ?
+          }
      } else {
 	  // No synth method -- what should we return?
      }
+     eventcount = 0;
+     output_backlog = 0;
 
-     eventcount = 0;
      if (myinfo->m_audioouts.size() == 1) {
 	  memcpy(pout[0], outputs[0], sizeof(float) * numsamples);
 	  memcpy(pout[1], outputs[0], sizeof(float) * numsamples);

--- a/src/plugins/dssidapter/dssidapter.h
+++ b/src/plugins/dssidapter/dssidapter.h
@@ -100,6 +100,7 @@ struct dssidapter : plugin, event_handle
      LADSPA_Data *data_values;
      float inputs[16][256];
      float outputs[16][256];
+     int output_backlog;
      snd_seq_event_t *events;
      long unsigned int eventcount;
      zzub_plugin_t* _metaplugin;