From ed620b139dfcada50667c2c5a343b60e4e4ded38 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 23 Feb 2014 10:55:28 +0000 Subject: [PATCH] Always return a valid ptr on standalone; Cleanup --- resources/resources.qrc | 2 + resources/ui/carla_host.ui | 59 ++++++ source/backend/CarlaHost.h | 110 ++-------- source/backend/standalone/CarlaStandalone.cpp | 193 +++++++++++++++--- source/carla_backend.py | 37 +++- source/carla_database.py | 24 +-- source/carla_host.py | 18 +- source/carla_rack.py | 5 +- source/carla_settings.py | 9 +- source/carla_shared.py | 9 +- source/carla_skin.py | 21 +- source/carla_widgets.py | 57 +++--- 12 files changed, 345 insertions(+), 199 deletions(-) diff --git a/resources/resources.qrc b/resources/resources.qrc index 6814d0c32..b2f36d05f 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -122,6 +122,8 @@ bitmaps/style/arrow.png bitmaps/style/groupbox.png + bitmaps/thumbs/zita-rev1.png + bitmaps/zita-rev/ambsect.png bitmaps/zita-rev/eq1sect.png bitmaps/zita-rev/eq2sect.png diff --git a/resources/ui/carla_host.ui b/resources/ui/carla_host.ui index f0081bdd5..b2388bc4e 100644 --- a/resources/ui/carla_host.ui +++ b/resources/ui/carla_host.ui @@ -140,6 +140,65 @@ Plugins + + + 0 + + + 0 + + + 0 + + + 0 + + + 1 + + + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + QAbstractItemView::DragOnly + + + QAbstractItemView::SelectRows + + + + 150 + 50 + + + + Qt::ElideMiddle + + + QListView::Static + + + QListView::TopToBottom + + + QListView::IconMode + + + + + + + + Presets + diff --git a/source/backend/CarlaHost.h b/source/backend/CarlaHost.h index ea1caea90..9e9983fe1 100644 --- a/source/backend/CarlaHost.h +++ b/source/backend/CarlaHost.h @@ -134,42 +134,10 @@ typedef struct _CarlaPluginInfo { /*! * C++ constructor. */ - _CarlaPluginInfo() noexcept - : type(CarlaBackend::PLUGIN_NONE), - category(CarlaBackend::PLUGIN_CATEGORY_NONE), - hints(0x0), - optionsAvailable(0x0), - optionsEnabled(0x0), - filename(nullptr), - name(nullptr), - label(nullptr), - maker(nullptr), - copyright(nullptr), - iconName(nullptr), - uniqueId(0) {} - - /*! - * C++ destructor. - */ - ~_CarlaPluginInfo() - { - if (label != nullptr) - { - delete[] label; - label = nullptr; - } - if (maker != nullptr) - { - delete[] maker; - maker = nullptr; - } - if (copyright != nullptr) - { - delete[] copyright; - copyright = nullptr; - } - } + _CarlaPluginInfo() noexcept; + ~_CarlaPluginInfo() noexcept; #endif + } CarlaPluginInfo; /*! @@ -242,20 +210,9 @@ typedef struct _CarlaNativePluginInfo { /*! * C++ constructor. */ - _CarlaNativePluginInfo() noexcept - : category(CarlaBackend::PLUGIN_CATEGORY_NONE), - hints(0x0), - audioIns(0), - audioOuts(0), - midiIns(0), - midiOuts(0), - parameterIns(0), - parameterOuts(0), - name(nullptr), - label(nullptr), - maker(nullptr), - copyright(nullptr) {} + _CarlaNativePluginInfo() noexcept; #endif + } CarlaNativePluginInfo; /*! @@ -307,34 +264,10 @@ typedef struct _CarlaParameterInfo { /*! * C++ constructor. */ - _CarlaParameterInfo() noexcept - : name(nullptr), - symbol(nullptr), - unit(nullptr), - scalePointCount(0) {} - - /*! - * C++ destructor. - */ - ~_CarlaParameterInfo() - { - if (name != nullptr) - { - delete[] name; - name = nullptr; - } - if (symbol != nullptr) - { - delete[] symbol; - symbol = nullptr; - } - if (unit != nullptr) - { - delete[] unit; - unit = nullptr; - } - } + _CarlaParameterInfo() noexcept; + ~_CarlaParameterInfo() noexcept; #endif + } CarlaParameterInfo; /*! @@ -356,22 +289,10 @@ typedef struct _CarlaScalePointInfo { /*! * C++ constructor. */ - _CarlaScalePointInfo() noexcept - : value(0.0f), - label(nullptr) {} - - /*! - * C++ destructor. - */ - ~_CarlaScalePointInfo() - { - if (label != nullptr) - { - delete[] label; - label = nullptr; - } - } + _CarlaScalePointInfo() noexcept; + ~_CarlaScalePointInfo() noexcept; #endif + } CarlaScalePointInfo; /*! @@ -413,14 +334,9 @@ typedef struct _CarlaTransportInfo { /*! * C++ constructor. */ - _CarlaTransportInfo() noexcept - : playing(false), - frame(0), - bar(0), - beat(0), - tick(0), - bpm(0.0) {} + _CarlaTransportInfo() noexcept; #endif + } CarlaTransportInfo; /* ------------------------------------------------------------------------------------------------------------ diff --git a/source/backend/standalone/CarlaStandalone.cpp b/source/backend/standalone/CarlaStandalone.cpp index c738ff0f3..796885447 100644 --- a/source/backend/standalone/CarlaStandalone.cpp +++ b/source/backend/standalone/CarlaStandalone.cpp @@ -191,6 +191,92 @@ struct CarlaBackendStandalone { static CarlaBackendStandalone gStandalone; +// ------------------------------------------------------------------------------------------------------------------- +// Always return a valid string ptr + +static const char* const gNullCharPtr = ""; + +static void checkStringPtr(const char*& charPtr) +{ + if (charPtr == nullptr) + charPtr = gNullCharPtr; +} + +// ------------------------------------------------------------------------------------------------------------------- +// Constructors + +_CarlaPluginInfo::_CarlaPluginInfo() noexcept + : type(CB::PLUGIN_NONE), + category(CB::PLUGIN_CATEGORY_NONE), + hints(0x0), + optionsAvailable(0x0), + optionsEnabled(0x0), + filename(gNullCharPtr), + name(gNullCharPtr), + label(gNullCharPtr), + maker(gNullCharPtr), + copyright(gNullCharPtr), + iconName(gNullCharPtr), + uniqueId(0) {} + +_CarlaPluginInfo::~_CarlaPluginInfo() noexcept +{ + if (label != gNullCharPtr) + delete[] label; + if (maker != gNullCharPtr) + delete[] maker; + if (copyright != gNullCharPtr) + delete[] copyright; +} + +_CarlaNativePluginInfo::_CarlaNativePluginInfo() noexcept + : category(CB::PLUGIN_CATEGORY_NONE), + hints(0x0), + audioIns(0), + audioOuts(0), + midiIns(0), + midiOuts(0), + parameterIns(0), + parameterOuts(0), + name(gNullCharPtr), + label(gNullCharPtr), + maker(gNullCharPtr), + copyright(gNullCharPtr) {} + +_CarlaParameterInfo::_CarlaParameterInfo() noexcept + : name(gNullCharPtr), + symbol(gNullCharPtr), + unit(gNullCharPtr), + scalePointCount(0) {} + +_CarlaParameterInfo::~_CarlaParameterInfo() noexcept +{ + if (name != gNullCharPtr) + delete[] name; + if (symbol != gNullCharPtr) + delete[] symbol; + if (unit != gNullCharPtr) + delete[] unit; +} + +_CarlaScalePointInfo::_CarlaScalePointInfo() noexcept + : value(0.0f), + label(gNullCharPtr) {} + +_CarlaScalePointInfo::~_CarlaScalePointInfo() noexcept +{ + if (label != gNullCharPtr) + delete[] label; +} + +_CarlaTransportInfo::_CarlaTransportInfo() noexcept + : playing(false), + frame(0), + bar(0), + beat(0), + tick(0), + bpm(0.0) {} + // ------------------------------------------------------------------------------------------------------------------- // API @@ -363,7 +449,19 @@ const EngineDriverDeviceInfo* carla_get_engine_driver_device_info(unsigned int i CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); carla_debug("carla_get_engine_driver_device_info(%i, \"%s\")", index, name); - return CarlaEngine::getDriverDeviceInfo(index, name); + if (const EngineDriverDeviceInfo* const ret = CarlaEngine::getDriverDeviceInfo(index, name)) + { + static EngineDriverDeviceInfo devInfo; + static const uint32_t nullBufferSizes[] = { 0 }; + static const double nullSampleRates[] = { 0.0 }; + + devInfo.hints = ret->hints; + devInfo.bufferSizes = (ret->bufferSizes != nullptr) ? ret->bufferSizes : nullBufferSizes; + devInfo.sampleRates = (ret->sampleRates != nullptr) ? ret->sampleRates : nullSampleRates; + return &devInfo; + } + + return nullptr; } // ------------------------------------------------------------------------------------------------------------------- @@ -417,6 +515,11 @@ const CarlaNativePluginInfo* carla_get_internal_plugin_info(unsigned int index) info.maker = nativePlugin->maker; info.copyright = nativePlugin->copyright; + checkStringPtr(info.name); + checkStringPtr(info.label); + checkStringPtr(info.maker); + checkStringPtr(info.copyright); + return &info; #else return nullptr; @@ -1071,28 +1174,28 @@ const CarlaPluginInfo* carla_get_plugin_info(uint pluginId) info.hints = 0x0; info.optionsAvailable = 0x0; info.optionsEnabled = 0x0; - info.filename = nullptr; - info.name = nullptr; - info.iconName = nullptr; + info.filename = gNullCharPtr; + info.name = gNullCharPtr; + info.iconName = gNullCharPtr; info.uniqueId = 0; // cleanup - if (info.label != nullptr) + if (info.label != gNullCharPtr) { delete[] info.label; - info.label = nullptr; + info.label = gNullCharPtr; } - if (info.maker != nullptr) + if (info.maker != gNullCharPtr) { delete[] info.maker; - info.maker = nullptr; + info.maker = gNullCharPtr; } - if (info.copyright != nullptr) + if (info.copyright != gNullCharPtr) { delete[] info.copyright; - info.copyright = nullptr; + info.copyright = gNullCharPtr; } CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); @@ -1127,6 +1230,10 @@ const CarlaPluginInfo* carla_get_plugin_info(uint pluginId) plugin->getCopyright(strBufCopyright); info.copyright = carla_strdup(strBufCopyright); + checkStringPtr(info.filename); + checkStringPtr(info.name); + checkStringPtr(info.iconName); + return &info; } @@ -1212,22 +1319,22 @@ const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t param info.scalePointCount = 0; // cleanup - if (info.name != nullptr) + if (info.name != gNullCharPtr) { delete[] info.name; - info.name = nullptr; + info.name = gNullCharPtr; } - if (info.symbol != nullptr) + if (info.symbol != gNullCharPtr) { delete[] info.symbol; - info.symbol = nullptr; + info.symbol = gNullCharPtr; } - if (info.unit != nullptr) + if (info.unit != gNullCharPtr) { delete[] info.unit; - info.unit = nullptr; + info.unit = gNullCharPtr; } CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); @@ -1276,10 +1383,10 @@ const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, ui info.value = 0.0f; // cleanup - if (info.label != nullptr) + if (info.label != gNullCharPtr) { delete[] info.label; - info.label = nullptr; + info.label = gNullCharPtr; } CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); @@ -1359,42 +1466,64 @@ const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiP { carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); - static const MidiProgramData fallbackMidiProgData = { 0, 0, nullptr }; + static MidiProgramData midiProgData; - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackMidiProgData); + // reset + midiProgData.bank = 0; + midiProgData.program = 0; + midiProgData.name = gNullCharPtr; + + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &midiProgData); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { if (midiProgramId < plugin->getMidiProgramCount()) - return &plugin->getMidiProgramData(midiProgramId); + { + const MidiProgramData& ret(plugin->getMidiProgramData(midiProgramId)); + carla_copyStruct(midiProgData, ret); + checkStringPtr(midiProgData.name); + return &midiProgData; + } carla_stderr2("carla_get_midi_program_data(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); - return &fallbackMidiProgData; + return &midiProgData; } carla_stderr2("carla_get_midi_program_data(%i, %i) - could not find plugin", pluginId, midiProgramId); - return &fallbackMidiProgData; + return &midiProgData; } const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId) { carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); - static const CustomData fallbackCustomData = { nullptr, nullptr, nullptr }; + static CustomData customData; + + // reset + customData.type = gNullCharPtr; + customData.key = gNullCharPtr; + customData.value = gNullCharPtr; - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackCustomData); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &customData); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { if (customDataId < plugin->getCustomDataCount()) - return &plugin->getCustomData(customDataId); + { + const CustomData& ret(plugin->getCustomData(customDataId)); + carla_copyStruct(customData, ret); + checkStringPtr(customData.type); + checkStringPtr(customData.key); + checkStringPtr(customData.value); + return &customData; + } carla_stderr2("carla_get_custom_data(%i, %i) - customDataId out of bounds", pluginId, customDataId); - return &fallbackCustomData; + return &customData; } carla_stderr2("carla_get_custom_data(%i, %i) - could not find plugin", pluginId, customDataId); - return &fallbackCustomData; + return &customData; } const char* carla_get_chunk_data(uint pluginId) @@ -1492,12 +1621,12 @@ const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId, float carla_debug("carla_get_parameter_text(%i, %i)", pluginId, parameterId); static char textBuf[STR_MAX+1]; - carla_zeroChar(textBuf, STR_MAX+1); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { if (parameterId < plugin->getParameterCount()) { + carla_zeroChar(textBuf, STR_MAX+1); plugin->getParameterText(parameterId, value, textBuf); return textBuf; } @@ -1516,12 +1645,12 @@ const char* carla_get_program_name(uint pluginId, uint32_t programId) carla_debug("carla_get_program_name(%i, %i)", pluginId, programId); static char programName[STR_MAX+1]; - carla_zeroChar(programName, STR_MAX+1); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { if (programId < plugin->getProgramCount()) { + carla_zeroChar(programName, STR_MAX+1); plugin->getProgramName(programId, programName); return programName; } @@ -1540,12 +1669,12 @@ const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId) carla_debug("carla_get_midi_program_name(%i, %i)", pluginId, midiProgramId); static char midiProgramName[STR_MAX+1]; - carla_zeroChar(midiProgramName, STR_MAX+1); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { if (midiProgramId < plugin->getMidiProgramCount()) { + carla_zeroChar(midiProgramName, STR_MAX+1); plugin->getMidiProgramName(midiProgramId, midiProgramName); return midiProgramName; } @@ -1564,10 +1693,10 @@ const char* carla_get_real_plugin_name(uint pluginId) carla_debug("carla_get_real_plugin_name(%i)", pluginId); static char realPluginName[STR_MAX+1]; - carla_zeroChar(realPluginName, STR_MAX+1); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { + carla_zeroChar(realPluginName, STR_MAX+1); plugin->getRealName(realPluginName); return realPluginName; } diff --git a/source/carla_backend.py b/source/carla_backend.py index 96cc76809..1f30c2a75 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -111,11 +111,46 @@ def numPtrToList(numPtr): return numList +# ------------------------------------------------------------------------------------------------------------ +# Convert a ctypes value into a python one + +c_int_types = (c_int, c_int8, c_int16, c_int32, c_int64, c_uint, c_uint8, c_uint16, c_uint32, c_uint64, c_long, c_longlong) +c_float_types = (c_float, c_double, c_longdouble) +c_intp_types = tuple(POINTER(i) for i in c_int_types) +c_floatp_types = tuple(POINTER(i) for i in c_float_types) + +def toPythonType(value, attr): + #if value is None: + #return None + if isinstance(value, (bool, int, float)): + return value + if isinstance(value, bytes): + return charPtrToString(value) + #if isinstance(value, c_bool): + #return bool(value) + #if isinstance(value, c_char_p): + #return charPtrToString(value) + #if isinstance(value, c_int_types): + #return int(value) + #if isinstance(value, c_float_types): + #return float(value) + if isinstance(value, c_intp_types): + return numPtrToList(value) + if isinstance(value, c_floatp_types): + return numPtrToList(value) + if isinstance(value, POINTER(c_char_p)): + return charPtrPtrToStringList(value) + print("..............", attr, ".....................", value, ":", type(value)) + #raise Exception("error here!!!") + #from sys import exit + #exit(1) + return value + # ------------------------------------------------------------------------------------------------------------ # Convert a ctypes struct into a python dict def structToDict(struct): - return dict((attr, getattr(struct, attr)) for attr, value in struct._fields_) + return dict((attr, toPythonType(getattr(struct, attr), attr)) for attr, value in struct._fields_) # ------------------------------------------------------------------------------------------------------------ # Carla Backend API (base definitions) diff --git a/source/carla_database.py b/source/carla_database.py index 776b3464c..1c43c10b9 100755 --- a/source/carla_database.py +++ b/source/carla_database.py @@ -278,22 +278,22 @@ def checkPluginInternal(desc): pinfo = deepcopy(PyPluginInfo) pinfo['build'] = BINARY_NATIVE pinfo['type'] = PLUGIN_INTERNAL - pinfo['hints'] = int(desc['hints']) - pinfo['name'] = charPtrToString(desc['name']) - pinfo['label'] = charPtrToString(desc['label']) - pinfo['maker'] = charPtrToString(desc['maker']) - pinfo['copyright'] = charPtrToString(desc['copyright']) - - pinfo['audio.ins'] = int(desc['audioIns']) - pinfo['audio.outs'] = int(desc['audioOuts']) + pinfo['hints'] = desc['hints'] + pinfo['name'] = desc['name'] + pinfo['label'] = desc['label'] + pinfo['maker'] = desc['maker'] + pinfo['copyright'] = desc['copyright'] + + pinfo['audio.ins'] = desc['audioIns'] + pinfo['audio.outs'] = desc['audioOuts'] pinfo['audio.total'] = pinfo['audio.ins'] + pinfo['audio.outs'] - pinfo['midi.ins'] = int(desc['midiIns']) - pinfo['midi.outs'] = int(desc['midiOuts']) + pinfo['midi.ins'] = desc['midiIns'] + pinfo['midi.outs'] = desc['midiOuts'] pinfo['midi.total'] = pinfo['midi.ins'] + pinfo['midi.outs'] - pinfo['parameters.ins'] = int(desc['parameterIns']) - pinfo['parameters.outs'] = int(desc['parameterOuts']) + pinfo['parameters.ins'] = desc['parameterIns'] + pinfo['parameters.outs'] = desc['parameterOuts'] pinfo['parameters.total'] = pinfo['parameters.ins'] + pinfo['parameters.outs'] plugins.append(pinfo) diff --git a/source/carla_host.py b/source/carla_host.py index e1afe7755..312b921b1 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -20,7 +20,7 @@ # Imports (Global) from PyQt4.QtCore import qCritical, QModelIndex, QTimer -from PyQt4.QtGui import QApplication, QFileSystemModel, QMainWindow, QPalette +from PyQt4.QtGui import QApplication, QFileSystemModel, QListWidgetItem, QMainWindow, QPalette # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) @@ -232,7 +232,7 @@ class HostWindow(QMainWindow): self.setTransportMenuEnabled(False) # ------------------------------------------------------------- - # Set up GUI (right panel) + # Set up GUI (disk) self.fDirModel = QFileSystemModel(self) self.fDirModel.setRootPath(HOME) @@ -247,6 +247,18 @@ class HostWindow(QMainWindow): self.ui.fileTreeView.setColumnHidden(3, True) self.ui.fileTreeView.setHeaderHidden(True) + # ------------------------------------------------------------- + # Set up GUI (disk) + + #self.item1 = QListWidgetItem(self.ui.lw_plugins) + #self.item1.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled|Qt.ItemIsDragEnabled) + #self.item1.setIcon(QIcon(":/bitmaps/thumbs/zita-rev1.png")) + #self.item1.setText("zita-rev1") + #item1.setTextAlignment(Qt.ali) + #self.ui.lw_plugins.() + + # ------------------------------------------------------------- + self.setProperWindowTitle() # ------------------------------------------------------------- @@ -895,7 +907,7 @@ class HostWindow(QMainWindow): extraPtr = self.getExtraPtr(dialog.fRetPlugin) if not gCarla.host.add_plugin(btype, ptype, filename, None, label, uniqueId, extraPtr): - CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), charPtrToString(gCarla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) + CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), gCarla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) return @pyqtSlot() diff --git a/source/carla_rack.py b/source/carla_rack.py index 38cd29baf..3bf613222 100644 --- a/source/carla_rack.py +++ b/source/carla_rack.py @@ -74,10 +74,11 @@ class CarlaRackList(QListWidget): # plugin files exts.append("dll") - exts.append("so") if MACOS: exts.append("dylib") + if not WINDOWS: + exts.append("so") self.fSupportedExtensions = tuple(i.replace("*.","") for i in exts) self.fWasLastDragValid = False @@ -103,7 +104,7 @@ class CarlaRackList(QListWidget): if os.path.isdir(filename): if os.path.exists(os.path.join(filename, "manifest.ttl")): - return False + return True elif os.path.isfile(filename): if filename.lower().endswith(self.fSupportedExtensions): diff --git a/source/carla_settings.py b/source/carla_settings.py index a20ae96cb..78cf9043d 100755 --- a/source/carla_settings.py +++ b/source/carla_settings.py @@ -145,7 +145,7 @@ class DriverSettingsW(QDialog): # fill combo-boxes first self.slot_updateDeviceInfo() - if 2 < audioNumPeriods < 3: + if audioNumPeriods in (2, 3): self.ui.sb_numperiods.setValue(audioNumPeriods) else: self.ui.sb_numperiods.setValue(CARLA_DEFAULT_AUDIO_NUM_PERIODS) @@ -184,10 +184,9 @@ class DriverSettingsW(QDialog): self.ui.cb_samplerate.clear() if deviceName and gCarla.host is not None: - driverDeviceInfo = gCarla.host.get_engine_driver_device_info(self.fDriverIndex, deviceName) - - self.fBufferSizes = numPtrToList(driverDeviceInfo['bufferSizes']) - self.fSampleRates = numPtrToList(driverDeviceInfo['sampleRates']) + driverDeviceInfo = gCarla.host.get_engine_driver_device_info(self.fDriverIndex, deviceName) + self.fBufferSizes = driverDeviceInfo['bufferSizes'] + self.fSampleRates = driverDeviceInfo['sampleRates'] else: self.fBufferSizes = BUFFER_SIZE_LIST self.fSampleRates = SAMPLE_RATE_LIST diff --git a/source/carla_shared.py b/source/carla_shared.py index f0881741c..d083d2f77 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -428,7 +428,6 @@ if readEnvVars: gCarla.DEFAULT_GIG_PATH = os.getenv("GIG_PATH", DEFAULT_GIG_PATH).split(splitter) gCarla.DEFAULT_SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter) gCarla.DEFAULT_SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter) - else: gCarla.DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter) gCarla.DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter) @@ -447,10 +446,10 @@ else: CWD = sys.path[0] # make it work with cxfreeze -if CWD.endswith("/carla"): - CWD = CWD.rsplit("/carla", 1)[0] -elif CWD.endswith("\\carla.exe"): - CWD = CWD.rsplit("\\carla.exe", 1)[0] +if WINDOWS and CWD.endswith(".exe"): + CWD = CWD.rsplit("\\", 1)[0] +elif CWD.endswith("/carla") or CWD.endswith("/carla-plugin") or CWD.endswith("/carla-patchbay") or CWD.endswith("/carla-rack"): + CWD = CWD.rsplit("/", 1)[0] # find tool def findTool(toolDir, toolName): diff --git a/source/carla_skin.py b/source/carla_skin.py index 8ef1284de..f72cd64ea 100644 --- a/source/carla_skin.py +++ b/source/carla_skin.py @@ -47,13 +47,6 @@ class AbstractPluginSlot(QFrame): self.fPluginId = pluginId self.fPluginInfo = gCarla.host.get_plugin_info(self.fPluginId) if gCarla.host is not None else gFakePluginInfo - self.fPluginInfo['filename'] = charPtrToString(self.fPluginInfo['filename']) - self.fPluginInfo['name'] = charPtrToString(self.fPluginInfo['name']) - self.fPluginInfo['label'] = charPtrToString(self.fPluginInfo['label']) - self.fPluginInfo['maker'] = charPtrToString(self.fPluginInfo['maker']) - self.fPluginInfo['copyright'] = charPtrToString(self.fPluginInfo['copyright']) - self.fPluginInfo['iconName'] = charPtrToString(self.fPluginInfo['iconName']) - if not gCarla.isLocal: self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI @@ -771,7 +764,7 @@ class PluginSlot_BasicFX(AbstractPluginSlot): if paramData['type'] != PARAMETER_INPUT: continue - paramName = charPtrToString(paramInfo['name']).split("/", 1)[0].split(" (", 1)[0].strip() + paramName = paramInfo['name'].split("/", 1)[0].split(" (", 1)[0].strip() paramLow = paramName.lower() if "Bandwidth" in paramName: @@ -1160,7 +1153,7 @@ class PluginSlot_ZynFX(AbstractPluginSlot): if paramData['type'] != PARAMETER_INPUT: continue - paramName = charPtrToString(paramInfo['name']) + paramName = paramInfo['name'] #paramLow = paramName.lower() # real zyn fx plugins @@ -1263,7 +1256,7 @@ class PluginSlot_ZynFX(AbstractPluginSlot): for i in range(midiProgramCount): mpData = gCarla.host.get_midi_program_data(self.fPluginId, i) - mpName = charPtrToString(mpData['name']) + mpName = mpData['name'] self.ui.cb_presets.addItem(mpName) @@ -1307,11 +1300,11 @@ class PluginSlot_ZynFX(AbstractPluginSlot): def createPluginSlot(parent, pluginId): pluginInfo = gCarla.host.get_plugin_info(pluginId) pluginName = gCarla.host.get_real_plugin_name(pluginId) - pluginLabel = charPtrToString(pluginInfo['label']) - uniqueId = int(pluginInfo['uniqueId']) + pluginLabel = pluginInfo['label'] + uniqueId = pluginInfo['uniqueId'] - #pluginMaker = charPtrToString(pluginInfo['maker']) - #pluginIcon = charPtrToString(pluginInfo['iconName']) + #pluginMaker = pluginInfo['maker'] + #pluginIcon = pluginInfo['iconName'] if pluginInfo['type'] == PLUGIN_INTERNAL: if pluginLabel.startswith("zyn") and pluginInfo['category'] != PLUGIN_CATEGORY_SYNTH: diff --git a/source/carla_widgets.py b/source/carla_widgets.py index 21d3e9404..f3a34d169 100755 --- a/source/carla_widgets.py +++ b/source/carla_widgets.py @@ -279,6 +279,9 @@ class PluginParameter(QWidget): def getTabIndex(self): return self.fTabIndex + def setPluginId(self, pluginId): + self.fPluginId = pluginId + def setDefault(self, value): self.ui.widget.setDefault(value) @@ -298,8 +301,7 @@ class PluginParameter(QWidget): self.ui.sb_channel.blockSignals(False) def setLabelWidth(self, width): - self.ui.label.setMinimumWidth(width) - self.ui.label.setMaximumWidth(width) + self.ui.label.setFixedWidth(width) @pyqtSlot() def slot_controlSpinboxCustomMenu(self): @@ -314,7 +316,7 @@ class PluginParameter(QWidget): for cc in MIDI_CC_LIST: action = menu.addAction(cc) - if self.fMidiControl != -1 and int(cc.split(" ")[0], 16) == self.fMidiControl: + if self.fMidiControl != -1 and int(cc.split(" ", 1)[0], 16) == self.fMidiControl: action.setCheckable(True) action.setChecked(True) @@ -326,7 +328,7 @@ class PluginParameter(QWidget): self.ui.sb_control.setValue(-1) else: selControlStr = actSel.text() - selControl = int(selControlStr.split(" ")[0], 16) + selControl = int(selControlStr.split(" ", 1)[0], 16) self.ui.sb_control.setValue(selControl) @pyqtSlot() @@ -348,15 +350,13 @@ class PluginParameter(QWidget): @pyqtSlot(int) def slot_controlSpinboxChanged(self, control): - if self.fMidiControl != control: - self.midiControlChanged.emit(self.fParameterId, control) - self.fMidiControl = control + self.fMidiControl = control + self.midiControlChanged.emit(self.fParameterId, control) @pyqtSlot(int) def slot_channelSpinboxChanged(self, channel): - if self.fMidiChannel != channel: - self.midiChannelChanged.emit(self.fParameterId, channel) - self.fMidiChannel = channel + self.fMidiChannel = channel + self.midiChannelChanged.emit(self.fParameterId, channel) @pyqtSlot(float) def slot_widgetValueChanged(self, value): @@ -457,12 +457,14 @@ class PluginEdit(QDialog): self.ui.dial_vol.valueChanged.connect(self.slot_volumeChanged) self.ui.dial_b_left.valueChanged.connect(self.slot_balanceLeftChanged) self.ui.dial_b_right.valueChanged.connect(self.slot_balanceRightChanged) + self.ui.dial_pan.valueChanged.connect(self.slot_panChanged) self.ui.sb_ctrl_channel.valueChanged.connect(self.slot_ctrlChannelChanged) self.ui.dial_drywet.customContextMenuRequested.connect(self.slot_knobCustomMenu) self.ui.dial_vol.customContextMenuRequested.connect(self.slot_knobCustomMenu) self.ui.dial_b_left.customContextMenuRequested.connect(self.slot_knobCustomMenu) self.ui.dial_b_right.customContextMenuRequested.connect(self.slot_knobCustomMenu) + self.ui.dial_pan.customContextMenuRequested.connect(self.slot_knobCustomMenu) self.ui.sb_ctrl_channel.customContextMenuRequested.connect(self.slot_channelCustomMenu) self.ui.keyboard.noteOn.connect(self.slot_noteOn) @@ -484,7 +486,7 @@ class PluginEdit(QDialog): # Update current program text if self.ui.cb_programs.count() > 0: pIndex = self.ui.cb_programs.currentIndex() - pName = charPtrToString(gCarla.host.get_program_name(self.fPluginId, pIndex)) + pName = gCarla.host.get_program_name(self.fPluginId, pIndex) #pName = pName[:40] + (pName[40:] and "...") self.ui.cb_programs.setItemText(pIndex, pName) @@ -492,9 +494,9 @@ class PluginEdit(QDialog): if self.ui.cb_midi_programs.count() > 0: mpIndex = self.ui.cb_midi_programs.currentIndex() mpData = gCarla.host.get_midi_program_data(self.fPluginId, mpIndex) - mpBank = int(mpData['bank']) - mpProg = int(mpData['program']) - mpName = charPtrToString(mpData['name']) + mpBank = mpData['bank'] + mpProg = mpData['program'] + mpName = mpData['name'] #mpName = mpName[:40] + (mpName[40:] and "...") self.ui.cb_midi_programs.setItemText(mpIndex, "%03i:%03i - %s" % (mpBank+1, mpProg+1, mpName)) @@ -510,12 +512,6 @@ class PluginEdit(QDialog): def reloadAll(self): if gCarla.host is not None: self.fPluginInfo = gCarla.host.get_plugin_info(self.fPluginId) - self.fPluginInfo['filename'] = charPtrToString(self.fPluginInfo['filename']) - self.fPluginInfo['name'] = charPtrToString(self.fPluginInfo['name']) - self.fPluginInfo['label'] = charPtrToString(self.fPluginInfo['label']) - self.fPluginInfo['maker'] = charPtrToString(self.fPluginInfo['maker']) - self.fPluginInfo['copyright'] = charPtrToString(self.fPluginInfo['copyright']) - self.fPluginInfo['iconName'] = charPtrToString(self.fPluginInfo['iconName']) if not gCarla.isLocal: self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI @@ -700,8 +696,8 @@ class PluginEdit(QDialog): parameter = { 'type': paramData['type'], 'hints': paramData['hints'], - 'name': charPtrToString(paramInfo['name']), - 'unit': charPtrToString(paramInfo['unit']), + 'name': paramInfo['name'], + 'unit': paramInfo['unit'], 'scalePoints': [], 'index': paramData['index'], @@ -722,7 +718,7 @@ class PluginEdit(QDialog): parameter['scalePoints'].append({ 'value': scalePointInfo['value'], - 'label': charPtrToString(scalePointInfo['label']) + 'label': scalePointInfo['label'] }) #parameter['name'] = parameter['name'][:30] + (parameter['name'][30:] and "...") @@ -815,7 +811,7 @@ class PluginEdit(QDialog): self.ui.label_programs.setEnabled(True) for i in range(programCount): - pName = charPtrToString(gCarla.host.get_program_name(self.fPluginId, i)) + pName = gCarla.host.get_program_name(self.fPluginId, i) #pName = pName[:40] + (pName[40:] and "...") self.ui.cb_programs.addItem(pName) @@ -841,9 +837,9 @@ class PluginEdit(QDialog): for i in range(midiProgramCount): mpData = gCarla.host.get_midi_program_data(self.fPluginId, i) - mpBank = int(mpData['bank']) - mpProg = int(mpData['program']) - mpName = charPtrToString(mpData['name']) + mpBank = mpData['bank'] + mpProg = mpData['program'] + mpName = mpData['name'] #mpName = mpName[:40] + (mpName[40:] and "...") self.ui.cb_midi_programs.addItem("%03i:%03i - %s" % (mpBank+1, mpProg+1, mpName)) @@ -1062,7 +1058,7 @@ class PluginEdit(QDialog): presetList = [] for i in range(gCarla.host.get_program_count(self.fPluginId)): - presetList.append("%03i - %s" % (i+1, charPtrToString(gCarla.host.get_program_name(self.fPluginId, i)))) + presetList.append("%03i - %s" % (i+1, gCarla.host.get_program_name(self.fPluginId, i))) ret = QInputDialog.getItem(self, self.tr("Open LV2 Preset"), self.tr("Select an LV2 Preset:"), presetList, 0, False) @@ -1135,6 +1131,11 @@ class PluginEdit(QDialog): if gCarla.host is not None: gCarla.host.set_balance_right(self.fPluginId, float(value)/1000) + @pyqtSlot(int) + def slot_panChanged(self, value): + if gCarla.host is not None: + gCarla.host.set_panning(self.fPluginId, float(value)/1000) + @pyqtSlot(int) def slot_panningChanged(self, value): if gCarla.host is not None: