| @@ -13,12 +13,8 @@ OBJS_standalone = \ | |||||
| $(OBJDIR)/CarlaStandalone.cpp.o \ | $(OBJDIR)/CarlaStandalone.cpp.o \ | ||||
| $(OBJDIR)/CarlaStandaloneNSM.cpp.o | $(OBJDIR)/CarlaStandaloneNSM.cpp.o | ||||
| OBJS_utils = \ | |||||
| $(OBJDIR)/CarlaUtils.cpp.o | |||||
| TARGETS = \ | TARGETS = \ | ||||
| $(BINDIR)/libcarla_standalone2$(LIB_EXT) \ | |||||
| $(BINDIR)/libcarla_utils$(LIB_EXT) | |||||
| $(BINDIR)/libcarla_standalone2$(LIB_EXT) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -44,9 +40,6 @@ endif | |||||
| STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a | STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a | ||||
| STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a | STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a | ||||
| UTILS_LIBS += $(MODULEDIR)/lilv.a | |||||
| UTILS_LIBS += $(MODULEDIR)/water.files.a | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| STANDALONE_LINK_FLAGS = $(JACKBRIDGE_LIBS) | STANDALONE_LINK_FLAGS = $(JACKBRIDGE_LIBS) | ||||
| @@ -64,17 +57,6 @@ STANDALONE_LINK_FLAGS += $(FLUIDSYNTH_LIBS) | |||||
| STANDALONE_LINK_FLAGS += $(LINUXSAMPLER_LIBS) | STANDALONE_LINK_FLAGS += $(LINUXSAMPLER_LIBS) | ||||
| STANDALONE_LINK_FLAGS += $(X11_LIBS) | STANDALONE_LINK_FLAGS += $(X11_LIBS) | ||||
| UTILS_LINK_FLAGS += $(LILV_LIBS) | |||||
| UTILS_LINK_FLAGS += $(WATER_LIBS) | |||||
| ifeq ($(HAVE_X11),true) | |||||
| UTILS_LINK_FLAGS += $(X11_LIBS) | |||||
| endif | |||||
| ifneq ($(HAIKU),true) | |||||
| UTILS_LINK_FLAGS += -lpthread | |||||
| endif | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| all: $(TARGETS) | all: $(TARGETS) | ||||
| @@ -82,9 +64,10 @@ all: $(TARGETS) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| clean: | clean: | ||||
| rm -f $(OBJS_standalone) $(OBJS_utils) $(TARGETS) | |||||
| rm -f $(OBJS_standalone) $(TARGETS) | |||||
| $(MAKE) clean -C engine | $(MAKE) clean -C engine | ||||
| $(MAKE) clean -C plugin | $(MAKE) clean -C plugin | ||||
| $(MAKE) clean -C utils | |||||
| debug: | debug: | ||||
| $(MAKE) DEBUG=true | $(MAKE) DEBUG=true | ||||
| @@ -99,11 +82,6 @@ $(BINDIR)/libcarla_standalone2$(LIB_EXT): $(OBJS_standalone) $(STANDALONE_LIBS) | |||||
| @echo "Linking libcarla_standalone2$(LIB_EXT)" | @echo "Linking libcarla_standalone2$(LIB_EXT)" | ||||
| @$(CXX) $(OBJS_standalone) $(LIBS_START) $(STANDALONE_LIBS) $(LIBS_END) $(LINK_FLAGS) $(STANDALONE_LINK_FLAGS) $(SHARED) -o $@ | @$(CXX) $(OBJS_standalone) $(LIBS_START) $(STANDALONE_LIBS) $(LIBS_END) $(LINK_FLAGS) $(STANDALONE_LINK_FLAGS) $(SHARED) -o $@ | ||||
| $(BINDIR)/libcarla_utils$(LIB_EXT): $(OBJS_utils) $(UTILS_LIBS) | |||||
| -@mkdir -p $(BINDIR) | |||||
| @echo "Linking libcarla_utils$(LIB_EXT)" | |||||
| @$(CXX) $(OBJS_utils) $(LIBS_START) $(UTILS_LIBS) $(LIBS_END) $(LINK_FLAGS) $(UTILS_LINK_FLAGS) $(SHARED) -o $@ | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -111,11 +89,6 @@ $(OBJDIR)/CarlaStandalone.cpp.o: CarlaStandalone.cpp | |||||
| -@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
| @echo "Compiling $<" | @echo "Compiling $<" | ||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | ||||
| $(OBJDIR)/CarlaUtils.cpp.o: CarlaUtils.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling $<" | |||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | |||||
| endif | endif | ||||
| $(OBJDIR)/%.cpp.o: %.cpp | $(OBJDIR)/%.cpp.o: %.cpp | ||||
| @@ -124,6 +97,5 @@ $(OBJDIR)/%.cpp.o: %.cpp | |||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
| -include $(OBJS_standalone:%.o=%.d) | -include $(OBJS_standalone:%.o=%.d) | ||||
| -include $(OBJS_utils:%.o=%.d) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -18,28 +18,8 @@ | |||||
| #include "CarlaUtils.h" | #include "CarlaUtils.h" | ||||
| #include "CarlaNative.h" | #include "CarlaNative.h" | ||||
| #include "CarlaBackendUtils.hpp" | |||||
| #include "CarlaString.hpp" | |||||
| #include "CarlaLv2Utils.hpp" | #include "CarlaLv2Utils.hpp" | ||||
| #include "CarlaPipeUtils.hpp" | |||||
| #include "CarlaThread.hpp" | |||||
| #include "LinkedList.hpp" | |||||
| #include "water/files/File.h" | |||||
| #ifdef CARLA_OS_MAC | |||||
| # import <Cocoa/Cocoa.h> | |||||
| #endif | |||||
| #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| # include "rtaudio/RtAudio.h" | |||||
| # include "rtmidi/RtMidi.h" | |||||
| # ifdef HAVE_X11 | |||||
| # include <X11/Xlib.h> | |||||
| # endif | |||||
| #endif | |||||
| #include "../native-plugins/_data.all.cpp" | |||||
| namespace CB = CarlaBackend; | namespace CB = CarlaBackend; | ||||
| @@ -429,409 +409,8 @@ const CarlaCachedPluginInfo* carla_get_cached_plugin_info(CB::PluginType ptype, | |||||
| return &info; | return &info; | ||||
| } | } | ||||
| #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| const char* carla_get_complete_license_text() | |||||
| { | |||||
| carla_debug("carla_get_complete_license_text()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| "<p>This current Carla build is using the following features and 3rd-party code:</p>" | |||||
| "<ul>" | |||||
| // Plugin formats | |||||
| "<li>LADSPA plugin support</li>" | |||||
| "<li>DSSI plugin support</li>" | |||||
| "<li>LV2 plugin support</li>" | |||||
| "<li>VST2 plugin support using VeSTige header by Javier Serrano Polo</li>" | |||||
| // Sample kit libraries | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "<li>FluidSynth library for SF2/3 support</li>" | |||||
| #endif | |||||
| "<li>SFZero module for SFZ support</li>" | |||||
| // misc libs | |||||
| "<li>base64 utilities based on code by Ren\u00E9 Nyffenegger</li>" | |||||
| "<li>liblo library for OSC support</li>" | |||||
| "<li>rtmempool library by Nedko Arnaudov" | |||||
| "<li>serd, sord, sratom and lilv libraries for LV2 discovery</li>" | |||||
| "<li>RtAudio v" RTAUDIO_VERSION " and RtMidi v" RTMIDI_VERSION " for native Audio and MIDI support</li>" | |||||
| // Internal plugins | |||||
| "<li>MIDI Sequencer UI code by Perry Nguyen</li>" | |||||
| // External plugins | |||||
| #ifdef HAVE_EXTERNAL_PLUGINS | |||||
| "<li>Nekobi plugin code based on nekobee by Sean Bolton and others</li>" | |||||
| "<li>VectorJuice and WobbleJuice plugin code by Andre Sklenar</li>" | |||||
| # ifdef HAVE_ZYN_DEPS | |||||
| "<li>ZynAddSubFX plugin code by Mark McCurry and Nasca Octavian Paul</li>" | |||||
| # endif | |||||
| #endif // HAVE_EXTERNAL_PLUGINS | |||||
| // end | |||||
| "</ul>"; | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| const char* const* carla_get_supported_file_extensions() | |||||
| { | |||||
| carla_debug("carla_get_supported_file_extensions()"); | |||||
| // NOTE: please keep in sync with CarlaEngine::loadFile!! | |||||
| static const char* const extensions[] = { | |||||
| // Base types | |||||
| "carxp", "carxs", | |||||
| // plugin files and resources | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "sf2", "sf3", | |||||
| #endif | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| "xmz", "xiz", | |||||
| #endif | |||||
| #if defined(CARLA_OS_MAC) | |||||
| "vst", | |||||
| #else | |||||
| "dll", | |||||
| "so", | |||||
| #endif | |||||
| // Audio files | |||||
| #ifdef HAVE_SNDFILE | |||||
| "aif", "aifc", "aiff", "au", "bwf", "flac", "htk", "iff", "mat4", "mat5", "oga", "ogg", | |||||
| "paf", "pvf", "pvf5", "sd2", "sf", "snd", "svx", "vcc", "w64", "wav", "xi", | |||||
| #endif | |||||
| #ifdef HAVE_FFMPEG | |||||
| "3g2", "3gp", "aac", "ac3", "amr", "ape", "mp2", "mp3", "mpc", "wma", | |||||
| # ifdef HAVE_SNDFILE | |||||
| // FFmpeg without sndfile | |||||
| "flac", "oga", "ogg", "w64", "wav", | |||||
| # endif | |||||
| #endif | |||||
| // MIDI files | |||||
| "mid", "midi", | |||||
| // SFZ | |||||
| "sfz", | |||||
| // terminator | |||||
| nullptr | |||||
| }; | |||||
| return extensions; | |||||
| } | |||||
| const char* const* carla_get_supported_features() | |||||
| { | |||||
| carla_debug("carla_get_supported_features()"); | |||||
| static const char* const features[] = { | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "sf2", | |||||
| #endif | |||||
| #ifdef HAVE_HYLIA | |||||
| "link", | |||||
| #endif | |||||
| #ifdef HAVE_LIBLO | |||||
| "osc", | |||||
| #endif | |||||
| #if defined(HAVE_LIBMAGIC) || defined(CARLA_OS_WIN) | |||||
| "bridges", | |||||
| #endif | |||||
| #ifdef HAVE_PYQT | |||||
| "gui", | |||||
| #endif | |||||
| nullptr | |||||
| }; | |||||
| return features; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| void carla_fflush(bool err) | |||||
| { | |||||
| std::fflush(err ? stderr : stdout); | |||||
| } | |||||
| void carla_fputs(bool err, const char* string) | |||||
| { | |||||
| std::fputs(string, err ? stderr : stdout); | |||||
| } | |||||
| void carla_set_process_name(const char* name) | |||||
| { | |||||
| carla_debug("carla_set_process_name(\"%s\")", name); | |||||
| CarlaThread::setCurrentThreadName(name); | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| class CarlaPipeClientPlugin : public CarlaPipeClient | |||||
| { | |||||
| public: | |||||
| CarlaPipeClientPlugin(const CarlaPipeCallbackFunc callbackFunc, void* const callbackPtr) noexcept | |||||
| : CarlaPipeClient(), | |||||
| fCallbackFunc(callbackFunc), | |||||
| fCallbackPtr(callbackPtr), | |||||
| fLastReadLine(nullptr) | |||||
| { | |||||
| CARLA_SAFE_ASSERT(fCallbackFunc != nullptr); | |||||
| } | |||||
| ~CarlaPipeClientPlugin() override | |||||
| { | |||||
| if (fLastReadLine != nullptr) | |||||
| { | |||||
| delete[] fLastReadLine; | |||||
| fLastReadLine = nullptr; | |||||
| } | |||||
| } | |||||
| const char* readlineblock(const uint timeout) noexcept | |||||
| { | |||||
| delete[] fLastReadLine; | |||||
| fLastReadLine = CarlaPipeClient::_readlineblock(timeout); | |||||
| return fLastReadLine; | |||||
| } | |||||
| bool msgReceived(const char* const msg) noexcept override | |||||
| { | |||||
| if (fCallbackFunc != nullptr) | |||||
| { | |||||
| try { | |||||
| fCallbackFunc(fCallbackPtr, msg); | |||||
| } CARLA_SAFE_EXCEPTION("msgReceived"); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| private: | |||||
| const CarlaPipeCallbackFunc fCallbackFunc; | |||||
| void* const fCallbackPtr; | |||||
| const char* fLastReadLine; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClientPlugin) | |||||
| }; | |||||
| CarlaPipeClientHandle carla_pipe_client_new(const char* argv[], CarlaPipeCallbackFunc callbackFunc, void* callbackPtr) | |||||
| { | |||||
| carla_debug("carla_pipe_client_new(%p, %p, %p)", argv, callbackFunc, callbackPtr); | |||||
| CarlaPipeClientPlugin* const pipe(new CarlaPipeClientPlugin(callbackFunc, callbackPtr)); | |||||
| if (! pipe->initPipeClient(argv)) | |||||
| { | |||||
| delete pipe; | |||||
| return nullptr; | |||||
| } | |||||
| return pipe; | |||||
| } | |||||
| void carla_pipe_client_idle(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| ((CarlaPipeClientPlugin*)handle)->idlePipe(); | |||||
| } | |||||
| bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->isPipeRunning(); | |||||
| } | |||||
| void carla_pipe_client_lock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| return ((CarlaPipeClientPlugin*)handle)->lockPipe(); | |||||
| } | |||||
| void carla_pipe_client_unlock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| return ((CarlaPipeClientPlugin*)handle)->unlockPipe(); | |||||
| } | |||||
| const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); | |||||
| return ((CarlaPipeClientPlugin*)handle)->readlineblock(timeout); | |||||
| } | |||||
| bool carla_pipe_client_write_msg(CarlaPipeClientHandle handle, const char* msg) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeMessage(msg); | |||||
| } | |||||
| bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMessage(msg); | |||||
| } | |||||
| bool carla_pipe_client_flush(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->flushMessages(); | |||||
| } | |||||
| bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||||
| const bool ret(pipe->flushMessages()); | |||||
| pipe->unlockPipe(); | |||||
| return ret; | |||||
| } | |||||
| void carla_pipe_client_destroy(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| carla_debug("carla_pipe_client_destroy(%p)", handle); | |||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||||
| pipe->closePipeClient(); | |||||
| delete pipe; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| const char* carla_get_library_filename() | |||||
| { | |||||
| carla_debug("carla_get_library_filename()"); | |||||
| static CarlaString ret; | |||||
| if (ret.isEmpty()) | |||||
| { | |||||
| using water::File; | |||||
| ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| const char* carla_get_library_folder() | |||||
| { | |||||
| carla_debug("carla_get_library_folder()"); | |||||
| static CarlaString ret; | |||||
| if (ret.isEmpty()) | |||||
| { | |||||
| using water::File; | |||||
| ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| void carla_x11_reparent_window(uintptr_t winId1, uintptr_t winId2) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(winId1 != 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(winId2 != 0,); | |||||
| #ifdef HAVE_X11 | |||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| XReparentWindow(disp, winId1, winId2, 0, 0); | |||||
| XMapWindow(disp, winId1); | |||||
| XCloseDisplay(disp); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void carla_x11_move_window(uintptr_t winId, int x, int y) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(winId != 0,); | |||||
| #ifdef HAVE_X11 | |||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| XMoveWindow(disp, winId, x, y); | |||||
| XCloseDisplay(disp); | |||||
| } | |||||
| #else | |||||
| // unused | |||||
| return; (void)x; (void)y; | |||||
| #endif | |||||
| } | |||||
| int* carla_x11_get_window_pos(uintptr_t winId) | |||||
| { | |||||
| static int pos[2]; | |||||
| if (winId == 0) | |||||
| { | |||||
| pos[0] = 0; | |||||
| pos[1] = 0; | |||||
| } | |||||
| #ifdef HAVE_X11 | |||||
| else if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| int x, y; | |||||
| Window child; | |||||
| XWindowAttributes xwa; | |||||
| XTranslateCoordinates(disp, winId, XRootWindow(disp, 0), 0, 0, &x, &y, &child); | |||||
| XGetWindowAttributes(disp, winId, &xwa); | |||||
| XCloseDisplay(disp); | |||||
| pos[0] = x - xwa.x; | |||||
| pos[1] = y - xwa.y; | |||||
| } | |||||
| #endif | |||||
| else | |||||
| { | |||||
| pos[0] = 0; | |||||
| pos[1] = 0; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int carla_cocoa_get_window(void* nsViewPtr) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(nsViewPtr != nullptr, 0); | |||||
| #ifdef CARLA_OS_MAC | |||||
| NSView* nsView = (NSView*)nsViewPtr; | |||||
| return [[nsView window] windowNumber]; | |||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| #include "CarlaPipeUtils.cpp" | |||||
| #if !(defined(DEBUG) || defined(BUILDING_CARLA_FOR_WINDOWS)) | |||||
| # include "water/misc/Time.cpp" | |||||
| #endif | |||||
| #include "../native-plugins/_data.all.cpp" | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| #endif // CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| @@ -0,0 +1,186 @@ | |||||
| /* | |||||
| * Carla Plugin Host | |||||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 2 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 doc/GPL.txt file. | |||||
| */ | |||||
| #include "CarlaUtils.h" | |||||
| #include "CarlaString.hpp" | |||||
| #include "rtaudio/RtAudio.h" | |||||
| #include "rtmidi/RtMidi.h" | |||||
| #include "water/files/File.h" | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| const char* carla_get_complete_license_text() | |||||
| { | |||||
| carla_debug("carla_get_complete_license_text()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| "<p>This current Carla build is using the following features and 3rd-party code:</p>" | |||||
| "<ul>" | |||||
| // Plugin formats | |||||
| "<li>LADSPA plugin support</li>" | |||||
| "<li>DSSI plugin support</li>" | |||||
| "<li>LV2 plugin support</li>" | |||||
| "<li>VST2 plugin support using VeSTige header by Javier Serrano Polo</li>" | |||||
| // Sample kit libraries | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "<li>FluidSynth library for SF2/3 support</li>" | |||||
| #endif | |||||
| "<li>SFZero module for SFZ support</li>" | |||||
| // misc libs | |||||
| "<li>base64 utilities based on code by Ren\u00E9 Nyffenegger</li>" | |||||
| "<li>liblo library for OSC support</li>" | |||||
| "<li>rtmempool library by Nedko Arnaudov" | |||||
| "<li>serd, sord, sratom and lilv libraries for LV2 discovery</li>" | |||||
| "<li>RtAudio v" RTAUDIO_VERSION " and RtMidi v" RTMIDI_VERSION " for native Audio and MIDI support</li>" | |||||
| // Internal plugins | |||||
| "<li>MIDI Sequencer UI code by Perry Nguyen</li>" | |||||
| // External plugins | |||||
| #ifdef HAVE_EXTERNAL_PLUGINS | |||||
| "<li>Nekobi plugin code based on nekobee by Sean Bolton and others</li>" | |||||
| "<li>VectorJuice and WobbleJuice plugin code by Andre Sklenar</li>" | |||||
| # ifdef HAVE_ZYN_DEPS | |||||
| "<li>ZynAddSubFX plugin code by Mark McCurry and Nasca Octavian Paul</li>" | |||||
| # endif | |||||
| #endif // HAVE_EXTERNAL_PLUGINS | |||||
| // end | |||||
| "</ul>"; | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| const char* const* carla_get_supported_file_extensions() | |||||
| { | |||||
| carla_debug("carla_get_supported_file_extensions()"); | |||||
| // NOTE: please keep in sync with CarlaEngine::loadFile!! | |||||
| static const char* const extensions[] = { | |||||
| // Base types | |||||
| "carxp", "carxs", | |||||
| // plugin files and resources | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "sf2", "sf3", | |||||
| #endif | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| "xmz", "xiz", | |||||
| #endif | |||||
| #if defined(CARLA_OS_MAC) | |||||
| "vst", | |||||
| #else | |||||
| "dll", | |||||
| "so", | |||||
| #endif | |||||
| // Audio files | |||||
| #ifdef HAVE_SNDFILE | |||||
| "aif", "aifc", "aiff", "au", "bwf", "flac", "htk", "iff", "mat4", "mat5", "oga", "ogg", | |||||
| "paf", "pvf", "pvf5", "sd2", "sf", "snd", "svx", "vcc", "w64", "wav", "xi", | |||||
| #endif | |||||
| #ifdef HAVE_FFMPEG | |||||
| "3g2", "3gp", "aac", "ac3", "amr", "ape", "mp2", "mp3", "mpc", "wma", | |||||
| # ifdef HAVE_SNDFILE | |||||
| // FFmpeg without sndfile | |||||
| "flac", "oga", "ogg", "w64", "wav", | |||||
| # endif | |||||
| #endif | |||||
| // MIDI files | |||||
| "mid", "midi", | |||||
| // SFZ | |||||
| "sfz", | |||||
| // terminator | |||||
| nullptr | |||||
| }; | |||||
| return extensions; | |||||
| } | |||||
| const char* const* carla_get_supported_features() | |||||
| { | |||||
| carla_debug("carla_get_supported_features()"); | |||||
| static const char* const features[] = { | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "sf2", | |||||
| #endif | |||||
| #ifdef HAVE_HYLIA | |||||
| "link", | |||||
| #endif | |||||
| #ifdef HAVE_LIBLO | |||||
| "osc", | |||||
| #endif | |||||
| #if defined(HAVE_LIBMAGIC) || defined(CARLA_OS_WIN) | |||||
| "bridges", | |||||
| #endif | |||||
| #ifdef HAVE_PYQT | |||||
| "gui", | |||||
| #endif | |||||
| nullptr | |||||
| }; | |||||
| return features; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| const char* carla_get_library_filename() | |||||
| { | |||||
| carla_debug("carla_get_library_filename()"); | |||||
| static CarlaString ret; | |||||
| if (ret.isEmpty()) | |||||
| { | |||||
| using water::File; | |||||
| ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| const char* carla_get_library_folder() | |||||
| { | |||||
| carla_debug("carla_get_library_folder()"); | |||||
| static CarlaString ret; | |||||
| if (ret.isEmpty()) | |||||
| { | |||||
| using water::File; | |||||
| ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -0,0 +1,72 @@ | |||||
| #!/usr/bin/make -f | |||||
| # Makefile for carla-plugin # | |||||
| # ------------------------- # | |||||
| # Created by falkTX | |||||
| # | |||||
| CWD=../.. | |||||
| include ../Makefile.mk | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| OBJS = \ | |||||
| $(OBJDIR)/CachedPlugins.cpp.o \ | |||||
| $(OBJDIR)/Information.cpp.o \ | |||||
| $(OBJDIR)/PipeClient.cpp.o \ | |||||
| $(OBJDIR)/System.cpp.o \ | |||||
| $(OBJDIR)/Windows.cpp.o | |||||
| TARGETS = $(BINDIR)/libcarla_utils$(LIB_EXT) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| LIBS = $(MODULEDIR)/lilv.a | |||||
| LIBS += $(MODULEDIR)/water.files.a | |||||
| LINK_FLAGS += $(LILV_LIBS) | |||||
| LINK_FLAGS += $(WATER_LIBS) | |||||
| ifeq ($(HAVE_X11),true) | |||||
| LINK_FLAGS += $(X11_LIBS) | |||||
| endif | |||||
| ifneq ($(HAIKU),true) | |||||
| LINK_FLAGS += -lpthread | |||||
| endif | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| all: $(TARGETS) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| clean: | |||||
| rm -f $(OBJS) $(TARGETS) | |||||
| debug: | |||||
| $(MAKE) DEBUG=true | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| $(BINDIR)/libcarla_utils$(LIB_EXT): $(OBJS) $(LIBS) | |||||
| -@mkdir -p $(BINDIR) | |||||
| @echo "Linking libcarla_utils$(LIB_EXT)" | |||||
| @$(CXX) $(OBJS) $(LIBS_START) $(LIBS) $(LIBS_END) $(LINK_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@ | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| ifeq ($(MACOS),true) | |||||
| $(OBJDIR)/Windows.cpp.o: Windows.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling $<" | |||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | |||||
| endif | |||||
| $(OBJDIR)/%.cpp.o: %.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling $<" | |||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
| -include $(OBJS:%.o=%.d) | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -0,0 +1,170 @@ | |||||
| /* | |||||
| * Carla Plugin Host | |||||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 2 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 doc/GPL.txt file. | |||||
| */ | |||||
| #include "CarlaUtils.h" | |||||
| #include "CarlaPipeUtils.hpp" | |||||
| namespace CB = CarlaBackend; | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| class CarlaPipeClientPlugin : public CarlaPipeClient | |||||
| { | |||||
| public: | |||||
| CarlaPipeClientPlugin(const CarlaPipeCallbackFunc callbackFunc, void* const callbackPtr) noexcept | |||||
| : CarlaPipeClient(), | |||||
| fCallbackFunc(callbackFunc), | |||||
| fCallbackPtr(callbackPtr), | |||||
| fLastReadLine(nullptr) | |||||
| { | |||||
| CARLA_SAFE_ASSERT(fCallbackFunc != nullptr); | |||||
| } | |||||
| ~CarlaPipeClientPlugin() override | |||||
| { | |||||
| if (fLastReadLine != nullptr) | |||||
| { | |||||
| delete[] fLastReadLine; | |||||
| fLastReadLine = nullptr; | |||||
| } | |||||
| } | |||||
| const char* readlineblock(const uint timeout) noexcept | |||||
| { | |||||
| delete[] fLastReadLine; | |||||
| fLastReadLine = CarlaPipeClient::_readlineblock(timeout); | |||||
| return fLastReadLine; | |||||
| } | |||||
| bool msgReceived(const char* const msg) noexcept override | |||||
| { | |||||
| if (fCallbackFunc != nullptr) | |||||
| { | |||||
| try { | |||||
| fCallbackFunc(fCallbackPtr, msg); | |||||
| } CARLA_SAFE_EXCEPTION("msgReceived"); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| private: | |||||
| const CarlaPipeCallbackFunc fCallbackFunc; | |||||
| void* const fCallbackPtr; | |||||
| const char* fLastReadLine; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClientPlugin) | |||||
| }; | |||||
| CarlaPipeClientHandle carla_pipe_client_new(const char* argv[], CarlaPipeCallbackFunc callbackFunc, void* callbackPtr) | |||||
| { | |||||
| carla_debug("carla_pipe_client_new(%p, %p, %p)", argv, callbackFunc, callbackPtr); | |||||
| CarlaPipeClientPlugin* const pipe(new CarlaPipeClientPlugin(callbackFunc, callbackPtr)); | |||||
| if (! pipe->initPipeClient(argv)) | |||||
| { | |||||
| delete pipe; | |||||
| return nullptr; | |||||
| } | |||||
| return pipe; | |||||
| } | |||||
| void carla_pipe_client_idle(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| ((CarlaPipeClientPlugin*)handle)->idlePipe(); | |||||
| } | |||||
| bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->isPipeRunning(); | |||||
| } | |||||
| void carla_pipe_client_lock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| return ((CarlaPipeClientPlugin*)handle)->lockPipe(); | |||||
| } | |||||
| void carla_pipe_client_unlock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| return ((CarlaPipeClientPlugin*)handle)->unlockPipe(); | |||||
| } | |||||
| const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); | |||||
| return ((CarlaPipeClientPlugin*)handle)->readlineblock(timeout); | |||||
| } | |||||
| bool carla_pipe_client_write_msg(CarlaPipeClientHandle handle, const char* msg) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeMessage(msg); | |||||
| } | |||||
| bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMessage(msg); | |||||
| } | |||||
| bool carla_pipe_client_flush(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| return ((CarlaPipeClientPlugin*)handle)->flushMessages(); | |||||
| } | |||||
| bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||||
| const bool ret(pipe->flushMessages()); | |||||
| pipe->unlockPipe(); | |||||
| return ret; | |||||
| } | |||||
| void carla_pipe_client_destroy(CarlaPipeClientHandle handle) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
| carla_debug("carla_pipe_client_destroy(%p)", handle); | |||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||||
| pipe->closePipeClient(); | |||||
| delete pipe; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| #include "CarlaPipeUtils.cpp" | |||||
| #include "water/misc/Time.cpp" | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -0,0 +1,41 @@ | |||||
| /* | |||||
| * Carla Plugin Host | |||||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 2 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 doc/GPL.txt file. | |||||
| */ | |||||
| #include "CarlaUtils.h" | |||||
| #include "CarlaThread.hpp" | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| void carla_fflush(bool err) | |||||
| { | |||||
| std::fflush(err ? stderr : stdout); | |||||
| } | |||||
| void carla_fputs(bool err, const char* string) | |||||
| { | |||||
| std::fputs(string, err ? stderr : stdout); | |||||
| } | |||||
| void carla_set_process_name(const char* name) | |||||
| { | |||||
| carla_debug("carla_set_process_name(\"%s\")", name); | |||||
| CarlaThread::setCurrentThreadName(name); | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -0,0 +1,108 @@ | |||||
| /* | |||||
| * Carla Plugin Host | |||||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 2 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 doc/GPL.txt file. | |||||
| */ | |||||
| #include "CarlaUtils.h" | |||||
| #include "CarlaUtils.hpp" | |||||
| #ifdef CARLA_OS_MAC | |||||
| # import <Cocoa/Cocoa.h> | |||||
| #endif | |||||
| #ifdef HAVE_X11 | |||||
| # include <X11/Xlib.h> | |||||
| #endif | |||||
| namespace CB = CarlaBackend; | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| void carla_x11_reparent_window(uintptr_t winId1, uintptr_t winId2) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(winId1 != 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(winId2 != 0,); | |||||
| #ifdef HAVE_X11 | |||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| XReparentWindow(disp, winId1, winId2, 0, 0); | |||||
| XMapWindow(disp, winId1); | |||||
| XCloseDisplay(disp); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void carla_x11_move_window(uintptr_t winId, int x, int y) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(winId != 0,); | |||||
| #ifdef HAVE_X11 | |||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| XMoveWindow(disp, winId, x, y); | |||||
| XCloseDisplay(disp); | |||||
| } | |||||
| #else | |||||
| // unused | |||||
| return; (void)x; (void)y; | |||||
| #endif | |||||
| } | |||||
| int* carla_x11_get_window_pos(uintptr_t winId) | |||||
| { | |||||
| static int pos[2]; | |||||
| if (winId == 0) | |||||
| { | |||||
| pos[0] = 0; | |||||
| pos[1] = 0; | |||||
| } | |||||
| #ifdef HAVE_X11 | |||||
| else if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | |||||
| int x, y; | |||||
| Window child; | |||||
| XWindowAttributes xwa; | |||||
| XTranslateCoordinates(disp, winId, XRootWindow(disp, 0), 0, 0, &x, &y, &child); | |||||
| XGetWindowAttributes(disp, winId, &xwa); | |||||
| XCloseDisplay(disp); | |||||
| pos[0] = x - xwa.x; | |||||
| pos[1] = y - xwa.y; | |||||
| } | |||||
| #endif | |||||
| else | |||||
| { | |||||
| pos[0] = 0; | |||||
| pos[1] = 0; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int carla_cocoa_get_window(void* nsViewPtr) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(nsViewPtr != nullptr, 0); | |||||
| #ifdef CARLA_OS_MAC | |||||
| NSView* const nsView = (NSView*)nsViewPtr; | |||||
| return [[nsView window] windowNumber]; | |||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||