| @@ -11,11 +11,6 @@ PREFIX ?= /usr/local | |||
| DESTDIR ?= | |||
| SYSDEPS ?= false | |||
| # -------------------------------------------------------------- | |||
| # List of modules to build, based on their C++ model name | |||
| MODULES += SpringReverb | |||
| # -------------------------------------------------------------- | |||
| # Import base definitions | |||
| @@ -27,6 +22,9 @@ include ../dpf/Makefile.base.mk | |||
| BUILD_DIR = ../build/lv2export | |||
| # BASE_FLAGS += -DHEADLESS | |||
| BASE_FLAGS += -DPRIVATE= | |||
| ifeq ($(MACOS),true) | |||
| BASE_FLAGS += -DARCH_MAC | |||
| else ifeq ($(WINDOWS),true) | |||
| @@ -42,8 +40,10 @@ BASE_FLAGS += -I../include | |||
| BASE_FLAGS += -I../include/neon-compat | |||
| BASE_FLAGS += -I../src/Rack/include | |||
| ifeq ($(SYSDEPS),true) | |||
| BASE_FLAGS += -DCARDINAL_SYSDEPS | |||
| BASE_FLAGS += $(shell pkg-config --cflags jansson libarchive samplerate speexdsp) | |||
| else | |||
| BASE_FLAGS += -DZSTDLIB_VISIBILITY= | |||
| BASE_FLAGS += -I../src/Rack/dep/include | |||
| endif | |||
| BASE_FLAGS += -I../src/Rack/dep/filesystem/include | |||
| @@ -62,20 +62,18 @@ BASE_FLAGS += -I../include/mingw-compat | |||
| BASE_FLAGS += -I../include/mingw-std-threads | |||
| endif | |||
| ifeq ($(HEADLESS),true) | |||
| BASE_FLAGS += -DHEADLESS | |||
| endif | |||
| ifeq ($(WITH_LTO),true) | |||
| BASE_FLAGS += -fno-strict-aliasing -flto | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| # FIXME lots of warnings from VCV side | |||
| # lots of warnings from VCV side | |||
| BASE_FLAGS += -Wno-unused-but-set-variable | |||
| BASE_FLAGS += -Wno-unused-parameter | |||
| BASE_FLAGS += -Wno-unused-result | |||
| BASE_FLAGS += -Wno-unused-variable | |||
| ifeq ($(MACOS),true) | |||
| BASE_FLAGS += -Wno-unknown-warning-option | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| # extra linker flags | |||
| @@ -98,16 +96,11 @@ ifeq ($(SYSDEPS),true) | |||
| EXTRA_LIBS += $(shell pkg-config --libs jansson libarchive samplerate speexdsp) | |||
| endif | |||
| ifeq ($(WITH_LTO),true) | |||
| LINK_FLAGS += -fno-strict-aliasing -flto -Werror=odr -Werror=lto-type-mismatch | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| # Build targets | |||
| # Build files | |||
| BUILD_FILES = lv2plugin.cpp | |||
| BUILD_FILES += test.cpp | |||
| BUILD_FILES += dep.cpp | |||
| # BUILD_FILES += test.cpp | |||
| BUILD_FILES = dep.cpp | |||
| BUILD_FILES += dep2.cpp | |||
| BUILD_FILES += ../src/Rack/src/logger.cpp | |||
| BUILD_FILES += ../src/Rack/src/random.cpp | |||
| @@ -118,14 +111,11 @@ BUILD_FILES += ../src/Rack/src/Quantity.cpp | |||
| BUILD_FILES += ../src/Rack/src/engine/Module.cpp | |||
| BUILD_FILES += ../src/Rack/src/engine/ParamQuantity.cpp | |||
| BUILD_FILES += ../src/Rack/src/engine/PortInfo.cpp | |||
| ifneq ($(SYSDEPS),true) | |||
| BUILD_FILES += ../src/Rack/dep/pffft/pffft.c | |||
| BUILD_FILES += ../src/Rack/dep/pffft/fftpack.c | |||
| endif | |||
| TARGETS = test$(APP_EXT) lv2plugin$(LIB_EXT) | |||
| all: $(TARGETS) | |||
| BUILD_OBJS = $(BUILD_FILES:%=$(BUILD_DIR)/%.o) | |||
| BUILD_OBJS += $(BUILD_DIR)/lv2plugin/chowdsp-chorus.o | |||
| EXTRA_LIBS = ../plugins/plugins.a | |||
| @@ -142,18 +132,23 @@ EXTRA_LIBS += ../src/Rack/dep/lib/libzstd.a | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| # Build commands | |||
| # Build targets | |||
| TARGETS = ../bin/CardinalModules.lv2/manifest.ttl | |||
| TARGETS += ../bin/CardinalModules.lv2/plugins$(LIB_EXT) | |||
| # OBJS = $(BUILD_FILES:%=$(BUILD_DIR)/%.o) | |||
| all: $(TARGETS) | |||
| FILES1 = $(filter-out lv2plugin.cpp,$(BUILD_FILES)) | |||
| FILES2 = $(filter-out test.cpp,$(BUILD_FILES)) | |||
| # -------------------------------------------------------------- | |||
| # Build commands | |||
| test$(APP_EXT): $(FILES1:%=$(BUILD_DIR)/%.o) | |||
| ../bin/CardinalModules.lv2/manifest.ttl: manifest.ttl.in | |||
| -@mkdir -p $(shell dirname $@) | |||
| $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) -o $@ | |||
| sed -e "s/@LIB_EXT@/$(LIB_EXT)/" $< > $@ | |||
| # FIXME wildcard install | |||
| install -m 644 lv2ttl/* ../bin/CardinalModules.lv2/ | |||
| lv2plugin$(LIB_EXT): $(FILES2:%=$(BUILD_DIR)/%.o) | |||
| ../bin/CardinalModules.lv2/plugins$(LIB_EXT): $(BUILD_OBJS) | |||
| -@mkdir -p $(shell dirname $@) | |||
| $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(SHARED) -o $@ | |||
| @@ -166,3 +161,11 @@ $(BUILD_DIR)/%.cpp.o: %.cpp | |||
| -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" | |||
| @echo "Compiling $<" | |||
| $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| $(BUILD_DIR)/lv2plugin/chowdsp-chorus.o: lv2plugin.cpp | |||
| -@mkdir -p "$(shell dirname $@)" | |||
| @echo "Compiling $< (ChowDSP Chorus)" | |||
| $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -UPRIVATE -c -o $@ \ | |||
| -DPLUGIN_INSTANCE=pluginInstance__ChowDSP \ | |||
| -DPLUGIN_MODEL=modelChowChorus \ | |||
| -DPLUGIN_URI='"modelChowChorus"' | |||
| @@ -16,9 +16,48 @@ | |||
| */ | |||
| #include <rack.hpp> | |||
| #include <context.hpp> | |||
| using namespace rack; | |||
| namespace rack { | |||
| namespace settings { | |||
| bool cpuMeter = false; | |||
| } | |||
| Context::~Context() { | |||
| } | |||
| static thread_local Context* threadContext; | |||
| Context* contextGet() { | |||
| DISTRHO_SAFE_ASSERT(threadContext != nullptr); | |||
| return threadContext; | |||
| } | |||
| // Apple's clang incorrectly compiles this function when -O2 or higher is enabled. | |||
| #ifdef ARCH_MAC | |||
| __attribute__((optnone)) | |||
| #endif | |||
| void contextSet(Context* const context) { | |||
| // DISTRHO_SAFE_ASSERT(threadContext == nullptr); | |||
| threadContext = context; | |||
| } | |||
| Exception::Exception(const char* format, ...) | |||
| { | |||
| va_list args; | |||
| va_start(args, format); | |||
| msg = string::fV(format, args); | |||
| va_end(args); | |||
| } | |||
| namespace asset { | |||
| std::string plugin(plugin::Plugin* plugin, std::string filename) { return {}; } | |||
| std::string system(std::string filename) { return {}; } | |||
| } | |||
| namespace engine { | |||
| float Engine::getParamValue(Module* module, int paramId) { return 0.0f; } | |||
| float Engine::getParamSmoothValue(Module* module, int paramId) { return 0.0f; } | |||
| void Engine::setParamValue(Module* module, int paramId, float value) {} | |||
| void Engine::setParamSmoothValue(Module* module, int paramId, float value) {} | |||
| } | |||
| } | |||
| namespace rack { | |||
| namespace app { | |||
| @@ -15,54 +15,33 @@ | |||
| * For a full copy of the GNU General Public License see the LICENSE file. | |||
| */ | |||
| #ifndef PLUGIN_INSTANCE | |||
| # error PLUGIN_INSTANCE undefined | |||
| #endif | |||
| #ifndef PLUGIN_MODEL | |||
| # error PLUGIN_MODEL undefined | |||
| #endif | |||
| #ifndef PLUGIN_URI | |||
| # error PLUGIN_URI undefined | |||
| #endif | |||
| #undef PRIVATE | |||
| // #include <common.hpp> | |||
| #include <rack.hpp> | |||
| #include "src/lv2/buf-size.h" | |||
| #include "src/lv2/options.h" | |||
| #include <rack.hpp> | |||
| #include <context.hpp> | |||
| #include "DistrhoUtils.hpp" | |||
| using namespace rack; | |||
| extern Model* modelSpringReverb; | |||
| Plugin* pluginInstance__Befaco; | |||
| extern Model* PLUGIN_MODEL; | |||
| Plugin* PLUGIN_INSTANCE; | |||
| namespace rack { | |||
| namespace settings { | |||
| bool cpuMeter = false; | |||
| } | |||
| Context::~Context() { | |||
| } | |||
| static thread_local Context* threadContext; | |||
| Context* contextGet() { | |||
| DISTRHO_SAFE_ASSERT(threadContext != nullptr); | |||
| return threadContext; | |||
| } | |||
| // Apple's clang incorrectly compiles this function when -O2 or higher is enabled. | |||
| #ifdef ARCH_MAC | |||
| __attribute__((optnone)) | |||
| #endif | |||
| void contextSet(Context* const context) { | |||
| // DISTRHO_SAFE_ASSERT(threadContext == nullptr); | |||
| threadContext = context; | |||
| } | |||
| Exception::Exception(const char* format, ...) | |||
| { | |||
| va_list args; | |||
| va_start(args, format); | |||
| msg = string::fV(format, args); | |||
| va_end(args); | |||
| } | |||
| namespace asset { | |||
| std::string plugin(plugin::Plugin* plugin, std::string filename) { return {}; } | |||
| std::string system(std::string filename) { return {}; } | |||
| } | |||
| namespace engine { | |||
| float Engine::getParamValue(Module* module, int paramId) { return 0.0f; } | |||
| float Engine::getParamSmoothValue(Module* module, int paramId) { return 0.0f; } | |||
| void Engine::setParamValue(Module* module, int paramId, float value) {} | |||
| void Engine::setParamSmoothValue(Module* module, int paramId, float value) {} | |||
| } | |||
| namespace plugin { | |||
| void Plugin::addModel(Model* model) | |||
| { | |||
| @@ -84,25 +63,39 @@ struct PluginLv2 { | |||
| engine::Module* module; | |||
| float sampleRate; | |||
| int frameCount = 0; | |||
| void* ports[11]; | |||
| int numInputs, numOutputs, numParams, numLights; | |||
| void** ports; | |||
| PluginLv2(double sr) | |||
| { | |||
| sampleRate = sr; | |||
| // FIXME shared instance for these 2 | |||
| plugin = new Plugin; | |||
| pluginInstance__Befaco = plugin; | |||
| plugin->addModel(modelSpringReverb); | |||
| module = modelSpringReverb->createModule(); | |||
| // FIXME we need to detect if something is connected | |||
| // module->inputs[0].channels = 1; | |||
| // module->inputs[1].channels = 1; | |||
| module->inputs[2].channels = 1; | |||
| module->inputs[3].channels = 1; | |||
| module->inputs[4].channels = 1; | |||
| module->outputs[0].channels = 1; | |||
| module->outputs[1].channels = 1; | |||
| PLUGIN_INSTANCE = plugin; | |||
| sampleRate = sr; | |||
| plugin->addModel(PLUGIN_MODEL); | |||
| module = PLUGIN_MODEL->createModule(); | |||
| numInputs = module->getNumInputs(); | |||
| numOutputs = module->getNumOutputs(); | |||
| numParams = module->getNumParams(); | |||
| numLights = module->getNumLights(); | |||
| ports = new void*[numInputs+numOutputs+numParams+numLights]; | |||
| // FIXME for CV ports we need to detect if something is connected | |||
| for (int i=numInputs; --i >=0;) | |||
| module->inputs[i].channels = 1; | |||
| for (int i=numOutputs; --i >=0;) | |||
| module->outputs[i].channels = 1; | |||
| } | |||
| PluginLv2() | |||
| { | |||
| delete[] ports; | |||
| delete module; | |||
| // FIXME shared instance for this | |||
| delete plugin; | |||
| } | |||
| void lv2_connect_port(const uint32_t port, void* const dataLocation) | |||
| @@ -110,6 +103,11 @@ struct PluginLv2 { | |||
| ports[port] = dataLocation; | |||
| } | |||
| void lv2_activate() | |||
| { | |||
| module->onReset(); | |||
| } | |||
| void lv2_run(const uint32_t sampleCount) | |||
| { | |||
| if (sampleCount == 0) | |||
| @@ -121,40 +119,24 @@ struct PluginLv2 { | |||
| frameCount | |||
| }; | |||
| // const float* CV1_INPUT = (float*)ports[0]; | |||
| // const float* CV2_INPUT = (float*)ports[1]; | |||
| const float* IN1_INPUT = (float*)ports[2]; | |||
| const float* IN2_INPUT = (float*)ports[3]; | |||
| const float* MIX_CV_INPUT = (float*)ports[4]; | |||
| float* MIX_OUTPUT = (float*)ports[5]; | |||
| float* WET_OUTPUT = (float*)ports[6]; | |||
| const float drywet = *(float*)ports[7] * 0.01f; | |||
| const float lvl1 = *(float*)ports[8] * 0.01f; | |||
| const float lvl2 = *(float*)ports[9] * 0.01f; | |||
| const float hpf = *(float*)ports[10]; | |||
| module->params[0].setValue(drywet); | |||
| module->params[1].setValue(lvl1); | |||
| module->params[2].setValue(lvl2); | |||
| module->params[3].setValue(hpf); | |||
| for (uint32_t i=0; i<sampleCount; ++i) | |||
| for (int i=numParams; --i >=0;) | |||
| module->params[i].setValue(*static_cast<float*>(ports[numInputs+numOutputs+i])); | |||
| for (uint32_t s=0; s<sampleCount; ++s) | |||
| { | |||
| // module->inputs[0].setVoltage(CV1_INPUT[i]); | |||
| // module->inputs[1].setVoltage(CV2_INPUT[i]); | |||
| module->inputs[2].setVoltage(IN1_INPUT[i] * 10); | |||
| module->inputs[3].setVoltage(IN2_INPUT[i] * 10); | |||
| module->inputs[4].setVoltage(MIX_CV_INPUT[i]); | |||
| for (int i=numInputs; --i >=0;) | |||
| module->inputs[i].setVoltage(static_cast<float*>(ports[i])[s] * 10.0f); | |||
| module->doProcess(args); | |||
| MIX_OUTPUT[i] = module->outputs[0].getVoltage() * 0.1f; | |||
| WET_OUTPUT[i] = module->outputs[1].getVoltage() * 0.1f; | |||
| for (int i=numOutputs; --i >=0;) | |||
| static_cast<float*>(ports[numInputs+i])[s] = module->outputs[i].getVoltage() * 0.1f; | |||
| ++args.frame; | |||
| } | |||
| frameCount += sampleCount; | |||
| } | |||
| }; | |||
| static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, const char* bundlePath, const LV2_Feature* const* features) | |||
| @@ -173,6 +155,7 @@ static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocat | |||
| static void lv2_activate(LV2_Handle instance) | |||
| { | |||
| instancePtr->lv2_activate(); | |||
| } | |||
| static void lv2_run(LV2_Handle instance, uint32_t sampleCount) | |||
| @@ -201,7 +184,7 @@ static const void* lv2_extension_data(const char* uri) | |||
| // ----------------------------------------------------------------------- | |||
| static const LV2_Descriptor sLv2Descriptor = { | |||
| "urn:Cardinal:Befaco", | |||
| PLUGIN_URI, | |||
| lv2_instantiate, | |||
| lv2_connect_port, | |||
| lv2_activate, | |||
| @@ -0,0 +1,64 @@ | |||
| @prefix doap: <http://usefulinc.com/ns/doap#> . | |||
| @prefix foaf: <http://xmlns.com/foaf/0.1/> . | |||
| @prefix lv2: <http://lv2plug.in/ns/lv2core#> . | |||
| @prefix mod: <http://moddevices.com/ns/mod#> . | |||
| @prefix unit: <http://lv2plug.in/ns/extensions/units#> . | |||
| <urn:cardinal:chow:chorus> | |||
| a lv2:Plugin, doap:Project ; | |||
| lv2:port [ | |||
| a lv2:InputPort, lv2:AudioPort ; | |||
| lv2:index 0 ; | |||
| lv2:symbol "in" ; | |||
| lv2:name "Input" ; | |||
| ] , [ | |||
| a lv2:OutputPort, lv2:AudioPort ; | |||
| lv2:index 1 ; | |||
| lv2:symbol "left_out" ; | |||
| lv2:name "Left output" ; | |||
| ] , [ | |||
| a lv2:OutputPort, lv2:AudioPort ; | |||
| lv2:index 2 ; | |||
| lv2:symbol "right_out" ; | |||
| lv2:name "Right output" ; | |||
| ] , [ | |||
| a lv2:InputPort, lv2:ControlPort ; | |||
| lv2:index 3 ; | |||
| lv2:name "Rate" ; | |||
| lv2:symbol "rate" ; | |||
| lv2:default 50 ; | |||
| lv2:minimum 0 ; | |||
| lv2:maximum 100 ; | |||
| unit:unit unit:pc; | |||
| ] , [ | |||
| a lv2:InputPort, lv2:ControlPort ; | |||
| lv2:index 4 ; | |||
| lv2:name "Depth" ; | |||
| lv2:symbol "depth" ; | |||
| lv2:default 50 ; | |||
| lv2:minimum 0 ; | |||
| lv2:maximum 100 ; | |||
| unit:unit unit:pc; | |||
| ] , [ | |||
| a lv2:InputPort, lv2:ControlPort ; | |||
| lv2:index 5 ; | |||
| lv2:name "Feedback" ; | |||
| lv2:symbol "Feedback" ; | |||
| lv2:default 0 ; | |||
| lv2:minimum 0 ; | |||
| lv2:maximum 100 ; | |||
| unit:unit unit:pc; | |||
| ] , [ | |||
| a lv2:InputPort, lv2:ControlPort ; | |||
| lv2:index 6 ; | |||
| lv2:name "Mix" ; | |||
| lv2:symbol "mix" ; | |||
| lv2:default 50 ; | |||
| lv2:minimum 0 ; | |||
| lv2:maximum 100 ; | |||
| unit:unit unit:pc; | |||
| ] ; | |||
| mod:brand "ChowDSP" ; | |||
| doap:name "ChowChorus" . | |||
| @@ -1,7 +1,7 @@ | |||
| @prefix lv2: <http://lv2plug.in/ns/lv2core#> . | |||
| @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |||
| <urn:Cardinal:Befaco> | |||
| <urn:cardinal:chow:chorus> | |||
| a lv2:Plugin ; | |||
| lv2:binary <lv2plugin.dylib> ; | |||
| rdfs:seeAlso <lv2plugin.ttl> . | |||
| lv2:binary <plugins.dylib> ; | |||
| rdfs:seeAlso <chow-chorus.ttl> . | |||