| @@ -80,6 +80,7 @@ carla-discovery-posix32 | |||
| carla-discovery-posix64 | |||
| carla-lv2-export | |||
| carla-native-plugin | |||
| carla-rest-server | |||
| zynaddsubfx-ui | |||
| @@ -316,14 +316,17 @@ endif | |||
| # Adjust PREFIX, LIBDIR and INCLUDEDIR in pkg-config files | |||
| sed $(SED_ARGS) 's?X-PREFIX-X?$(PREFIX)?' \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-native-plugin.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-standalone.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-utils.pc | |||
| sed $(SED_ARGS) 's?X-LIBDIR-X?$(LIBDIR)?' \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-native-plugin.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-standalone.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-utils.pc | |||
| sed $(SED_ARGS) 's?X-INCLUDEDIR-X?$(INCLUDEDIR)?' \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-native-plugin.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-standalone.pc \ | |||
| $(DESTDIR)$(LIBDIR)/pkgconfig/carla-utils.pc | |||
| @@ -340,6 +343,8 @@ endif | |||
| install -m 644 \ | |||
| source/includes/CarlaDefines.h \ | |||
| source/includes/CarlaMIDI.h \ | |||
| source/includes/CarlaNative.h \ | |||
| source/includes/CarlaNativePlugin.h \ | |||
| $(DESTDIR)$(INCLUDEDIR)/carla/includes | |||
| # ------------------------------------------------------------------------------------------------------------- | |||
| @@ -552,7 +557,9 @@ install: install_main install_external_plugins | |||
| uninstall: | |||
| rm -f $(DESTDIR)$(BINDIR)/carla* | |||
| rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/carla-native-plugin.pc | |||
| rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/carla-standalone.pc | |||
| rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/carla-utils.pc | |||
| rm -f $(DESTDIR)$(DATADIR)/applications/carla.desktop | |||
| rm -f $(DESTDIR)$(DATADIR)/applications/carla-control.desktop | |||
| rm -f $(DESTDIR)$(DATADIR)/icons/hicolor/*/apps/carla.png | |||
| @@ -0,0 +1,9 @@ | |||
| prefix=X-PREFIX-X | |||
| libdir=X-LIBDIR-X/carla | |||
| includedir=X-INCLUDEDIR-X/carla | |||
| Name: carla-native-plugin | |||
| Version: 1.9.11 | |||
| Description: Carla Native Plugin | |||
| Libs: -Wl,rpath=${libdir} -L${libdir} -lcarla_native-plugin | |||
| Cflags: -DREAL_BUILD -I${includedir} -I${includedir}/includes | |||
| @@ -3,7 +3,7 @@ libdir=X-LIBDIR-X/carla | |||
| includedir=X-INCLUDEDIR-X/carla | |||
| Name: carla-standalone | |||
| Version: 1.9.5 | |||
| Version: 1.9.11 | |||
| Description: Carla Host Standalone | |||
| Libs: -Wl,rpath=${libdir} -L${libdir} -lcarla_standalone2 | |||
| Cflags: -DREAL_BUILD -I${includedir} -I${includedir}/includes | |||
| @@ -3,7 +3,7 @@ libdir=X-LIBDIR-X/carla | |||
| includedir=X-INCLUDEDIR-X/carla | |||
| Name: carla-utils | |||
| Version: 1.9.5 | |||
| Version: 1.9.11 | |||
| Description: Carla Host Utilities | |||
| Libs: -Wl,rpath=${libdir} -L${libdir} -lcarla_utils | |||
| Cflags: -DREAL_BUILD -I${includedir} -I${includedir}/includes -I${includedir}/utils | |||
| @@ -378,6 +378,8 @@ if [ ! -f qtbase-opensource-src-${QT5_VERSION}/build-done ]; then | |||
| if [ ! -f carla-patched ]; then | |||
| sed -i -e "s|PNG_WARNINGS_SUPPORTED|PNG_WARNINGS_NOT_SUPPORTED|" src/3rdparty/libpng/pnglibconf.h | |||
| sed -i -e "s|AWK=.*|AWK=/opt/local/bin/gawk|" configure | |||
| sed -i -e "s|/usr/bin/xcrun -find xcrun|true|" configure | |||
| sed -i -e "s|/usr/bin/xcrun -find xcrun|echo hello|" mkspecs/features/mac/default_pre.prf | |||
| patch -p1 -i ../patches/qt55-newosx-fix.patch | |||
| touch carla-patched | |||
| fi | |||
| @@ -69,3 +69,16 @@ index cd73148..3f8429e 100644 | |||
| -- | |||
| 2.7.4 | |||
| diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | |||
| index 7e1dfd9..674c037 100644 | |||
| --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | |||
| +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | |||
| @@ -736,7 +736,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl | |||
| QFixed QCoreTextFontEngine::emSquareSize() const | |||
| { | |||
| - return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); | |||
| + return QFixed(int(CTFontGetUnitsPerEm(ctfont))); | |||
| } | |||
| QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const | |||
| @@ -314,6 +314,9 @@ struct CARLA_API EngineTimeInfo { | |||
| EngineTimeInfo(const EngineTimeInfo&) noexcept; | |||
| EngineTimeInfo& operator=(const EngineTimeInfo&) noexcept; | |||
| // fast comparison, doesn't check all values | |||
| bool compareIgnoringRollingFrames(const EngineTimeInfo& timeInfo, const uint32_t maxFrames) const noexcept; | |||
| // quick operator, doesn't check all values | |||
| bool operator==(const EngineTimeInfo& timeInfo) const noexcept; | |||
| bool operator!=(const EngineTimeInfo& timeInfo) const noexcept; | |||
| @@ -356,6 +356,40 @@ EngineTimeInfo& EngineTimeInfo::operator=(const EngineTimeInfo& info) noexcept | |||
| return *this; | |||
| } | |||
| bool EngineTimeInfo::compareIgnoringRollingFrames(const EngineTimeInfo& timeInfo, const uint32_t maxFrames) const noexcept | |||
| { | |||
| if (timeInfo.playing != playing || timeInfo.bbt.valid != bbt.valid) | |||
| return false; | |||
| if (bbt.valid) | |||
| { | |||
| if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar)) | |||
| return false; | |||
| if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute)) | |||
| return false; | |||
| } | |||
| // frame matches, nothing else to compare | |||
| if (timeInfo.frame == frame) | |||
| return true; | |||
| // if we went back in time, so a case of reposition | |||
| if (frame > timeInfo.frame) | |||
| return false; | |||
| // not playing, so dont bother checking transport | |||
| // assume frame changed, likely playback has stopped | |||
| if (! playing) | |||
| return false; | |||
| // if we are within expected bounds, assume we are rolling normally | |||
| if (frame + maxFrames <= timeInfo.frame) | |||
| return true; | |||
| // out of bounds, another reposition | |||
| return false; | |||
| } | |||
| bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept | |||
| { | |||
| if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.bbt.valid != bbt.valid) | |||
| @@ -333,7 +333,7 @@ EngineNextAction::EngineNextAction() noexcept | |||
| mutex(), | |||
| needsPost(false), | |||
| postDone(false), | |||
| sem(carla_sem_create()) {} | |||
| sem(carla_sem_create(false)) {} | |||
| EngineNextAction::~EngineNextAction() noexcept | |||
| { | |||
| @@ -645,8 +645,10 @@ public: | |||
| carla_msleep(20); | |||
| } | |||
| if (! fBridgeThread.isThreadRunning()) | |||
| return carla_stderr("CarlaPluginBridge::waitForSaved() - Bridge is not running"); | |||
| if (! fSaved) | |||
| carla_stderr("CarlaPluginBridge::waitForSaved() - Timeout while requesting save state"); | |||
| return carla_stderr("CarlaPluginBridge::waitForSaved() - Timeout while requesting save state"); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -1757,7 +1759,9 @@ public: | |||
| void waitForBridgeSaveSignal() noexcept override | |||
| { | |||
| waitForSaved(); | |||
| // VSTs only save chunks, for which we already have a waitForSaved there | |||
| if (fPluginType != PLUGIN_VST2) | |||
| waitForSaved(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -79,6 +79,9 @@ public: | |||
| fMacBundleRef(nullptr), | |||
| fMacBundleRefNum(0), | |||
| #endif | |||
| fFirstActive(true), | |||
| fBufferSize(engine->getBufferSize()), | |||
| fLastTimeInfo(), | |||
| fEvents(), | |||
| fUI(), | |||
| fUnique2(2) | |||
| @@ -1038,7 +1041,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,); | |||
| const int32_t iBufferSize = static_cast<int32_t>(pData->engine->getBufferSize()); | |||
| const int32_t iBufferSize = static_cast<int32_t>(fBufferSize); | |||
| const float fSampleRate = static_cast<float>(pData->engine->getSampleRate()); | |||
| dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32); | |||
| @@ -1053,6 +1056,8 @@ public: | |||
| try { | |||
| dispatcher(effStartProcess, 0, 0); | |||
| } catch(...) {} | |||
| fFirstActive = true; | |||
| } | |||
| void deactivate() noexcept override | |||
| @@ -1129,7 +1134,13 @@ public: | |||
| const EngineTimeInfo timeInfo(pData->engine->getTimeInfo()); | |||
| fTimeInfo.flags = kVstTransportChanged; | |||
| fTimeInfo.flags = 0; | |||
| if (fFirstActive || ! fLastTimeInfo.compareIgnoringRollingFrames(timeInfo, fBufferSize)) | |||
| { | |||
| fTimeInfo.flags |= kVstTransportChanged; | |||
| carla_copyStruct(fLastTimeInfo, timeInfo); | |||
| } | |||
| if (timeInfo.playing) | |||
| fTimeInfo.flags |= kVstTransportPlaying; | |||
| @@ -1543,6 +1554,8 @@ public: | |||
| } | |||
| } // End of MIDI Output | |||
| fFirstActive = false; | |||
| } | |||
| bool processSingle(const float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) | |||
| @@ -1699,6 +1712,8 @@ public: | |||
| CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize); | |||
| carla_debug("CarlaPluginVST2::bufferSizeChanged(%i)", newBufferSize); | |||
| fBufferSize = pData->engine->getBufferSize(); | |||
| if (pData->active) | |||
| deactivate(); | |||
| @@ -2285,7 +2300,7 @@ public: | |||
| fEffect->ptr1 = this; | |||
| const int32_t iBufferSize = static_cast<int32_t>(pData->engine->getBufferSize()); | |||
| const int32_t iBufferSize = static_cast<int32_t>(fBufferSize); | |||
| const float fSampleRate = static_cast<float>(pData->engine->getSampleRate()); | |||
| dispatcher(effIdentify); | |||
| @@ -2398,6 +2413,10 @@ private: | |||
| CFBundleRefNum fMacBundleRefNum; | |||
| #endif | |||
| bool fFirstActive; // first process() call after activate() | |||
| uint32_t fBufferSize; | |||
| EngineTimeInfo fLastTimeInfo; | |||
| struct FixedVstEvents { | |||
| int32_t numEvents; | |||
| intptr_t reserved; | |||
| @@ -2444,7 +2463,7 @@ private: | |||
| // ------------------------------------------------------------------- | |||
| static bool compareMagic (int32_t magic, const char* name) noexcept | |||
| static bool compareMagic(int32_t magic, const char* name) noexcept | |||
| { | |||
| return magic == (int32_t)ByteOrder::littleEndianInt (name) | |||
| || magic == (int32_t)ByteOrder::bigEndianInt (name); | |||
| @@ -453,6 +453,7 @@ int main(int argc, char* argv[]) | |||
| // Initialize OS features | |||
| #ifdef CARLA_OS_WIN | |||
| OleInitialize(nullptr); | |||
| CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); | |||
| # ifndef __WINPTHREADS_VERSION | |||
| // (non-portable) initialization of statically linked pthread library | |||
| @@ -560,6 +561,7 @@ int main(int argc, char* argv[]) | |||
| pthread_win32_process_detach_np(); | |||
| #endif | |||
| CoUninitialize(); | |||
| OleUninitialize(); | |||
| #endif | |||
| return ret; | |||
| @@ -86,6 +86,10 @@ ifeq ($(HAVE_DGL),true) | |||
| LIBS_native += $(MODULEDIR)/dgl.a | |||
| endif | |||
| ifeq ($(WIN32),true) | |||
| EXTRA_LINK_FLAGS += -lole32 -mwindows | |||
| endif | |||
| # ---------------------------------------------------------------------------------------------------------------------- | |||
| OBJS_native = \ | |||
| @@ -171,7 +175,7 @@ win64: $(BINDIR)/$(MODULENAME)-win64.exe | |||
| $(BINDIR)/$(MODULENAME)-native$(APP_EXT): $(OBJS_native) $(LIBS_native) | |||
| -@mkdir -p $(BINDIR) | |||
| @echo "Linking $(MODULENAME)-native$(APP_EXT)" | |||
| @$(CXX) $(OBJS_native) $(LIBS_START) $(LIBS_native) $(LIBS_END) $(LINK_FLAGS) $(NATIVE_LINK_FLAGS) -o $@ | |||
| @$(CXX) $(OBJS_native) $(LIBS_START) $(LIBS_native) $(LIBS_END) $(LINK_FLAGS) $(EXTRA_LINK_FLAGS) $(NATIVE_LINK_FLAGS) -o $@ | |||
| $(BINDIR)/$(MODULENAME)-lv2$(LIB_EXT): $(OBJS_lv2) $(LIBS_native) | |||
| -@mkdir -p $(BINDIR) | |||
| @@ -191,12 +195,12 @@ $(BINDIR)/$(MODULENAME)-posix64: $(OBJS_posix64) $(LIBS_posix64) | |||
| $(BINDIR)/$(MODULENAME)-win32.exe: $(OBJS_win32) $(LIBS_win32) | |||
| -@mkdir -p $(BINDIR) | |||
| @echo "Linking $(MODULENAME)-win32.exe" | |||
| @$(CXX) $(OBJS_win32) $(LIBS_START) $(LIBS_win32) $(LIBS_END) $(LINK_FLAGS) $(32BIT_FLAGS) -o $@ | |||
| @$(CXX) $(OBJS_win32) $(LIBS_START) $(LIBS_win32) $(LIBS_END) $(LINK_FLAGS) $(EXTRA_LINK_FLAGS) $(32BIT_FLAGS) -o $@ | |||
| $(BINDIR)/$(MODULENAME)-win64.exe: $(OBJS_win64) $(LIBS_win64) | |||
| -@mkdir -p $(BINDIR) | |||
| @echo "Linking $(MODULENAME)-win64.exe" | |||
| @$(CXX) $(OBJS_win64) $(LIBS_START) $(LIBS_win64) $(LIBS_END) $(LINK_FLAGS) $(64BIT_FLAGS) -o $@ | |||
| @$(CXX) $(OBJS_win64) $(LIBS_START) $(LIBS_win64) $(LIBS_END) $(LINK_FLAGS) $(EXTRA_LINK_FLAGS) $(64BIT_FLAGS) -o $@ | |||
| # ---------------------------------------------------------------------------------------------------------------------- | |||
| # native | |||
| @@ -35,7 +35,7 @@ BUILD_CXX_FLAGS += -ObjC++ | |||
| endif | |||
| ifeq ($(WIN32),true) | |||
| LINK_FLAGS += -mwindows | |||
| LINK_FLAGS += -lole32 -mwindows | |||
| endif | |||
| 32BIT_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH | |||
| @@ -33,6 +33,11 @@ | |||
| # import <Foundation/Foundation.h> | |||
| #endif | |||
| #ifdef CARLA_OS_WIN | |||
| # include <pthread.h> | |||
| # include <objbase.h> | |||
| #endif | |||
| #ifdef HAVE_FLUIDSYNTH | |||
| # include <fluidsynth.h> | |||
| #endif | |||
| @@ -1411,6 +1416,21 @@ int main(int argc, char* argv[]) | |||
| openLib = false; | |||
| #endif | |||
| // --------------------------------------------------------------------- | |||
| // Initialize OS features | |||
| #ifdef CARLA_OS_WIN | |||
| OleInitialize(nullptr); | |||
| CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); | |||
| # ifndef __WINPTHREADS_VERSION | |||
| // (non-portable) initialization of statically linked pthread library | |||
| pthread_win32_process_attach_np(); | |||
| pthread_win32_thread_attach_np(); | |||
| # endif | |||
| #endif | |||
| // --------------------------------------------------------------------- | |||
| if (openLib) | |||
| { | |||
| handle = lib_open(filename); | |||
| @@ -1428,6 +1448,8 @@ int main(int argc, char* argv[]) | |||
| if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") != nullptr) | |||
| doInit = false; | |||
| // --------------------------------------------------------------------- | |||
| if (doInit && openLib && handle != nullptr) | |||
| { | |||
| // test fast loading & unloading DLL without initializing the plugin(s) | |||
| @@ -1480,6 +1502,17 @@ int main(int argc, char* argv[]) | |||
| if (openLib && handle != nullptr) | |||
| lib_close(handle); | |||
| // --------------------------------------------------------------------- | |||
| #ifdef CARLA_OS_WIN | |||
| #ifndef __WINPTHREADS_VERSION | |||
| pthread_win32_thread_detach_np(); | |||
| pthread_win32_process_detach_np(); | |||
| #endif | |||
| CoUninitialize(); | |||
| OleUninitialize(); | |||
| #endif | |||
| return 0; | |||
| } | |||
| @@ -168,7 +168,7 @@ def getColorFromCategory(category): | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # | |||
| def setPixmapDialStyle(widget, parameterId, parameterCount, darkStyle, skinStyle): | |||
| def setPixmapDialStyle(widget, parameterId, parameterCount, whiteLabels, skinStyle): | |||
| if skinStyle.startswith("calf"): | |||
| widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT) | |||
| widget.setPixmap(7) | |||
| @@ -196,7 +196,7 @@ def setPixmapDialStyle(widget, parameterId, parameterCount, darkStyle, skinStyle | |||
| widget.setCustomPaintColor(QColor(_r, _g, _b)) | |||
| widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_COLOR) | |||
| if darkStyle: | |||
| if whiteLabels: | |||
| colorEnabled = QColor("#BBB") | |||
| colorDisabled = QColor("#555") | |||
| else: | |||
| @@ -359,10 +359,12 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
| isCalfSkin = self.fSkinStyle.startswith("calf") and not isinstance(self, PluginSlot_Compact) | |||
| imageSuffix = "white" if self.fDarkStyle else "black" | |||
| whiteLabels = self.fDarkStyle | |||
| if self.fSkinStyle.startswith("calf") or self.fSkinStyle.startswith("openav") or self.fSkinStyle in ( | |||
| "3bandeq", "3bandsplitter", "pingpongpan", "nekobi", "calf_black", "zynfx"): | |||
| imageSuffix = "white" | |||
| whiteLabels = True | |||
| if self.b_enable is not None: | |||
| self.b_enable.setChecked(self.fIsActive) | |||
| @@ -598,7 +600,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
| if isInteger: | |||
| widget.setPrecision(paramRanges['max']-paramRanges['min'], True) | |||
| setPixmapDialStyle(widget, i, parameterCount, self.fDarkStyle, self.fSkinStyle) | |||
| setPixmapDialStyle(widget, i, parameterCount, whiteLabels, self.fSkinStyle) | |||
| index += 1 | |||
| self.fParameterList.append([i, widget]) | |||
| @@ -609,7 +611,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
| widget.setLabel("Dry/Wet") | |||
| widget.setMinimum(0.0) | |||
| widget.setMaximum(1.0) | |||
| setPixmapDialStyle(widget, PARAMETER_DRYWET, 0, self.fDarkStyle, self.fSkinStyle) | |||
| setPixmapDialStyle(widget, PARAMETER_DRYWET, 0, whiteLabels, self.fSkinStyle) | |||
| self.fParameterList.append([PARAMETER_DRYWET, widget]) | |||
| self.w_knobs_right.layout().addWidget(widget) | |||
| @@ -619,7 +621,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
| widget.setLabel("Volume") | |||
| widget.setMinimum(0.0) | |||
| widget.setMaximum(1.27) | |||
| setPixmapDialStyle(widget, PARAMETER_VOLUME, 0, self.fDarkStyle, self.fSkinStyle) | |||
| setPixmapDialStyle(widget, PARAMETER_VOLUME, 0, whiteLabels, self.fSkinStyle) | |||
| self.fParameterList.append([PARAMETER_VOLUME, widget]) | |||
| self.w_knobs_right.layout().addWidget(widget) | |||
| @@ -1752,13 +1754,9 @@ class PluginSlot_Presets(AbstractPluginSlot): | |||
| # ------------------------------------------------------------- | |||
| def setupZynFxParams(self): | |||
| parameterCount = self.host.get_parameter_count(self.fPluginId) | |||
| parameterCount = min(self.host.get_parameter_count(self.fPluginId), 8) | |||
| index = 0 | |||
| for i in range(parameterCount): | |||
| if index >= 8: | |||
| break | |||
| paramInfo = self.host.get_parameter_info(self.fPluginId, i) | |||
| paramData = self.host.get_parameter_data(self.fPluginId, i) | |||
| paramRanges = self.host.get_parameter_ranges(self.fPluginId, i) | |||
| @@ -157,9 +157,9 @@ class CarlaAboutW(QDialog): | |||
| "</ul>")) | |||
| self.ui.l_vst2.setText(self.tr("About 85% complete (missing vst bank/presets and some minor stuff)")) | |||
| # 2nd tab is usually longer than the 1st | |||
| # 3rd tab is usually longer than the 1st | |||
| # adjust appropriately | |||
| self.ui.tabWidget.setCurrentIndex(1) | |||
| self.ui.tabWidget.setCurrentIndex(2) | |||
| self.adjustSize() | |||
| self.ui.tabWidget.setCurrentIndex(0) | |||
| @@ -135,11 +135,49 @@ kPcKeys_qwertz = [ | |||
| str(Qt.Key_P), | |||
| ] | |||
| kPcKeys_azerty = [ | |||
| # 1st octave | |||
| str(Qt.Key_W), | |||
| str(Qt.Key_S), | |||
| str(Qt.Key_X), | |||
| str(Qt.Key_D), | |||
| str(Qt.Key_C), | |||
| str(Qt.Key_V), | |||
| str(Qt.Key_G), | |||
| str(Qt.Key_B), | |||
| str(Qt.Key_H), | |||
| str(Qt.Key_N), | |||
| str(Qt.Key_J), | |||
| str(Qt.Key_Comma), | |||
| # 2nd octave | |||
| str(Qt.Key_A), | |||
| str(Qt.Key_Eacute), | |||
| str(Qt.Key_Z), | |||
| str(Qt.Key_QuoteDbl), | |||
| str(Qt.Key_E), | |||
| str(Qt.Key_R), | |||
| str(Qt.Key_ParenLeft), | |||
| str(Qt.Key_T), | |||
| str(Qt.Key_Minus), | |||
| str(Qt.Key_Y), | |||
| str(Qt.Key_Egrave), | |||
| str(Qt.Key_U), | |||
| # 3rd octave | |||
| str(Qt.Key_I), | |||
| str(Qt.Key_Ccedilla), | |||
| str(Qt.Key_O), | |||
| str(Qt.Key_Agrave), | |||
| str(Qt.Key_P), | |||
| ] | |||
| kPcKeysLayouts = { | |||
| 'qwerty': kPcKeys_qwerty, | |||
| 'qwertz': kPcKeys_qwertz, | |||
| 'azerty': kPcKeys_azerty, | |||
| } | |||
| kValidColors = ("Blue", "Green", "Orange", "Red") | |||
| kBlackNotes = (1, 3, 6, 8, 10) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| @@ -168,7 +206,7 @@ class PixmapKeyboard(QWidget): | |||
| self.fPixmapNormal = QPixmap(":/bitmaps/kbd_normal.png") | |||
| self.fPixmapDown = QPixmap(":/bitmaps/kbd_down-blue.png") | |||
| self.fHighlightColor = "Blue" | |||
| self.fHighlightColor = kValidColors[0] | |||
| self.fkPcKeyLayout = "qwerty" | |||
| self.fkPcKeys = kPcKeysLayouts["qwerty"] | |||
| @@ -197,9 +235,9 @@ class PixmapKeyboard(QWidget): | |||
| def loadSettings(self): | |||
| settings = QSettings("falkTX", "CarlaKeyboard") | |||
| self.setPcKeyboardLayout(settings.value("PcKeyboardLayout", "qwerty", type=str)) | |||
| self.setPcKeyboardOffset(settings.value("PcKeyboardOffset", 2, type=int)) | |||
| self.setColor(settings.value("HighlightColor", "Blue", type=str)) | |||
| self.setPcKeyboardLayout(settings.value("PcKeyboardLayout", self.fkPcKeyLayout, type=str)) | |||
| self.setPcKeyboardOffset(settings.value("PcKeyboardOffset", self.fPcKeybOffset, type=int)) | |||
| self.setColor(settings.value("HighlightColor", self.fHighlightColor, type=str)) | |||
| del settings | |||
| def allNotesOff(self, sendSignal=True): | |||
| @@ -235,7 +273,7 @@ class PixmapKeyboard(QWidget): | |||
| self.notesOff.emit() | |||
| def setColor(self, color): | |||
| if color not in ("Blue", "Green", "Orange", "Red"): | |||
| if color not in kValidColors: | |||
| return | |||
| if self.fHighlightColor == color: | |||
| @@ -343,27 +381,24 @@ class PixmapKeyboard(QWidget): | |||
| menu.addAction("Note: restart carla to apply globally").setEnabled(False) | |||
| menu.addSeparator() | |||
| menuColor = QMenu("Highlight color", menu) | |||
| actColorBlue = menuColor.addAction("Blue") | |||
| actColorGreen = menuColor.addAction("Green") | |||
| actColorOrange = menuColor.addAction("Orange") | |||
| actColorRed = menuColor.addAction("Red") | |||
| actColors = (actColorBlue, actColorGreen, actColorOrange, actColorRed) | |||
| menuColor = QMenu("Highlight color", menu) | |||
| menuLayout = QMenu("PC Keyboard layout", menu) | |||
| actColors = [] | |||
| actLayouts = [] | |||
| for act in actColors: | |||
| for color in kValidColors: | |||
| act = menuColor.addAction(color) | |||
| act.setCheckable(True) | |||
| if self.fHighlightColor == act.text(): | |||
| if self.fHighlightColor == color: | |||
| act.setChecked(True) | |||
| actColors.append(act) | |||
| menuLayout = QMenu("PC Keyboard layout", menu) | |||
| actLayout_qwerty = menuLayout.addAction("qwerty") | |||
| actLayout_qwertz = menuLayout.addAction("qwertz") | |||
| actLayouts = (actLayout_qwerty, actLayout_qwertz) | |||
| for act in actLayouts: | |||
| for pcKeyLayout in kPcKeysLayouts.keys(): | |||
| act = menuLayout.addAction(pcKeyLayout) | |||
| act.setCheckable(True) | |||
| if self.fkPcKeyLayout == act.text(): | |||
| if self.fkPcKeyLayout == pcKeyLayout: | |||
| act.setChecked(True) | |||
| actLayouts.append(act) | |||
| menu.addMenu(menuColor) | |||
| menu.addMenu(menuLayout) | |||
| @@ -20,32 +20,32 @@ | |||
| #include "CarlaBackend.h" | |||
| #include "CarlaNative.h" | |||
| #include "CarlaEngine.hpp" | |||
| /*! | |||
| * Get the absolute filename of this carla library. | |||
| */ | |||
| CARLA_EXPORT const char* carla_get_library_filename(); | |||
| /*! | |||
| * Get the folder where this carla library resides. | |||
| */ | |||
| CARLA_EXPORT const char* carla_get_library_folder(); | |||
| /*! | |||
| * Get the native plugin descriptor for the carla-rack plugin. | |||
| */ | |||
| CARLA_EXPORT const NativePluginDescriptor* carla_get_native_rack_plugin(); | |||
| /*! | |||
| * Get the folder where this carla library resides. | |||
| * Get the native plugin descriptor for the carla-patchbay plugin. | |||
| */ | |||
| CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay_plugin(); | |||
| #ifdef __cplusplus | |||
| CARLA_BACKEND_USE_NAMESPACE | |||
| static inline | |||
| CarlaEngine* carla_plugin_get_engine(const NativePluginDescriptor* desc, NativePluginHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(desc != nullptr, nullptr); | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); | |||
| const intptr_t enginePtr = desc->dispatcher(handle, NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE, 0, 0, nullptr, 0.0f); | |||
| CARLA_SAFE_ASSERT_RETURN(enginePtr != 0, nullptr); | |||
| return (CarlaEngine*)static_cast<uintptr_t>(enginePtr); | |||
| } | |||
| /*! | |||
| * Get the internal CarlaEngine instance. | |||
| */ | |||
| CARLA_EXPORT CarlaBackend::CarlaEngine* carla_get_native_plugin_engine(const NativePluginDescriptor* desc, NativePluginHandle handle); | |||
| #endif | |||
| #endif /* CARLA_NATIVE_PLUGIN_H_INCLUDED */ | |||
| @@ -30,7 +30,7 @@ bool jackbridge_sem_init(void* sem) noexcept | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| return carla_sem_create2(*(carla_sem_t*)sem); | |||
| return carla_sem_create2(*(carla_sem_t*)sem, true); | |||
| #endif | |||
| } | |||
| @@ -74,10 +74,14 @@ LINK_FLAGS += $(MAGIC_LIBS) | |||
| LINK_FLAGS += $(X11_LIBS) | |||
| ifeq ($(MACOS),true) | |||
| SYMBOLS_NATIVE = -Wl,-exported_symbol,_carla_get_native_rack_plugin -Wl,-exported_symbol,_carla_get_native_patchbay_plugin | |||
| SYMBOLS_LV2 = -Wl,-exported_symbol,_lv2_descriptor -Wl,-exported_symbol,_lv2ui_descriptor | |||
| SYMBOLS_LV2_UI = -Wl,-exported_symbol,_lv2ui_descriptor | |||
| SYMBOLS_VST = # TODO | |||
| SYMBOLS_NATIVE = -Wl,-exported_symbol,_carla_get_native_rack_plugin | |||
| SYMBOLS_NATIVE += -Wl,-exported_symbol,_carla_get_native_patchbay_plugin | |||
| SYMBOLS_NATIVE += -Wl,-exported_symbol,_carla_get_library_filename | |||
| SYMBOLS_NATIVE += -Wl,-exported_symbol,_carla_get_library_folder | |||
| SYMBOLS_LV2 = -Wl,-exported_symbol,_lv2_descriptor | |||
| SYMBOLS_LV2 += -Wl,-exported_symbol,_lv2ui_descriptor | |||
| SYMBOLS_LV2_UI = -Wl,-exported_symbol,_lv2ui_descriptor | |||
| SYMBOLS_VST = # TODO | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| @@ -89,7 +93,7 @@ LIBS_ui = $(MODULEDIR)/water.a | |||
| TARGETS = \ | |||
| $(BINDIR)/carla-native-plugin$(APP_EXT) \ | |||
| $(BINDIR)/libcarla-native-plugin$(LIB_EXT) | |||
| $(BINDIR)/libcarla_native-plugin$(LIB_EXT) | |||
| TARGETS += \ | |||
| $(BINDIR)/carla.lv2/carla$(LIB_EXT) | |||
| @@ -140,7 +144,7 @@ $(BINDIR)/carla-native-plugin$(APP_EXT): $(OBJDIR)/carla-native-plugin.cpp.o $(L | |||
| @echo "Linking carla-native-plugin$(APP_EXT)" | |||
| @$(CXX) $< $(LIBS_START) $(LIBS) $(LIBS_END) $(LINK_FLAGS) -o $@ | |||
| $(BINDIR)/libcarla-native-plugin$(LIB_EXT): $(OBJDIR)/carla-native-plugin.cpp.o $(LIBS) | |||
| $(BINDIR)/libcarla_native-plugin$(LIB_EXT): $(OBJDIR)/carla-native-plugin.cpp.o $(LIBS) | |||
| -@mkdir -p $(BINDIR) | |||
| @echo "Linking libcarla-native-plugin$(LIB_EXT)" | |||
| @$(CXX) $< $(LIBS_START) $(LIBS) $(LIBS_END) $(SHARED) $(SYMBOLS_NATIVE) $(LINK_FLAGS) -o $@ | |||
| @@ -15,9 +15,29 @@ | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaUtils.hpp" | |||
| #include "CarlaNativePlugin.h" | |||
| #include "CarlaEngine.hpp" | |||
| #include "CarlaString.hpp" | |||
| #include "water/files/File.h" | |||
| CARLA_BACKEND_USE_NAMESPACE | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| CarlaEngine* carla_get_native_plugin_engine(const NativePluginDescriptor* desc, NativePluginHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(desc != nullptr, nullptr); | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); | |||
| return (CarlaEngine*)static_cast<uintptr_t>(desc->dispatcher(handle, | |||
| NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE, | |||
| 0, 0, nullptr, 0.0f)); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static uint32_t get_buffer_size(NativeHostHandle) | |||
| { | |||
| return 128; | |||
| @@ -35,17 +55,21 @@ static bool is_offline(NativeHostHandle) | |||
| int main() | |||
| { | |||
| const char* const filename = carla_get_library_filename(); | |||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', 1); | |||
| const char* const folder = carla_get_library_folder(); | |||
| CARLA_SAFE_ASSERT_RETURN(folder != nullptr && folder[0] != '\0', 1); | |||
| const NativePluginDescriptor* const rack = carla_get_native_rack_plugin(); | |||
| CARLA_SAFE_ASSERT_RETURN(rack != nullptr, 1); | |||
| const NativePluginDescriptor* const patchbay = carla_get_native_patchbay_plugin(); | |||
| CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr, 1); | |||
| const char* const resourceDir = get_current_dir_name(); | |||
| const NativeHostDescriptor host = { | |||
| nullptr, | |||
| resourceDir, | |||
| "", // resourceDir | |||
| "Carla Plugin UI", | |||
| 0, | |||
| @@ -65,12 +89,12 @@ int main() | |||
| nullptr, // ui_save_file | |||
| nullptr, // dispatcher | |||
| }; | |||
| const NativePluginHandle handle = rack->instantiate(&host); | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1); | |||
| CarlaEngine* const engine = carla_plugin_get_engine(rack, handle); | |||
| CarlaEngine* const engine = carla_get_native_plugin_engine(rack, handle); | |||
| CARLA_SAFE_ASSERT_RETURN(engine != nullptr, 1); | |||
| carla_stdout("Got Engine %p, %s, %i, %f", | |||
| @@ -79,3 +103,5 @@ int main() | |||
| rack->cleanup(handle); | |||
| return 0; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -40,7 +40,7 @@ const char* findBinaryInBundle(const char* const bundleDir) | |||
| const CFURLRef absoluteURL = CFURLCopyAbsoluteURL(exeRef); | |||
| CARLA_SAFE_ASSERT_RETURN(absoluteURL != nullptr, nullptr); | |||
| const NSString* strRef = (NSString*)CFURLCopyFileSystemPath(absoluteURL, nil); | |||
| const NSString* strRef = (NSString*)CFURLCopyFileSystemPath(absoluteURL, kCFURLPOSIXPathStyle); | |||
| CARLA_SAFE_ASSERT_RETURN(strRef != nullptr, nullptr); | |||
| static CarlaString ret; | |||
| @@ -41,7 +41,7 @@ struct carla_sem_t { char bootname[32]; semaphore_t sem; semaphore_t sem2; }; | |||
| # include <syscall.h> | |||
| # include <sys/time.h> | |||
| # include <linux/futex.h> | |||
| struct carla_sem_t { int count; }; | |||
| struct carla_sem_t { int count; bool external; }; | |||
| #else | |||
| # include <cerrno> | |||
| # include <semaphore.h> | |||
| @@ -54,7 +54,7 @@ struct carla_sem_t { sem_t sem; }; | |||
| * Create a new semaphore, pre-allocated version. | |||
| */ | |||
| static inline | |||
| bool carla_sem_create2(carla_sem_t& sem) noexcept | |||
| bool carla_sem_create2(carla_sem_t& sem, const bool externalIPC) noexcept | |||
| { | |||
| carla_zeroStruct(sem); | |||
| #if defined(CARLA_OS_WIN) | |||
| @@ -63,16 +63,21 @@ bool carla_sem_create2(carla_sem_t& sem) noexcept | |||
| sa.nLength = sizeof(SECURITY_ATTRIBUTES); | |||
| sa.bInheritHandle = TRUE; | |||
| sem.handle = ::CreateSemaphore(&sa, 0, 1, nullptr); | |||
| sem.handle = ::CreateSemaphoreA(externalIPC ? &sa : nullptr, 0, 1, nullptr); | |||
| return (sem.handle != INVALID_HANDLE_VALUE); | |||
| #elif defined(CARLA_OS_MAC) | |||
| mach_port_t bootport; | |||
| const mach_port_t task = ::mach_task_self(); | |||
| mach_port_t bootport; | |||
| CARLA_SAFE_ASSERT_RETURN(task_get_bootstrap_port(task, &bootport) == KERN_SUCCESS, false); | |||
| if (externalIPC) { | |||
| CARLA_SAFE_ASSERT_RETURN(task_get_bootstrap_port(task, &bootport) == KERN_SUCCESS, false); | |||
| } | |||
| CARLA_SAFE_ASSERT_RETURN(::semaphore_create(task, &sem.sem, SYNC_POLICY_FIFO, 0) == KERN_SUCCESS, false); | |||
| if (! externalIPC) | |||
| return true; | |||
| static int bootcounter = 0; | |||
| std::snprintf(sem.bootname, 31, "crlsm_%i_%i_%p", ++bootcounter, ::getpid(), &sem); | |||
| sem.bootname[31] = '\0'; | |||
| @@ -80,12 +85,14 @@ bool carla_sem_create2(carla_sem_t& sem) noexcept | |||
| if (::bootstrap_register(bootport, sem.bootname, sem.sem) == KERN_SUCCESS) | |||
| return true; | |||
| sem.bootname[0] = '\0'; | |||
| ::semaphore_destroy(task, sem.sem); | |||
| return false; | |||
| #elif defined(CARLA_USE_FUTEXES) | |||
| sem.external = externalIPC; | |||
| return true; | |||
| #else | |||
| return (::sem_init(&sem.sem, 1, 0) == 0); | |||
| return (::sem_init(&sem.sem, externalIPC, 0) == 0); | |||
| #endif | |||
| } | |||
| @@ -93,11 +100,11 @@ bool carla_sem_create2(carla_sem_t& sem) noexcept | |||
| * Create a new semaphore. | |||
| */ | |||
| static inline | |||
| carla_sem_t* carla_sem_create() noexcept | |||
| carla_sem_t* carla_sem_create(const bool externalIPC) noexcept | |||
| { | |||
| if (carla_sem_t* const sem = (carla_sem_t*)std::malloc(sizeof(carla_sem_t))) | |||
| { | |||
| if (carla_sem_create2(*sem)) | |||
| if (carla_sem_create2(*sem, externalIPC)) | |||
| return sem; | |||
| std::free(sem); | |||
| @@ -173,7 +180,7 @@ void carla_sem_post(carla_sem_t& sem, const bool server = true) noexcept | |||
| #elif defined(CARLA_USE_FUTEXES) | |||
| const bool unlocked = __sync_bool_compare_and_swap(&sem.count, 0, 1); | |||
| CARLA_SAFE_ASSERT_RETURN(unlocked,); | |||
| ::syscall(__NR_futex, &sem.count, FUTEX_WAKE, 1, nullptr, nullptr, 0); | |||
| ::syscall(__NR_futex, &sem.count, sem.external ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0); | |||
| #else | |||
| ::sem_post(&sem.sem); | |||
| #endif | |||
| @@ -209,7 +216,7 @@ bool carla_sem_timedwait(carla_sem_t& sem, const uint msecs, const bool server = | |||
| if (__sync_bool_compare_and_swap(&sem.count, 1, 0)) | |||
| return true; | |||
| if (::syscall(__NR_futex, &sem.count, FUTEX_WAIT, 0, &timeout, nullptr, 0) != 0) | |||
| if (::syscall(__NR_futex, &sem.count, sem.external ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, 0, &timeout, nullptr, 0) != 0) | |||
| if (errno != EAGAIN && errno != EINTR) | |||
| return false; | |||
| } | |||