From e768dbd0e666c9c561b07508ba57acc330a8dda5 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 19 Jun 2022 10:18:51 +0100 Subject: [PATCH] Start work on CardinalRemote, WIP Signed-off-by: falkTX --- src/CardinalRemote/CardinalCommon.cpp | 1 + src/CardinalRemote/DistrhoPluginInfo.h | 1 + src/CardinalRemote/Makefile | 292 +++++++++++++++++++++++++ src/CardinalRemote/RemoteUI.cpp | 91 ++++++++ src/CardinalRemote/RemoteUI.hpp | 36 +++ src/CardinalRemote/Window.cpp | 1 + src/CardinalRemote/common.cpp | 1 + src/CardinalRemote/glfw.cpp | 1 + src/CardinalRemote/main.cpp | 160 ++++++++++++++ 9 files changed, 584 insertions(+) create mode 120000 src/CardinalRemote/CardinalCommon.cpp create mode 120000 src/CardinalRemote/DistrhoPluginInfo.h create mode 100644 src/CardinalRemote/Makefile create mode 100644 src/CardinalRemote/RemoteUI.cpp create mode 100644 src/CardinalRemote/RemoteUI.hpp create mode 120000 src/CardinalRemote/Window.cpp create mode 120000 src/CardinalRemote/common.cpp create mode 120000 src/CardinalRemote/glfw.cpp create mode 100644 src/CardinalRemote/main.cpp diff --git a/src/CardinalRemote/CardinalCommon.cpp b/src/CardinalRemote/CardinalCommon.cpp new file mode 120000 index 0000000..76b4b5f --- /dev/null +++ b/src/CardinalRemote/CardinalCommon.cpp @@ -0,0 +1 @@ +../CardinalCommon.cpp \ No newline at end of file diff --git a/src/CardinalRemote/DistrhoPluginInfo.h b/src/CardinalRemote/DistrhoPluginInfo.h new file mode 120000 index 0000000..8c39022 --- /dev/null +++ b/src/CardinalRemote/DistrhoPluginInfo.h @@ -0,0 +1 @@ +../Cardinal/DistrhoPluginInfo.h \ No newline at end of file diff --git a/src/CardinalRemote/Makefile b/src/CardinalRemote/Makefile new file mode 100644 index 0000000..8c0666f --- /dev/null +++ b/src/CardinalRemote/Makefile @@ -0,0 +1,292 @@ +#!/usr/bin/make -f +# Makefile for DISTRHO Plugins # +# ---------------------------- # +# Created by falkTX +# + +# -------------------------------------------------------------- +# Carla stuff + +CWD = ../../carla/source +STATIC_PLUGIN_TARGET = true +include $(CWD)/Makefile.deps.mk + +CARLA_BUILD_DIR = ../../carla/build +ifeq ($(DEBUG),true) +CARLA_BUILD_TYPE = Debug +else +CARLA_BUILD_TYPE = Release +endif + +CARLA_EXTRA_LIBS = $(CARLA_BUILD_DIR)/plugin/$(CARLA_BUILD_TYPE)/carla-host-plugin.cpp.o +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_engine_plugin.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_plugin.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/native-plugins.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/audio_decoder.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/jackbridge.min.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/lilv.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/rtmempool.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/sfzero.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/water.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/ysfx.a +CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/zita-resampler.a + +# -------------------------------------------------------------- +# Import base definitions + +USE_NANOVG_FBO = true +include ../../dpf/Makefile.base.mk + +# -------------------------------------------------------------- +# Build config + +PREFIX ?= /usr/local + +ifeq ($(BSD),true) +SYSDEPS ?= true +else +SYSDEPS ?= false +endif + +ifeq ($(SYSDEPS),true) +DEP_LIB_PATH = $(abspath ../../deps/sysroot/lib) +else +DEP_LIB_PATH = $(abspath ../Rack/dep/lib) +endif + +# -------------------------------------------------------------- +# Extra libraries to link against + +RACK_EXTRA_LIBS = ../../plugins/plugins.a +RACK_EXTRA_LIBS += ../rack.a +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libquickjs.a + +ifneq ($(SYSDEPS),true) +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libjansson.a +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libsamplerate.a +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libspeexdsp.a +ifeq ($(WINDOWS),true) +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libarchive_static.a +else +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libarchive.a +endif +RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libzstd.a +endif + +# -------------------------------------------------------------- + +EXTRA_DEPENDENCIES = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) +EXTRA_LIBS = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) $(STATIC_CARLA_PLUGIN_LIBS) + +ifeq ($(shell pkg-config --exists fftw3f && echo true),true) +EXTRA_DEPENDENCIES += ../../deps/aubio/libaubio.a +EXTRA_LIBS += ../../deps/aubio/libaubio.a +EXTRA_LIBS += $(shell $(PKG_CONFIG) --libs fftw3f) +endif + +# -------------------------------------------------------------- +# Extra flags for liblo + +BASE_FLAGS += -DHAVE_LIBLO +BASE_FLAGS += $(LIBLO_FLAGS) +LINK_FLAGS += $(LIBLO_LIBS) + +# -------------------------------------------------------------- +# Extra flags for VCV stuff + +ifeq ($(MACOS),true) +BASE_FLAGS += -DARCH_MAC +else ifeq ($(WINDOWS),true) +BASE_FLAGS += -DARCH_WIN +else +BASE_FLAGS += -DARCH_LIN +endif + +BASE_FLAGS += -DPRIVATE= +BASE_FLAGS += -I.. +BASE_FLAGS += -I../../dpf/dgl/src/nanovg +BASE_FLAGS += -I../../include +BASE_FLAGS += -I../../include/neon-compat +BASE_FLAGS += -I../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../Rack/dep/include +endif +BASE_FLAGS += -I../Rack/dep/glfw/include +BASE_FLAGS += -I../Rack/dep/nanosvg/src +BASE_FLAGS += -I../Rack/dep/oui-blendish + +ifeq ($(WASM),true) +BASE_FLAGS += -DNANOVG_GLES2=1 +BASE_FLAGS += -msse -msse2 -msse3 -msimd128 +else ifneq ($(HAIKU),true) +BASE_FLAGS += -pthread +endif + +ifeq ($(WINDOWS),true) +BASE_FLAGS += -D_USE_MATH_DEFINES +BASE_FLAGS += -DWIN32_LEAN_AND_MEAN +BASE_FLAGS += -I../../include/mingw-compat +BASE_FLAGS += -I../../include/mingw-std-threads +endif + +BUILD_C_FLAGS += -std=gnu11 +BUILD_C_FLAGS += -fno-finite-math-only -fno-strict-aliasing +BUILD_CXX_FLAGS += -fno-finite-math-only -fno-strict-aliasing + +ifneq ($(MACOS),true) +BUILD_CXX_FLAGS += -faligned-new -Wno-abi +endif + +# Rack code is not tested for this flag, unset it +BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS + +# -------------------------------------------------------------- +# FIXME lots of warnings from VCV side + +BASE_FLAGS += -Wno-unused-parameter +BASE_FLAGS += -Wno-unused-variable + +# -------------------------------------------------------------- +# extra linker flags + +ifeq ($(HAIKU),true) +LINK_FLAGS += -lpthread +else +LINK_FLAGS += -pthread +endif + +ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) +ifneq ($(STATIC_BUILD),true) +LINK_FLAGS += -ldl +endif +endif + +ifeq ($(BSD),true) +ifeq ($(DEBUG),true) +LINK_FLAGS += -lexecinfo +endif +endif + +ifeq ($(MACOS),true) +LINK_FLAGS += -framework IOKit +else ifeq ($(WINDOWS),true) +# needed by VCVRack +EXTRA_LIBS += -ldbghelp -lshlwapi -Wl,--stack,0x100000 +# needed by JW-Modules +EXTRA_LIBS += -lws2_32 -lwinmm +endif + +ifeq ($(SYSDEPS),true) +EXTRA_LIBS += $(shell pkg-config --libs jansson libarchive samplerate speexdsp) +endif + +ifeq ($(WITH_LTO),true) +# false positive +LINK_FLAGS += -Wno-alloc-size-larger-than +ifneq ($(SYSDEPS),true) +# triggered by jansson +LINK_FLAGS += -Wno-stringop-overflow +endif +endif + +# -------------------------------------------------------------- +# fallback path to resource files + +ifneq ($(CIBUILD),true) +ifneq ($(SYSDEPS),true) + +ifeq ($(EXE_WRAPPER),wine) +SOURCE_DIR = Z:$(subst /,\\,$(abspath $(CURDIR)/..)) +else +SOURCE_DIR = $(abspath $(CURDIR)/..) +endif + +BUILD_CXX_FLAGS += -DCARDINAL_PLUGIN_SOURCE_DIR='"$(SOURCE_DIR)"' + +endif +endif + +# -------------------------------------------------------------- +# install path prefix for resource files + +BUILD_CXX_FLAGS += -DCARDINAL_PLUGIN_PREFIX='"$(PREFIX)"' + +# -------------------------------------------------------------- +# Files to build + +FILES = main.cpp +FILES += RemoteUI.cpp +FILES += CardinalCommon.cpp +FILES += common.cpp +FILES += glfw.cpp +FILES += Window.cpp + +ifeq ($(WINDOWS),true) +FILES += distrho.rc +endif + +# -------------------------------------------------------------- +# Build setup + +TARGET_DIR = ../../bin +BUILD_DIR = ../../build/CardinalRemote +DPF_PATH = ../../dpf + +DGL_FLAGS += -DDGL_OPENGL -DHAVE_DGL +DGL_FLAGS += $(OPENGL_FLAGS) +DGL_LIBS += $(OPENGL_LIBS) +DGL_LIBS += $(DGL_SYSTEM_LIBS) -lm +DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a + +BUILD_C_FLAGS += -I. +BUILD_CXX_FLAGS += -I. -I$(DPF_PATH)/distrho -I$(DPF_PATH)/dgl + +OBJS = $(FILES:%=$(BUILD_DIR)/%.o) + +all: $(TARGET_DIR)/CardinalRemote$(APP_EXT) + +# --------------------------------------------------------------------------------------------------------------------- + +$(TARGET_DIR)/CardinalRemote$(APP_EXT): $(OBJS) $(DGL_LIB) + -@mkdir -p $(shell dirname $@) + @echo "Linking CardinalRemote" + $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(DGL_LIBS) $(JACK_LIBS) -o $@ + +# --------------------------------------------------------------------------------------------------------------------- +# Common + +$(BUILD_DIR)/%.S.o: %.S + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + @$(CC) $< $(BUILD_C_FLAGS) -c -o $@ + +$(BUILD_DIR)/%.c.o: %.c + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + $(SILENT)$(CC) $< $(BUILD_C_FLAGS) -c -o $@ + +$(BUILD_DIR)/%.cc.o: %.cc + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +$(BUILD_DIR)/%.cpp.o: %.cpp + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +# -------------------------------------------------------------- +# Extra rules for Windows icon + +ifeq ($(WINDOWS),true) +JACK_LIBS += -Wl,-subsystem,windows + +$(BUILD_DIR)/distrho.rc.o: ../../utils/distrho.rc ../../utils/distrho.ico + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling distrho.rc" + $(SILENT)$(WINDRES) $< -O coff -o $@ +endif diff --git a/src/CardinalRemote/RemoteUI.cpp b/src/CardinalRemote/RemoteUI.cpp new file mode 100644 index 0000000..1295f13 --- /dev/null +++ b/src/CardinalRemote/RemoteUI.cpp @@ -0,0 +1,91 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2022 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or any later version. + * + * 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 for more details. + * + * For a full copy of the GNU General Public License see the LICENSE file. + */ + +#include "RemoteUI.hpp" + +// #include +// #include +#include +#include +#include + +#include +#include + +CardinalRemoteUI::CardinalRemoteUI(Window& window, const std::string& templatePath) + : NanoTopLevelWidget(window), + context(nullptr) +{ + // create unique temporary path for this instance + try { + char uidBuf[24]; + const std::string tmp = rack::system::getTempDirectory(); + + for (int i=1;; ++i) + { + std::snprintf(uidBuf, sizeof(uidBuf), "CardinalRemote.%04d", i); + const std::string trypath = rack::system::join(tmp, uidBuf); + + if (! rack::system::exists(trypath)) + { + if (rack::system::createDirectories(trypath)) + autosavePath = trypath; + break; + } + } + } DISTRHO_SAFE_EXCEPTION("create unique temporary path"); + + rack::contextSet(&context); + + context.bufferSize = 512; + rack::settings::sampleRate = context.sampleRate = 48000; + + context.engine = new rack::engine::Engine; + context.engine->setSampleRate(context.sampleRate); + + context.history = new rack::history::State; + context.patch = new rack::patch::Manager; + context.patch->autosavePath = autosavePath; + context.patch->templatePath = templatePath; + + context.event = new rack::widget::EventState; + context.scene = new rack::app::Scene; + context.event->rootWidget = context.scene; + context.window = new rack::window::Window; + + context.patch->loadTemplate(); + context.scene->rackScroll->reset(); + + context.nativeWindowId = getWindow().getNativeWindowHandle(); +} + +CardinalRemoteUI::~CardinalRemoteUI() +{ + rack::contextSet(&context); + + context.nativeWindowId = 0; + context.patch->clear(); + + if (! autosavePath.empty()) + rack::system::removeRecursively(autosavePath); +} + +void CardinalRemoteUI::onNanoDisplay() +{ + rack::contextSet(&context); + context.window->step(); +} diff --git a/src/CardinalRemote/RemoteUI.hpp b/src/CardinalRemote/RemoteUI.hpp new file mode 100644 index 0000000..1ed4696 --- /dev/null +++ b/src/CardinalRemote/RemoteUI.hpp @@ -0,0 +1,36 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2022 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or any later version. + * + * 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 for more details. + * + * For a full copy of the GNU General Public License see the LICENSE file. + */ + +#pragma once + +#include "NanoVG.hpp" +#include "PluginContext.hpp" + +class CardinalRemoteUI : public NanoTopLevelWidget +{ + CardinalPluginContext context; + std::string autosavePath; + +public: + explicit CardinalRemoteUI(Window& window, const std::string& templatePath); + ~CardinalRemoteUI() override; + +protected: + void onNanoDisplay() override; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CardinalRemoteUI) +}; diff --git a/src/CardinalRemote/Window.cpp b/src/CardinalRemote/Window.cpp new file mode 120000 index 0000000..759f272 --- /dev/null +++ b/src/CardinalRemote/Window.cpp @@ -0,0 +1 @@ +../override/Window.cpp \ No newline at end of file diff --git a/src/CardinalRemote/common.cpp b/src/CardinalRemote/common.cpp new file mode 120000 index 0000000..915948e --- /dev/null +++ b/src/CardinalRemote/common.cpp @@ -0,0 +1 @@ +../override/common.cpp \ No newline at end of file diff --git a/src/CardinalRemote/glfw.cpp b/src/CardinalRemote/glfw.cpp new file mode 120000 index 0000000..8c6a6e4 --- /dev/null +++ b/src/CardinalRemote/glfw.cpp @@ -0,0 +1 @@ +../custom/glfw.cpp \ No newline at end of file diff --git a/src/CardinalRemote/main.cpp b/src/CardinalRemote/main.cpp new file mode 100644 index 0000000..4ac0be2 --- /dev/null +++ b/src/CardinalRemote/main.cpp @@ -0,0 +1,160 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2022 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or any later version. + * + * 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 for more details. + * + * For a full copy of the GNU General Public License see the LICENSE file. + */ + +#include "Application.hpp" +#include "Window.hpp" +#include "RemoteUI.hpp" + +#include +#include +#include +#include + +#include +#include + +namespace rack { +namespace plugin { + void initStaticPlugins(); + void destroyStaticPlugins(); +} +} + +int main(const int argc, const char* argv[]) +{ + using namespace rack; + + settings::allowCursorLock = false; + settings::autoCheckUpdates = false; + settings::autosaveInterval = 0; + settings::devMode = true; + settings::discordUpdateActivity = false; + settings::isPlugin = true; + settings::skipLoadOnLaunch = true; + settings::showTipsOnLaunch = false; + settings::windowPos = math::Vec(0, 0); + + // copied from https://community.vcvrack.com/t/16-colour-cable-palette/15951 + settings::cableColors = { + color::fromHexString("#ff5252"), + color::fromHexString("#ff9352"), + color::fromHexString("#ffd452"), + color::fromHexString("#e8ff52"), + color::fromHexString("#a8ff52"), + color::fromHexString("#67ff52"), + color::fromHexString("#52ff7d"), + color::fromHexString("#52ffbe"), + color::fromHexString("#52ffff"), + color::fromHexString("#52beff"), + color::fromHexString("#527dff"), + color::fromHexString("#6752ff"), + color::fromHexString("#a852ff"), + color::fromHexString("#e952ff"), + color::fromHexString("#ff52d4"), + color::fromHexString("#ff5293"), + }; + + system::init(); + logger::init(); + random::init(); + ui::init(); + + std::string templatePath; + #ifdef CARDINAL_PLUGIN_SOURCE_DIR + // Make system dir point to source code location as fallback + asset::systemDir = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "Rack"; + + if (system::exists(system::join(asset::systemDir, "res"))) + { + templatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "template.vcv"; + } + // If source code dir does not exist use install target prefix as system dir + else + #endif + { + #if defined(ARCH_MAC) + asset::systemDir = "/Library/Application Support/Cardinal"; + #elif defined(ARCH_WIN) + const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles); + if (! commonprogfiles.empty()) + asset::systemDir = system::join(commonprogfiles, "Cardinal"); + #else + asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal"; + #endif + + if (! asset::systemDir.empty()) + { + asset::bundlePath = system::join(asset::systemDir, "PluginManifests"); + templatePath = system::join(asset::systemDir, "template.vcv"); + } + } + + asset::userDir = asset::systemDir; + + // Log environment + INFO("%s %s v%s", APP_NAME.c_str(), APP_EDITION.c_str(), APP_VERSION.c_str()); + INFO("%s", system::getOperatingSystemInfo().c_str()); +// INFO("Binary filename: %s", getBinaryFilename()); + INFO("System directory: %s", asset::systemDir.c_str()); + INFO("User directory: %s", asset::userDir.c_str()); + INFO("Template patch: %s", templatePath.c_str()); + + // Report to user if something is wrong with the installation + if (asset::systemDir.empty()) + { + d_stderr2("Failed to locate Cardinal plugin bundle.\n" + "Install Cardinal with its bundle folder intact and try again."); + } + else if (! system::exists(asset::systemDir)) + { + d_stderr2("System directory \"%s\" does not exist.\n" + "Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str()); + } + + INFO("Initializing plugins"); + plugin::initStaticPlugins(); + + INFO("Initializing plugin browser DB"); + app::browserInit(); + + Application app; + Window win(app); + win.setTitle("CardinalRemote"); + ScopedPointer remoteUI; + + { + remoteUI = new CardinalRemoteUI(win, templatePath); + } + + app.exec(); + + INFO("Clearing asset paths"); + asset::bundlePath.clear(); + asset::systemDir.clear(); + asset::userDir.clear(); + + INFO("Destroying plugins"); + plugin::destroyStaticPlugins(); + + INFO("Destroying settings"); + settings::destroy(); + + INFO("Destroying logger"); + logger::destroy(); + + return 0; +}