| @@ -122,6 +122,8 @@ | |||
| <file>bitmaps/style/arrow.png</file> | |||
| <file>bitmaps/style/groupbox.png</file> | |||
| <file>bitmaps/thumbs/zita-rev1.png</file> | |||
| <file>bitmaps/zita-rev/ambsect.png</file> | |||
| <file>bitmaps/zita-rev/eq1sect.png</file> | |||
| <file>bitmaps/zita-rev/eq2sect.png</file> | |||
| @@ -140,6 +140,65 @@ | |||
| <attribute name="title"> | |||
| <string>Plugins</string> | |||
| </attribute> | |||
| <layout class="QVBoxLayout" name="verticalLayout"> | |||
| <property name="spacing"> | |||
| <number>0</number> | |||
| </property> | |||
| <property name="leftMargin"> | |||
| <number>0</number> | |||
| </property> | |||
| <property name="topMargin"> | |||
| <number>0</number> | |||
| </property> | |||
| <property name="rightMargin"> | |||
| <number>0</number> | |||
| </property> | |||
| <property name="bottomMargin"> | |||
| <number>1</number> | |||
| </property> | |||
| <item> | |||
| <widget class="QListWidget" name="lw_plugins"> | |||
| <property name="editTriggers"> | |||
| <set>QAbstractItemView::NoEditTriggers</set> | |||
| </property> | |||
| <property name="showDropIndicator" stdset="0"> | |||
| <bool>false</bool> | |||
| </property> | |||
| <property name="dragEnabled"> | |||
| <bool>true</bool> | |||
| </property> | |||
| <property name="dragDropMode"> | |||
| <enum>QAbstractItemView::DragOnly</enum> | |||
| </property> | |||
| <property name="selectionBehavior"> | |||
| <enum>QAbstractItemView::SelectRows</enum> | |||
| </property> | |||
| <property name="iconSize"> | |||
| <size> | |||
| <width>150</width> | |||
| <height>50</height> | |||
| </size> | |||
| </property> | |||
| <property name="textElideMode"> | |||
| <enum>Qt::ElideMiddle</enum> | |||
| </property> | |||
| <property name="movement"> | |||
| <enum>QListView::Static</enum> | |||
| </property> | |||
| <property name="flow"> | |||
| <enum>QListView::TopToBottom</enum> | |||
| </property> | |||
| <property name="viewMode"> | |||
| <enum>QListView::IconMode</enum> | |||
| </property> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| <widget class="QWidget" name="presets"> | |||
| <attribute name="title"> | |||
| <string>Presets</string> | |||
| </attribute> | |||
| </widget> | |||
| </widget> | |||
| </item> | |||
| @@ -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; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| @@ -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<MidiProgramData>(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>(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; | |||
| } | |||
| @@ -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) | |||
| @@ -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) | |||
| @@ -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() | |||
| @@ -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): | |||
| @@ -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 | |||
| @@ -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): | |||
| @@ -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: | |||
| @@ -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: | |||