From 6ecedf2754d1f2de144443cb95068ecf62837786 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 3 May 2023 18:43:06 +0200 Subject: [PATCH] Update for wasm build fixes Signed-off-by: falkTX --- dpf/Makefile.base.mk | 4 +- dpf/cmake/DPF-plugin.cmake | 32 +++++- dpf/distrho/DistrhoUIMain.cpp | 9 +- dpf/distrho/src/DistrhoUIInternal.hpp | 7 ++ dpf/distrho/src/DistrhoUtils.cpp | 2 + dpf/distrho/src/jackbridge/JackBridge.cpp | 110 +++++++++++++++---- dpf/distrho/src/jackbridge/JackBridge.hpp | 5 + dpf/distrho/src/jackbridge/RtAudioBridge.hpp | 3 +- plugins/Nekobi/Makefile | 2 + 9 files changed, 148 insertions(+), 26 deletions(-) diff --git a/dpf/Makefile.base.mk b/dpf/Makefile.base.mk index 45adc95..ab7891b 100644 --- a/dpf/Makefile.base.mk +++ b/dpf/Makefile.base.mk @@ -352,7 +352,7 @@ endif # --------------------------------------------------------------------------------------------------------------------- # Check for required libraries -ifneq ($(HAIKU),true) +ifneq ($(HAIKU)$(WASM),true) HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true) endif @@ -763,7 +763,7 @@ features: # --------------------------------------------------------------------------------------------------------------------- # Extra rules for MOD Audio stuff -# NOTE: note path must be absolute +# NOTE: path must be absolute MOD_WORKDIR ?= $(HOME)/mod-workdir MOD_ENVIRONMENT = \ AR=${1}/host/usr/bin/${2}-gcc-ar \ diff --git a/dpf/cmake/DPF-plugin.cmake b/dpf/cmake/DPF-plugin.cmake index ceb6906..e9f28dd 100644 --- a/dpf/cmake/DPF-plugin.cmake +++ b/dpf/cmake/DPF-plugin.cmake @@ -192,6 +192,8 @@ function(dpf_add_plugin NAME) dpf__build_vst3("${NAME}" "${_dgl_has_ui}") elseif(_target STREQUAL "clap") dpf__build_clap("${NAME}" "${_dgl_has_ui}") + elseif(_target STREQUAL "static") + dpf__build_static("${NAME}" "${_dgl_has_ui}") else() message(FATAL_ERROR "Unrecognized target type for plugin: ${_target}") endif() @@ -510,7 +512,7 @@ endfunction() # dpf__build_clap # ------------------------------------------------------------------------------ # -# Add build rules for a VST2 plugin. +# Add build rules for a CLAP plugin. # function(dpf__build_clap NAME HAS_UI) dpf__create_dummy_source_list(_no_srcs) @@ -540,6 +542,34 @@ function(dpf__build_clap NAME HAS_UI) endif() endfunction() +# dpf__build_static +# ------------------------------------------------------------------------------ +# +# Add build rules for a static library. +# +function(dpf__build_static NAME HAS_UI) + dpf__create_dummy_source_list(_no_srcs) + + dpf__add_module("${NAME}-static" ${_no_srcs} STATIC) + dpf__add_plugin_main("${NAME}-static" "static") + dpf__add_ui_main("${NAME}-static" "static" "${HAS_UI}") + target_link_libraries("${NAME}-static" PRIVATE "${NAME}-dsp" "${NAME}-ui") + + get_target_property(dsp_srcs "${NAME}-dsp" SOURCES) + get_target_property(ui_srcs "${NAME}-ui" SOURCES) + foreach(src ${dsp_srcs}) + target_sources("${NAME}-static" PRIVATE ${src}) + endforeach() + foreach(src ${ui_srcs}) + target_sources("${NAME}-static" PRIVATE ${src}) + endforeach() + + set_target_properties("${NAME}-static" PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" + OUTPUT_NAME "${NAME}" + PREFIX "") +endfunction() + # dpf__add_dgl_cairo # ------------------------------------------------------------------------------ # diff --git a/dpf/distrho/DistrhoUIMain.cpp b/dpf/distrho/DistrhoUIMain.cpp index 572b62e..13d337b 100644 --- a/dpf/distrho/DistrhoUIMain.cpp +++ b/dpf/distrho/DistrhoUIMain.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2022 Filipe Coelho + * Copyright (C) 2012-2023 Filipe Coelho * * 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 @@ -16,10 +16,13 @@ #include "src/DistrhoUI.cpp" -#if ! DISTRHO_PLUGIN_HAS_UI +// we might be building a plugin with external UI, which works on most formats except VST2/3 +#if ! DISTRHO_PLUGIN_HAS_UI && ! defined(DISTRHO_PLUGIN_VST_HPP_INCLUDED) # error Trying to build UI without DISTRHO_PLUGIN_HAS_UI set to 1 #endif +#if DISTRHO_PLUGIN_HAS_UI + #if defined(DISTRHO_PLUGIN_TARGET_CARLA) # define DISTRHO_PLUGIN_AND_UI_IN_SINGLE_OBJECT 1 #elif defined(DISTRHO_PLUGIN_TARGET_CLAP) @@ -51,3 +54,5 @@ # endif # include "src/DistrhoUtils.cpp" #endif + +#endif diff --git a/dpf/distrho/src/DistrhoUIInternal.hpp b/dpf/distrho/src/DistrhoUIInternal.hpp index 65c0b82..00239a8 100644 --- a/dpf/distrho/src/DistrhoUIInternal.hpp +++ b/dpf/distrho/src/DistrhoUIInternal.hpp @@ -261,6 +261,13 @@ public: uiData->app.quit(); } + #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI + void repaint() + { + uiData->window->repaint(); + } + #endif + // ------------------------------------------------------------------- #if defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS) diff --git a/dpf/distrho/src/DistrhoUtils.cpp b/dpf/distrho/src/DistrhoUtils.cpp index 3ca3e4b..cf01598 100644 --- a/dpf/distrho/src/DistrhoUtils.cpp +++ b/dpf/distrho/src/DistrhoUtils.cpp @@ -99,6 +99,8 @@ const char* getPluginFormatName() noexcept return "VST3"; #elif defined(DISTRHO_PLUGIN_TARGET_CLAP) return "CLAP"; +#elif defined(DISTRHO_PLUGIN_TARGET_STATIC) && defined(DISTRHO_PLUGIN_TARGET_STATIC_NAME) + return DISTRHO_PLUGIN_TARGET_STATIC_NAME; #else return "Unknown"; #endif diff --git a/dpf/distrho/src/jackbridge/JackBridge.cpp b/dpf/distrho/src/jackbridge/JackBridge.cpp index 5f85ee4..518f763 100644 --- a/dpf/distrho/src/jackbridge/JackBridge.cpp +++ b/dpf/distrho/src/jackbridge/JackBridge.cpp @@ -101,6 +101,7 @@ typedef int (JACKSYM_API *JackSymSyncCallback)(jack_transport_state_t, jack_pos typedef void (JACKSYM_API *JackSymTimebaseCallback)(jack_transport_state_t, jack_nframes_t, jack_position_t*, int, void*); typedef void (JACKSYM_API *JackSymSessionCallback)(jack_session_event_t*, void*); typedef void (JACKSYM_API *JackSymPropertyChangeCallback)(jack_uuid_t, const char*, jack_property_change_t, void*); +typedef void* (JACKSYM_API *JackSymThreadCallback)(void*); typedef void (JACKSYM_API *jacksym_get_version)(int*, int*, int*, int*); typedef const char* (JACKSYM_API *jacksym_get_version_string)(void); @@ -217,6 +218,10 @@ typedef int (JACKSYM_API *jacksym_remove_properties)(jack_client_t*, jack_uuid_ typedef int (JACKSYM_API *jacksym_remove_all_properties)(jack_client_t*); typedef int (JACKSYM_API *jacksym_set_property_change_callback)(jack_client_t*, JackSymPropertyChangeCallback, void*); +typedef bool (JACKSYM_API *jacksym_set_process_thread)(jack_client_t*, JackSymThreadCallback callback, void*); +typedef jack_nframes_t (JACKSYM_API *jacksym_cycle_wait)(jack_client_t*); +typedef void (JACKSYM_API *jacksym_cycle_signal)(jack_client_t*, int); + #ifdef __WINE__ typedef int (JACKSYM_API *jacksym_thread_creator_t)(pthread_t*, const pthread_attr_t*, void *(*)(void*), void*); typedef void (JACKSYM_API *jacksym_set_thread_creator)(jacksym_thread_creator_t); @@ -344,6 +349,10 @@ struct JackBridge { jacksym_remove_all_properties remove_all_properties_ptr; jacksym_set_property_change_callback set_property_change_callback_ptr; + jacksym_set_process_thread set_process_thread_ptr; + jacksym_cycle_wait cycle_wait_ptr; + jacksym_cycle_signal cycle_signal_ptr; + #ifdef __WINE__ jacksym_set_thread_creator set_thread_creator_ptr; #endif @@ -441,7 +450,10 @@ struct JackBridge { remove_property_ptr(nullptr), remove_properties_ptr(nullptr), remove_all_properties_ptr(nullptr), - set_property_change_callback_ptr(nullptr) + set_property_change_callback_ptr(nullptr), + set_process_thread_ptr(nullptr), + cycle_wait_ptr(nullptr), + cycle_signal_ptr(nullptr) #ifdef __WINE__ , set_thread_creator_ptr(nullptr) #endif @@ -587,6 +599,10 @@ struct JackBridge { LIB_SYMBOL(remove_all_properties) LIB_SYMBOL(set_property_change_callback) + LIB_SYMBOL(set_process_thread) + LIB_SYMBOL(cycle_wait) + LIB_SYMBOL(cycle_signal) + #ifdef __WINE__ LIB_SYMBOL(set_thread_creator) #endif @@ -650,6 +666,7 @@ struct WineBridge { JackTimebaseCallback timebase_cb; JackSessionCallback session_cb; JackPropertyChangeCallback prop_change_cb; + JackThreadCallback proc_thread_cb; void* (*creator_func)(void*); void* creator_arg; @@ -676,6 +693,7 @@ struct WineBridge { timebase_cb(nullptr), session_cb(nullptr), prop_change_cb(nullptr), + proc_thread_cb(nullptr), creator_func(nullptr), creator_arg(nullptr), creator_handle(nullptr), @@ -687,24 +705,25 @@ struct WineBridge { return bridge; } - void set_latency (JackLatencyCallback cb) noexcept { latency_cb = cb; } - void set_process (JackProcessCallback cb) noexcept { process_cb = cb; } - void set_thread_init (JackThreadInitCallback cb) noexcept { thread_init_cb = cb; } - void set_graph_order (JackGraphOrderCallback cb) noexcept { graph_order_cb = cb; } - void set_xrun (JackXRunCallback cb) noexcept { xrun_cb = cb; } - void set_bufsize (JackBufferSizeCallback cb) noexcept { bufsize_cb = cb; } - void set_srate (JackSampleRateCallback cb) noexcept { srate_cb = cb; } - void set_port_reg (JackPortRegistrationCallback cb) noexcept { port_reg_cb = cb; } - void set_client_reg (JackClientRegistrationCallback cb) noexcept { client_reg_cb = cb; } - void set_port_conn (JackPortConnectCallback cb) noexcept { port_conn_cb = cb; } - void set_port_rename (JackPortRenameCallback cb) noexcept { port_rename_cb = cb; } - void set_freewheel (JackFreewheelCallback cb) noexcept { freewheel_cb = cb; } - void set_shutdown (JackShutdownCallback cb) noexcept { shutdown_cb = cb; } - void set_info_shutdown(JackInfoShutdownCallback cb) noexcept { info_shutdown_cb = cb; } - void set_sync (JackSyncCallback cb) noexcept { sync_cb = cb; } - void set_timebase (JackTimebaseCallback cb) noexcept { timebase_cb = cb; } - void set_session (JackSessionCallback cb) noexcept { session_cb = cb; } - void set_prop_change (JackPropertyChangeCallback cb) noexcept { prop_change_cb = cb; } + void set_latency (JackLatencyCallback cb) noexcept { latency_cb = cb; } + void set_process (JackProcessCallback cb) noexcept { process_cb = cb; } + void set_thread_init (JackThreadInitCallback cb) noexcept { thread_init_cb = cb; } + void set_graph_order (JackGraphOrderCallback cb) noexcept { graph_order_cb = cb; } + void set_xrun (JackXRunCallback cb) noexcept { xrun_cb = cb; } + void set_bufsize (JackBufferSizeCallback cb) noexcept { bufsize_cb = cb; } + void set_srate (JackSampleRateCallback cb) noexcept { srate_cb = cb; } + void set_port_reg (JackPortRegistrationCallback cb) noexcept { port_reg_cb = cb; } + void set_client_reg (JackClientRegistrationCallback cb) noexcept { client_reg_cb = cb; } + void set_port_conn (JackPortConnectCallback cb) noexcept { port_conn_cb = cb; } + void set_port_rename (JackPortRenameCallback cb) noexcept { port_rename_cb = cb; } + void set_freewheel (JackFreewheelCallback cb) noexcept { freewheel_cb = cb; } + void set_shutdown (JackShutdownCallback cb) noexcept { shutdown_cb = cb; } + void set_info_shutdown (JackInfoShutdownCallback cb) noexcept { info_shutdown_cb = cb; } + void set_sync (JackSyncCallback cb) noexcept { sync_cb = cb; } + void set_timebase (JackTimebaseCallback cb) noexcept { timebase_cb = cb; } + void set_session (JackSessionCallback cb) noexcept { session_cb = cb; } + void set_prop_change (JackPropertyChangeCallback cb) noexcept { prop_change_cb = cb; } + void set_process_thread(JackThreadCallback cb) noexcept { proc_thread_cb = cb; } static DWORD WINAPI thread_creator_helper(LPVOID) { @@ -832,6 +851,11 @@ struct WineBridge { return getInstance().prop_change_cb(subject, key, change, arg); } + static void* process_thread(void* arg) + { + return getInstance().proc_thread_cb(arg); + } + DISTRHO_DECLARE_NON_COPYABLE(WineBridge); }; @@ -2292,8 +2316,54 @@ bool jackbridge_set_property_change_callback(jack_client_t* client, JackProperty return false; } +bool jackbridge_set_process_thread(jack_client_t* client, JackThreadCallback callback, void* arg) +{ +#if defined(JACKBRIDGE_DUMMY) +#elif defined(JACKBRIDGE_DIRECT) + return (jack_set_process_thread(client, callback, arg) == 0); +#else + if (usingRealJACK && getBridgeInstance().set_process_thread_ptr != nullptr) + { +# ifdef __WINE__ + WineBridge::getInstance().set_process_thread(callback); + return (getBridgeInstance().set_process_thread_ptr(client, WineBridge::process_thread, arg) == 0); +# else + return (getBridgeInstance().set_process_thread_ptr(client, callback, arg) == 0); +# endif + } +#endif + return false; +} + +jack_nframes_t jackbridge_cycle_wait(jack_client_t* client) +{ +#if defined(JACKBRIDGE_DUMMY) +#elif defined(JACKBRIDGE_DIRECT) + return jack_cycle_wait(client); +#else + if (usingRealJACK) + if (getBridgeInstance().cycle_wait_ptr != nullptr) + return getBridgeInstance().cycle_wait_ptr(client); +#endif + return 0; +} + +void jackbridge_cycle_signal(jack_client_t* client, int status) +{ +#if defined(JACKBRIDGE_DUMMY) +#elif defined(JACKBRIDGE_DIRECT) + jack_cycle_signal(client, status); +#else + if (usingRealJACK) + if (getBridgeInstance().cycle_signal_ptr != nullptr) + getBridgeInstance().cycle_signal_ptr(client, status); +#endif +} + // ----------------------------------------------------------------------------- +#ifndef JACKBRIDGE_SKIP_NATIVE_UTILS + START_NAMESPACE_DISTRHO bool isUsingNativeAudio() noexcept @@ -2388,4 +2458,6 @@ bool requestMIDI() END_NAMESPACE_DISTRHO +#endif // JACKBRIDGE_SKIP_NATIVE_UTILS + // ----------------------------------------------------------------------------- diff --git a/dpf/distrho/src/jackbridge/JackBridge.hpp b/dpf/distrho/src/jackbridge/JackBridge.hpp index b287b47..60e604e 100644 --- a/dpf/distrho/src/jackbridge/JackBridge.hpp +++ b/dpf/distrho/src/jackbridge/JackBridge.hpp @@ -287,6 +287,7 @@ typedef int (JACKBRIDGE_API *JackSyncCallback)(jack_transport_state_t state, ja typedef void (JACKBRIDGE_API *JackTimebaseCallback)(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg); typedef void (JACKBRIDGE_API *JackSessionCallback)(jack_session_event_t* event, void* arg); typedef void (JACKBRIDGE_API *JackPropertyChangeCallback)(jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg); +typedef void *(JACKBRIDGE_API *JackThreadCallback)(void* arg); } // extern "C" @@ -409,4 +410,8 @@ JACKBRIDGE_API int jackbridge_remove_properties(jack_client_t* client, jack_uui JACKBRIDGE_API bool jackbridge_remove_all_properties(jack_client_t* client); JACKBRIDGE_API bool jackbridge_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); +JACKBRIDGE_API bool jackbridge_set_process_thread(jack_client_t* client, JackThreadCallback callback, void* arg); +JACKBRIDGE_API jack_nframes_t jackbridge_cycle_wait(jack_client_t* client); +JACKBRIDGE_API void jackbridge_cycle_signal(jack_client_t* client, int status); + #endif // JACKBRIDGE_HPP_INCLUDED diff --git a/dpf/distrho/src/jackbridge/RtAudioBridge.hpp b/dpf/distrho/src/jackbridge/RtAudioBridge.hpp index cd2fc76..49673fd 100644 --- a/dpf/distrho/src/jackbridge/RtAudioBridge.hpp +++ b/dpf/distrho/src/jackbridge/RtAudioBridge.hpp @@ -1,6 +1,6 @@ /* * RtAudio Bridge for DPF - * Copyright (C) 2021-2022 Filipe Coelho + * Copyright (C) 2021-2023 Filipe Coelho * * 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 @@ -162,7 +162,6 @@ struct RtAudioBridge : NativeBridge { bool isMIDIEnabled() const override { - d_stdout("%s %d", __PRETTY_FUNCTION__, __LINE__); #if defined(RTMIDI_API_TYPE) && DISTRHO_PLUGIN_WANT_MIDI_INPUT if (!midiIns.empty()) return true; diff --git a/plugins/Nekobi/Makefile b/plugins/Nekobi/Makefile index c89dfb1..0a62590 100644 --- a/plugins/Nekobi/Makefile +++ b/plugins/Nekobi/Makefile @@ -29,8 +29,10 @@ include ../../dpf/Makefile.plugins.mk # -------------------------------------------------------------- # Extra flags +ifneq ($(WASM),true) BASE_FLAGS += -pthread LINK_FLAGS += -pthread +endif # -------------------------------------------------------------- # Enable all possible plugin types