From ccfc58395846ff27c16b88257ddc581910523d9b Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 24 Nov 2014 21:24:14 +0000 Subject: [PATCH] More pipe work; Enable extui-plugins on Windows --- source/backend/Makefile | 5 +- source/backend/engine/CarlaEngineNative.cpp | 13 ++-- source/backend/engine/Makefile | 14 ++--- source/carla_app.py | 2 +- source/discovery/carla-discovery.cpp | 10 +-- source/externalui.py | 62 +++++++++---------- source/modules/jackbridge/JackBridge1.cpp | 2 +- source/modules/native-plugins/Makefile | 2 - source/modules/native-plugins/_all.c | 4 -- source/modules/native-plugins/bigmeter.cpp | 6 +- source/modules/native-plugins/notes.cpp | 6 +- .../native-plugins/resources/carla-plugin | 6 ++ source/utils/CarlaPipeUtils.cpp | 52 +++++++++++++--- 13 files changed, 103 insertions(+), 81 deletions(-) diff --git a/source/backend/Makefile b/source/backend/Makefile index ff4945f59..764fdbbdd 100644 --- a/source/backend/Makefile +++ b/source/backend/Makefile @@ -79,7 +79,10 @@ ifeq ($(UNIX),true) STANDALONE_FLAGS += -lmagic endif -UTILS_FLAGS = $(JUCE_CORE_LIBS) +UTILS_FLAGS = $(JUCE_CORE_LIBS) +ifneq ($(HAIKU),true) +UTILS_FLAGS += -lpthread +endif # -------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 69184f465..535a5af16 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -20,9 +20,6 @@ #ifdef BUILD_BRIDGE # error This file should not be compiled if building bridge #endif -#ifdef CARLA_OS_WIN -# error This file should not be compiled for Windows -#endif #include "CarlaEngineInternal.hpp" #include "CarlaPlugin.hpp" @@ -1418,10 +1415,12 @@ protected: CarlaString path(pHost->resourceDir); if (kIsPatchbay) - path += "/carla-plugin-patchbay"; + path += CARLA_OS_SEP_STR "carla-plugin-patchbay"; else - path += "/carla-plugin"; - + path += CARLA_OS_SEP_STR "carla-plugin"; +#ifdef CARLA_OS_WIN + path += ".exe"; +#endif carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer()); fUiServer.setData(path, pData->sampleRate, pHost->uiName); @@ -1463,6 +1462,7 @@ protected: const CarlaMutexLocker cml(fUiServer.getLock()); const ScopedLocale csl; +#ifndef CARLA_OS_WIN // FIXME // send transport fUiServer.writeAndFixMsg("transport"); fUiServer.writeMsg(timeInfo.playing ? "true\n" : "false\n"); @@ -1482,6 +1482,7 @@ protected: } fUiServer.flush(); +#endif // send peaks and param outputs for all plugins for (uint i=0; i < pData->curPluginCount; ++i) diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index 4eaa6bdd8..8f44f22dc 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -20,23 +20,17 @@ OBJS = \ CarlaEngineThread.cpp.o OBJSa = $(OBJS) \ - CarlaEngineJack.cpp.o + CarlaEngineJack.cpp.o \ + CarlaEngineNative.cpp.o ifeq ($(MACOS_OR_WIN32),true) -OBJSa += \ - CarlaEngineJuce.cpp.o +OBJSa += CarlaEngineJuce.cpp.o else -OBJSa += \ - CarlaEngineRtAudio.cpp.o +OBJSa += CarlaEngineRtAudio.cpp.o endif -ifneq ($(WIN32),true) -OBJSa += \ - CarlaEngineNative.cpp.o - OBJSp = $(OBJS) \ CarlaEngineNative.cpp.exp.o -endif TARGETS = \ ../carla_engine.a \ diff --git a/source/carla_app.py b/source/carla_app.py index e7a38af45..583ce2499 100644 --- a/source/carla_app.py +++ b/source/carla_app.py @@ -50,7 +50,7 @@ class CarlaApplication(object): QApplication.addLibraryPath(CWD) # Needed for local wine build - if WINDOWS and CWD.endswith("source"): + if WINDOWS and (CWD.endswith("source") or os.getenv("CXFREEZE") is not None): QApplication.addLibraryPath("C:\\Python34\\Lib\\site-packages\\PyQt5\\plugins") # Use binary dir as library path (except in Windows) diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index 0f5d32687..43108ce2d 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -401,7 +401,7 @@ private: // ------------------------------ Plugin Checks ----------------------------- -static void do_ladspa_check(void*& libHandle, const char* const filename, const bool doInit) +static void do_ladspa_check(lib_t& libHandle, const char* const filename, const bool doInit) { LADSPA_Descriptor_Function descFn = lib_symbol(libHandle, "ladspa_descriptor"); @@ -634,7 +634,7 @@ static void do_ladspa_check(void*& libHandle, const char* const filename, const } } -static void do_dssi_check(void*& libHandle, const char* const filename, const bool doInit) +static void do_dssi_check(lib_t& libHandle, const char* const filename, const bool doInit) { DSSI_Descriptor_Function descFn = lib_symbol(libHandle, "dssi_descriptor"); @@ -984,7 +984,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) if (doInit) { // test if DLL is loadable, twice - void* const libHandle1 = lib_open(rdfDescriptor->Binary); + const lib_t libHandle1 = lib_open(rdfDescriptor->Binary); if (libHandle1 == nullptr) { @@ -995,7 +995,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) lib_close(libHandle1); - void* const libHandle2 = lib_open(rdfDescriptor->Binary); + const lib_t libHandle2 = lib_open(rdfDescriptor->Binary); if (libHandle2 == nullptr) { @@ -1142,7 +1142,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) } #ifndef CARLA_OS_MAC -static void do_vst_check(void*& libHandle, const bool doInit) +static void do_vst_check(lib_t& libHandle, const bool doInit) { VST_Function vstFn = lib_symbol(libHandle, "VSTPluginMain"); diff --git a/source/externalui.py b/source/externalui.py index 40041f9d9..44744ce56 100755 --- a/source/externalui.py +++ b/source/externalui.py @@ -16,11 +16,6 @@ # # For a full copy of the GNU General Public License see the doc/GPL.txt file. -# ------------------------------------------------------------------------------------------------------------ -# Imports (Global) - -from sys import argv - # ------------------------------------------------------------------------------------------------------------ # Imports (Custom Stuff) @@ -35,9 +30,9 @@ class ExternalUI(object): self.fQuitReceived = False - if len(argv) > 1: - self.fSampleRate = float(argv[1]) - self.fUiName = argv[2] + if len(sys.argv) > 1: + self.fSampleRate = float(sys.argv[1]) + self.fUiName = sys.argv[2] self.fPipeClient = gCarla.utils.pipe_client_new(lambda s,msg: self.msgCallback(msg)) else: self.fSampleRate = 44100.0 @@ -48,10 +43,7 @@ class ExternalUI(object): # Public methods def ready(self): - if self.fPipeClient is not None: - # send empty line (just newline char) - self.send([""]) - else: + if self.fPipeClient is None: # testing, show UI only self.uiShow() @@ -65,12 +57,14 @@ class ExternalUI(object): gCarla.utils.pipe_client_idle(self.fPipeClient) def closeExternalUI(self): + if self.fPipeClient is None: + return + if not self.fQuitReceived: self.send(["exiting"]) - if self.fPipeClient is not None: - gCarla.utils.pipe_client_destroy(self.fPipeClient) - self.fPipeClient = None + gCarla.utils.pipe_client_destroy(self.fPipeClient) + self.fPipeClient = None # ------------------------------------------------------------------- # Host DSP State @@ -176,7 +170,7 @@ class ExternalUI(object): if self.fPipeClient is None: return "" - return gCarla.utils.pipe_client_readlineblock(self.fPipeClient, 50) + return gCarla.utils.pipe_client_readlineblock(self.fPipeClient, 5000) def send(self, lines): if self.fPipeClient is None or len(lines) == 0: @@ -184,21 +178,25 @@ class ExternalUI(object): gCarla.utils.pipe_client_lock(self.fPipeClient) - for line in lines: - if line is None: - line2 = "(null)" - elif isinstance(line, str): - line2 = line.replace("\n", "\r") - elif isinstance(line, bool): - line2 = "true" if line else "false" - elif isinstance(line, int): - line2 = "%i" % line - elif isinstance(line, float): - line2 = "%.10f" % line - else: - print("unknown data type to send:", type(line)) - return - - gCarla.utils.pipe_client_write_msg(self.fPipeClient, line2 + "\n") + # this must never fail, we need to unlock at the end + try: + for line in lines: + if line is None: + line2 = "(null)" + elif isinstance(line, str): + line2 = line.replace("\n", "\r") + elif isinstance(line, bool): + line2 = "true" if line else "false" + elif isinstance(line, int): + line2 = "%i" % line + elif isinstance(line, float): + line2 = "%.10f" % line + else: + print("unknown data type to send:", type(line)) + return + + gCarla.utils.pipe_client_write_msg(self.fPipeClient, line2 + "\n") + except: + pass gCarla.utils.pipe_client_flush_and_unlock(self.fPipeClient) diff --git a/source/modules/jackbridge/JackBridge1.cpp b/source/modules/jackbridge/JackBridge1.cpp index 197a9a174..6ed92b6c6 100644 --- a/source/modules/jackbridge/JackBridge1.cpp +++ b/source/modules/jackbridge/JackBridge1.cpp @@ -140,7 +140,7 @@ typedef int (__cdecl *jacksym_set_property_change_callback)(jack_client_t*, Jac // ----------------------------------------------------------------------------- struct JackBridge { - void* lib; + lib_t lib; jacksym_get_version get_version_ptr; jacksym_get_version_string get_version_string_ptr; diff --git a/source/modules/native-plugins/Makefile b/source/modules/native-plugins/Makefile index 4a21868c7..8f441675e 100644 --- a/source/modules/native-plugins/Makefile +++ b/source/modules/native-plugins/Makefile @@ -57,14 +57,12 @@ OBJS += \ audio-file.cpp.o \ midi-file.cpp.o -ifneq ($(WIN32),true) # -------------------------------------------------------------- # External-UI plugins OBJS += \ bigmeter.cpp.o \ notes.cpp.o -endif # -------------------------------------------------------------- # ZynAddSubFX diff --git a/source/modules/native-plugins/_all.c b/source/modules/native-plugins/_all.c index 73fda0436..f9bfa74d4 100644 --- a/source/modules/native-plugins/_all.c +++ b/source/modules/native-plugins/_all.c @@ -32,14 +32,12 @@ extern void carla_register_native_plugin_audiofile(void); // MIDI File extern void carla_register_native_plugin_midifile(void); -#ifndef CARLA_OS_WIN // Carla extern void carla_register_native_plugin_carla(void); // External-UI plugins extern void carla_register_native_plugin_bigmeter(void); extern void carla_register_native_plugin_notes(void); -#endif #ifdef WANT_ZYNADDSUBFX // ZynAddSubFX @@ -66,14 +64,12 @@ void carla_register_all_plugins(void) // MIDI File carla_register_native_plugin_midifile(); -#ifndef CARLA_OS_WIN // Carla carla_register_native_plugin_carla(); // External-UI plugins carla_register_native_plugin_bigmeter(); carla_register_native_plugin_notes(); -#endif #ifdef WANT_ZYNADDSUBFX // ZynAddSubFX diff --git a/source/modules/native-plugins/bigmeter.cpp b/source/modules/native-plugins/bigmeter.cpp index 8a3c22d3d..4077e370b 100644 --- a/source/modules/native-plugins/bigmeter.cpp +++ b/source/modules/native-plugins/bigmeter.cpp @@ -17,10 +17,6 @@ #include "CarlaDefines.h" -#ifdef CARLA_OS_WIN -# error This file should not be compiled for Windows -#endif - #include "CarlaMathUtils.hpp" #include "CarlaNativeExtUI.hpp" @@ -34,7 +30,7 @@ class BigMeterPlugin : public NativePluginAndUiClass { public: BigMeterPlugin(const NativeHostDescriptor* const host) - : NativePluginAndUiClass(host, "/bigmeter-ui"), + : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "bigmeter-ui"), fColor(1), fStyle(1), fOutLeft(0.0f), diff --git a/source/modules/native-plugins/notes.cpp b/source/modules/native-plugins/notes.cpp index bc86e58e0..8651cfec4 100644 --- a/source/modules/native-plugins/notes.cpp +++ b/source/modules/native-plugins/notes.cpp @@ -17,10 +17,6 @@ #include "CarlaDefines.h" -#ifdef CARLA_OS_WIN -# error This file should not be compiled for Windows -#endif - #include "CarlaNativeExtUI.hpp" // ----------------------------------------------------------------------- @@ -29,7 +25,7 @@ class NotesPlugin : public NativePluginAndUiClass { public: NotesPlugin(const NativeHostDescriptor* const host) - : NativePluginAndUiClass(host, "/notes-ui"), + : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "notes-ui"), fCurPage(1), leakDetector_NotesPlugin() {} diff --git a/source/modules/native-plugins/resources/carla-plugin b/source/modules/native-plugins/resources/carla-plugin index 5fd2fc328..2808de1c7 100755 --- a/source/modules/native-plugins/resources/carla-plugin +++ b/source/modules/native-plugins/resources/carla-plugin @@ -117,6 +117,12 @@ class CarlaMiniW(ExternalUI, HostWindow): # Custom callback def msgCallback(self, msg): + try: + self.msgCallback2(msg) + except: + print("msgCallback error, skipped for", msg) + + def msgCallback2(self, msg): msg = charPtrToString(msg) #if not msg: diff --git a/source/utils/CarlaPipeUtils.cpp b/source/utils/CarlaPipeUtils.cpp index 1f75dc634..d44ea89a2 100644 --- a/source/utils/CarlaPipeUtils.cpp +++ b/source/utils/CarlaPipeUtils.cpp @@ -60,7 +60,7 @@ struct OverlappedEvent { }; static inline -ssize_t ReadFileNonBlock(const HANDLE pipeh, const HANDLE cancelh, void* buf, size_t numBytes) +ssize_t ReadFileNonBlock(const HANDLE pipeh, const HANDLE cancelh, void* const buf, const std::size_t numBytes) { DWORD dsize; OverlappedEvent over; @@ -68,17 +68,47 @@ ssize_t ReadFileNonBlock(const HANDLE pipeh, const HANDLE cancelh, void* buf, si if (::ReadFile(pipeh, buf, numBytes, &dsize, &over.over) != FALSE) return static_cast(dsize); - if (GetLastError() == ERROR_IO_PENDING) + if (::GetLastError() == ERROR_IO_PENDING) { HANDLE handles[] = { over.over.hEvent, cancelh }; - if (WaitForMultipleObjects(2, handles, FALSE, 0) != WAIT_OBJECT_0) + if (::WaitForMultipleObjects(2, handles, FALSE, 0) != WAIT_OBJECT_0) { - CancelIo(pipeh); + ::CancelIo(pipeh); return -1; } - if (GetOverlappedResult(pipeh, &over.over, &dsize, FALSE) != FALSE) + if (::GetOverlappedResult(pipeh, &over.over, &dsize, FALSE) != FALSE) + return static_cast(dsize); + } + + return -1; +} +static inline +ssize_t WriteFileNonBlock(const HANDLE pipeh, const HANDLE cancelh, const void* const buf, const std::size_t numBytes) +{ + DWORD dsize; + if (::WriteFile(pipeh, buf, numBytes, &dsize, nullptr) != FALSE) + return static_cast(dsize); + return -1; + + //DWORD dsize; + OverlappedEvent over; + + if (::WriteFile(pipeh, buf, numBytes, &dsize, &over.over) != FALSE) + return static_cast(dsize); + + if (::GetLastError() == ERROR_IO_PENDING) + { + HANDLE handles[] = { over.over.hEvent, cancelh }; + + if (::WaitForMultipleObjects(2, handles, FALSE, 0) != WAIT_OBJECT_0) + { + ::CancelIo(pipeh); + return -1; + } + + if (::GetOverlappedResult(pipeh, &over.over, &dsize, FALSE) != FALSE) return static_cast(dsize); } @@ -113,12 +143,12 @@ bool startProcess(const char* const argv[], PROCESS_INFORMATION& processInfo) STARTUPINFOW startupInfo; carla_zeroStruct(startupInfo); -//# if 1 +# if 0 startupInfo.hStdInput = INVALID_HANDLE_VALUE; startupInfo.hStdOutput = INVALID_HANDLE_VALUE; startupInfo.hStdError = INVALID_HANDLE_VALUE; startupInfo.dwFlags = STARTF_USESTDHANDLES; -//# endif +# endif startupInfo.cb = sizeof(STARTUPINFOW); return CreateProcessW(nullptr, const_cast(command.toWideCharPointer()), @@ -798,13 +828,17 @@ bool CarlaPipeCommon::writeMsgBuffer(const char* const msg, const std::size_t si CARLA_SAFE_ASSERT_RETURN(pData->pipeSend != INVALID_PIPE_VALUE, false); + ssize_t ret; + try { #ifdef CARLA_OS_WIN - return (::WriteFile(pData->pipeSend, msg, size, nullptr, nullptr) != FALSE); + ret = ::WriteFileNonBlock(pData->pipeSend, pData->cancelEvent, msg, size); #else - return (::write(pData->pipeSend, msg, size) == static_cast(size)); + ret = ::write(pData->pipeSend, msg, size); #endif } CARLA_SAFE_EXCEPTION_RETURN("CarlaPipeCommon::writeMsgBuffer", false); + + return (ret == static_cast(size)); } // -----------------------------------------------------------------------