static gboolean
gst_lv2_filter_stop (GstBaseTransform * transform)
{
    GstLV2Filter *lv2 = (GstLV2Filter *) transform;

    if (lv2->activated == FALSE) {
        GST_ERROR_OBJECT (transform, "Deactivating but LV2 plugin not activated");

        return TRUE;
    }

    if (lv2->instance == NULL) {
        GST_ERROR_OBJECT (transform, "Deactivating but no LV2 plugin set");

        return TRUE;
    }

    GST_DEBUG_OBJECT (lv2, "deactivating");

    lilv_instance_deactivate (lv2->instance);

    lv2->activated = FALSE;

    lilv_instance_free (lv2->instance);
    lv2->instance = NULL;

    return TRUE;
}
Example #2
0
void
LV2Module::deactivate()
{
   if (instance != nullptr && active)
   {
       lilv_instance_deactivate (instance);
       active = false;
   }
}
Example #3
0
EFFECT_LV2::~EFFECT_LV2 (void)
{
  release();

  if (plugin_desc != 0) {
    for(unsigned int n = 0; n < plugins_rep.size(); n++) {
      lilv_instance_deactivate(plugins_rep[n]->me);
      lilv_instance_free(plugins_rep[n]->me);
      delete plugins_rep[n];
    }
  }
}
Example #4
0
void EFFECT_LV2::init(SAMPLE_BUFFER *insample)
{
  EFFECT_BASE::init(insample);

  DBC_CHECK(samples_per_second() > 0);

  if (buffer_repp != insample) {
    release();
    buffer_repp = insample;
    buffer_repp->get_pointer_reflock();
  }

  if (plugin_desc != 0) {
    for(unsigned int n = 0; n < plugins_rep.size(); n++) {
      lilv_instance_deactivate(plugins_rep[n]->me);
      lilv_instance_free(plugins_rep[n]->me);
      delete plugins_rep[n];
    }
    plugins_rep.clear();
  }
  DBC_CHECK(plugins_rep.size() == 0);

  if (in_audio_ports > 1 ||
      out_audio_ports > 1) {
    //Just insert into the first location
    plugins_rep.push_back(Lilv::Instance::create(plugin_desc,samples_per_second(),NULL));
    int inport = 0;
    int outport = 0;
    for(unsigned long m = 0; m < port_count_rep; m++) {
      Lilv::Port p= plugin_desc.get_port_by_index(m);
      if (p.is_a(ECA_LV2_WORLD::AudioClassNode())) {
        if (p.is_a(ECA_LV2_WORLD::InputClassNode())) {
          if (inport < channels()) {
            plugins_rep[0]->connect_port(m, buffer_repp->buffer[inport]);
          }
          ++inport;
        } else if(p.is_a(ECA_LV2_WORLD::OutputClassNode())) {
          if (outport < channels()) {
            plugins_rep[0]->connect_port(m, buffer_repp->buffer[outport]);
          }
          ++outport;
        }
      }
    }

    if (inport > channels())
      ECA_LOG_MSG(ECA_LOGGER::info,
                  "WARNING: chain has less channels than plugin has input ports ("
                  + name() + ").");
    if (outport > channels())
      ECA_LOG_MSG(ECA_LOGGER::info,
                  "WARNING: chain has less channels than plugin has output ports ("
                  + name() + ").");
  } else {
    for(int n = 0; n < channels(); n++) {
      plugins_rep.push_back(Lilv::Instance::create(plugin_desc,samples_per_second(),NULL));
      for(unsigned long m = 0; m < port_count_rep; m++) {
        Lilv::Port p= plugin_desc.get_port_by_index(m);
        if (p.is_a(ECA_LV2_WORLD::AudioClassNode())) {
          plugins_rep[n]->connect_port(m,buffer_repp->buffer[n]);
        }
      }
    }
  }

  ECA_LOG_MSG(ECA_LOGGER::system_objects,
              "Instantiated " +
              kvu_numtostr(plugins_rep.size()) +
              " LV2 plugin(s), each with " +
              kvu_numtostr(in_audio_ports) +
              " audio input port(s) and " +
              kvu_numtostr(out_audio_ports) +
              " output port(s), to chain with " +
              kvu_numtostr(channels()) +
              " channel(s) and srate of " +
              kvu_numtostr(samples_per_second()) +
              ".");

  int data_index = 0;
  for(unsigned long m = 0; m < port_count_rep; m++) {
    Lilv::Port p=plugin_desc.get_port_by_index(m);
    if (p.is_a(ECA_LV2_WORLD::ControlClassNode())) {
      for(unsigned int n = 0; n < plugins_rep.size(); n++) {
        plugins_rep[n]->connect_port(m,&(params[data_index]));
      }
      ++data_index;
    }
  }
  for(unsigned long m = 0; m < plugins_rep.size(); m++)
    plugins_rep[m]->activate();

}
Example #5
0
bool LV2Effect::ProcessStereo(int count,
                              WaveTrack *left,
                              WaveTrack *right,
                              sampleCount lstart, 
                              sampleCount rstart,
                              sampleCount len)
{
   /* Allocate buffers */
   if (mBlockSize == 0)
   {
      mBlockSize = left->GetMaxBlockSize() * 2;

      fInBuffer = new float *[mAudioInputs.GetCount()];
      for (size_t i = 0; i < mAudioInputs.GetCount(); i++)
      {
         fInBuffer[i] = new float[mBlockSize];
      }

      fOutBuffer = new float *[mAudioOutputs.GetCount()];
      for (size_t i = 0; i < mAudioOutputs.GetCount(); i++)
      {
         fOutBuffer[i] = new float[mBlockSize];
      }
   }

   /* Instantiate the plugin */
   LilvInstance *handle = lilv_plugin_instantiate(mData,
                                                  left->GetRate(), 
                                                  gLV2Features);
   if (!handle)
   {
      wxMessageBox(wxString::Format(_("Unable to load plug-in %s"), pluginName.c_str()));
      return false;
   }

   /* Write the Note On to the MIDI event buffer and connect it */
   LV2_Event_Buffer *midiBuffer = NULL;
   int noteOffTime;
   if (mMidiInput)
   {
      midiBuffer = lv2_event_buffer_new(40, 2);
      LV2_Event_Iterator iter;
      lv2_event_begin(&iter, midiBuffer);
      uint8_t noteOn[] = { 0x90, mNoteKey, mNoteVelocity };
      lv2_event_write(&iter, 0, 0, 1, 3, noteOn);
      noteOffTime = mNoteLength * left->GetRate();
      if (noteOffTime < len && noteOffTime < mBlockSize) {
         uint8_t noteOff[] = { 0x80, mNoteKey, 64 };
         lv2_event_write(&iter, noteOffTime, 0, 1, 3, noteOff);
      }
      lilv_instance_connect_port(handle, mMidiInput->mIndex, midiBuffer);
   }

   for (size_t p = 0; p < mAudioInputs.GetCount(); p++)
   {
      lilv_instance_connect_port(handle, mAudioInputs[p].mIndex, fInBuffer[p]);
   }

   for (size_t p = 0; p < mAudioOutputs.GetCount(); p++)
   {
      lilv_instance_connect_port(handle, mAudioOutputs[p].mIndex, fOutBuffer[p]);
   }

   for (size_t p = 0; p < mControlInputs.GetCount(); p++)
   {
      lilv_instance_connect_port(handle, mControlInputs[p].mIndex,
                                 &mControlInputs[p].mControlBuffer);
   }

   for (size_t p = 0; p < mControlOutputs.GetCount(); p++)
   {
      lilv_instance_connect_port(handle, mControlOutputs[p].mIndex, 
                                 &mControlOutputs[p].mControlBuffer);
   }

   float latency = 0.0;
   if (mLatencyPortIndex >= 0)
   {
      lilv_instance_connect_port(handle, mLatencyPortIndex, &latency);
   }

   lilv_instance_activate(handle);

   // Actually perform the effect here

   sampleCount originalLen = len;
   sampleCount ls = lstart;
   sampleCount rs = rstart;
   sampleCount ols = ls;
   sampleCount ors = rs;
   bool noteOver = false;

   sampleCount delayed = 0;
   sampleCount delay = 0;
   bool cleared = false;

   while (len || delayed)
   {
      int block = mBlockSize;

      if (len)
      {
         if (block > len)
         {
            block = len;
         }
   
         if (left &&  mAudioInputs.GetCount() > 0)
         {
            left->Get((samplePtr)fInBuffer[0], floatSample, ls, block);
         }
   
         if (right && mAudioInputs.GetCount() > 1)
         {
            right->Get((samplePtr)fInBuffer[1], floatSample, rs, block);
         }
      }
      else if (delayed)
      {
         // At the end if we don't have enough left for a whole block
         if (block > delayed)
         {
            block = delayed;
         }

         // Clear the input buffer so that we only pass zeros to the effect.
         if (!cleared)
         {
            for (int i = 0; i < mBlockSize; i++)
            {
               fInBuffer[0][i] = 0.0;
            }

            if (right)
            {
               memcpy(fInBuffer[1], fOutBuffer[0], mBlockSize);
            }
            cleared = true;
         }
      }

      lilv_instance_run(handle, block);

      if (delayed == 0 && latency != 0)
      {
         delayed = delay = latency;
      }

      if (delay >= block)
      {
         delay -= block;
      }
      else if (delay > 0)
      {
         sampleCount oblock = block - delay;
         if (left && mAudioOutputs.GetCount() > 0)
         {
            left->Set((samplePtr)(fOutBuffer[0] + delay), floatSample, ols, oblock);
         }
         
         if (right && mAudioOutputs.GetCount() > 1)
         {
            right->Set((samplePtr)(fOutBuffer[1] + delay), floatSample, ors, oblock);
         }
         ols += oblock;
         ors += oblock;
         delay = 0;
      }
      else
      {
         if (left && mAudioOutputs.GetCount() > 0)
         {
            left->Set((samplePtr)fOutBuffer[0], floatSample, ols, block);
         }
         
         if (right && mAudioOutputs.GetCount() > 1)
         {
            right->Set((samplePtr)fOutBuffer[1], floatSample, ors, block);
         }
         ols += block;
         ors += block;
      }

      if (len)
      {
         len -= block;
         noteOffTime -= block;

         // Clear the event buffer and add the note off event if needed
         if (mMidiInput)
         {
            lv2_event_buffer_reset(midiBuffer, 1, 
                                   (uint8_t *)midiBuffer + 
                                   sizeof(LV2_Event_Buffer));
   
            if (!noteOver && noteOffTime < len && noteOffTime < block)
            {
               LV2_Event_Iterator iter;
               lv2_event_begin(&iter, midiBuffer);
               uint8_t noteOff[] = { 0x80, mNoteKey, 64 };
               lv2_event_write(&iter, noteOffTime, 0, 1, 3, noteOff);
               noteOver = true;
            }
         }         
      }
      else if (delayed)
      {
         delayed -= block;
      }
      ls += block;
      rs += block;
      
      if (mAudioInputs.GetCount() > 1)
      {
         if (TrackGroupProgress(count, (ls-lstart)/(double)originalLen))
         {
            return false;
         }
      }
      else
      {
         if (TrackProgress(count, (ls-lstart)/(double)originalLen))
         {
            return false;
         }
      }
      
   }
   
   lilv_instance_deactivate(handle);
   lilv_instance_free(handle);
   
   return true;
}
Example #6
0
static double
bench(const LilvPlugin* p, uint32_t sample_count, uint32_t block_size)
{
	URITable uri_table;
	uri_table_init(&uri_table);

	LV2_URID_Map       map           = { &uri_table, uri_table_map };
	LV2_Feature        map_feature   = { LV2_URID_MAP_URI, &map };
	LV2_URID_Unmap     unmap         = { &uri_table, uri_table_unmap };
	LV2_Feature        unmap_feature = { LV2_URID_UNMAP_URI, &unmap };
	const LV2_Feature* features[]    = { &map_feature, &unmap_feature, NULL };

	float* const buf = (float*)calloc(block_size * 2, sizeof(float));
	float* const in  = buf;
	float* const out = buf + block_size;
	if (!buf) {
		fprintf(stderr, "Out of memory\n");
		return 0.0;
	}

	LV2_Atom_Sequence seq = {
		{ sizeof(LV2_Atom_Sequence_Body),
		  uri_table_map(&uri_table, LV2_ATOM__Sequence) },
		{ 0, 0 } };

	const char* uri      = lilv_node_as_string(lilv_plugin_get_uri(p));
	LilvNodes*  required = lilv_plugin_get_required_features(p);
	LILV_FOREACH(nodes, i, required) {
		const LilvNode* feature = lilv_nodes_get(required, i);
		if (!lilv_node_equals(feature, urid_map)) {
			fprintf(stderr, "<%s> requires feature <%s>, skipping\n",
			        uri, lilv_node_as_uri(feature));
			free(buf);
			uri_table_destroy(&uri_table);
			return 0.0;
		}
	}

	LilvInstance* instance = lilv_plugin_instantiate(p, 48000.0, features);
	if (!instance) {
		fprintf(stderr, "Failed to instantiate <%s>\n",
		        lilv_node_as_uri(lilv_plugin_get_uri(p)));
		free(buf);
		uri_table_destroy(&uri_table);
		return 0.0;
	}

	float* controls = (float*)calloc(
		lilv_plugin_get_num_ports(p), sizeof(float));
	lilv_plugin_get_port_ranges_float(p, NULL, NULL, controls);

	const uint32_t n_ports = lilv_plugin_get_num_ports(p);
	for (uint32_t index = 0; index < n_ports; ++index) {
		const LilvPort* port = lilv_plugin_get_port_by_index(p, index);
		if (lilv_port_is_a(p, port, lv2_ControlPort)) {
			lilv_instance_connect_port(instance, index, &controls[index]);
		} else if (lilv_port_is_a(p, port, lv2_AudioPort) ||
		           lilv_port_is_a(p, port, lv2_CVPort)) {
			if (lilv_port_is_a(p, port, lv2_InputPort)) {
				lilv_instance_connect_port(instance, index, in);
			} else if (lilv_port_is_a(p, port, lv2_OutputPort)) {
				lilv_instance_connect_port(instance, index, out);
			} else {
				fprintf(stderr, "<%s> port %d neither input nor output, skipping\n",
				        uri, index);
				lilv_instance_free(instance);
				free(buf);
				free(controls);
				uri_table_destroy(&uri_table);
				return 0.0;
			}
		} else if (lilv_port_is_a(p, port, atom_AtomPort)) {
			lilv_instance_connect_port(instance, index, &seq);
		} else {
			fprintf(stderr, "<%s> port %d has unknown type, skipping\n",
			        uri, index);
			lilv_instance_free(instance);
			free(buf);
			free(controls);
			uri_table_destroy(&uri_table);
			return 0.0;
		}
	}

	lilv_instance_activate(instance);

	struct timespec ts = bench_start();
	for (uint32_t i = 0; i < (sample_count / block_size); ++i) {
		lilv_instance_run(instance, block_size);
	}
	const double elapsed = bench_end(&ts);

	lilv_instance_deactivate(instance);
	lilv_instance_free(instance);

	uri_table_destroy(&uri_table);

	if (full_output) {
		printf("%d %d ", block_size, sample_count);
	}
	printf("%lf %s\n", elapsed, uri);

	free(buf);
	free(controls);
	return elapsed;
}