Browse Source

Always return a valid ptr on standalone; Cleanup

tags/1.9.4
falkTX 11 years ago
parent
commit
ed620b139d
12 changed files with 345 additions and 199 deletions
  1. +2
    -0
      resources/resources.qrc
  2. +59
    -0
      resources/ui/carla_host.ui
  3. +13
    -97
      source/backend/CarlaHost.h
  4. +161
    -32
      source/backend/standalone/CarlaStandalone.cpp
  5. +36
    -1
      source/carla_backend.py
  6. +12
    -12
      source/carla_database.py
  7. +15
    -3
      source/carla_host.py
  8. +3
    -2
      source/carla_rack.py
  9. +4
    -5
      source/carla_settings.py
  10. +4
    -5
      source/carla_shared.py
  11. +7
    -14
      source/carla_skin.py
  12. +29
    -28
      source/carla_widgets.py

+ 2
- 0
resources/resources.qrc View File

@@ -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>


+ 59
- 0
resources/ui/carla_host.ui View 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>


+ 13
- 97
source/backend/CarlaHost.h View File

@@ -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;

/* ------------------------------------------------------------------------------------------------------------


+ 161
- 32
source/backend/standalone/CarlaStandalone.cpp View File

@@ -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;
}


+ 36
- 1
source/carla_backend.py View File

@@ -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)


+ 12
- 12
source/carla_database.py View File

@@ -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)


+ 15
- 3
source/carla_host.py View File

@@ -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()


+ 3
- 2
source/carla_rack.py View File

@@ -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):


+ 4
- 5
source/carla_settings.py View File

@@ -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


+ 4
- 5
source/carla_shared.py View File

@@ -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):


+ 7
- 14
source/carla_skin.py View File

@@ -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:


+ 29
- 28
source/carla_widgets.py View File

@@ -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:


Loading…
Cancel
Save