| @@ -411,7 +411,7 @@ endif | |||
| # -------------------------------------------------------------- | |||
| # Set libs stuff (part 3) | |||
| HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml zlib && echo true) | |||
| HAVE_ZYN_DEPS = $(shell pkg-config --exists liblo fftw3 mxml zlib && echo true) | |||
| ifeq ($(HAVE_FLTK),true) | |||
| HAVE_ZYN_UI_DEPS = true | |||
| endif | |||
| @@ -434,14 +434,14 @@ endif | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| BASE_FLAGS += -DHAVE_ZYN_DEPS | |||
| NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs fftw3 mxml zlib) | |||
| NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs liblo fftw3 mxml zlib) | |||
| ifeq ($(HAVE_ZYN_UI_DEPS),true) | |||
| BASE_FLAGS += -DHAVE_ZYN_UI_DEPS | |||
| ifeq ($(HAVE_NTK),true) | |||
| NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs ntk_images ntk) | |||
| else | |||
| NATIVE_PLUGINS_LIBS += $(shell fltk-config --use-images --ldstaticflags) | |||
| endif | |||
| # ifeq ($(HAVE_NTK),true) | |||
| # NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs ntk_images ntk) | |||
| # else | |||
| # NATIVE_PLUGINS_LIBS += $(shell fltk-config --use-images --ldstaticflags) | |||
| # endif | |||
| endif | |||
| endif | |||
| @@ -1627,7 +1627,7 @@ protected: | |||
| break; | |||
| case CarlaExternalUI::UiHide: | |||
| pHost->ui_closed(pHost->handle); | |||
| //fUiServer.stopPipeServer(1000); | |||
| fUiServer.stopPipeServer(1000); | |||
| break; | |||
| } | |||
| } | |||
| @@ -178,6 +178,7 @@ public: | |||
| fHost(), | |||
| fDescriptor(nullptr), | |||
| fIsProcessing(false), | |||
| fIsUiAvailable(false), | |||
| fIsUiVisible(false), | |||
| fAudioInBuffers(nullptr), | |||
| fAudioOutBuffers(nullptr), | |||
| @@ -744,12 +745,12 @@ public: | |||
| if (fDescriptor->ui_show == nullptr) | |||
| return; | |||
| const bool oldIsUiVisible(fIsUiVisible); | |||
| fIsUiAvailable = true; | |||
| fDescriptor->ui_show(fHandle, yesNo); | |||
| // UI might not be available, see NATIVE_HOST_OPCODE_UI_UNAVAILABLE | |||
| if (fIsUiVisible == yesNo || fIsUiVisible != oldIsUiVisible) | |||
| if (yesNo && ! fIsUiAvailable) | |||
| return; | |||
| fIsUiVisible = yesNo; | |||
| @@ -2265,7 +2266,7 @@ protected: | |||
| break; | |||
| case NATIVE_HOST_OPCODE_UI_UNAVAILABLE: | |||
| pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, nullptr); | |||
| fIsUiVisible = false; | |||
| fIsUiAvailable = false; | |||
| break; | |||
| case NATIVE_HOST_OPCODE_HOST_IDLE: | |||
| pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | |||
| @@ -2434,6 +2435,7 @@ private: | |||
| const NativePluginDescriptor* fDescriptor; | |||
| bool fIsProcessing; | |||
| bool fIsUiAvailable; | |||
| bool fIsUiVisible; | |||
| float** fAudioInBuffers; | |||
| @@ -36,10 +36,17 @@ public: | |||
| NativePluginAndUiClass(const NativeHostDescriptor* const host, const char* const extUiPath) | |||
| : NativePluginClass(host), | |||
| CarlaExternalUI(), | |||
| fExtUiPath(extUiPath), | |||
| leakDetector_NativePluginAndUiClass() {} | |||
| fExtUiPath(getResourceDir()), | |||
| leakDetector_NativePluginAndUiClass() | |||
| { | |||
| fExtUiPath += CARLA_OS_SEP_STR; | |||
| fExtUiPath += extUiPath; | |||
| } | |||
| //~NativePluginAndUiClass() noexcept override {} | |||
| const char* getExtUiPath() const noexcept | |||
| { | |||
| return fExtUiPath; | |||
| } | |||
| protected: | |||
| // ------------------------------------------------------------------- | |||
| @@ -57,15 +64,19 @@ protected: | |||
| return; | |||
| } | |||
| CarlaString path(getResourceDir() + fExtUiPath); | |||
| carla_stdout("Trying to start UI using \"%s\"", path.buffer()); | |||
| carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer()); | |||
| CarlaExternalUI::setData(path, getSampleRate(), getUiName()); | |||
| CarlaExternalUI::startPipeServer(true); | |||
| CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName()); | |||
| if (! CarlaExternalUI::startPipeServer(true)) | |||
| { | |||
| uiClosed(); | |||
| hostUiUnavailable(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| CarlaExternalUI::stopPipeServer(5000); | |||
| CarlaExternalUI::stopPipeServer(2000); | |||
| } | |||
| } | |||
| @@ -79,11 +90,12 @@ protected: | |||
| case CarlaExternalUI::UiShow: | |||
| break; | |||
| case CarlaExternalUI::UiCrashed: | |||
| uiClosed(); | |||
| hostUiUnavailable(); | |||
| break; | |||
| case CarlaExternalUI::UiHide: | |||
| uiClosed(); | |||
| //CarlaExternalUI::stopPipeServer(2000); | |||
| CarlaExternalUI::stopPipeServer(1000); | |||
| break; | |||
| } | |||
| } | |||
| @@ -153,6 +165,17 @@ protected: | |||
| flushMessages(); | |||
| } | |||
| void uiNameChanged(const char* const uiName) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',); | |||
| const CarlaMutexLocker cml(getPipeLock()); | |||
| writeMessage("uiTitle\n", 10); | |||
| writeAndFixMessage(uiName); | |||
| flushMessages(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Pipe Server calls | |||
| @@ -19,21 +19,29 @@ BUILD_CXX_FLAGS += -I.. -isystem $(CWD)/modules -I$(CWD)/modules/distrho | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) -isystem zynaddsubfx | |||
| ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib) | |||
| ZYN_LD_FLAGS = $(shell pkg-config --libs liblo) | |||
| ifeq ($(HAVE_ZYN_UI_DEPS),true) | |||
| ifeq ($(HAVE_NTK),true) | |||
| FLUID = ntk-fluid | |||
| ZYN_CXX_FLAGS += -DNTK_GUI | |||
| ZYN_CXX_FLAGS += $(shell pkg-config --cflags ntk_images ntk) | |||
| ZYN_LD_FLAGS += $(shell pkg-config --libs ntk_images ntk) | |||
| else # HAVE_NTK | |||
| FLUID = fluid | |||
| ZYN_CXX_FLAGS += -DFLTK_GUI | |||
| ZYN_CXX_FLAGS += $(shell fltk-config --use-images --cxxflags) | |||
| ZYN_LD_FLAGS += $(shell fltk-config --use-images --ldstaticflags) | |||
| endif # HAVE_NTK | |||
| else # HAVE_ZYN_UI_DEPS | |||
| ZYN_CXX_FLAGS += -DNO_UI | |||
| endif # HAVE_ZYN_UI_DEPS | |||
| endif # HAVE_ZYN_DEPS | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| # Set targets | |||
| TARGETS = $(MODULEDIR)/$(MODULENAME).a | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| # Set objects | |||
| @@ -95,8 +103,7 @@ OBJS += \ | |||
| $(OBJDIR)/zynaddsubfx-src.cpp.o | |||
| ifeq ($(HAVE_ZYN_UI_DEPS),true) | |||
| OBJS += \ | |||
| $(OBJDIR)/zynaddsubfx-ui.cpp.o | |||
| TARGETS += resources/zynaddsubfx-ui$(APP_EXT) | |||
| ZYN_UI_FILES_CPP = \ | |||
| zynaddsubfx/UI/ADnoteUI.cpp \ | |||
| @@ -148,7 +155,7 @@ endif | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| all: $(MODULEDIR)/$(MODULENAME).a | |||
| all: $(TARGETS) | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| @@ -166,6 +173,11 @@ $(MODULEDIR)/$(MODULENAME).a: $(OBJS) | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| resources/zynaddsubfx-ui$(APP_EXT): $(OBJDIR)/zynaddsubfx-ui.cpp.o $(MODULEDIR)/rtosc.a | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Linking zynaddsubfx-ui" | |||
| @$(CXX) $^ $(ZYN_LD_FLAGS) -o $@ | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| zynaddsubfx/UI/%.cpp: zynaddsubfx/UI/%.fl | |||
| @@ -283,5 +295,6 @@ $(OBJDIR)/%.cpp.o: %.cpp | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| -include $(OBJS:%.o=%.d) | |||
| -include $(OBJDIR)/zynaddsubfx-ui.cpp.d | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| @@ -31,7 +31,7 @@ class BigMeterPlugin : public NativePluginAndUiClass | |||
| { | |||
| public: | |||
| BigMeterPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "bigmeter-ui"), | |||
| : NativePluginAndUiClass(host, "bigmeter-ui"), | |||
| fColor(1), | |||
| fStyle(1), | |||
| fOutLeft(0.0f), | |||
| @@ -31,7 +31,7 @@ public: | |||
| }; | |||
| MidiSequencerPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "midiseq-ui"), | |||
| : NativePluginAndUiClass(host, "midiseq-ui"), | |||
| fNeedsAllNotesOff(false), | |||
| fWantInEvents(false), | |||
| fWasPlayingBefore(false), | |||
| @@ -25,7 +25,7 @@ class NotesPlugin : public NativePluginAndUiClass | |||
| { | |||
| public: | |||
| NotesPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "notes-ui"), | |||
| : NativePluginAndUiClass(host, "notes-ui"), | |||
| fCurPage(1), | |||
| leakDetector_NotesPlugin() {} | |||
| @@ -91,6 +91,7 @@ extern "C" { | |||
| // SYNTH_T* synth = nullptr; | |||
| class WavFile; | |||
| namespace Nio { | |||
| void masterSwap(Master*){} | |||
| // bool start(void){return 1;} | |||
| // void stop(void){} | |||
| // bool setSource(std::string){return true;} | |||
| @@ -15,7 +15,7 @@ | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaNative.hpp" | |||
| #include "CarlaNativeExtUI.hpp" | |||
| #include "CarlaMIDI.h" | |||
| #include "CarlaThread.hpp" | |||
| #include "LinkedList.hpp" | |||
| @@ -24,30 +24,12 @@ | |||
| #include "DSP/FFTwrapper.h" | |||
| #include "Misc/Master.h" | |||
| #include "Misc/MiddleWare.h" | |||
| #include "Misc/Part.h" | |||
| #include "Misc/Util.h" | |||
| #ifdef HAVE_ZYN_UI_DEPS | |||
| # define WANT_ZYNADDSUBFX_UI | |||
| #endif | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| # ifdef override | |||
| # define override_hack | |||
| # undef override | |||
| # endif | |||
| # include "UI/MasterUI.h" | |||
| # include <FL/Fl_Shared_Image.H> | |||
| # include <FL/Fl_Tiled_Image.H> | |||
| # ifdef NTK_GUI | |||
| # include <FL/Fl_Theme.H> | |||
| # endif | |||
| # ifdef override_hack | |||
| # define override | |||
| # undef override_hack | |||
| # endif | |||
| # include "UI/Connection.h" | |||
| #endif | |||
| #include <ctime> | |||
| @@ -58,8 +40,34 @@ | |||
| using juce::roundToIntAccurate; | |||
| using juce::FloatVectorOperations; | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| extern CarlaString gUiPixmapPath; | |||
| // ----------------------------------------------------------------------- | |||
| #ifdef HAVE_ZYN_UI_DEPS | |||
| namespace GUI { | |||
| Fl_Osc_Interface* genOscInterface(MiddleWare*) | |||
| { | |||
| return nullptr; | |||
| } | |||
| void raiseUi(ui_handle_t, const char *) | |||
| { | |||
| } | |||
| #if 0 | |||
| ui_handle_t createUi(Fl_Osc_Interface*, void *exit) | |||
| { | |||
| return nullptr; | |||
| } | |||
| void destroyUi(ui_handle_t) | |||
| { | |||
| } | |||
| void raiseUi(ui_handle_t, const char *, const char *, ...) | |||
| { | |||
| } | |||
| void tickUi(ui_handle_t) | |||
| { | |||
| //usleep(100000); | |||
| } | |||
| #endif | |||
| }; | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -227,30 +235,16 @@ static ZynAddSubFxPrograms sPrograms; | |||
| class ZynAddSubFxThread : public CarlaThread | |||
| { | |||
| public: | |||
| ZynAddSubFxThread(Master* const master, CarlaMutex& mutex, const NativeHostDescriptor* const host) | |||
| ZynAddSubFxThread(Master* const master, CarlaMutex& mutex) noexcept | |||
| : CarlaThread("ZynAddSubFxThread"), | |||
| fMaster(master), | |||
| fMutex(mutex), | |||
| kHost(host), | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| fUi(nullptr), | |||
| fUiClosed(0), | |||
| fNextUiAction(-1), | |||
| #endif | |||
| fChangeProgram(false), | |||
| fNextChannel(0), | |||
| fNextBank(0), | |||
| fNextProgram(0) {} | |||
| ~ZynAddSubFxThread() | |||
| { | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| // must be closed by now | |||
| CARLA_SAFE_ASSERT(fUi == nullptr); | |||
| #endif | |||
| } | |||
| void loadProgramLater(const uint8_t channel, const uint32_t bank, const uint32_t program) | |||
| void loadProgramLater(const uint8_t channel, const uint32_t bank, const uint32_t program) noexcept | |||
| { | |||
| fNextChannel = channel; | |||
| fNextBank = bank; | |||
| @@ -258,7 +252,7 @@ public: | |||
| fChangeProgram = true; | |||
| } | |||
| void stopLoadProgramLater() | |||
| void stopLoadProgramLater() noexcept | |||
| { | |||
| fChangeProgram = false; | |||
| fNextChannel = 0; | |||
| @@ -266,89 +260,16 @@ public: | |||
| fNextProgram = 0; | |||
| } | |||
| void setMaster(Master* const master) | |||
| void setMaster(Master* const master) noexcept | |||
| { | |||
| fMaster = master; | |||
| } | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| void uiHide() | |||
| { | |||
| fNextUiAction = 0; | |||
| } | |||
| void uiShow() | |||
| { | |||
| fNextUiAction = 1; | |||
| } | |||
| void uiRepaint() | |||
| { | |||
| if (fUi != nullptr) | |||
| fNextUiAction = 2; | |||
| } | |||
| void uiChangeName(const char* const name) | |||
| { | |||
| if (fUi != nullptr) | |||
| { | |||
| Fl::lock(); | |||
| fUi->masterwindow->label(name); | |||
| Fl::unlock(); | |||
| } | |||
| } | |||
| #endif | |||
| protected: | |||
| void run() override | |||
| { | |||
| while (! shouldThreadExit()) | |||
| { | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| Fl::lock(); | |||
| if (fNextUiAction == 2) // repaint | |||
| { | |||
| CARLA_ASSERT(fUi != nullptr); | |||
| if (fUi != nullptr) | |||
| fUi->refresh_master_ui(); | |||
| } | |||
| else if (fNextUiAction == 1) // init/show | |||
| { | |||
| if (fUi == nullptr) | |||
| { | |||
| fUiClosed = 0; | |||
| fUi = new MasterUI(&fUiClosed, &fOscIface); | |||
| fUi->masterwindow->label(kHost->uiName); | |||
| } | |||
| fUi->showUI(1); | |||
| } | |||
| else if (fNextUiAction == 0) // close | |||
| { | |||
| CARLA_ASSERT(fUi != nullptr); | |||
| if (fUi != nullptr) | |||
| { | |||
| delete fUi; | |||
| fUi = nullptr; | |||
| } | |||
| } | |||
| fNextUiAction = -1; | |||
| if (fUiClosed != 0) | |||
| { | |||
| fUiClosed = 0; | |||
| fNextUiAction = 0; | |||
| kHost->ui_closed(kHost->handle); | |||
| } | |||
| Fl::check(); | |||
| Fl::unlock(); | |||
| #endif | |||
| if (fChangeProgram) | |||
| { | |||
| fChangeProgram = false; | |||
| @@ -357,15 +278,6 @@ protected: | |||
| fNextBank = 0; | |||
| fNextProgram = 0; | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| if (fUi != nullptr) | |||
| { | |||
| Fl::lock(); | |||
| fUi->refresh_master_ui(); | |||
| Fl::unlock(); | |||
| } | |||
| #endif | |||
| carla_msleep(15); | |||
| } | |||
| else | |||
| @@ -373,30 +285,11 @@ protected: | |||
| carla_msleep(30); | |||
| } | |||
| } | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| if (fUi != nullptr) | |||
| { | |||
| Fl::lock(); | |||
| delete fUi; | |||
| fUi = nullptr; | |||
| Fl::check(); | |||
| Fl::unlock(); | |||
| } | |||
| #endif | |||
| } | |||
| private: | |||
| Master* fMaster; | |||
| CarlaMutex& fMutex; | |||
| const NativeHostDescriptor* const kHost; | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| MasterUI* fUi; | |||
| int fUiClosed; | |||
| volatile int fNextUiAction; | |||
| Fl_Osc_Interface fOscIface; | |||
| #endif | |||
| volatile bool fChangeProgram; | |||
| volatile uint8_t fNextChannel; | |||
| @@ -409,7 +302,7 @@ private: | |||
| // ----------------------------------------------------------------------- | |||
| class ZynAddSubFxPlugin : public NativePluginClass | |||
| class ZynAddSubFxPlugin : public NativePluginAndUiClass | |||
| { | |||
| public: | |||
| enum Parameters { | |||
| @@ -423,12 +316,13 @@ public: | |||
| }; | |||
| ZynAddSubFxPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginClass(host), | |||
| : NativePluginAndUiClass(host, "zynaddsubfx-ui"), | |||
| fMiddleWare(nullptr), | |||
| fMaster(nullptr), | |||
| fSynth(), | |||
| fIsActive(false), | |||
| fMutex(), | |||
| fThread(nullptr, fMutex, host), | |||
| fThread(nullptr, fMutex), | |||
| leakDetector_ZynAddSubFxPlugin() | |||
| { | |||
| // init parameters to default | |||
| @@ -447,9 +341,6 @@ public: | |||
| fSynth.alias(); | |||
| // FIXME | |||
| fSynth.samplerate_f = getSampleRate(); | |||
| _initMaster(); | |||
| sPrograms.initIfNeeded(); | |||
| @@ -565,9 +456,6 @@ protected: | |||
| if (isOffline() || ! fIsActive) | |||
| { | |||
| sPrograms.load(fMaster, fMutex, channel, bank, program); | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| fThread.uiRepaint(); | |||
| #endif | |||
| return; | |||
| } | |||
| @@ -674,16 +562,44 @@ protected: | |||
| fMutex.unlock(); | |||
| } | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| // ------------------------------------------------------------------- | |||
| // Plugin UI calls | |||
| #ifdef HAVE_ZYN_UI_DEPS | |||
| void uiShow(const bool show) override | |||
| { | |||
| if (show) | |||
| fThread.uiShow(); | |||
| { | |||
| if (isPipeRunning()) | |||
| { | |||
| const CarlaMutexLocker cml(getPipeLock()); | |||
| writeMessage("focus\n", 6); | |||
| flushMessages(); | |||
| return; | |||
| } | |||
| carla_stdout("Trying to start UI using \"%s\"", getExtUiPath()); | |||
| CarlaExternalUI::setData(getExtUiPath(), fMiddleWare->getServerAddress(), getUiName()); | |||
| if (! CarlaExternalUI::startPipeServer(true)) | |||
| { | |||
| uiClosed(); | |||
| hostUiUnavailable(); | |||
| } | |||
| } | |||
| else | |||
| fThread.uiHide(); | |||
| { | |||
| CarlaExternalUI::stopPipeServer(2000); | |||
| } | |||
| } | |||
| void uiIdle() override | |||
| { | |||
| NativePluginAndUiClass::uiIdle(); | |||
| if (isPipeRunning()) | |||
| fMiddleWare->tick(); | |||
| } | |||
| #endif | |||
| @@ -738,9 +654,6 @@ protected: | |||
| fSynth.samplerate = static_cast<uint>(sampleRate); | |||
| fSynth.alias(); | |||
| // FIXME | |||
| fSynth.samplerate_f = sampleRate; | |||
| _initMaster(); | |||
| if (state != nullptr) | |||
| @@ -751,20 +664,15 @@ protected: | |||
| } | |||
| } | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| void uiNameChanged(const char* const uiName) override | |||
| { | |||
| fThread.uiChangeName(uiName); | |||
| } | |||
| #endif | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| Master* fMaster; | |||
| SYNTH_T fSynth; | |||
| bool fIsActive; | |||
| float fParameters[kParamCount]; | |||
| MiddleWare* fMiddleWare; | |||
| Master* fMaster; | |||
| SYNTH_T fSynth; | |||
| bool fIsActive; | |||
| float fParameters[kParamCount]; | |||
| CarlaMutex fMutex; | |||
| ZynAddSubFxThread fThread; | |||
| @@ -796,7 +704,8 @@ private: | |||
| void _initMaster() | |||
| { | |||
| fMaster = new Master(fSynth); | |||
| fMiddleWare = new MiddleWare(fSynth); | |||
| fMaster = fMiddleWare->spawnMaster(); | |||
| fThread.setMaster(fMaster); | |||
| fThread.startThread(); | |||
| @@ -817,8 +726,9 @@ private: | |||
| //ensure that everything has stopped | |||
| fThread.stopThread(-1); | |||
| delete fMaster; | |||
| fMaster = nullptr; | |||
| delete fMiddleWare; | |||
| fMiddleWare = nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -839,10 +749,6 @@ public: | |||
| denormalkillbuf = new float[8192]; | |||
| for (int i=0; i < 8192; ++i) | |||
| denormalkillbuf[i] = (RND - 0.5f) * 1e-16f; | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| gUiPixmapPath = CarlaString(host->resourceDir) + CARLA_OS_SEP_STR "zynaddsubfx" CARLA_OS_SEP_STR; | |||
| #endif | |||
| } | |||
| return new ZynAddSubFxPlugin(host); | |||
| @@ -861,7 +767,7 @@ public: | |||
| static const NativePluginDescriptor zynaddsubfxDesc = { | |||
| /* category */ NATIVE_PLUGIN_CATEGORY_SYNTH, | |||
| /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH | |||
| #ifdef WANT_ZYNADDSUBFX_UI | |||
| #ifdef HAVE_ZYN_UI_DEPS | |||
| |NATIVE_PLUGIN_HAS_UI | |||
| #endif | |||
| |NATIVE_PLUGIN_USES_MULTI_PROGS | |||
| @@ -15,7 +15,7 @@ | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaString.hpp" | |||
| #include "CarlaPipeUtils.cpp" | |||
| #ifdef CARLA_OS_WIN | |||
| #define errx(...) | |||
| @@ -23,10 +23,10 @@ | |||
| #endif | |||
| #define PLUGINVERSION | |||
| #define SOURCE_DIR "/usr/share/zynaddsubfx/examples" | |||
| #define SOURCE_DIR "/usr/share/zynaddsubfx" | |||
| #undef override | |||
| CarlaString gUiPixmapPath; | |||
| CarlaString gUiPixmapPath("/usr/share/carla/resources/zynaddsubfx/"); | |||
| // zynaddsubfx ui includes | |||
| #include "zynaddsubfx/UI/NioUI.cpp" | |||
| @@ -35,7 +35,7 @@ CarlaString gUiPixmapPath; | |||
| #include "zynaddsubfx/UI/BankUI.cpp" | |||
| #include "zynaddsubfx/UI/BankView.cpp" | |||
| #include "zynaddsubfx/UI/ConfigUI.cpp" | |||
| #include "zynaddsubfx/UI/Connection.cpp" | |||
| // #include "zynaddsubfx/UI/Connection.cpp" | |||
| #include "zynaddsubfx/UI/EffUI.cpp" | |||
| #include "zynaddsubfx/UI/EnvelopeFreeEdit.cpp" | |||
| #include "zynaddsubfx/UI/EnvelopeUI.cpp" | |||
| @@ -69,3 +69,167 @@ CarlaString gUiPixmapPath; | |||
| #include "zynaddsubfx/UI/ResonanceUI.cpp" | |||
| #include "zynaddsubfx/UI/SUBnoteUI.cpp" | |||
| #include "zynaddsubfx/UI/VirKeyboard.cpp" | |||
| #include "zynaddsubfx/UI/guimain.cpp" | |||
| class ZynPipeClient : public CarlaPipeClient | |||
| { | |||
| public: | |||
| ZynPipeClient() noexcept | |||
| : CarlaPipeClient(), | |||
| fQuitReceived(false) {} | |||
| ~ZynPipeClient() noexcept override | |||
| { | |||
| if (fQuitReceived) | |||
| return; | |||
| const CarlaMutexLocker cml(getPipeLock()); | |||
| writeMessage("exiting\n"); | |||
| flushMessages(); | |||
| } | |||
| protected: | |||
| bool msgReceived(const char* const msg) noexcept override | |||
| { | |||
| if (std::strcmp(msg, "show") == 0) | |||
| { | |||
| try { | |||
| GUI::raiseUi(gui, "/show", "i", 1); | |||
| } CARLA_SAFE_EXCEPTION("msgReceived show"); | |||
| return true; | |||
| } | |||
| if (std::strcmp(msg, "hide") == 0) | |||
| { | |||
| try { | |||
| GUI::raiseUi(gui, "/hide", ""); | |||
| } CARLA_SAFE_EXCEPTION("msgReceived hide"); | |||
| return true; | |||
| } | |||
| if (std::strcmp(msg, "focus") == 0) | |||
| { | |||
| try { | |||
| GUI::raiseUi(gui, "/focus", ""); | |||
| } CARLA_SAFE_EXCEPTION("msgReceived focus"); | |||
| return true; | |||
| } | |||
| if (std::strcmp(msg, "uiTitle") == 0) | |||
| { | |||
| const char* uiTitle; | |||
| CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uiTitle), true); | |||
| try { | |||
| GUI::raiseUi(gui, "/title", "s", uiTitle); | |||
| } CARLA_SAFE_EXCEPTION("msgReceived uiTitle"); | |||
| return true; | |||
| } | |||
| if (std::strcmp(msg, "quit") == 0) | |||
| { | |||
| fQuitReceived = true; | |||
| try { | |||
| GUI::raiseUi(gui, "/close-ui", ""); | |||
| } CARLA_SAFE_EXCEPTION("msgReceived quit"); | |||
| return true; | |||
| } | |||
| carla_stderr("ZynPipeClient::msgReceived : %s", msg); | |||
| } | |||
| private: | |||
| bool fQuitReceived; | |||
| }; | |||
| int main(int argc, const char* argv[]) | |||
| { | |||
| ZynPipeClient pipe; | |||
| const char* uiTitle = nullptr; | |||
| // Startup Liblo Link | |||
| if (argc > 1) { | |||
| sendtourl = argv[1]; | |||
| uiTitle = argv[2]; | |||
| if (! pipe.initPipeClient(argv)) | |||
| return 1; | |||
| server = lo_server_new_with_proto(NULL, LO_UDP, liblo_error_cb); | |||
| lo_server_add_method(server, NULL, NULL, handler_function, 0); | |||
| } | |||
| gui = GUI::createUi(new UI_Interface(), &Pexitprogram); | |||
| if (argc == 1) | |||
| GUI::raiseUi(gui, "/show", "i", 1); | |||
| while(Pexitprogram == 0) { | |||
| if(server) | |||
| while(lo_server_recv_noblock(server, 0)); | |||
| pipe.idlePipe(); | |||
| GUI::tickUi(gui); | |||
| } | |||
| GUI::destroyUi(gui); | |||
| gui = nullptr; | |||
| return 0; | |||
| } | |||
| // -------------------------------------------------------------------------------------------- | |||
| // we need juce::Time::getMillisecondCounter() | |||
| #ifdef CARLA_OS_WIN | |||
| #include <ctime> | |||
| #else | |||
| #include <sys/time.h> | |||
| #endif | |||
| namespace juce { | |||
| #include "juce_core/native/juce_BasicNativeHeaders.h" | |||
| #include "juce_core/juce_core.h" | |||
| static uint32 lastMSCounterValue = 0; | |||
| #ifdef CARLA_OS_WIN | |||
| uint32 juce_millisecondsSinceStartup() noexcept | |||
| { | |||
| return (uint32) timeGetTime(); | |||
| } | |||
| #else | |||
| uint32 juce_millisecondsSinceStartup() noexcept | |||
| { | |||
| timespec t; | |||
| clock_gettime (CLOCK_MONOTONIC, &t); | |||
| return t.tv_sec * 1000 + t.tv_nsec / 1000000; | |||
| } | |||
| #endif | |||
| uint32 Time::getMillisecondCounter() noexcept | |||
| { | |||
| const uint32 now = juce_millisecondsSinceStartup(); | |||
| if (now < lastMSCounterValue) | |||
| { | |||
| // in multi-threaded apps this might be called concurrently, so | |||
| // make sure that our last counter value only increases and doesn't | |||
| // go backwards.. | |||
| if (now < lastMSCounterValue - 1000) | |||
| lastMSCounterValue = now; | |||
| } | |||
| else | |||
| { | |||
| lastMSCounterValue = now; | |||
| } | |||
| return now; | |||
| } | |||
| } // namespace juce | |||
| // -------------------------------------------------------------------------------------------- | |||
| @@ -1,7 +1,4 @@ | |||
| #ifndef ALLOCATOR_H | |||
| #define ALLOCATOR_H | |||
| #pragma once | |||
| #include <cstdlib> | |||
| #include <utility> | |||
| @@ -109,5 +106,3 @@ extern Allocator DummyAlloc; | |||
| * * A new one is constructed with a deep copy | |||
| * * The old one is returned to middleware for deallocation | |||
| */ | |||
| #endif | |||
| @@ -612,7 +612,6 @@ void Master::AudioOut(float *outl, float *outr) | |||
| while(uToB && uToB->hasNext() && events < 10) { | |||
| const char *msg = uToB->read(); | |||
| #ifndef PLUGINVERSION | |||
| if(!strcmp(msg, "/load-master")) { | |||
| Master *this_master = this; | |||
| Master *new_master = *(Master**)rtosc_argument(msg, 0).b.data; | |||
| @@ -621,7 +620,6 @@ void Master::AudioOut(float *outl, float *outr) | |||
| bToU->write("/free", "sb", "Master", sizeof(Master*), &this_master); | |||
| return; | |||
| } | |||
| #endif | |||
| //XXX yes, this is not realtime safe, but it is useful... | |||
| if(strcmp(msg, "/get-vu") && false) { | |||
| @@ -650,7 +648,7 @@ void Master::AudioOut(float *outl, float *outr) | |||
| } | |||
| if(events>1 && false) | |||
| fprintf(stderr, "backend: %d events per cycle\n",events); | |||
| //Swaps the Left channel with Right Channel | |||
| if(swaplr) | |||
| @@ -204,11 +204,15 @@ void refreshBankView(const Bank &bank, unsigned loc, Fl_Osc_Interface *osc) | |||
| errx(1, "Failure to handle bank update properly..."); | |||
| osc->tryLink(response); | |||
| if (osc) | |||
| osc->tryLink(response); | |||
| } | |||
| void bankList(Bank &bank, Fl_Osc_Interface *osc) | |||
| { | |||
| if (! osc) | |||
| return; | |||
| char response[2048]; | |||
| int i = 0; | |||
| @@ -242,7 +246,8 @@ void bankPos(Bank &bank, Fl_Osc_Interface *osc) | |||
| if(!rtosc_message(response, 2048, "/loadbank", "i", bank.bankpos)) | |||
| errx(1, "Failure to handle bank update properly..."); | |||
| osc->tryLink(response); | |||
| if (osc) | |||
| osc->tryLink(response); | |||
| } | |||
| /***************************************************************************** | |||
| @@ -1289,8 +1294,13 @@ void MiddleWare::activeUrl(std::string u) | |||
| { | |||
| impl->last_url = u; | |||
| } | |||
| const SYNTH_T &MiddleWare::getSynth(void) const | |||
| { | |||
| return impl->synth; | |||
| } | |||
| const char* MiddleWare::getServerAddress(void) const | |||
| { | |||
| return lo_server_get_url(impl->server); | |||
| } | |||
| @@ -35,6 +35,8 @@ class MiddleWare | |||
| void activeUrl(std::string u); | |||
| //View Synthesis Parameters | |||
| const SYNTH_T &getSynth(void) const; | |||
| //liblo stuff | |||
| const char* getServerAddress(void) const; | |||
| private: | |||
| class MiddleWareImpl *impl; | |||
| }; | |||
| @@ -273,9 +273,6 @@ const Ports &ADnoteParameters::ports = adPorts; | |||
| const Ports &ADnoteVoiceParam::ports = voicePorts; | |||
| const Ports &ADnoteGlobalParam::ports = globalPorts; | |||
| int ADnote_unison_sizes[] = | |||
| {1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; | |||
| ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_) | |||
| :PresetsArray() | |||
| { | |||
| @@ -29,7 +29,8 @@ | |||
| enum FMTYPE { | |||
| NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD | |||
| }; | |||
| extern int ADnote_unison_sizes[]; | |||
| static const int ADnote_unison_sizes[] = | |||
| {1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; | |||
| /*****************************************************************/ | |||
| /* GLOBAL PARAMETERS */ | |||
| @@ -34,9 +34,6 @@ NSM_Client *nsm = 0; | |||
| lo_server server; | |||
| std::string sendtourl; | |||
| int ADnote_unison_sizes[] = | |||
| {1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; | |||
| /* | |||
| * Program exit | |||
| */ | |||
| @@ -128,23 +125,38 @@ ui_handle_t GUI::createUi(Fl_Osc_Interface *osc, void *exit) | |||
| Fl_Dial::default_style(Fl_Dial::PIXMAP_DIAL); | |||
| #ifdef CARLA_VERSION_STRING | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(gUiPixmapPath + "knob.png")) | |||
| Fl_Dial::default_image(img); | |||
| #else | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(PIXMAP_PATH "/knob.png")) | |||
| Fl_Dial::default_image(img); | |||
| #endif | |||
| else if(Fl_Shared_Image *img = Fl_Shared_Image::get(SOURCE_DIR "/pixmaps/knob.png")) | |||
| Fl_Dial::default_image(img); | |||
| else | |||
| errx(1, "ERROR: Cannot find pixmaps/knob.png"); | |||
| #ifdef CARLA_VERSION_STRING | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(gUiPixmapPath + "window_backdrop.png")) | |||
| Fl::scheme_bg(new Fl_Tiled_Image(img)); | |||
| #else | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(PIXMAP_PATH "/window_backdrop.png")) | |||
| Fl::scheme_bg(new Fl_Tiled_Image(img)); | |||
| #endif | |||
| else if(Fl_Shared_Image *img = Fl_Shared_Image::get(SOURCE_DIR "/pixmaps/window_backdrop.png")) | |||
| Fl::scheme_bg(new Fl_Tiled_Image(img)); | |||
| else | |||
| errx(1, "ERROR: Cannot find pixmaps/window_backdrop.png"); | |||
| #ifdef CARLA_VERSION_STRING | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(gUiPixmapPath + "module_backdrop.png")) | |||
| module_backdrop = new Fl_Tiled_Image(img); | |||
| #else | |||
| if(Fl_Shared_Image *img = Fl_Shared_Image::get(PIXMAP_PATH "/module_backdrop.png")) | |||
| module_backdrop = new Fl_Tiled_Image(img); | |||
| #endif | |||
| else if(Fl_Shared_Image *img = Fl_Shared_Image::get(SOURCE_DIR "/pixmaps/module_backdrop.png")) | |||
| module_backdrop = new Fl_Tiled_Image(img); | |||
| else | |||
| @@ -510,6 +522,7 @@ static int handler_function(const char *path, const char *types, lo_arg **argv, | |||
| return 0; | |||
| } | |||
| #ifndef CARLA_VERSION_STRING | |||
| int main(int argc, char *argv[]) | |||
| { | |||
| //Startup Liblo Link | |||
| @@ -531,3 +544,4 @@ int main(int argc, char *argv[]) | |||
| exitprogram(); | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -35,8 +35,8 @@ public: | |||
| CarlaExternalUI() noexcept | |||
| : fFilename(), | |||
| fSampleRate(), | |||
| fUiTitle(), | |||
| fArg1(), | |||
| fArg2(), | |||
| fUiState(UiNone), | |||
| leakDetector_CarlaExternalUI() {} | |||
| @@ -52,16 +52,23 @@ public: | |||
| return uiState; | |||
| } | |||
| void setData(const char* const filename, const char* const arg1, const char* const arg2) noexcept | |||
| { | |||
| fFilename = filename; | |||
| fArg1 = arg1; | |||
| fArg2 = arg2; | |||
| } | |||
| void setData(const char* const filename, const double sampleRate, const char* const uiTitle) noexcept | |||
| { | |||
| fFilename = filename; | |||
| fSampleRate = CarlaString(sampleRate); | |||
| fUiTitle = uiTitle; | |||
| fFilename = filename; | |||
| fArg1 = CarlaString(sampleRate); | |||
| fArg2 = uiTitle; | |||
| } | |||
| bool startPipeServer(const bool show = true) noexcept | |||
| { | |||
| if (CarlaPipeServer::startPipeServer(fFilename, fSampleRate, fUiTitle)) | |||
| if (CarlaPipeServer::startPipeServer(fFilename, fArg1, fArg2)) | |||
| { | |||
| if (show) | |||
| writeShowMessage(); | |||
| @@ -87,8 +94,8 @@ protected: | |||
| private: | |||
| CarlaString fFilename; | |||
| CarlaString fSampleRate; | |||
| CarlaString fUiTitle; | |||
| CarlaString fArg1; | |||
| CarlaString fArg2; | |||
| UiState fUiState; | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaExternalUI) | |||