zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 845b5135eeffeb563feda67a0e7f5415625ed615
parent 1b51421abb388457628b1175d99c8a5008f42841
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Wed,  3 Feb 2016 13:11:48 -0500

Merge branch 'dpf-plugin'

Conflicts:
	src/Misc/Master.cpp

Diffstat:
MCMakeLists.txt | 2++
Msrc/CMakeLists.txt | 7+++++--
Msrc/Misc/Master.cpp | 10+++++++---
Msrc/Misc/Master.h | 2+-
Msrc/Misc/MiddleWare.cpp | 13-------------
Msrc/Misc/Util.cpp | 2++
Msrc/Misc/Util.h | 2++
Asrc/Plugin/AbstractFX.hpp | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/AlienWah/AlienWah.cpp | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/AlienWah/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/AlienWah/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/CMakeLists.txt | 14++++++++++++++
Asrc/Plugin/Chorus/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/Chorus/Chorus.cpp | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Chorus/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Distortion/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/Distortion/Distortion.cpp | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Distortion/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/DynamicFilter/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/DynamicFilter/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/DynamicFilter/DynamicFilter.cpp | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Echo/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/Echo/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Echo/Echo.cpp | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Phaser/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/Phaser/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Phaser/Phaser.cpp | 229+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Reverb/CMakeLists.txt | 31+++++++++++++++++++++++++++++++
Asrc/Plugin/Reverb/DistrhoPluginInfo.h | 38++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/Reverb/Reverb.cpp | 223+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/CMakeLists.txt | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/DistrhoPluginInfo.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/DistrhoUI.cpp | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/DistrhoUI.hpp | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/DistrhoUIInternal.hpp | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/ZynAddSubFX-UI.cpp | 215+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Plugin/ZynAddSubFX/ZynAddSubFX.cpp | 587+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/UI/ConfigUI.fl | 5++++-
Msrc/UI/MasterUI.fl | 15+++++----------
Msrc/UI/guimain.cpp | 32+++++++++++++++++++++++++++++---
40 files changed, 3574 insertions(+), 33 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -39,3 +39,5 @@ install(DIRECTORY instruments/banks DESTINATION share/zynaddsubfx) install(DIRECTORY instruments/examples DESTINATION share/zynaddsubfx) +install(DIRECTORY instruments/ZynAddSubFX.lv2presets + DESTINATION lib/lv2) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -80,6 +80,8 @@ SET (DssiEnable ${DSSI_FOUND} CACHE BOOL "Enable DSSI Plugin compilation") SET (LibloEnable ${LIBLO_FOUND} CACHE BOOL "Enable Liblo") +SET (NoNeonPlease False CACHE BOOL + "Workaround For Broken Neon Detection") # Now, handle the incoming settings and set define flags/variables based # on this @@ -265,9 +267,9 @@ else (BuildForDebug) set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BuildOptions_SSE}") endif (SUPPORT_SSE) - if (SUPPORT_NEON) + if (SUPPORT_NEON AND NOT NoNeonPlease) set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BuildOptions_NEON}") - endif (SUPPORT_NEON) + endif (SUPPORT_NEON AND NOT NoNeonPlease) message (STATUS "Building for ${CMAKE_BUILD_TYPE}, flags: ${CMAKE_CXX_FLAGS_RELEASE}") endif (BuildForDebug) @@ -387,6 +389,7 @@ add_subdirectory(Effects) add_subdirectory(Params) add_subdirectory(DSP) add_subdirectory(Nio) +add_subdirectory(Plugin) add_library(zynaddsubfx_core STATIC globals.cpp diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp @@ -631,7 +631,7 @@ int msg_id=0; /* * Master audio out (the final sound) */ -void Master::AudioOut(float *outr, float *outl) +bool Master::AudioOut(float *outr, float *outl) { //Danger Limits if(memory->lowMemory(2,1024*1024)) @@ -658,7 +658,7 @@ void Master::AudioOut(float *outr, float *outl) if (mastercb) mastercb(mastercb_ptr, new_master); bToU->write("/free", "sb", "Master", sizeof(Master*), &this_master); - return; + return false; } //XXX yes, this is not realtime safe, but it is useful... @@ -834,6 +834,8 @@ void Master::AudioOut(float *outr, float *outl) //update the global frame timer time++; + + return true; } //TODO review the respective code from yoshimi for this @@ -859,7 +861,9 @@ void Master::GetAudioOutSamples(size_t nsamples, nsamples -= smps; //generate samples - AudioOut(bufl, bufr); + if (! AudioOut(bufl, bufr)) + return; + off = 0; out_off += smps; smps = synth.buffersize; diff --git a/src/Misc/Master.h b/src/Misc/Master.h @@ -100,7 +100,7 @@ class Master void vuUpdate(const float *outl, const float *outr); /**Audio Output*/ - void AudioOut(float *outl, float *outr) REALTIME; + bool AudioOut(float *outl, float *outr) REALTIME; /**Audio Output (for callback mode). * This allows the program to be controled by an external program*/ void GetAudioOutSamples(size_t nsamples, diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -423,19 +423,6 @@ class MiddleWareImpl MiddleWare *parent; private: - //Detect if the name of the process is 'zynaddsubfx' - bool isPlugin() const - { - std::string proc_file = "/proc/" + to_s(getpid()) + "/comm"; - std::ifstream ifs(proc_file); - if(ifs.good()) { - std::string comm_name; - ifs >> comm_name; - return comm_name != "zynaddsubfx"; - } - return true; - } - public: Config* const config; MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, Config* config, diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -44,6 +44,8 @@ #include <rtosc/rtosc.h> +bool isPlugin = false; + prng_t prng_state = 0x1234; /* diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -35,6 +35,8 @@ using std::max; //Velocity Sensing function extern float VelF(float velocity, unsigned char scaling); +extern bool isPlugin; + bool fileexists(const char *filename); #define N_DETUNE_TYPES 4 //the number of detune types diff --git a/src/Plugin/AbstractFX.hpp b/src/Plugin/AbstractFX.hpp @@ -0,0 +1,290 @@ +/* + ZynAddSubFX - a software synthesizer + + AbstractFX.hpp - DPF Abstract Effect class + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef ZYNADDSUBFX_ABSTRACTFX_HPP_INCLUDED +#define ZYNADDSUBFX_ABSTRACTFX_HPP_INCLUDED + +// DPF includes +#include "DistrhoPlugin.hpp" + +// ZynAddSubFX includes +#include "Effects/Effect.h" +#include "Misc/Allocator.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Abstract plugin class */ + +template<class ZynFX> +class AbstractPluginFX : public Plugin +{ +public: + AbstractPluginFX(const uint32_t params, const uint32_t programs) + : Plugin(params-2, programs, 0), + paramCount(params-2), // volume and pan handled by host + programCount(programs), + bufferSize(getBufferSize()), + sampleRate(getSampleRate()), + effect(nullptr), + efxoutl(nullptr), + efxoutr(nullptr) + { + efxoutl = new float[bufferSize]; + efxoutr = new float[bufferSize]; + std::memset(efxoutl, 0, sizeof(float)*bufferSize); + std::memset(efxoutr, 0, sizeof(float)*bufferSize); + + doReinit(true); + } + + ~AbstractPluginFX() override + { + delete[] efxoutl; + delete[] efxoutr; + delete effect; + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin author/maker. + */ + const char* getMaker() const noexcept override + { + return "ZynAddSubFX Team"; + } + + /** + Get the plugin homepage. + Optional, returns nothing by default. + */ + const char* getHomePage() const noexcept override + { + return "http://zynaddsubfx.sourceforge.net"; + } + + /** + Get the plugin license (a single line of text or a URL). + */ + const char* getLicense() const noexcept override + { + return "GPL v2"; + } + + /** + Get the plugin version, in hexadecimal. + */ + uint32_t getVersion() const noexcept override + { + // TODO: use config.h or globals.h + return d_version(2, 5, 3); + } + + /* -------------------------------------------------------------------------------------------------------- + * Internal data */ + + /** + Get the current value of a parameter. + The host may call this function from any context, including realtime processing. + */ + float getParameterValue(uint32_t index) const override + { + return static_cast<float>(effect->getpar(static_cast<int>(index+2))); + } + + /** + Change a parameter value. + The host may call this function from any context, including realtime processing. + When a parameter is marked as automable, you must ensure no non-realtime operations are performed. + @note This function will only be called for parameter inputs. + */ + void setParameterValue(uint32_t index, float value) override + { + // make sure value is in bounds for uchar conversion + if (value < 0.0f) + value = 0.0f; + else if (value > 127.0f) + value = 127.0f; + + // safely cast to int + const int ivalue = (int)(value+0.5f); + + // ok! + effect->changepar(static_cast<int>(index+2), static_cast<uchar>(ivalue)); + } + + /** + Load a program. + The host may call this function from any context, including realtime processing. + */ + void loadProgram(uint32_t index) override + { + effect->setpreset(static_cast<uchar>(index)); + + // reset volume and pan + effect->changepar(0, 127); + effect->changepar(1, 64); + } + + /* -------------------------------------------------------------------------------------------------------- + * Audio/MIDI Processing */ + + /** + Activate this plugin. + */ + void activate() override + { + effect->cleanup(); + } + + /** + Run/process function for plugins without MIDI input. + @note Some parameters might be null if there are no audio inputs or outputs. + */ + void run(const float** inputs, float** outputs, uint32_t frames) override + { + if (outputs[0] != inputs[0]) + copyWithMultiply(outputs[0], inputs[0], 0.5f, frames); + else + multiply(outputs[0], 0.5f, frames); + + if (outputs[1] != inputs[1]) + copyWithMultiply(outputs[1], inputs[1], 0.5f, frames); + else + multiply(outputs[1], 0.5f, frames); + + // FIXME: Make Zyn use const floats + effect->out(Stereo<float*>((float*)inputs[0], (float*)inputs[1])); + + addWithMultiply(outputs[0], efxoutl, 0.5f, frames); + addWithMultiply(outputs[1], efxoutr, 0.5f, frames); + } + + /* -------------------------------------------------------------------------------------------------------- + * Callbacks (optional) */ + + /** + Optional callback to inform the plugin about a buffer size change. + This function will only be called when the plugin is deactivated. + @note This value is only a hint! + Hosts might call run() with a higher or lower number of frames. + */ + void bufferSizeChanged(uint32_t newBufferSize) override + { + if (bufferSize == newBufferSize) + return; + + bufferSize = newBufferSize; + + delete[] efxoutl; + delete[] efxoutr; + efxoutl = new float[bufferSize]; + efxoutr = new float[bufferSize]; + std::memset(efxoutl, 0, sizeof(float)*bufferSize); + std::memset(efxoutr, 0, sizeof(float)*bufferSize); + + doReinit(false); + } + + /** + Optional callback to inform the plugin about a sample rate change. + This function will only be called when the plugin is deactivated. + */ + void sampleRateChanged(double newSampleRate) override + { + if (sampleRate == newSampleRate) + return; + + sampleRate = newSampleRate; + + doReinit(false); + } + + // ------------------------------------------------------------------------------------------------------- + +private: + const uint32_t paramCount; + const uint32_t programCount; + + uint32_t bufferSize; + double sampleRate; + + Effect* effect; + float* efxoutl; + float* efxoutr; + + AllocatorClass allocator; + + void doReinit(const bool firstInit) + { + // save current param values before recreating effect + uchar params[paramCount]; + + if (effect != nullptr) + { + for (int i=0, count=static_cast<int>(paramCount); i<count; ++i) + params[i] = effect->getpar(i+2); + + delete effect; + } + + EffectParams pars(allocator, false, efxoutl, efxoutr, 0, static_cast<uint>(sampleRate), static_cast<int>(bufferSize)); + effect = new ZynFX(pars); + + if (firstInit) + { + effect->setpreset(0); + } + else + { + for (int i=0, count=static_cast<int>(paramCount); i<count; ++i) + effect->changepar(i+2, params[i]); + } + + // reset volume and pan + effect->changepar(0, 127); + effect->changepar(1, 64); + } + + void addWithMultiply(float* dst, const float* src, const float multiplier, const uint32_t frames) noexcept + { + for (uint32_t i=0; i<frames; ++i) + dst[i] += src[i] * multiplier; + } + + void copyWithMultiply(float* dst, const float* src, const float multiplier, const uint32_t frames) noexcept + { + for (uint32_t i=0; i<frames; ++i) + dst[i] = src[i] * multiplier; + } + + void multiply(float* dst, const float multiplier, const uint32_t frames) noexcept + { + for (uint32_t i=0; i<frames; ++i) + dst[i] *= multiplier; + } + + DISTRHO_DECLARE_NON_COPY_CLASS(AbstractPluginFX) +}; + +#endif // ZYNADDSUBFX_ABSTRACTFX_HPP_INCLUDED diff --git a/src/Plugin/AlienWah/AlienWah.cpp b/src/Plugin/AlienWah/AlienWah.cpp @@ -0,0 +1,187 @@ +/* + ZynAddSubFX - a software synthesizer + + AlienWah.cpp - DPF + Zyn Plugin for AlienWah + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Alienwah.h" + +/* ------------------------------------------------------------------------------------------------------------ + * AlienWah plugin class */ + +class AlienWahPlugin : public AbstractPluginFX<Alienwah> +{ +public: + AlienWahPlugin() + : AbstractPluginFX(11, 4) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "AlienWah"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'a', 'w'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.hints |= kParameterIsAutomable; + parameter.name = "LFO Frequency"; + parameter.symbol = "lfofreq"; + parameter.ranges.def = 70.0f; + break; + case 1: + parameter.hints |= kParameterIsAutomable; + parameter.name = "LFO Randomness"; + parameter.symbol = "lforand"; + parameter.ranges.def = 0.0f; + break; + case 2: + parameter.hints |= kParameterIsAutomable; + parameter.name = "LFO Type"; + parameter.symbol = "lfotype"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[0].label = "Sine"; + scalePoints[1].label = "Triangle"; + scalePoints[0].value = 0.0f; + scalePoints[1].value = 1.0f; + */ + break; + case 3: + parameter.hints |= kParameterIsAutomable; + parameter.name = "LFO Stereo"; + parameter.symbol = "lfostereo"; + parameter.ranges.def = 62.0f; + break; + case 4: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Depth"; + parameter.symbol = "depth"; + parameter.ranges.def = 60.0f; + break; + case 5: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Feedback"; + parameter.symbol = "fb"; + parameter.ranges.def = 105.0f; + break; + case 6: + parameter.name = "Delay"; + parameter.symbol = "delay"; + parameter.ranges.def = 25.0f; + parameter.ranges.min = 1.0f; + parameter.ranges.max = 100.0f; + break; + case 7: + parameter.hints |= kParameterIsAutomable; + parameter.name = "L/R Cross"; + parameter.symbol = "lrcross"; + parameter.ranges.def = 0.0f; + break; + case 8: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Phase"; + parameter.symbol = "phase"; + parameter.ranges.def = 64.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "AlienWah 1"; + break; + case 1: + programName = "AlienWah 2"; + break; + case 2: + programName = "AlienWah 3"; + break; + case 3: + programName = "AlienWah 4"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(AlienWahPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new AlienWahPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/AlienWah/CMakeLists.txt b/src/Plugin/AlienWah/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynAlienWah_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp AlienWah.cpp) +add_library(ZynAlienWah_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp AlienWah.cpp) + +set_target_properties(ZynAlienWah_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynAlienWah_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynAlienWah_lv2 PROPERTIES OUTPUT_NAME "ZynAlienWah") +set_target_properties(ZynAlienWah_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynAlienWah_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynAlienWah_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynAlienWah_vst PROPERTIES OUTPUT_NAME "ZynAlienWah") +set_target_properties(ZynAlienWah_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynAlienWah_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynAlienWah_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynAlienWah_lv2 LIBRARY DESTINATION lib/lv2/ZynAlienWah.lv2/) +install(TARGETS ZynAlienWah_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynAlienWah_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynAlienWah_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynAlienWah.ttl + DESTINATION lib/lv2/ZynAlienWah.lv2/) diff --git a/src/Plugin/AlienWah/DistrhoPluginInfo.h b/src/Plugin/AlienWah/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynAlienWah" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#AlienWah" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:PhaserPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/CMakeLists.txt b/src/Plugin/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable(lv2-ttl-generator ${CMAKE_SOURCE_DIR}/DPF/utils/lv2-ttl-generator/lv2_ttl_generator.c) + +# TODO: make this !win32 only +target_link_libraries(lv2-ttl-generator "dl") + +add_subdirectory(AlienWah) +add_subdirectory(Chorus) +add_subdirectory(Distortion) +add_subdirectory(DynamicFilter) +add_subdirectory(Echo) +add_subdirectory(Phaser) +add_subdirectory(Reverb) +add_subdirectory(ZynAddSubFX) diff --git a/src/Plugin/Chorus/CMakeLists.txt b/src/Plugin/Chorus/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynChorus_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Chorus.cpp) +add_library(ZynChorus_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Chorus.cpp) + +set_target_properties(ZynChorus_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynChorus_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynChorus_lv2 PROPERTIES OUTPUT_NAME "ZynChorus") +set_target_properties(ZynChorus_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynChorus_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynChorus_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynChorus_vst PROPERTIES OUTPUT_NAME "ZynChorus") +set_target_properties(ZynChorus_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynChorus_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynChorus_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynChorus_lv2 LIBRARY DESTINATION lib/lv2/ZynChorus.lv2/) +install(TARGETS ZynChorus_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynChorus_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynChorus_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynChorus.ttl + DESTINATION lib/lv2/ZynChorus.lv2/) diff --git a/src/Plugin/Chorus/Chorus.cpp b/src/Plugin/Chorus/Chorus.cpp @@ -0,0 +1,204 @@ +/* + ZynAddSubFX - a software synthesizer + + Chorus.cpp - DPF + Zyn Plugin for Chorus + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Chorus.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Chorus plugin class */ + +class ChorusPlugin : public AbstractPluginFX<Chorus> +{ +public: + ChorusPlugin() + : AbstractPluginFX(12, 10) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "Chorus"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'c', 'h'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger|kParameterIsAutomable; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.name = "LFO Frequency"; + parameter.symbol = "lfofreq"; + parameter.ranges.def = 50.0f; + break; + case 1: + parameter.name = "LFO Randomness"; + parameter.symbol = "lforand"; + parameter.ranges.def = 0.0f; + break; + case 2: + parameter.name = "LFO Type"; + parameter.symbol = "lfotype"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[0].label = "Sine"; + scalePoints[1].label = "Triangle"; + scalePoints[0].value = 0.0f; + scalePoints[1].value = 1.0f; + */ + break; + case 3: + parameter.name = "LFO Stereo"; + parameter.symbol = "lfostereo"; + parameter.ranges.def = 90.0f; + break; + case 4: + parameter.name = "Depth"; + parameter.symbol = "depth"; + parameter.ranges.def = 40.0f; + break; + case 5: + parameter.name = "Delay"; + parameter.symbol = "delay"; + parameter.ranges.def = 85.0f; + break; + case 6: + parameter.name = "Feedback"; + parameter.symbol = "fb"; + parameter.ranges.def = 64.0f; + break; + case 7: + parameter.name = "L/R Cross"; + parameter.symbol = "lrcross"; + parameter.ranges.def = 119.0f; + break; + case 8: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Flange Mode"; + parameter.symbol = "flang"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 9: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Subtract Output"; + parameter.symbol = "subsout"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Chorus 1"; + break; + case 1: + programName = "Chorus 2"; + break; + case 2: + programName = "Chorus 3"; + break; + case 3: + programName = "Celeste 1"; + break; + case 4: + programName = "Celeste 2"; + break; + case 5: + programName = "Flange 1"; + break; + case 6: + programName = "Flange 2"; + break; + case 7: + programName = "Flange 3"; + break; + case 8: + programName = "Flange 4"; + break; + case 9: + programName = "Flange 5"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(ChorusPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new ChorusPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/Chorus/DistrhoPluginInfo.h b/src/Plugin/Chorus/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynChorus" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#Chorus" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ChorusPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/Distortion/CMakeLists.txt b/src/Plugin/Distortion/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynDistortion_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Distortion.cpp) +add_library(ZynDistortion_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Distortion.cpp) + +set_target_properties(ZynDistortion_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynDistortion_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynDistortion_lv2 PROPERTIES OUTPUT_NAME "ZynDistortion") +set_target_properties(ZynDistortion_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynDistortion_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynDistortion_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynDistortion_vst PROPERTIES OUTPUT_NAME "ZynDistortion") +set_target_properties(ZynDistortion_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynDistortion_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynDistortion_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynDistortion_lv2 LIBRARY DESTINATION lib/lv2/ZynDistortion.lv2/) +install(TARGETS ZynDistortion_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynDistortion_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynDistortion_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynDistortion.ttl + DESTINATION lib/lv2/ZynDistortion.lv2/) diff --git a/src/Plugin/Distortion/Distortion.cpp b/src/Plugin/Distortion/Distortion.cpp @@ -0,0 +1,213 @@ +/* + ZynAddSubFX - a software synthesizer + + Distortion.cpp - DPF + Zyn Plugin for Distortion + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Distorsion.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Distortion plugin class */ + +class DistortionPlugin : public AbstractPluginFX<Distorsion> +{ +public: + DistortionPlugin() + : AbstractPluginFX(11, 6) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "Distortion"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'd', 's'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger|kParameterIsAutomable; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.name = "L/R Cross"; + parameter.symbol = "lrcross"; + parameter.ranges.def = 35.0f; + break; + case 1: + parameter.name = "Drive"; + parameter.symbol = "drive"; + parameter.ranges.def = 56.0f; + break; + case 2: + parameter.name = "Level"; + parameter.symbol = "level"; + parameter.ranges.def = 70.0f; + break; + case 3: + parameter.name = "Type"; + parameter.symbol = "type"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 13.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[ 0].label = "Arctangent"; + scalePoints[ 1].label = "Asymmetric"; + scalePoints[ 2].label = "Pow"; + scalePoints[ 3].label = "Sine"; + scalePoints[ 4].label = "Quantisize"; + scalePoints[ 5].label = "Zigzag"; + scalePoints[ 6].label = "Limiter"; + scalePoints[ 7].label = "Upper Limiter"; + scalePoints[ 8].label = "Lower Limiter"; + scalePoints[ 9].label = "Inverse Limiter"; + scalePoints[10].label = "Clip"; + scalePoints[11].label = "Asym2"; + scalePoints[12].label = "Pow2"; + scalePoints[13].label = "Sigmoid"; + scalePoints[ 0].value = 0.0f; + scalePoints[ 1].value = 1.0f; + scalePoints[ 2].value = 2.0f; + scalePoints[ 3].value = 3.0f; + scalePoints[ 4].value = 4.0f; + scalePoints[ 5].value = 5.0f; + scalePoints[ 6].value = 6.0f; + scalePoints[ 7].value = 7.0f; + scalePoints[ 8].value = 8.0f; + scalePoints[ 9].value = 9.0f; + scalePoints[10].value = 10.0f; + scalePoints[11].value = 11.0f; + scalePoints[12].value = 12.0f; + scalePoints[13].value = 13.0f; + */ + break; + case 4: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Negate"; + parameter.symbol = "negate"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 5: + parameter.name = "Low-Pass Filter"; + parameter.symbol = "lpf"; + parameter.ranges.def = 96.0f; + break; + case 6: + parameter.name = "High-Pass Filter"; + parameter.symbol = "hpf"; + parameter.ranges.def = 0.0f; + break; + case 7: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Stereo"; + parameter.symbol = "stereo"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 8: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Pre-Filtering"; + parameter.symbol = "pf"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Overdrive 1"; + break; + case 1: + programName = "Overdrive 2"; + break; + case 2: + programName = "A. Exciter 1"; + break; + case 3: + programName = "A. Exciter 2"; + break; + case 4: + programName = "Guitar Amp"; + break; + case 5: + programName = "Quantisize"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(DistortionPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new DistortionPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/Distortion/DistrhoPluginInfo.h b/src/Plugin/Distortion/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynDistortion" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#Distortion" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:DistortionPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/DynamicFilter/CMakeLists.txt b/src/Plugin/DynamicFilter/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynDynamicFilter_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp DynamicFilter.cpp) +add_library(ZynDynamicFilter_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp DynamicFilter.cpp) + +set_target_properties(ZynDynamicFilter_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynDynamicFilter_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynDynamicFilter_lv2 PROPERTIES OUTPUT_NAME "ZynDynamicFilter") +set_target_properties(ZynDynamicFilter_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynDynamicFilter_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynDynamicFilter_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynDynamicFilter_vst PROPERTIES OUTPUT_NAME "ZynDynamicFilter") +set_target_properties(ZynDynamicFilter_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynDynamicFilter_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynDynamicFilter_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynDynamicFilter_lv2 LIBRARY DESTINATION lib/lv2/ZynDynamicFilter.lv2/) +install(TARGETS ZynDynamicFilter_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynDynamicFilter_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynDynamicFilter_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynDynamicFilter.ttl + DESTINATION lib/lv2/ZynDynamicFilter.lv2/) diff --git a/src/Plugin/DynamicFilter/DistrhoPluginInfo.h b/src/Plugin/DynamicFilter/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynDynamicFilter" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#DynamicFilter" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:FilterPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/DynamicFilter/DynamicFilter.cpp b/src/Plugin/DynamicFilter/DynamicFilter.cpp @@ -0,0 +1,177 @@ +/* + ZynAddSubFX - a software synthesizer + + DynamicFilter.cpp - DPF + Zyn Plugin for DynamicFilter + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/DynamicFilter.h" + +/* ------------------------------------------------------------------------------------------------------------ + * DynamicFilter plugin class */ + +class DynamicFilterPlugin : public AbstractPluginFX<DynamicFilter> +{ +public: + DynamicFilterPlugin() + : AbstractPluginFX(10, 5) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "DynamicFilter"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'd', 'f'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger|kParameterIsAutomable; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.name = "LFO Frequency"; + parameter.symbol = "lfofreq"; + parameter.ranges.def = 80.0f; + break; + case 1: + parameter.name = "LFO Randomness"; + parameter.symbol = "lforand"; + parameter.ranges.def = 0.0f; + break; + case 2: + parameter.name = "LFO Type"; + parameter.symbol = "lfotype"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[0].label = "Sine"; + scalePoints[1].label = "Triangle"; + scalePoints[0].value = 0.0f; + scalePoints[1].value = 1.0f; + */ + break; + case 3: + parameter.name = "LFO Stereo"; + parameter.symbol = "lfostereo"; + parameter.ranges.def = 64.0f; + break; + case 4: + parameter.name = "LFO Depth"; + parameter.symbol = "lfodepth"; + parameter.ranges.def = 0.0f; + break; + case 5: + parameter.name = "Amp sns"; + parameter.symbol = "ampsns"; + parameter.ranges.def = 90.0f; + break; + case 6: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Amp sns inv"; + parameter.symbol = "ampsnsinv"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 7: + parameter.name = "Amp Smooth"; + parameter.symbol = "ampsmooth"; + parameter.ranges.def = 60.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Wah Wah"; + break; + case 1: + programName = "Auto Wah"; + break; + case 2: + programName = "Sweep"; + break; + case 3: + programName = "Vocal Morph 1"; + break; + case 4: + programName = "Vocal Morph 2"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(DynamicFilterPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new DynamicFilterPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/Echo/CMakeLists.txt b/src/Plugin/Echo/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynEcho_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Echo.cpp) +add_library(ZynEcho_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Echo.cpp) + +set_target_properties(ZynEcho_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynEcho_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynEcho_lv2 PROPERTIES OUTPUT_NAME "ZynEcho") +set_target_properties(ZynEcho_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynEcho_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynEcho_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynEcho_vst PROPERTIES OUTPUT_NAME "ZynEcho") +set_target_properties(ZynEcho_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynEcho_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynEcho_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynEcho_lv2 LIBRARY DESTINATION lib/lv2/ZynEcho.lv2/) +install(TARGETS ZynEcho_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynEcho_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynEcho_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynEcho.ttl + DESTINATION lib/lv2/ZynEcho.lv2/) diff --git a/src/Plugin/Echo/DistrhoPluginInfo.h b/src/Plugin/Echo/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynEcho" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#Echo" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:DelayPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/Echo/Echo.cpp b/src/Plugin/Echo/Echo.cpp @@ -0,0 +1,164 @@ +/* + ZynAddSubFX - a software synthesizer + + Echo.cpp - DPF + Zyn Plugin for Echo + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Echo.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Echo plugin class */ + +class EchoPlugin : public AbstractPluginFX<Echo> +{ +public: + EchoPlugin() + : AbstractPluginFX(7, 9) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "Echo"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'e', 'c'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger|kParameterIsAutomable; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.name = "Delay"; + parameter.symbol = "delay"; + parameter.ranges.def = 35.0f; + break; + case 1: + parameter.name = "L/R Delay"; + parameter.symbol = "lrdelay"; + parameter.ranges.def = 64.0f; + break; + case 2: + parameter.name = "L/R Cross"; + parameter.symbol = "lrcross"; + parameter.ranges.def = 30.0f; + break; + case 3: + parameter.name = "Feedback"; + parameter.symbol = "fb"; + parameter.ranges.def = 59.0f; + break; + case 4: + parameter.name = "High Damp"; + parameter.symbol = "damp"; + parameter.ranges.def = 0.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Echo 1"; + break; + case 1: + programName = "Echo 2"; + break; + case 2: + programName = "Echo 3"; + break; + case 3: + programName = "Simple Echo"; + break; + case 4: + programName = "Canyon"; + break; + case 5: + programName = "Panning Echo 1"; + break; + case 6: + programName = "Panning Echo 2"; + break; + case 7: + programName = "Panning Echo 3"; + break; + case 8: + programName = "Feedback Echo"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(EchoPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new EchoPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/Phaser/CMakeLists.txt b/src/Plugin/Phaser/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynPhaser_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Phaser.cpp) +add_library(ZynPhaser_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Phaser.cpp) + +set_target_properties(ZynPhaser_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynPhaser_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynPhaser_lv2 PROPERTIES OUTPUT_NAME "ZynPhaser") +set_target_properties(ZynPhaser_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynPhaser_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynPhaser_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynPhaser_vst PROPERTIES OUTPUT_NAME "ZynPhaser") +set_target_properties(ZynPhaser_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynPhaser_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynPhaser_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynPhaser_lv2 LIBRARY DESTINATION lib/lv2/ZynPhaser.lv2/) +install(TARGETS ZynPhaser_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynPhaser_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynPhaser_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynPhaser.ttl + DESTINATION lib/lv2/ZynPhaser.lv2/) diff --git a/src/Plugin/Phaser/DistrhoPluginInfo.h b/src/Plugin/Phaser/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynPhaser" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#Phaser" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:PhaserPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/Phaser/Phaser.cpp b/src/Plugin/Phaser/Phaser.cpp @@ -0,0 +1,229 @@ +/* + ZynAddSubFX - a software synthesizer + + Phaser.cpp - DPF + Zyn Plugin for Phaser + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Phaser.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Phaser plugin class */ + +class PhaserPlugin : public AbstractPluginFX<Phaser> +{ +public: + PhaserPlugin() + : AbstractPluginFX(15, 12) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "Phaser"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'p', 'h'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger|kParameterIsAutomable; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.name = "LFO Frequency"; + parameter.symbol = "lfofreq"; + parameter.ranges.def = 36.0f; + break; + case 1: + parameter.name = "LFO Randomness"; + parameter.symbol = "lforand"; + parameter.ranges.def = 0.0f; + break; + case 2: + parameter.name = "LFO Type"; + parameter.symbol = "lfotype"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[0].label = "Sine"; + scalePoints[1].label = "Triangle"; + scalePoints[0].value = 0.0f; + scalePoints[1].value = 1.0f; + */ + break; + case 3: + parameter.name = "LFO Stereo"; + parameter.symbol = "lfostereo"; + parameter.ranges.def = 64.0f; + break; + case 4: + parameter.name = "Depth"; + parameter.symbol = "depth"; + parameter.ranges.def = 110.0f; + break; + case 5: + parameter.name = "Feedback"; + parameter.symbol = "fb"; + parameter.ranges.def = 64.0f; + break; + case 6: + parameter.name = "Stages"; + parameter.symbol = "stages"; + parameter.ranges.def = 1.0f; + parameter.ranges.min = 1.0f; + parameter.ranges.max = 12.0f; + break; + case 7: + parameter.name = "L/R Cross|Offset"; + parameter.symbol = "lrcross"; + parameter.ranges.def = 0.0f; + break; + case 8: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Subtract Output"; + parameter.symbol = "subsout"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 9: + parameter.name = "Phase|Width"; + parameter.symbol = "phase"; + parameter.ranges.def = 20.0f; + break; + case 10: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Hyper"; + parameter.symbol = "hyper"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + case 11: + parameter.name = "Distortion"; + parameter.symbol = "dist"; + parameter.ranges.def = 0.0f; + break; + case 12: + parameter.hints |= kParameterIsBoolean; + parameter.name = "Analog"; + parameter.symbol = "analog"; + parameter.ranges.def = 0.0f; + parameter.ranges.max = 1.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Phaser 1"; + break; + case 1: + programName = "Phaser 2"; + break; + case 2: + programName = "Phaser 3"; + break; + case 3: + programName = "Phaser 4"; + break; + case 4: + programName = "Phaser 5"; + break; + case 5: + programName = "Phaser 6"; + break; + case 6: + programName = "Analog Phaser 1"; + break; + case 7: + programName = "Analog Phaser 2"; + break; + case 8: + programName = "Analog Phaser 3"; + break; + case 9: + programName = "Analog Phaser 4"; + break; + case 10: + programName = "Analog Phaser 5"; + break; + case 11: + programName = "Analog Phaser 6"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(PhaserPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new PhaserPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/Reverb/CMakeLists.txt b/src/Plugin/Reverb/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +add_library(ZynReverb_lv2 SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Reverb.cpp) +add_library(ZynReverb_vst SHARED ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp Reverb.cpp) + +set_target_properties(ZynReverb_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynReverb_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynReverb_lv2 PROPERTIES OUTPUT_NAME "ZynReverb") +set_target_properties(ZynReverb_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynReverb_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynReverb_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynReverb_vst PROPERTIES OUTPUT_NAME "ZynReverb") +set_target_properties(ZynReverb_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynReverb_lv2 zynaddsubfx_core ${OS_LIBRARIES}) +target_link_libraries(ZynReverb_vst zynaddsubfx_core ${OS_LIBRARIES}) + +install(TARGETS ZynReverb_lv2 LIBRARY DESTINATION lib/lv2/ZynReverb.lv2/) +install(TARGETS ZynReverb_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynReverb_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynReverb_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynReverb.ttl + DESTINATION lib/lv2/ZynReverb.lv2/) diff --git a/src/Plugin/Reverb/DistrhoPluginInfo.h b/src/Plugin/Reverb/DistrhoPluginInfo.h @@ -0,0 +1,38 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynReverb" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net/fx#Reverb" + +#define DISTRHO_PLUGIN_HAS_UI 0 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ReverbPlugin" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/Reverb/Reverb.cpp b/src/Plugin/Reverb/Reverb.cpp @@ -0,0 +1,223 @@ +/* + ZynAddSubFX - a software synthesizer + + Reverb.cpp - DPF + Zyn Plugin for Reverb + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "../AbstractFX.hpp" + +// ZynAddSubFX includes +#include "Effects/Reverb.h" + +/* ------------------------------------------------------------------------------------------------------------ + * Reverb plugin class */ + +class ReverbPlugin : public AbstractPluginFX<Reverb> +{ +public: + ReverbPlugin() + : AbstractPluginFX(13, 13) {} + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "Reverb"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'X', 'r', 'v'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + parameter.hints = kParameterIsInteger; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 127.0f; + + switch (index) + { + case 0: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Time"; + parameter.symbol = "time"; + parameter.ranges.def = 63.0f; + break; + case 1: + parameter.name = "Delay"; + parameter.symbol = "delay"; + parameter.ranges.def = 24.0f; + break; + case 2: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Feedback"; + parameter.symbol = "fb"; + parameter.ranges.def = 0.0f; + break; + case 3: + // FIXME: unused + parameter.name = "bw (unused)"; + parameter.symbol = "unused_bw"; + parameter.ranges.def = 0.0f; + break; + case 4: + // FIXME: unused + parameter.name = "E/R (unused)"; + parameter.symbol = "unused_er"; + parameter.ranges.def = 0.0f; + break; + case 5: + parameter.name = "Low-Pass Filter"; + parameter.symbol = "lpf"; + parameter.ranges.def = 85.0f; + break; + case 6: + parameter.name = "High-Pass Filter"; + parameter.symbol = "hpf"; + parameter.ranges.def = 5.0f; + break; + case 7: + parameter.hints |= kParameterIsAutomable; + parameter.name = "Damp"; + parameter.symbol = "damp"; + parameter.ranges.def = 83.0f; + parameter.ranges.min = 64.0f; + break; + case 8: + parameter.name = "Type"; + parameter.symbol = "type"; + parameter.ranges.def = 1.0f; + parameter.ranges.max = 2.0f; + /* + TODO: support for scalePoints in DPF + scalePoints[0].label = "Random"; + scalePoints[1].label = "Freeverb"; + scalePoints[2].label = "Bandwidth"; + scalePoints[0].value = 0.0f; + scalePoints[1].value = 1.0f; + scalePoints[2].value = 2.0f; + */ + break; + case 9: + parameter.name = "Room size"; + parameter.symbol = "size"; + parameter.ranges.def = 64.0f; + parameter.ranges.min = 1.0f; + break; + case 10: + parameter.name = "Bandwidth"; + parameter.symbol = "bw"; + parameter.ranges.def = 20.0f; + break; + } + } + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) noexcept override + { + switch (index) + { + case 0: + programName = "Cathedral 1"; + break; + case 1: + programName = "Cathedral 2"; + break; + case 2: + programName = "Cathedral 3"; + break; + case 3: + programName = "Hall 1"; + break; + case 4: + programName = "Hall 2"; + break; + case 5: + programName = "Room 1"; + break; + case 6: + programName = "Room 2"; + break; + case 7: + programName = "Basement"; + break; + case 8: + programName = "Tunnel"; + break; + case 9: + programName = "Echoed 1"; + break; + case 10: + programName = "Echoed 2"; + break; + case 11: + programName = "Very Long 1"; + break; + case 12: + programName = "Very Long 2"; + break; + } + } + + DISTRHO_DECLARE_NON_COPY_CLASS(ReverbPlugin) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + return new ReverbPlugin(); +} + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/ZynAddSubFX/CMakeLists.txt b/src/Plugin/ZynAddSubFX/CMakeLists.txt @@ -0,0 +1,79 @@ + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/DPF/distrho .) + +if(NtkGui) + +# UI Enabled +add_library(ZynAddSubFX_lv2 SHARED + ${CMAKE_SOURCE_DIR}/src/globals.cpp + ${CMAKE_SOURCE_DIR}/src/UI/ConnectionDummy.cpp + ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp + ZynAddSubFX.cpp) + +add_library(ZynAddSubFX_lv2_ui SHARED + DistrhoUI.cpp + ZynAddSubFX-UI.cpp) + +add_library(ZynAddSubFX_vst SHARED + ${CMAKE_SOURCE_DIR}/src/globals.cpp + ${CMAKE_SOURCE_DIR}/src/UI/ConnectionDummy.cpp + ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp + DistrhoUI.cpp + ZynAddSubFX.cpp + ZynAddSubFX-UI.cpp) + +else() + +# UI Disabled +add_library(ZynAddSubFX_lv2 SHARED + ${CMAKE_SOURCE_DIR}/src/globals.cpp + ${CMAKE_SOURCE_DIR}/src/UI/ConnectionDummy.cpp + ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp + ZynAddSubFX.cpp) + +add_library(ZynAddSubFX_vst SHARED + ${CMAKE_SOURCE_DIR}/src/globals.cpp + ${CMAKE_SOURCE_DIR}/src/UI/ConnectionDummy.cpp + ${CMAKE_SOURCE_DIR}/DPF/distrho/DistrhoPluginMain.cpp + ZynAddSubFX.cpp) + +endif() + +set_target_properties(ZynAddSubFX_lv2 PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynAddSubFX_lv2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynAddSubFX_lv2 PROPERTIES OUTPUT_NAME "ZynAddSubFX") +set_target_properties(ZynAddSubFX_lv2 PROPERTIES PREFIX "") + +set_target_properties(ZynAddSubFX_vst PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_VST") +set_target_properties(ZynAddSubFX_vst PROPERTIES LIBRARY_OUTPUT_DIRECTORY "vst") +set_target_properties(ZynAddSubFX_vst PROPERTIES OUTPUT_NAME "ZynAddSubFX") +set_target_properties(ZynAddSubFX_vst PROPERTIES PREFIX "") + +target_link_libraries(ZynAddSubFX_lv2 zynaddsubfx_core ${OS_LIBRARIES} ${LIBLO_LIBRARIES}) +target_link_libraries(ZynAddSubFX_vst zynaddsubfx_core ${OS_LIBRARIES} ${LIBLO_LIBRARIES}) + +install(TARGETS ZynAddSubFX_lv2 LIBRARY DESTINATION lib/lv2/ZynAddSubFX.lv2/) +install(TARGETS ZynAddSubFX_vst LIBRARY DESTINATION lib/vst/) + +add_custom_command(TARGET ZynAddSubFX_lv2 POST_BUILD + COMMAND lv2-ttl-generator $<TARGET_FILE:ZynAddSubFX_lv2> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lv2) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/manifest.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/presets.ttl + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynAddSubFX.ttl + DESTINATION lib/lv2/ZynAddSubFX.lv2/) + +if(NtkGui) +set_target_properties(ZynAddSubFX_lv2_ui PROPERTIES COMPILE_DEFINITIONS "DISTRHO_PLUGIN_TARGET_LV2") +set_target_properties(ZynAddSubFX_lv2_ui PROPERTIES LIBRARY_OUTPUT_DIRECTORY "lv2") +set_target_properties(ZynAddSubFX_lv2_ui PROPERTIES OUTPUT_NAME "ZynAddSubFX_ui") +set_target_properties(ZynAddSubFX_lv2_ui PROPERTIES PREFIX "") + +install(TARGETS ZynAddSubFX_lv2_ui LIBRARY DESTINATION lib/lv2/ZynAddSubFX.lv2/) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/lv2/ZynAddSubFX_ui.ttl + DESTINATION lib/lv2/ZynAddSubFX.lv2/) +endif() diff --git a/src/Plugin/ZynAddSubFX/DistrhoPluginInfo.h b/src/Plugin/ZynAddSubFX/DistrhoPluginInfo.h @@ -0,0 +1,55 @@ +/* + ZynAddSubFX - a software synthesizer + + DistrhoPluginInfo.h - DPF information header + Copyright (C) 2015 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_BRAND "ZynAddSubFX" +#define DISTRHO_PLUGIN_NAME "ZynAddSubFX" +#define DISTRHO_PLUGIN_URI "http://zynaddsubfx.sourceforge.net" + +#ifdef NTK_GUI + #define DISTRHO_PLUGIN_HAS_UI 1 +#else + #define DISTRHO_PLUGIN_HAS_UI 0 +#endif + +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 1 +#define DISTRHO_PLUGIN_NUM_INPUTS 0 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +#define DISTRHO_PLUGIN_WANT_STATE 1 +#define DISTRHO_PLUGIN_WANT_FULL_STATE 1 + +enum Parameters { + kParamOscPort, + kParamCount +}; + +// Needed for dpf code, external-ui is not official +#ifdef NTK_GUI + #define HAVE_DGL + #include "DistrhoUIInternal.hpp" +#endif + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/src/Plugin/ZynAddSubFX/DistrhoUI.cpp b/src/Plugin/ZynAddSubFX/DistrhoUI.cpp @@ -0,0 +1,64 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> + * + * 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. + * + * THE 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 "DistrhoUIInternal.hpp" + +START_NAMESPACE_DISTRHO + +/* ------------------------------------------------------------------------------------------------------------ + * Static data, see DistrhoUIInternal.hpp */ + +double d_lastUiSampleRate = 0.0; + +/* ------------------------------------------------------------------------------------------------------------ + * UI */ + +UI::UI() + : pData(new PrivateData()) +{ +} + +UI::~UI() +{ + delete pData; +} + +/* ------------------------------------------------------------------------------------------------------------ + * Host state */ + +void UI::editParameter(uint32_t index, bool started) +{ + pData->editParamCallback(index + pData->parameterOffset, started); +} + +void UI::setParameterValue(uint32_t index, float value) +{ + pData->setParamCallback(index + pData->parameterOffset, value); +} + +void UI::setState(const char* key, const char* value) +{ + pData->setStateCallback(key, value); +} + +void UI::sendNote(uint8_t channel, uint8_t note, uint8_t velocity) +{ + pData->sendNoteCallback(channel, note, velocity); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/src/Plugin/ZynAddSubFX/DistrhoUI.hpp b/src/Plugin/ZynAddSubFX/DistrhoUI.hpp @@ -0,0 +1,111 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> + * + * 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. + * + * THE 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. + */ + +#ifndef DISTRHO_UI_HPP_INCLUDED +#define DISTRHO_UI_HPP_INCLUDED + +#include "extra/LeakDetector.hpp" + +START_NAMESPACE_DISTRHO + +/* ------------------------------------------------------------------------------------------------------------ + * DPF UI */ + +/** + DPF UI class from where UI instances are created. + */ +class UI +{ +public: + /** + UI class constructor. + The UI should be initialized to a default state that matches the plugin side. + */ + UI(); + + /** + Destructor. + */ + virtual ~UI(); + + /* -------------------------------------------------------------------------------------------------------- + * Host state */ + + /** + editParameter. + */ + void editParameter(uint32_t index, bool started); + + /** + setParameterValue. + */ + void setParameterValue(uint32_t index, float value); + + /** + setState. + */ + void setState(const char* key, const char* value); + + /** + sendNote. + */ + void sendNote(uint8_t channel, uint8_t note, uint8_t velocity); + +protected: + /* -------------------------------------------------------------------------------------------------------- + * DSP/Plugin Callbacks */ + + /** + A parameter has changed on the plugin side.@n + This is called by the host to inform the UI about parameter changes. + */ + virtual void parameterChanged(uint32_t index, float value) = 0; + + /** + A program has been loaded on the plugin side.@n + This is called by the host to inform the UI about program changes. + */ + virtual void programLoaded(uint32_t index) = 0; + + /** + A state has changed on the plugin side.@n + This is called by the host to inform the UI about state changes. + */ + virtual void stateChanged(const char* key, const char* value) = 0; + + // ------------------------------------------------------------------------------------------------------- + +private: + struct PrivateData; + PrivateData* const pData; + friend class UIExporter; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create UI, entry point */ + +/** + createUI. + */ +extern UI* createUI(const intptr_t winId); + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO + +#endif // DISTRHO_UI_HPP_INCLUDED diff --git a/src/Plugin/ZynAddSubFX/DistrhoUIInternal.hpp b/src/Plugin/ZynAddSubFX/DistrhoUIInternal.hpp @@ -0,0 +1,222 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> + * + * 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. + * + * THE 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. + */ + +#ifndef DISTRHO_UI_INTERNAL_HPP_INCLUDED +#define DISTRHO_UI_INTERNAL_HPP_INCLUDED + +#include "DistrhoUI.hpp" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------- +// Static data, see DistrhoUI.cpp + +extern double d_lastUiSampleRate; + +// ----------------------------------------------------------------------- +// UI callbacks + +typedef void (*editParamFunc) (void* ptr, uint32_t rindex, bool started); +typedef void (*setParamFunc) (void* ptr, uint32_t rindex, float value); +typedef void (*setStateFunc) (void* ptr, const char* key, const char* value); +typedef void (*sendNoteFunc) (void* ptr, uint8_t channel, uint8_t note, uint8_t velo); +typedef void (*setSizeFunc) (void* ptr, uint width, uint height); + +// ----------------------------------------------------------------------- +// UI private data + +struct UI::PrivateData { + // DSP + uint32_t parameterOffset; + + // Callbacks + editParamFunc editParamCallbackFunc; + setParamFunc setParamCallbackFunc; + setStateFunc setStateCallbackFunc; + sendNoteFunc sendNoteCallbackFunc; + setSizeFunc setSizeCallbackFunc; + void* ptr; + + PrivateData() noexcept + : parameterOffset(0), + editParamCallbackFunc(nullptr), + setParamCallbackFunc(nullptr), + setStateCallbackFunc(nullptr), + sendNoteCallbackFunc(nullptr), + setSizeCallbackFunc(nullptr), + ptr(nullptr) + { +#ifdef DISTRHO_PLUGIN_TARGET_LV2 + // events in+out + parameterOffset += 4 /* 2 stereo outs + events in&out */; +#endif + } + + void editParamCallback(const uint32_t rindex, const bool started) + { + if (editParamCallbackFunc != nullptr) + editParamCallbackFunc(ptr, rindex, started); + } + + void setParamCallback(const uint32_t rindex, const float value) + { + if (setParamCallbackFunc != nullptr) + setParamCallbackFunc(ptr, rindex, value); + } + + void setStateCallback(const char* const key, const char* const value) + { + if (setStateCallbackFunc != nullptr) + setStateCallbackFunc(ptr, key, value); + } + + void sendNoteCallback(const uint8_t channel, const uint8_t note, const uint8_t velocity) + { + if (sendNoteCallbackFunc != nullptr) + sendNoteCallbackFunc(ptr, channel, note, velocity); + } + + void setSizeCallback(const uint width, const uint height) + { + if (setSizeCallbackFunc != nullptr) + setSizeCallbackFunc(ptr, width, height); + } +}; + +// ----------------------------------------------------------------------- +// UI exporter class + +class UIExporter +{ +public: + UIExporter(void* const ptr, const intptr_t winId, + const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const setSizeFunc setSizeCall, + void* const dspPtr = nullptr) + : fUI(createUI(winId)), + fData((fUI != nullptr) ? fUI->pData : nullptr) + { + DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); + + fData->ptr = ptr; + fData->editParamCallbackFunc = editParamCall; + fData->setParamCallbackFunc = setParamCall; + fData->setStateCallbackFunc = setStateCall; + fData->sendNoteCallbackFunc = sendNoteCall; + fData->setSizeCallbackFunc = setSizeCall; + } + + // ------------------------------------------------------------------- + + uint32_t getParameterOffset() const noexcept + { + DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); + + return fData->parameterOffset; + } + + // ------------------------------------------------------------------- + + void parameterChanged(const uint32_t index, const float value) + { + DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + + fUI->parameterChanged(index, value); + } + + void programLoaded(const uint32_t index) + { + DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + + fUI->programLoaded(index); + } + + void stateChanged(const char* const key, const char* const value) + { + DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); + DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,); + + fUI->stateChanged(key, value); + } + + // ------------------------------------------------------------------- + // compatibility calls, used for regular OpenGL windows + + uint getWidth() const noexcept + { + return 390; + } + + uint getHeight() const noexcept + { + return 525; + } + + intptr_t getWindowId() const noexcept + { + return 0; + } + + bool isVisible() const noexcept + { + return true; + } + + void setSampleRate(const double sampleRate, const bool doCallback = false) + { + } + + void setWindowSize(const uint width, const uint height, const bool updateUI = false) + { + } + + void setWindowTitle(const char* const uiTitle) + { + } + + void setWindowTransientWinId(const uintptr_t winId) + { + } + + bool setWindowVisible(const bool yesNo) + { + return true; + } + + bool idle() + { + return true; + } + + void quit() + { + } + +private: + // ------------------------------------------------------------------- + + UI* const fUI; + UI::PrivateData* const fData; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter) +}; + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO + +#endif // DISTRHO_UI_INTERNAL_HPP_INCLUDED diff --git a/src/Plugin/ZynAddSubFX/ZynAddSubFX-UI.cpp b/src/Plugin/ZynAddSubFX/ZynAddSubFX-UI.cpp @@ -0,0 +1,215 @@ +/* + ZynAddSubFX - a software synthesizer + + ZynAddSubFX-UI.cpp - DPF + ZynAddSubFX External UI + Copyright (C) 2015-2016 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "DistrhoUI.hpp" +#include "src/DistrhoPluginChecks.h" + +// Custom includes +#include <cerrno> +#include <sys/wait.h> +#include <unistd.h> + +/* ------------------------------------------------------------------------------------------------------------ + * External UI class */ + +// NOTE: The following code is non-portable! +// It's only meant to be used in linux + +class ExternalUI +{ +public: + ExternalUI(const intptr_t w) + : pid(0), + winId(w) {} + + ~ExternalUI() + { + terminateAndWaitForProcess(); + } + + void respawnAtURL(const int url) + { + terminateAndWaitForProcess(); + + char urlAsString[32]; + sprintf(urlAsString, "osc.udp://localhost:%i/", url); + + char winIdAsString[32]; + sprintf(winIdAsString, "%llu", (long long unsigned)winId); + + printf("Now respawning at '%s', using winId '%s'\n", urlAsString, winIdAsString); + + const char* args[] = { + "zynaddsubfx-ext-gui", + "--embed", + winIdAsString, + urlAsString, + nullptr + }; + + pid = vfork(); + + switch (pid) + { + case 0: + execvp(args[0], (char**)args); + _exit(1); + break; + + case -1: + printf("Could not start external ui\n"); + break; + } + } + +private: + pid_t pid; + const intptr_t winId; + + void terminateAndWaitForProcess() + { + if (pid <= 0) + return; + + printf("Waiting for previous process to stop,,,\n"); + + bool sendTerm = true; + + for (pid_t p;;) + { + p = ::waitpid(pid, nullptr, WNOHANG); + + switch (p) + { + case 0: + if (sendTerm) + { + sendTerm = false; + ::kill(pid, SIGTERM); + } + break; + + case -1: + if (errno == ECHILD) + { + printf("Done! (no such process)\n"); + pid = 0; + return; + } + break; + + default: + if (p == pid) + { + printf("Done! (clean wait)\n"); + pid = 0; + return; + } + break; + } + + // 5 msec + usleep(5*1000); + } + } +}; + +/* ------------------------------------------------------------------------------------------------------------ + * ZynAddSubFX UI class */ + +class ZynAddSubFXUI : public UI +{ +public: + ZynAddSubFXUI(const intptr_t winId) + : UI(), + externalUI(winId), + oscPort(0) + { + } + + ~ZynAddSubFXUI() override + { + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * DSP/Plugin Callbacks */ + + /** + A parameter has changed on the plugin side. + This is called by the host to inform the UI about parameter changes. + */ + void parameterChanged(uint32_t index, float value) override + { + switch (index) + { + case kParamOscPort: { + const int port = int(value+0.5f); + + if (oscPort != port) + { + oscPort = port; + externalUI.respawnAtURL(port); + } + } break; + } + } + + /** + A program has been loaded on the plugin side. + This is called by the host to inform the UI about program changes. + */ + void programLoaded(uint32_t index) override + { + } + + /** + A state has changed on the plugin side. + This is called by the host to inform the UI about state changes. + */ + void stateChanged(const char* key, const char* value) override + { + } + +private: + ExternalUI externalUI; + int oscPort; + + DISTRHO_DECLARE_NON_COPY_CLASS(ZynAddSubFXUI) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +UI* createUI(const intptr_t winId) +{ + return new ZynAddSubFXUI(winId); +} + +END_NAMESPACE_DISTRHO + +#ifdef DISTRHO_PLUGIN_TARGET_LV2 +#include "src/DistrhoUILV2.cpp" +#endif diff --git a/src/Plugin/ZynAddSubFX/ZynAddSubFX.cpp b/src/Plugin/ZynAddSubFX/ZynAddSubFX.cpp @@ -0,0 +1,587 @@ +/* + ZynAddSubFX - a software synthesizer + + ZynAddSubFX.cpp - DPF + ZynAddSubFX Plugin + Copyright (C) 2015-2016 Filipe Coelho + Author: Filipe Coelho + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +// DPF includes +#include "DistrhoPlugin.hpp" + +// ZynAddSubFX includes +#include "Misc/Master.h" +#include "Misc/MiddleWare.h" +#include "Misc/Part.h" +#include "Misc/Util.h" + +// Extra includes +#include "extra/Mutex.hpp" +#include "extra/Thread.hpp" +#include "extra/ScopedPointer.hpp" + +#include <lo/lo.h> + +/* ------------------------------------------------------------------------------------------------------------ + * MiddleWare thread class */ + +class MiddleWareThread : public Thread +{ +public: + class ScopedStopper + { + public: + ScopedStopper(MiddleWareThread& mwt) noexcept + : wasRunning(mwt.isThreadRunning()), + thread(mwt), + middleware(mwt.middleware) + { + if (wasRunning) + thread.stop(); + } + + ~ScopedStopper() noexcept + { + if (wasRunning) + thread.start(middleware); + } + + void updateMiddleWare(MiddleWare* const mw) noexcept + { + middleware = mw; + } + + private: + const bool wasRunning; + MiddleWareThread& thread; + MiddleWare* middleware; + + DISTRHO_PREVENT_HEAP_ALLOCATION + DISTRHO_DECLARE_NON_COPY_CLASS(ScopedStopper) + }; + + MiddleWareThread() + : Thread("ZynMiddleWare"), + middleware(nullptr) {} + + void start(MiddleWare* const mw) noexcept + { + middleware = mw; + startThread(); + } + + void stop() noexcept + { + stopThread(1000); + middleware = nullptr; + } + +protected: + void run() noexcept override + { + for (; ! shouldThreadExit();) + { + try { + middleware->tick(); + } catch(...) {} + + d_msleep(1); + } + } + +private: + MiddleWare* middleware; + + DISTRHO_DECLARE_NON_COPY_CLASS(MiddleWareThread) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * ZynAddSubFX plugin class */ + +class ZynAddSubFX : public Plugin +{ +public: + ZynAddSubFX() + : Plugin(kParamCount, 1, 1), // 1 program, 1 state + master(nullptr), + middleware(nullptr), + defaultState(nullptr), + oscPort(0), + middlewareThread(new MiddleWareThread()) + { + config.init(); + + synth.buffersize = static_cast<int>(getBufferSize()); + synth.samplerate = static_cast<uint>(getSampleRate()); + + if (synth.buffersize > 32) + synth.buffersize = 32; + + synth.alias(); + + _initMaster(); + + defaultState = _getState(); + + middlewareThread->start(middleware); + } + + ~ZynAddSubFX() override + { + middlewareThread->stop(); + _deleteMaster(); + std::free(defaultState); + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. + */ + const char* getLabel() const noexcept override + { + return "ZynAddSubFX"; + } + + /** + Get an extensive comment/description about the plugin. + */ + const char* getDescription() const noexcept override + { + // TODO + return ""; + } + + /** + Get the plugin author/maker. + */ + const char* getMaker() const noexcept override + { + return "ZynAddSubFX Team"; + } + + /** + Get the plugin homepage. + Optional, returns nothing by default. + */ + const char* getHomePage() const noexcept override + { + return "http://zynaddsubfx.sourceforge.net"; + } + + /** + Get the plugin license (a single line of text or a URL). + */ + const char* getLicense() const noexcept override + { + return "GPL v2"; + } + + /** + Get the plugin version, in hexadecimal. + */ + uint32_t getVersion() const noexcept override + { + // TODO: use config.h or globals.h + return d_version(2, 5, 3); + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t getUniqueId() const noexcept override + { + return d_cconst('Z', 'A', 'S', 'F'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Parameters, empty for now */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void initParameter(uint32_t index, Parameter& parameter) noexcept override + { + switch (index) + { + case kParamOscPort: + parameter.hints = kParameterIsOutput; + parameter.name = "OSC Port"; + parameter.symbol = "osc_port"; + parameter.unit = ""; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 999999.0f; + parameter.ranges.def = 0.0f; + break; + } + } + + /** + Get the current value of a parameter. + The host may call this function from any context, including realtime processing. + */ + float getParameterValue(uint32_t index) const noexcept override + { + switch (index) + { + case kParamOscPort: + return oscPort; + default: + return 0.0f; + } + } + + /** + Change a parameter value. + The host may call this function from any context, including realtime processing. + When a parameter is marked as automable, you must ensure no non-realtime operations are performed. + @note This function will only be called for parameter inputs. + */ + void setParameterValue(uint32_t /*index*/, float /*value*/) noexcept override + { + // only an output port for now + } + + /* -------------------------------------------------------------------------------------------------------- + * Programs */ + + /** + Set the name of the program @a index. + This function will be called once, shortly after the plugin is created. + */ + void initProgramName(uint32_t index, String& programName) override + { + programName = "Default"; + } + + /** + Load a program. + The host may call this function from any context, including realtime processing. + */ + void loadProgram(uint32_t index) override + { + setState(nullptr, defaultState); + } + + /* -------------------------------------------------------------------------------------------------------- + * States */ + + /** + Set the state key and default value of @a index. + This function will be called once, shortly after the plugin is created. + */ + void initState(uint32_t, String& stateKey, String& defaultStateValue) override + { + stateKey = "state"; + defaultStateValue = defaultState; + } + + /** + Get the value of an internal state. + The host may call this function from any non-realtime context. + */ + String getState(const char*) const override + { + return String(_getState(), false); + } + + /** + Change an internal state @a key to @a value. + */ + void setState(const char* key, const char* value) override + { + const MiddleWareThread::ScopedStopper mwss(*middlewareThread); + const MutexLocker cml(mutex); + + master->defaults(); + master->putalldata(value); + master->applyparameters(); + master->initialize_rt(); + + middleware->updateResources(master); + } + + /* -------------------------------------------------------------------------------------------------------- + * Audio/MIDI Processing */ + + /** + Run/process function for plugins with MIDI input. + @note Some parameters might be null if there are no audio inputs/outputs or MIDI events. + */ + void run(const float**, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount) override + { + if (! mutex.tryLock()) + { + //if (! isOffline()) + { + std::memset(outputs[0], 0, frames); + std::memset(outputs[1], 0, frames); + return; + } + + mutex.lock(); + } + + uint32_t framesOffset = 0; + + for (uint32_t i=0; i<midiEventCount; ++i) + { + const MidiEvent& midiEvent(midiEvents[i]); + + if (midiEvent.frame >= frames) + continue; + if (midiEvent.size > MidiEvent::kDataSize) + continue; + if (midiEvent.data[0] < 0x80 || midiEvent.data[0] >= 0xF0) + continue; + + if (midiEvent.frame > framesOffset) + { + master->GetAudioOutSamples(midiEvent.frame-framesOffset, synth.samplerate, outputs[0]+framesOffset, + outputs[1]+framesOffset); + framesOffset = midiEvent.frame; + } + + const uint8_t status = midiEvent.data[0] & 0xF0; + const char channel = midiEvent.data[0] & 0x0F; + + switch (status) + { + case 0x80: { + const char note = static_cast<char>(midiEvent.data[1]); + + master->noteOff(channel, note); + } break; + + case 0x90: { + const char note = static_cast<char>(midiEvent.data[1]); + const char velo = static_cast<char>(midiEvent.data[2]); + + master->noteOn(channel, note, velo); + } break; + + case 0xA0: { + const char note = static_cast<char>(midiEvent.data[1]); + const char pressure = static_cast<char>(midiEvent.data[2]); + + master->polyphonicAftertouch(channel, note, pressure); + } break; + + case 0xB0: { + const int control = midiEvent.data[1]; + const int value = midiEvent.data[2]; + + // skip controls which we map to parameters + //if (getIndexFromZynControl(midiEvent.data[1]) != kParamCount) + // continue; + + master->setController(channel, control, value); + } break; + + case 0xE0: { + const uint8_t lsb = midiEvent.data[1]; + const uint8_t msb = midiEvent.data[2]; + const int value = ((msb << 7) | lsb) - 8192; + + master->setController(channel, C_pitchwheel, value); + } break; + } + } + + if (frames > framesOffset) + master->GetAudioOutSamples(frames-framesOffset, synth.samplerate, outputs[0]+framesOffset, + outputs[1]+framesOffset); + + mutex.unlock(); + } + + /* -------------------------------------------------------------------------------------------------------- + * Callbacks */ + + /** + Callback to inform the plugin about a buffer size change. + This function will only be called when the plugin is deactivated. + @note This value is only a hint! + Hosts might call run() with a higher or lower number of frames. + */ + void bufferSizeChanged(uint32_t newBufferSize) override + { + MiddleWareThread::ScopedStopper mwss(*middlewareThread); + + char* const state(_getState()); + + _deleteMaster(); + + synth.buffersize = static_cast<int>(newBufferSize); + + if (synth.buffersize > 32) + synth.buffersize = 32; + + synth.alias(); + + _initMaster(); + mwss.updateMiddleWare(middleware); + + setState(nullptr, state); + std::free(state); + } + + /** + Callback to inform the plugin about a sample rate change. + This function will only be called when the plugin is deactivated. + */ + void sampleRateChanged(double newSampleRate) override + { + MiddleWareThread::ScopedStopper mwss(*middlewareThread); + + char* const state(_getState()); + + _deleteMaster(); + + synth.samplerate = static_cast<uint>(newSampleRate); + synth.alias(); + + _initMaster(); + mwss.updateMiddleWare(middleware); + + setState(nullptr, state); + std::free(state); + } + +private: + Config config; + Master* master; + MiddleWare* middleware; + SYNTH_T synth; + + Mutex mutex; + char* defaultState; + int oscPort; + + ScopedPointer<MiddleWareThread> middlewareThread; + + char* _getState() const + { + const MiddleWareThread::ScopedStopper mwss(*middlewareThread); + + char* data = nullptr; + master->getalldata(&data); + return data; + } + + void _initMaster() + { + middleware = new MiddleWare(std::move(synth), &config); + middleware->setUiCallback(__uiCallback, this); + middleware->setIdleCallback(__idleCallback, this); + _masterChangedCallback(middleware->spawnMaster()); + + if (char* url = lo_url_get_port(middleware->getServerAddress())) + { + oscPort = std::atoi(url); + std::free(url); + } + else + { + oscPort = 0; + } + } + + void _deleteMaster() + { + master = nullptr; + delete middleware; + middleware = nullptr; + } + + /* -------------------------------------------------------------------------------------------------------- + * ZynAddSubFX Callbacks */ + + void _masterChangedCallback(Master* m) + { + master = m; + master->setMasterChangedCallback(__masterChangedCallback, this); + } + + static void __masterChangedCallback(void* ptr, Master* m) + { + ((ZynAddSubFX*)ptr)->_masterChangedCallback(m); + } + + /* -------------------------------------------------------------------------------------------------------- */ + + void _uiCallback(const char* const) + { + // this can be used to receive messages from UI + // to be handled soon for parameters + } + + static void __uiCallback(void* ptr, const char* msg) + { + ((ZynAddSubFX*)ptr)->_uiCallback(msg); + } + + /* -------------------------------------------------------------------------------------------------------- */ + + void _idleCallback() + { + // this can be used to give host idle time + // for now LV2 doesn't support this, and only some VST hosts support it + } + + static void __idleCallback(void* ptr) + { + ((ZynAddSubFX*)ptr)->_idleCallback(); + } + + DISTRHO_DECLARE_NON_COPY_CLASS(ZynAddSubFX) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Create plugin, entry point */ + +START_NAMESPACE_DISTRHO + +Plugin* createPlugin() +{ + ::isPlugin = true; + return new ZynAddSubFX(); +} + +END_NAMESPACE_DISTRHO + +/* ------------------------------------------------------------------------------------------------------------ + * Dummy variables and functions for linking purposes */ + +class WavFile; +namespace Nio { + void masterSwap(Master*){} + bool setSource(std::string){return true;} + bool setSink(std::string){return true;} + std::set<std::string> getSources(void){return std::set<std::string>();} + std::set<std::string> getSinks(void){return std::set<std::string>();} + std::string getSource(void){return "";} + std::string getSink(void){return "";} + void waveNew(WavFile*){} + void waveStart(){} + void waveStop(){} +} diff --git a/src/UI/ConfigUI.fl b/src/UI/ConfigUI.fl @@ -68,7 +68,7 @@ class ConfigUI {} { Fl_Tabs {} { xywh {5 5 500 330} } { - Fl_Group {} { + Fl_Group mainsettings { label {Main settings} xywh {5 25 500 310} } { @@ -317,6 +317,9 @@ activatebutton_presetdir(true);} } Function {show()} {} { code { +if (isPlugin) { + mainsettings->deactivate(); +} rootsbrowse->update(); presetbrowse->update(); configwindow->show(); diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl @@ -238,13 +238,9 @@ class MasterUI {open } { Fl_Window masterwindow { label zynaddsubfx - callback {if (( -\#ifdef PLUGINVERSION -1 -\#elif USE_NSM -(nsm && nsm->is_active()) -\#else -0 + callback {if ((isPlugin +\#if USE_NSM + || (nsm && nsm->is_active()) \#endif || fl_choice("Exit and leave the unsaved data?","No","Yes",NULL))) { close(); @@ -957,9 +953,8 @@ updatepanel();} } Fl_Window simplemasterwindow { label ZynAddSubFX - callback {\#ifndef PLUGINVERSION -if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) -\#endif + callback { +if (isPlugin || fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { *exitprogram=1; };} open diff --git a/src/UI/guimain.cpp b/src/UI/guimain.cpp @@ -31,7 +31,8 @@ #include <sys/stat.h> GUI::ui_handle_t gui = 0; #if USE_NSM -NSM_Client *nsm = 0; +NSM_Client *nsm = NULL; +const char *embedId = NULL; #endif lo_server server; std::string sendtourl; @@ -75,6 +76,7 @@ int Pexitprogram = 0; #include <FL/Fl_Shared_Image.H> #include <FL/Fl_Tiled_Image.H> #include <FL/Fl_Dial.H> +#include <FL/x.H> #include <err.h> #endif // NTK_GUI @@ -84,6 +86,7 @@ int Pexitprogram = 0; using namespace GUI; class MasterUI *ui=0; +bool isPlugin = false; #ifdef NTK_GUI static Fl_Tiled_Image *module_backdrop; @@ -187,7 +190,26 @@ ui_handle_t GUI::createUi(Fl_Osc_Interface *osc, void *exit) //midi_win->show(); Fl::add_handler(kb_shortcut_handler); - return (void*) (ui = new MasterUI((int*)exit, osc)); + + ui = new MasterUI((int*)exit, osc); + +#ifdef NTK_GUI + if (embedId != NULL) + { + if (long long winId = atoll(embedId)) + { + // running embed as plugin + isPlugin = true; + MasterUI::menu_mastermenu[11].hide(); // file -> nio settings + MasterUI::menu_mastermenu[13].hide(); // file -> exit + MasterUI::menu_mastermenu[26].deactivate(); // misc -> switch interface mode + fl_embed(ui->masterwindow, winId); + ui->masterwindow->show(); + } + } +#endif + + return (void*) ui; } void GUI::destroyUi(ui_handle_t ui) { @@ -571,6 +593,10 @@ int main(int argc, char *argv[]) help = true; else if(!strcmp("--no-uri", argv[i])) no_uri = true; +#if USE_NSM + else if(!strcmp("--embed", argv[i])) + embedId = argv[++i]; +#endif else uri = argv[i]; } @@ -586,7 +612,7 @@ int main(int argc, char *argv[]) if(uri) { server = lo_server_new_with_proto(NULL, LO_UDP, liblo_error_cb); lo_server_add_method(server, NULL, NULL, handler_function, 0); - sendtourl = argv[1]; + sendtourl = uri; } fprintf(stderr, "ext client running on %d\n", lo_server_get_port(server)); std::thread lo_watch(watch_lo);