Commit be86b227 authored by Benjamin Heisch's avatar Benjamin Heisch
Browse files

A lot of documentation and some small refractorings.

parent a62e9b0d
Pipeline #19324 failed with stages
in 2 minutes and 14 seconds
...@@ -3,6 +3,8 @@ find_package(TortureTester) ...@@ -3,6 +3,8 @@ find_package(TortureTester)
find_package(VST3) find_package(VST3)
set(__DIR_OF_XPLUG_CMAKE ${CMAKE_CURRENT_LIST_DIR}) set(__DIR_OF_XPLUG_CMAKE ${CMAKE_CURRENT_LIST_DIR})
###########################HELPER_FUNCTIONS############################## ###########################HELPER_FUNCTIONS##############################
# Getting a String of the current architecture(Which is Vst3-Naming compliant)
# The Architecture stirng will be written in the ARCHITECTURE_NAME Variable.
function(get_architecture) function(get_architecture)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS") if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS")
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if(CMAKE_SIZEOF_VOID_P EQUAL 8)
...@@ -32,54 +34,61 @@ endfunction(get_architecture) ...@@ -32,54 +34,61 @@ endfunction(get_architecture)
###########################PACKAGE FUNCTIONS############################## ###########################PACKAGE FUNCTIONS##############################
# Creates an LV2-PACKAGE
# TARGET - LV2 Target to create Package from.
# PATH - Path to directory, where to create the package witch PACKAGE_NAME in it. The Default, is the current workingdirectory.
# PACKAGE_NAME - Name of the Package To generate. Defaults to {TARGET_NAME}.lv2
function(create_lv2_package) function(create_lv2_package)
cmake_parse_arguments(CREATE_LV2_PACKAGE "" "TARGET;PATH;PACKAGE_NAME" "" ${ARGN} ) cmake_parse_arguments(CREATE_LV2_PACKAGE "" "TARGET;PATH;PACKAGE_NAME" "" ${ARGN} )
if(NOT CREATE_LV2_PACKAGE_PATH) if(NOT CREATE_LV2_PACKAGE_PATH)
set(CREATE_LV2_PACKAGE_PATH "./") set(CREATE_LV2_PACKAGE_PATH "./")
endif(NOT CREATE_LV2_PACKAGE_PATH) endif(NOT CREATE_LV2_PACKAGE_PATH)
if(NOT CREATE_LV2_PACKAGE_PACKAGE_NAME) if(NOT CREATE_LV2_PACKAGE_PACKAGE_NAME)
set(CREATE_LV2_PACKAGE_PACKAGE_NAME ${TARGET}.lv2/) set(CREATE_LV2_PACKAGE_PACKAGE_NAME ${TARGET}.lv2/)
endif(NOT CREATE_LV2_PACKAGE_PACKAGE_NAME) endif(NOT CREATE_LV2_PACKAGE_PACKAGE_NAME)
set(LV2_PACKAGE_ROOT ${CREATE_LV2_PACKAGE_PATH}/${CREATE_LV2_PACKAGE_PACKAGE_NAME}) set(LV2_PACKAGE_ROOT ${CREATE_LV2_PACKAGE_PATH}/${CREATE_LV2_PACKAGE_PACKAGE_NAME})
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${LV2_PACKAGE_ROOT}) add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${LV2_PACKAGE_ROOT})
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET}> ${LV2_PACKAGE_ROOT}/$<TARGET_FILE_NAME:${TARGET}> add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET}> ${LV2_PACKAGE_ROOT}/$<TARGET_FILE_NAME:${TARGET}>
COMMAND TTLGenerator ARGS $<TARGET_FILE:${TARGET}> BYPRODUCTS ${LV2_PACKAGE_ROOT}/manifest.ttl COMMAND TTLGenerator ARGS $<TARGET_FILE:${TARGET}> BYPRODUCTS ${LV2_PACKAGE_ROOT}/manifest.ttl
${LV2_PACKAGE_ROOT}/${TARGET}.ttl WORKING_DIRECTORY ${LV2_PACKAGE_ROOT}) ${LV2_PACKAGE_ROOT}/${TARGET}.ttl WORKING_DIRECTORY ${LV2_PACKAGE_ROOT})
endfunction(create_lv2_package) endfunction(create_lv2_package)
# Creates an VST3-PACKAGE
# TARGET - VST3 Target to create Package from.
# PATH - Path to directory, where to create the package witch PACKAGE_NAME in it. The Default, is the current workingdirectory.
# PACKAGE_NAME - Name of the Package To generate. Defaults to {TARGET_NAME}.vst3
function(create_vst3_package) function(create_vst3_package)
cmake_parse_arguments(CREATE_VST3_PACKAGE "" "TARGET;PATH;PACKAGE_NAME" "" ${ARGN} ) cmake_parse_arguments(CREATE_VST3_PACKAGE "" "TARGET;PATH;PACKAGE_NAME" "" ${ARGN} )
if(NOT CREATE_VST3_PACKAGE_PATH) if(NOT CREATE_VST3_PACKAGE_PATH)
set(CREATE_VST3_PACKAGE_PATH "./") set(CREATE_VST3_PACKAGE_PATH "./")
endif(NOT CREATE_VST3_PACKAGE_PATH) endif(NOT CREATE_VST3_PACKAGE_PATH)
if(NOT CREATE_VST3_PACKAGE_PACKAGE_NAME) if(NOT CREATE_VST3_PACKAGE_PACKAGE_NAME)
set(CREATE_VST3_PACKAGE_PACKAGE_NAME ${TARGET}) set(CREATE_VST3_PACKAGE_PACKAGE_NAME ${TARGET}.vst3)
endif(NOT CREATE_VST3_PACKAGE_PACKAGE_NAME) endif(NOT CREATE_VST3_PACKAGE_PACKAGE_NAME)
set(VST3_PACKAGE_ROOT ${CREATE_VST3_PACKAGE_PATH}/${CREATE_VST3_PACKAGE_PACKAGE_NAME}) set(VST3_PACKAGE_ROOT ${CREATE_VST3_PACKAGE_PATH}/${CREATE_VST3_PACKAGE_PACKAGE_NAME})
get_architecture() get_architecture()
set_target_properties(${TARGET} PROPERTIES PREFIX "") set_target_properties(${TARGET} PROPERTIES PREFIX "")
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT} add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT}
COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT}/Contents/Resources COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT}/Contents/Resources
COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME} COMMAND ${CMAKE_COMMAND} -E make_directory ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET}> ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/$<TARGET_FILE_NAME:${TARGET}> COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET}> ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/$<TARGET_FILE_NAME:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy ${__DIR_OF_XPLUG_CMAKE}/speaker.ico ${VST3_PACKAGE_ROOT}/Plugin.ico) COMMAND ${CMAKE_COMMAND} -E copy ${__DIR_OF_XPLUG_CMAKE}/speaker.ico ${VST3_PACKAGE_ROOT}/Plugin.ico)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS") if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS")
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_desktop.ini CONTENT "[.ShellClassInfo]\nIconResource=Plugin.ico,0") file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_desktop.ini CONTENT "[.ShellClassInfo]\nIconResource=Plugin.ico,0")
set(WINDOWS_EXTRA_DIR "/${ARCHITECTURE_NAME}/") set(WINDOWS_EXTRA_DIR "/${ARCHITECTURE_NAME}/")
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated_desktop.ini ${VST3_PACKAGE_ROOT}/desktop.ini add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated_desktop.ini ${VST3_PACKAGE_ROOT}/desktop.ini
COMMAND attrib +s +r +h ${VST3_PACKAGE_ROOT}/desktop.ini COMMAND attrib +s +r +h ${VST3_PACKAGE_ROOT}/desktop.ini
COMMAND attrib +r +h ${VST3_PACKAGE_ROOT}/Plugin.ico COMMAND attrib +r +h ${VST3_PACKAGE_ROOT}/Plugin.ico
COMMAND ${CMAKE_COMMAND} -E rename ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/$<TARGET_FILE_NAME:${TARGET}> ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/${TARGET}.vst3 ) COMMAND ${CMAKE_COMMAND} -E rename ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/$<TARGET_FILE_NAME:${TARGET}> ${VST3_PACKAGE_ROOT}/Contents/${ARCHITECTURE_NAME}/${TARGET}.vst3 )
endif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS") endif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "MSYS")
endfunction(create_vst3_package) endfunction(create_vst3_package)
################################TEST FUNCTIONS########################## ################################TEST FUNCTIONS##########################
# Run pluginval tests with given TARGET. pluginval must be available as target or be installed. # Run all available VST2 Tests, which are installed on the current System.
function(run_vst2_test TARGET) function(run_vst2_test TARGET)
if(TARGET pluginval) if(TARGET pluginval)
add_test(NAME ${TARGET}_pluginval_vst2_test COMMAND pluginval " \" --validate-in-process --validate $<TARGET_FILE:${TARGET}> --strictness-level 10 \"" ) add_test(NAME ${TARGET}_pluginval_vst2_test COMMAND pluginval " \" --validate-in-process --validate $<TARGET_FILE:${TARGET}> --strictness-level 10 \"" )
...@@ -89,7 +98,7 @@ function(run_vst2_test TARGET) ...@@ -89,7 +98,7 @@ function(run_vst2_test TARGET)
add_test(NAME ${TARGET}_xvalidate_vst2_test COMMAND XValidate -vst2 -l 10 -p $<TARGET_FILE:${TARGET}> ) add_test(NAME ${TARGET}_xvalidate_vst2_test COMMAND XValidate -vst2 -l 10 -p $<TARGET_FILE:${TARGET}> )
endfunction(run_vst2_test TARGET) endfunction(run_vst2_test TARGET)
# Run pluginval tests with given TARGET. pluginval must be available as target or be installed. # Run all available VST3 Tests, which are installed on the current System.
function(run_vst3_test TARGET) function(run_vst3_test TARGET)
create_vst3_package(TARGET ${TARGET} PATH ${CMAKE_CURRENT_BINARY_DIR}/temp/ PACKAGE_NAME ${TARGET}.vst3) create_vst3_package(TARGET ${TARGET} PATH ${CMAKE_CURRENT_BINARY_DIR}/temp/ PACKAGE_NAME ${TARGET}.vst3)
if(TARGET pluginval) if(TARGET pluginval)
...@@ -107,23 +116,20 @@ function(run_vst3_test TARGET) ...@@ -107,23 +116,20 @@ function(run_vst3_test TARGET)
add_test(NAME ${TARGET}_xvalidate_vst3_test COMMAND XValidate -vst3 -l 10 -p $<TARGET_FILE:${TARGET}> ) add_test(NAME ${TARGET}_xvalidate_vst3_test COMMAND XValidate -vst3 -l 10 -p $<TARGET_FILE:${TARGET}> )
endfunction(run_vst3_test TARGET) endfunction(run_vst3_test TARGET)
# Run all available LADSPA Tests, which are installed on the current System.
function(run_ladspa_tests TARGET) function(run_ladspa_tests TARGET)
if(TARGET TortureTester) if(TARGET TortureTester)
add_test(NAME ${TARGET}_torture_ladspa_test COMMAND $<TARGET_FILE:TortureTester> --evil --denormals --ladspa --plugin $<TARGET_FILE:${TARGET}>) add_test(NAME ${TARGET}_torture_ladspa_test COMMAND $<TARGET_FILE:TortureTester> --evil --denormals --ladspa --plugin $<TARGET_FILE:${TARGET}>)
endif(TARGET TortureTester) endif(TARGET TortureTester)
add_test(NAME ${TARGET}_xvalidate_ladspa_test COMMAND XValidate -ladspa -l 10 -p $<TARGET_FILE:${TARGET}> ) add_test(NAME ${TARGET}_xvalidate_ladspa_test COMMAND XValidate -ladspa -l 10 -p $<TARGET_FILE:${TARGET}> )
endfunction(run_ladspa_tests TARGET) endfunction(run_ladspa_tests TARGET)
# Run all available LV2 Tests, which are installed on the current System.
function(run_lv2_tests TARGET) function(run_lv2_tests TARGET)
create_lv2_package(TARGET ${TARGET} PATH ${CMAKE_CURRENT_BINARY_DIR}/temp/ PACKAGE_NAME ${TARGET}.lv2) create_lv2_package(TARGET ${TARGET} PATH ${CMAKE_CURRENT_BINARY_DIR}/temp/ PACKAGE_NAME ${TARGET}.lv2)
set(LV2_TEMP_PACKAGE ${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}.lv2/) set(LV2_TEMP_PACKAGE ${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}.lv2/)
if(TARGET TortureTester) if(TARGET TortureTester)
add_test(NAME ${TARGET}_torture_lv2_test COMMAND $<TARGET_FILE:TortureTester> --evil --lv2 --plugin ${LV2_TEMP_PACKAGE}/$<TARGET_FILE_NAME:${TARGET}> ) add_test(NAME ${TARGET}_torture_lv2_test COMMAND $<TARGET_FILE:TortureTester> --evil --lv2 --plugin ${LV2_TEMP_PACKAGE}/$<TARGET_FILE_NAME:${TARGET}> )
endif(TARGET TortureTester) endif(TARGET TortureTester)
add_test(NAME ${TARGET}_xvalidate_lv2_test COMMAND XValidate -lv2 -l 10 -p ${LV2_TEMP_PACKAGE}/$<TARGET_FILE_NAME:${TARGET}> ) add_test(NAME ${TARGET}_xvalidate_lv2_test COMMAND XValidate -lv2 -l 10 -p ${LV2_TEMP_PACKAGE}/$<TARGET_FILE_NAME:${TARGET}> )
endfunction(run_lv2_tests TARGET) endfunction(run_lv2_tests TARGET)
/*
Copyright 2007-2019 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "lilv.h" #include "lilv.h"
#include <lv2/atom/atom.h> #include <lv2/atom/atom.h>
......
/**
* @file Exampleplugin, to show the use of an easy Start with LazyPlugin. Easy Midi Messaging Concepts are explained here.
*/
#include <base/PluginBases.hpp> #include <base/PluginBases.hpp>
#include <base/Ports.hpp> #include <base/Ports.hpp>
#include <tools/PortHandling.hpp> #include <tools/PortHandling.hpp>
using namespace XPlug; using namespace XPlug;
/**
* @brief MidiForwarder Example class, which has 1 Midi Input and 2 Midi
* Outputs. The Midi in signal is forwarded to the 2 Midi Outputs
*/
class MidiForwarder : public LazyPlugin class MidiForwarder : public LazyPlugin
{ {
public: public:
/**
* @brief Standard constructor, which creates on instantiation the needed
* Ports and Informations.
*/
MidiForwarder() MidiForwarder()
{ {
// Adding the needed in and output ports in our portcomponent
this->portComponent->addPort( this->portComponent->addPort(
std::make_shared<QueueMidiPort>("MidiIn", PortDirection::Input)); std::make_shared<QueueMidiPort>("MidiIn", PortDirection::Input));
this->portComponent->addPort( this->portComponent->addPort(
std::make_shared<QueueMidiPort>("MidiOut", PortDirection::Output)); std::make_shared<QueueMidiPort>("MidiOut", PortDirection::Output));
this->portComponent->addPort( this->portComponent->addPort(
std::make_shared<QueueMidiPort>("MidiOut2", PortDirection::Output)); std::make_shared<QueueMidiPort>("MidiOut2", PortDirection::Output));
// Detect the needed Features for this Plugin(exspecially MIDI support)
this->featureComponent->detectFeatures(this->getPortComponent()); this->featureComponent->detectFeatures(this->getPortComponent());
// Overwrite some default information
this->infoComponent->pluginName = "MidiForwarder"; this->infoComponent->pluginName = "MidiForwarder";
this->infoComponent->creatorName = "Benjamin Heisch"; this->infoComponent->creatorName = "Benjamin Heisch";
this->infoComponent->pluginUri = this->infoComponent->pluginUri =
...@@ -22,9 +38,11 @@ public: ...@@ -22,9 +38,11 @@ public:
// Geerbt über IPlugin // Geerbt über IPlugin
virtual void processAudio() override virtual void processAudio() override
{ {
// Get the needed ports, to operate on from the portcomponent.
auto in0 = getPortAt<IMidiPort>(this, 0, PortDirection::Input); auto in0 = getPortAt<IMidiPort>(this, 0, PortDirection::Input);
auto out0 = getPortAt<IMidiPort>(this, 0, PortDirection::Output); auto out0 = getPortAt<IMidiPort>(this, 0, PortDirection::Output);
auto out1 = getPortAt<IMidiPort>(this, 1, PortDirection::Output); auto out1 = getPortAt<IMidiPort>(this, 1, PortDirection::Output);
// Forward all Messages from the Inputs to the output.
while (!in0->empty()) { while (!in0->empty()) {
auto midiMsg = in0->get(); auto midiMsg = in0->get();
auto midiMsg2 = midiMsg; auto midiMsg2 = midiMsg;
...@@ -36,6 +54,5 @@ public: ...@@ -36,6 +54,5 @@ public:
virtual void deinit() override {} virtual void deinit() override {}
virtual void activate() override {} virtual void activate() override {}
virtual void deactivate() override {} virtual void deactivate() override {}
// virtual PluginInfo* getPluginInfo() override;
}; };
REGISTER_PLUGIN(MidiForwarder); REGISTER_PLUGIN(MidiForwarder);
...@@ -2,19 +2,33 @@ ...@@ -2,19 +2,33 @@
#include <base/Ports.hpp> #include <base/Ports.hpp>
#include <tools/PortHandling.hpp> #include <tools/PortHandling.hpp>
using namespace XPlug; using namespace XPlug;
/**
* @brief VolumePlguin class, which forwards audiodata and just changes the
* Volume. For an easy start its derived from LazyPlugin, to start easily.
*/
class VolumePlugin : public LazyPlugin class VolumePlugin : public LazyPlugin
{ {
protected: protected:
// Define an Input and an Outputport. (To optimize accesstime, not like in
// MidiForwarder)
std::shared_ptr<IAudioPort> in0 = std::shared_ptr<IAudioPort> in0 =
std::make_shared<MonoPort>("In0", PortDirection::Input); std::make_shared<MonoPort>("In0", PortDirection::Input);
std::shared_ptr<IAudioPort> out0 = std::shared_ptr<IAudioPort> out0 =
std::make_shared<MonoPort>("Out0", PortDirection::Output); std::make_shared<MonoPort>("Out0", PortDirection::Output);
public: public:
/**
* @brief Constructor, which adding the local defined Ports, to the
* PortComponent. Its also changed the needed Plugininformation.
*/
VolumePlugin() VolumePlugin()
{ {
// Adding the local ports to the portcomponent, so the plugininfrastructure
// can process it.
this->portComponent->addPort(in0); this->portComponent->addPort(in0);
this->portComponent->addPort(out0); this->portComponent->addPort(out0);
// Changing the Information about the Plugin, because the default Values
// are... not enough ;)
this->infoComponent->pluginName = "VolumePlugin"; this->infoComponent->pluginName = "VolumePlugin";
this->infoComponent->creatorName = "Benjamin Heisch"; this->infoComponent->creatorName = "Benjamin Heisch";
this->infoComponent->pluginUri = this->infoComponent->pluginUri =
...@@ -24,10 +38,11 @@ public: ...@@ -24,10 +38,11 @@ public:
// Geerbt über IPlugin // Geerbt über IPlugin
virtual void processAudio() override virtual void processAudio() override
{ {
// auto in0 = getPortAt<IAudioPort>(this, 0,PortDirection::Input); // Simple loop over the Dat and process.
// auto out0 = getPortAt<IAudioPort>(this, 0, PortDirection::Output); // Currently no Volumechanging is used, but it will be added later, when the
// Framework supports Parameter, so the Volume can be adjustet.
for (size_t i = 0; i < in0->size(); i++) { for (size_t i = 0; i < in0->size(); i++) {
for (size_t s = 0; s < in0->getSampleSize(); s++) { for (size_t s = 0; s < in0->getSampleCount(); s++) {
if (in0->at(i)->getData() != nullptr && if (in0->at(i)->getData() != nullptr &&
out0->at(i)->getData() != nullptr) out0->at(i)->getData() != nullptr)
out0->at(i)->getData()[s] = in0->at(i)->getData()[s]; out0->at(i)->getData()[s] = in0->at(i)->getData()[s];
...@@ -38,6 +53,10 @@ public: ...@@ -38,6 +53,10 @@ public:
virtual void deinit() override {} virtual void deinit() override {}
virtual void activate() override {} virtual void activate() override {}
virtual void deactivate() override {} virtual void deactivate() override {}
// virtual PluginInfo* getPluginInfo() override;
}; };
// Its very important to Register a Plugin in the GlobalData object, which is
// accessed through the GlobalData() Function.
// The easiest way ist to just use this REGISTER_PLUGIN macro. But use it in
// your sourcefile, because a static variable will be declared. And that just
// works in Sourcefiles.
REGISTER_PLUGIN(VolumePlugin); REGISTER_PLUGIN(VolumePlugin);
#ifndef EXAMPLE_PLUGIN_HPP
#define EXAMPLE_PLUGIN_HPP
#include <base/LazyPlugin.hpp>
using namespace XPlug;
class VolumePlugin : public LazyPlugin
{
public:
VolumePlugin();
// Geerbt ber IPlugin
virtual void processAudio() override;
virtual void init() override;
virtual void deinit() override;
virtual void activate() override;
virtual void deactivate() override;
// virtual PluginInfo* getInfoComponent() override;
};
#endif //! EXAMPLE_PLUGIN_HPP
\ No newline at end of file
/**
* @file Implementation file for the LADSPA Format. The needed API functions are
* defined here. Also the access to the Plugin is implemented here.
*/
#include "ladspa.h" #include "ladspa.h"
#include <cstring> #include <cstring>
#include <interfaces/IPlugin.hpp> #include <interfaces/IPlugin.hpp>
...@@ -7,8 +11,6 @@ ...@@ -7,8 +11,6 @@
using namespace XPlug; using namespace XPlug;
static std::vector<LADSPA_Descriptor*> ladspaDescriptorArray;
struct LADSPAHandleDataType struct LADSPAHandleDataType
{ {
IPlugin* plug; IPlugin* plug;
...@@ -17,23 +19,37 @@ struct LADSPAHandleDataType ...@@ -17,23 +19,37 @@ struct LADSPAHandleDataType
extern "C" extern "C"
{ {
/**
* @brief entrypoint for the LADSPA-Format. In this Function an
* LADSPA_Descriptor is created, which maps all needed Functioncalls to
* functionality of the inernal API. Due to the Support of multiple Plugins,
* multiple Plugins can be registered here.
* @param index INdex of a Plugin in the current Binary to load.
* @return if no Plugin is available, a nullptr is returned otherwhise an
* Instance which maps the internal API to the LADSPA-Format is returned.
*/
const LADSPA_Descriptor* ladspa_descriptor(unsigned long index) const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
{ {
if (index >= GlobalData().getNumberOfRegisteredPlugins()) if (index >=
GlobalData().getNumberOfRegisteredPlugins()) // index is obvously out of
// range, so return 0.
return nullptr; return nullptr;
PluginPtr plug = GlobalData().getPlugin(index); PluginPtr plug = GlobalData().getPlugin(index);
auto desc = new LADSPA_Descriptor(); auto desc = new LADSPA_Descriptor();
// add the needed Implementation data to the LADSPA_Descriptor
desc->ImplementationData = desc->ImplementationData =
new LADSPAHandleDataType{ GlobalData().getPlugin(index).get(), desc }; new LADSPAHandleDataType{ GlobalData().getPlugin(index).get(), desc };
/******************* INSTANTIATION**********************/ /******************* INSTANTIATION**********************/
desc->instantiate = [](const LADSPA_Descriptor* descriptor, desc->instantiate = [](const LADSPA_Descriptor* descriptor,
unsigned long) -> LADSPA_Handle { unsigned long) -> LADSPA_Handle {
// because the ImplementationData and the LADSPA_Handle are the Same, we
// can return the ImplementationData here. But we the pluginreference in
// this Function, so we pass that and all other needed Data over the
// ImplementationData.
auto data = auto data =
static_cast<LADSPAHandleDataType*>(descriptor->ImplementationData); static_cast<LADSPAHandleDataType*>(descriptor->ImplementationData);
data->plug->init(); data->plug->init();
return data; return data;
// return NULL;
}; };
desc->activate = [](LADSPA_Handle instance) { desc->activate = [](LADSPA_Handle instance) {
auto data = static_cast<LADSPAHandleDataType*>(instance); auto data = static_cast<LADSPAHandleDataType*>(instance);
...@@ -45,7 +61,9 @@ extern "C" ...@@ -45,7 +61,9 @@ extern "C"
}; };
desc->cleanup = [](LADSPA_Handle instance) { desc->cleanup = [](LADSPA_Handle instance) {
auto data = static_cast<LADSPAHandleDataType*>(instance); auto data = static_cast<LADSPAHandleDataType*>(instance);
data->plug->deinit(); data->plug
->deinit(); // is needed here, because its the opposite to instantiate.
// free everything.
for (size_t i = 0; i < data->desc->PortCount; i++) { for (size_t i = 0; i < data->desc->PortCount; i++) {
delete[] data->desc->PortNames[i]; delete[] data->desc->PortNames[i];
} }
...@@ -54,9 +72,9 @@ extern "C" ...@@ -54,9 +72,9 @@ extern "C"
delete data->desc; delete data->desc;
delete data; delete data;
}; };
// LADSPA_PROPERTY_HARD_RT_CAPABLE and other stuff, not supported yet.
desc->Properties = 0;
desc->Properties =
0; // LADSPA_PROPERTY_HARD_RT_CAPABLE and other stuff, not supported yet.
/*********************PORT HANDLING*********************/ /*********************PORT HANDLING*********************/
desc->PortCount = desc->PortCount =
static_cast<unsigned long>(getAudioChannelCount(plug.get())); static_cast<unsigned long>(getAudioChannelCount(plug.get()));
...@@ -64,8 +82,8 @@ extern "C" ...@@ -64,8 +82,8 @@ extern "C"
unsigned long portIndex, unsigned long portIndex,
LADSPA_Data* DataLocation) { LADSPA_Data* DataLocation) {
auto data = static_cast<LADSPAHandleDataType*>(instance); auto data = static_cast<LADSPAHandleDataType*>(instance);
if (portIndex < // portIndex is in or outputPort
getAudioChannelCount(data->plug)) { // portIndex is in or outputPort if (portIndex < getAudioChannelCount(data->plug)) {
getAudioChannelFromIndex(data->plug, portIndex)->feed(DataLocation); getAudioChannelFromIndex(data->plug, portIndex)->feed(DataLocation);
} else { } else {
// Not SUpported yet // Not SUpported yet
...@@ -73,13 +91,18 @@ extern "C" ...@@ -73,13 +91,18 @@ extern "C"
}; };
// TODO: When adding Parameter, the have to be mapped to ports here. // TODO: When adding Parameter, the have to be mapped to ports here.
int curIndex = 0; // Ugly allocations, but they are needed... Its just for compatiblity with
// c.
char** portNamesCArray = new char*[desc->PortCount * sizeof(const char*)]; char** portNamesCArray = new char*[desc->PortCount * sizeof(const char*)];
auto portDescripors = auto portDescripors =
new LADSPA_PortDescriptor[desc->PortCount * new LADSPA_PortDescriptor[desc->PortCount *
sizeof(LADSPA_PortDescriptor)]; sizeof(LADSPA_PortDescriptor)];
auto rangeHints = auto rangeHints =
new LADSPA_PortRangeHint[desc->PortCount * sizeof(LADSPA_PortDescriptor)]; new LADSPA_PortRangeHint[desc->PortCount * sizeof(LADSPA_PortDescriptor)];
int curIndex = 0;
// Iterate through all Audioports and try to allocate Portname, rangehints.
// Still needed for c compatibility. If someone has an more elegant and more
// c++ Way, pls make a commit!
iteratePorts<IAudioPort>( iteratePorts<IAudioPort>(
plug.get(), plug.get(),
[&portNamesCArray, &portDescripors, &rangeHints, &curIndex](IAudioPort* p, [&portNamesCArray, &portDescripors, &rangeHints, &curIndex](IAudioPort* p,
...@@ -112,9 +135,11 @@ extern "C" ...@@ -112,9 +135,11 @@ extern "C"
desc->run = [](LADSPA_Handle instance, unsigned long SampleCount) { desc->run = [](LADSPA_Handle instance, unsigned long SampleCount) {
auto data = static_cast<LADSPAHandleDataType*>(instance); auto data = static_cast<LADSPAHandleDataType*>(instance);
// Set current Samplesize/Count on everyrun, because she can be different.
// Maybe add some optimizations here.
iteratePorts<IAudioPort>(data->plug, iteratePorts<IAudioPort>(data->plug,
[SampleCount](IAudioPort* p, size_t) { [SampleCount](IAudioPort* p, size_t) {
p->setSampleSize(SampleCount); p->setSampleCount(SampleCount);
return false; return false;
}); });
data->plug->processAudio(); data->plug->processAudio();
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
#include "tools/LibLoading.hpp" #include "tools/LibLoading.hpp"
#include <vector> #include <vector>
using namespace XPlug; using namespace XPlug;
/**
* @brief LADSPA Test Suite for XValidate/system_tests
*/
class LADSPATestSuite : public FormatTestSuiteBase class LADSPATestSuite : public FormatTestSuiteBase
{ {
public: public:
...@@ -30,6 +33,7 @@ public: ...@@ -30,6 +33,7 @@ public:
LoadFunc<LADSPA_Descriptor_Function>(lib, "ladspa_descriptor"); LoadFunc<LADSPA_Descriptor_Function>(lib, "ladspa_descriptor");
size_t index = 0; size_t index = 0;
const LADSPA_Descriptor* desc = nullptr; const LADSPA_Descriptor* desc = nullptr;
// All things loaded. Than Run normal execution of Plugin.
while (desc = ladspa_descriptor_fnc(index++), desc != nullptr) { while (desc = ladspa_descriptor_fnc(index++), desc != nullptr) {
auto handle = desc->instantiate(desc, sampleRate); auto handle = desc->instantiate(desc, sampleRate);
desc->activate(handle); desc->activate(handle);
......
/**
* @file TtlGenerator helper application, to genereate LV2 ttl files.
*/
#include "lv2_ttl_generation.hpp" #include "lv2_ttl_generation.hpp"
#include <fstream> #include <fstream>
#include <interfaces/IPlugin.hpp> #include <interfaces/IPlugin.hpp>
...@@ -7,12 +10,11 @@ ...@@ -7,12 +10,11 @@
#include <tools/StringTools.hpp> #include <tools/StringTools.hpp>
using namespace XPlug; using namespace XPlug;
/********FUNCTION VARIABLES*********/