Browse Source

More cleanup; Add get_current_plugin_count and get_max_plugin_number C API

tags/1.9.5
falkTX 11 years ago
parent
commit
4ee4519a0b
8 changed files with 329 additions and 269 deletions
  1. +11
    -0
      source/backend/CarlaHost.h
  2. +18
    -0
      source/backend/CarlaStandalone.cpp
  3. +1
    -1
      source/backend/engine/CarlaEngine.cpp
  4. +33
    -35
      source/carla
  5. +35
    -0
      source/carla_backend.py
  6. +184
    -227
      source/carla_host.py
  7. +23
    -1
      source/carla_patchbay.py
  8. +24
    -5
      source/carla_rack.py

+ 11
- 0
source/backend/CarlaHost.h View File

@@ -545,6 +545,17 @@ CARLA_EXPORT uint64_t carla_get_current_transport_frame();
CARLA_EXPORT const CarlaTransportInfo* carla_get_transport_info(); CARLA_EXPORT const CarlaTransportInfo* carla_get_transport_info();
#endif #endif


/*!
* Current number of plugins loaded.
*/
CARLA_EXPORT uint32_t carla_get_current_plugin_count();

/*!
* Maximum number of loadable plugins allowed.
* Returns 0 if engine is not started.
*/
CARLA_EXPORT uint32_t carla_get_max_plugin_number();

/*! /*!
* Add a new plugin. * Add a new plugin.
* If you don't know the binary type use the BINARY_NATIVE macro. * If you don't know the binary type use the BINARY_NATIVE macro.


+ 18
- 0
source/backend/CarlaStandalone.cpp View File

@@ -1291,6 +1291,24 @@ const CarlaTransportInfo* carla_get_transport_info()


// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------


uint32_t carla_get_current_plugin_count()
{
if (gStandalone.engine != nullptr)
return gStandalone.engine->getCurrentPluginCount();

return 0;
}

uint32_t carla_get_max_plugin_number()
{
if (gStandalone.engine != nullptr)
return gStandalone.engine->getMaxPluginNumber();

return 0;
}

// -------------------------------------------------------------------------------------------------------------------

bool carla_add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* name, const char* label, int64_t uniqueId, const void* extraPtr) bool carla_add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* name, const char* label, int64_t uniqueId, const void* extraPtr)
{ {
CARLA_SAFE_ASSERT_RETURN(label != nullptr /*&& label[0] != '\0'*/, false); CARLA_SAFE_ASSERT_RETURN(label != nullptr /*&& label[0] != '\0'*/, false);


+ 1
- 1
source/backend/engine/CarlaEngine.cpp View File

@@ -729,7 +729,7 @@ bool CarlaEngine::replacePlugin(const uint id) noexcept
carla_debug("CarlaEngine::replacePlugin(%i)", id); carla_debug("CarlaEngine::replacePlugin(%i)", id);


// might use this to reset // might use this to reset
if (id == pData->curPluginCount || id == pData->maxPluginNumber)
if (id == pData->maxPluginNumber)
{ {
pData->nextPluginId = pData->maxPluginNumber; pData->nextPluginId = pData->maxPluginNumber;
return true; return true;


+ 33
- 35
source/carla View File

@@ -79,7 +79,6 @@ class CarlaMultiW(QTabWidget):


parent.ui.act_canvas_show_internal.triggered.connect(self.fPatchbay.slot_canvasShowInternal) parent.ui.act_canvas_show_internal.triggered.connect(self.fPatchbay.slot_canvasShowInternal)
parent.ui.act_canvas_show_external.triggered.connect(self.fPatchbay.slot_canvasShowExternal) parent.ui.act_canvas_show_external.triggered.connect(self.fPatchbay.slot_canvasShowExternal)
parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later
parent.ui.act_canvas_arrange.triggered.connect(self.fPatchbay.slot_canvasArrange) parent.ui.act_canvas_arrange.triggered.connect(self.fPatchbay.slot_canvasArrange)
parent.ui.act_canvas_refresh.triggered.connect(self.fPatchbay.slot_canvasRefresh) parent.ui.act_canvas_refresh.triggered.connect(self.fPatchbay.slot_canvasRefresh)
parent.ui.act_canvas_zoom_fit.triggered.connect(self.fPatchbay.slot_canvasZoomFit) parent.ui.act_canvas_zoom_fit.triggered.connect(self.fPatchbay.slot_canvasZoomFit)
@@ -89,8 +88,20 @@ class CarlaMultiW(QTabWidget):
parent.ui.act_canvas_print.triggered.connect(self.fPatchbay.slot_canvasPrint) parent.ui.act_canvas_print.triggered.connect(self.fPatchbay.slot_canvasPrint)
parent.ui.act_canvas_save_image.triggered.connect(self.fPatchbay.slot_canvasSaveImage) parent.ui.act_canvas_save_image.triggered.connect(self.fPatchbay.slot_canvasSaveImage)


# TODO, later
parent.ui.act_canvas_arrange.setEnabled(False)

parent.ui.act_settings_configure.triggered.connect(self.fPatchbay.slot_configureCarla) parent.ui.act_settings_configure.triggered.connect(self.fPatchbay.slot_configureCarla)


host.PluginAddedCallback.connect(self.fRack.slot_handlePluginAddedCallback)
host.PluginAddedCallback.connect(self.fPatchbay.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.fRack.slot_handlePluginRemovedCallback)
host.PluginRemovedCallback.connect(self.fPatchbay.slot_handlePluginRemovedCallback)
host.PluginRenamedCallback.connect(self.fRack.slot_handlePluginRenamedCallback)
host.PluginRenamedCallback.connect(self.fPatchbay.slot_handlePluginRenamedCallback)
host.PluginUnavailableCallback.connect(self.fRack.slot_handlePluginUnavailableCallback)
host.PluginUnavailableCallback.connect(self.fPatchbay.slot_handlePluginUnavailableCallback)

host.ParameterValueChangedCallback.connect(self.fRack.slot_handleParameterValueChangedCallback) host.ParameterValueChangedCallback.connect(self.fRack.slot_handleParameterValueChangedCallback)
host.ParameterValueChangedCallback.connect(self.fPatchbay.slot_handleParameterValueChangedCallback) host.ParameterValueChangedCallback.connect(self.fPatchbay.slot_handleParameterValueChangedCallback)
host.ParameterDefaultChangedCallback.connect(self.fRack.slot_handleParameterDefaultChangedCallback) host.ParameterDefaultChangedCallback.connect(self.fRack.slot_handleParameterDefaultChangedCallback)
@@ -124,24 +135,16 @@ class CarlaMultiW(QTabWidget):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


def getPluginCount(self):
return self.fRack.getPluginCount()

# -----------------------------------------------------------------

def addPlugin(self, pluginId, isProjectLoading):
self.fRack.addPlugin(pluginId, isProjectLoading)
self.fPatchbay.addPlugin(pluginId, isProjectLoading)

def removePlugin(self, pluginId):
self.fRack.removePlugin(pluginId)
self.fPatchbay.removePlugin(pluginId)
def fixCanvasPreviewSize(self):
self.fPatchbay.resize(self.fRack.size())
self.fPatchbay.slot_miniCanvasCheckSize()


def renamePlugin(self, pluginId, newName):
self.fRack.renamePlugin(pluginId, newName)
def setUseCustomPaint(self, useCustomPaint):
if self.fUseCustomPaint != useCustomPaint:
self.fUseCustomPaint = useCustomPaint
self.update()


def disablePlugin(self, pluginId, errorMsg):
self.fRack.disablePlugin(pluginId, errorMsg)
# -----------------------------------------------------------------


def removeAllPlugins(self): def removeAllPlugins(self):
self.fRack.removeAllPlugins() self.fRack.removeAllPlugins()
@@ -150,12 +153,12 @@ class CarlaMultiW(QTabWidget):
# ----------------------------------------------------------------- # -----------------------------------------------------------------


def engineStarted(self): def engineStarted(self):
pass
#self.fRack.engineStarted()
#self.fPatchbay.engineStarted()
self.fRack.engineStarted()
self.fPatchbay.engineStarted()
self.fParent.engineStarted()


def engineStopped(self): def engineStopped(self):
#self.fRack.engineStopped()
self.fRack.engineStopped()
self.fPatchbay.engineStopped() self.fPatchbay.engineStopped()
self.fParent.engineStopped() self.fParent.engineStopped()


@@ -173,7 +176,7 @@ class CarlaMultiW(QTabWidget):


def projectLoadingStarted(self): def projectLoadingStarted(self):
self.fRack.projectLoadingStarted() self.fRack.projectLoadingStarted()
#self.fPatchbay.projectLoadingStarted()
self.fPatchbay.projectLoadingStarted()


def projectLoadingFinished(self): def projectLoadingFinished(self):
self.fRack.projectLoadingFinished() self.fRack.projectLoadingFinished()
@@ -182,6 +185,7 @@ class CarlaMultiW(QTabWidget):
# ----------------------------------------------------------------- # -----------------------------------------------------------------


def saveSettings(self, settings): def saveSettings(self, settings):
self.fRack.saveSettings(settings)
self.fPatchbay.saveSettings(settings) self.fPatchbay.saveSettings(settings)


def showEditDialog(self, pluginId): def showEditDialog(self, pluginId):
@@ -189,15 +193,6 @@ class CarlaMultiW(QTabWidget):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


def fixCanvasPreviewSize(self):
self.fPatchbay.resize(self.fRack.size())
self.fPatchbay.slot_miniCanvasCheckSize()

def setUseCustomPaint(self, useCustomPaint):
if self.fUseCustomPaint != useCustomPaint:
self.fUseCustomPaint = useCustomPaint
self.update()

def paintEvent(self, event): def paintEvent(self, event):
QTabWidget.paintEvent(self, event) QTabWidget.paintEvent(self, event)


@@ -257,14 +252,17 @@ class CarlaHostW(HostWindow):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


def engineChanged(self):
self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.host.get_sample_rate(), self.host.get_buffer_size())
self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTextTransport))

def engineStarted(self):
self.engineChanged()

def engineStopped(self): def engineStopped(self):
self.fInfoText = "" self.fInfoText = ""
self.fInfoLabel.setText("Engine stopped") self.fInfoLabel.setText("Engine stopped")


#def engineChanged(self):
#self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (gCarla.sampleRate, gCarla.bufferSize)
#self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTextTransport))

# ----------------------------------------------------------------- # -----------------------------------------------------------------


def updateInfoLabelXandSize(self): def updateInfoLabelXandSize(self):


+ 35
- 0
source/carla_backend.py View File

@@ -1514,6 +1514,17 @@ class CarlaHostMeta(QObject):
def get_transport_info(self): def get_transport_info(self):
raise NotImplementedError raise NotImplementedError


# Current number of plugins loaded.
@abstractmethod
def get_current_plugin_count(self):
raise NotImplementedError

# Maximum number of loadable plugins allowed.
# Returns 0 if engine is not started.
@abstractmethod
def get_max_plugin_number(self):
raise NotImplementedError

# Add a new plugin. # Add a new plugin.
# If you don't know the binary type use the BINARY_NATIVE macro. # If you don't know the binary type use the BINARY_NATIVE macro.
# @param btype Binary type # @param btype Binary type
@@ -2035,6 +2046,12 @@ class CarlaHostNull(CarlaHostMeta):
def get_transport_info(self): def get_transport_info(self):
return PyCarlaTransportInfo return PyCarlaTransportInfo


def get_current_plugin_count(self):
return 0

def get_max_plugin_number(self):
return 0

def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr): def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr):
return False return False


@@ -2311,6 +2328,12 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_get_transport_info.argtypes = None self.lib.carla_get_transport_info.argtypes = None
self.lib.carla_get_transport_info.restype = POINTER(CarlaTransportInfo) self.lib.carla_get_transport_info.restype = POINTER(CarlaTransportInfo)


self.lib.carla_get_current_plugin_count.argtypes = None
self.lib.carla_get_current_plugin_count.restype = c_uint32

self.lib.carla_get_max_plugin_number.argtypes = None
self.lib.carla_get_max_plugin_number.restype = c_uint32

self.lib.carla_add_plugin.argtypes = [c_enum, c_enum, c_char_p, c_char_p, c_char_p, c_int64, c_void_p] self.lib.carla_add_plugin.argtypes = [c_enum, c_enum, c_char_p, c_char_p, c_char_p, c_int64, c_void_p]
self.lib.carla_add_plugin.restype = c_bool self.lib.carla_add_plugin.restype = c_bool


@@ -2579,6 +2602,12 @@ class CarlaHostDLL(CarlaHostMeta):
def get_transport_info(self): def get_transport_info(self):
return structToDict(self.lib.carla_get_transport_info().contents) return structToDict(self.lib.carla_get_transport_info().contents)


def get_current_plugin_count(self):
return int(self.lib.carla_get_current_plugin_count())

def get_max_plugin_number(self):
return int(self.lib.carla_get_max_plugin_number())

def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr): def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr):
cfilename = filename.encode("utf-8") if filename else None cfilename = filename.encode("utf-8") if filename else None
cname = name.encode("utf-8") if name else None cname = name.encode("utf-8") if name else None
@@ -2912,6 +2941,12 @@ class CarlaHostPlugin(CarlaHostMeta):
def get_transport_info(self): def get_transport_info(self):
return self.fTransportInfo return self.fTransportInfo


def get_current_plugin_count(self):
return len(self.fPluginsInfo)

def get_max_plugin_number(self):
return 0 # TODO

def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr): def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr):
return self.sendMsgAndSetError(["add_plugin", btype, ptype, filename, name, label, uniqueId]) return self.sendMsgAndSetError(["add_plugin", btype, ptype, filename, name, label, uniqueId])




+ 184
- 227
source/carla_host.py View File

@@ -62,20 +62,17 @@ class HostWidgetMeta(object):


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------


def getPluginCount(self):
raise NotImplementedError

def addPlugin(self, pluginId, isProjectLoading):
raise NotImplementedError
#def addPlugin(self, pluginId, isProjectLoading):
#raise NotImplementedError


def removePlugin(self, pluginId):
raise NotImplementedError
#def removePlugin(self, pluginId):
#raise NotImplementedError


def renamePlugin(self, pluginId, newName):
raise NotImplementedError
#def renamePlugin(self, pluginId, newName):
#raise NotImplementedError


def disablePlugin(self, pluginId, errorMsg):
raise NotImplementedError
#def disablePlugin(self, pluginId, errorMsg):
#raise NotImplementedError


def removeAllPlugins(self): def removeAllPlugins(self):
raise NotImplementedError raise NotImplementedError
@@ -256,24 +253,14 @@ class HostWindow(QMainWindow):
self.SIGUSR1.connect(self.slot_handleSIGUSR1) self.SIGUSR1.connect(self.slot_handleSIGUSR1)
self.SIGTERM.connect(self.slot_handleSIGTERM) self.SIGTERM.connect(self.slot_handleSIGTERM)


host.DebugCallback.connect(self.slot_handleDebugCallback)

host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
host.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback)
host.PluginUnavailableCallback.connect(self.slot_handlePluginUnavailableCallback)

# parameter (rack, patchbay)
# program, midi-program, ui-state (rack, patchbay)
# note on, off (rack, patchbay)
# update, reload (rack, patchbay)
# patchbay

host.EngineStartedCallback.connect(self.slot_handleEngineStartedCallback) host.EngineStartedCallback.connect(self.slot_handleEngineStartedCallback)
host.EngineStoppedCallback.connect(self.slot_handleEngineStoppedCallback) host.EngineStoppedCallback.connect(self.slot_handleEngineStoppedCallback)

host.SampleRateChangedCallback.connect(self.slot_handleSampleRateChangedCallback) host.SampleRateChangedCallback.connect(self.slot_handleSampleRateChangedCallback)


host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)

host.DebugCallback.connect(self.slot_handleDebugCallback)
host.InfoCallback.connect(self.slot_handleInfoCallback) host.InfoCallback.connect(self.slot_handleInfoCallback)
host.ErrorCallback.connect(self.slot_handleErrorCallback) host.ErrorCallback.connect(self.slot_handleErrorCallback)
host.QuitCallback.connect(self.slot_handleQuitCallback) host.QuitCallback.connect(self.slot_handleQuitCallback)
@@ -282,6 +269,7 @@ class HostWindow(QMainWindow):
# Final setup # Final setup


self.setProperWindowTitle() self.setProperWindowTitle()

QTimer.singleShot(0, self.slot_engineStart) QTimer.singleShot(0, self.slot_engineStart)


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
@@ -299,6 +287,15 @@ class HostWindow(QMainWindow):
# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
# Called by containers # Called by containers


def isProjectLoading(self):
return self.fIsProjectLoading

def getSavedSettings(self):
return self.fSavedSettings

def setLoadRDFsNeeded(self):
self.fLadspaRdfNeedsUpdate = True

def openSettingsWindow(self, hasCanvas, hasCanvasGL): def openSettingsWindow(self, hasCanvas, hasCanvasGL):
hasEngine = bool(self.fSessionManagerName != "Non Session Manager") hasEngine = bool(self.fSessionManagerName != "Non Session Manager")
dialog = CarlaSettingsW(self, self.host, hasCanvas, hasCanvasGL, hasEngine) dialog = CarlaSettingsW(self, self.host, hasCanvas, hasCanvasGL, hasEngine)
@@ -336,6 +333,19 @@ class HostWindow(QMainWindow):
self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen) self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen)
self.ui.miniCanvasPreview.init(self.fContainer.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING]) self.ui.miniCanvasPreview.init(self.fContainer.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])


# --------------------------------------------------------------------------------------------------------
# Called by the signal handler

@pyqtSlot()
def slot_handleSIGUSR1(self):
print("Got SIGUSR1 -> Saving project now")
self.slot_fileSave()

@pyqtSlot()
def slot_handleSIGTERM(self):
print("Got SIGTERM -> Closing now")
self.close()

# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
# Internal stuff (files) # Internal stuff (files)


@@ -382,7 +392,7 @@ class HostWindow(QMainWindow):


newFile = True newFile = True


if self.fContainer.getPluginCount() > 0:
if self.host.get_current_plugin_count() > 0:
ask = QMessageBox.question(self, self.tr("Question"), self.tr("There are some plugins loaded, do you want to remove them now?"), ask = QMessageBox.question(self, self.tr("Question"), self.tr("There are some plugins loaded, do you want to remove them now?"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
newFile = (ask == QMessageBox.Yes) newFile = (ask == QMessageBox.Yes)
@@ -516,7 +526,8 @@ class HostWindow(QMainWindow):


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------


def startEngine(self):
@pyqtSlot()
def slot_engineStart(self):
audioDriver = self.setEngineSettings() audioDriver = self.setEngineSettings()


if not self.host.engine_init(audioDriver, self.fClientName): if not self.host.engine_init(audioDriver, self.fClientName):
@@ -534,8 +545,9 @@ class HostWindow(QMainWindow):


self.fFirstEngineInit = False self.fFirstEngineInit = False


def stopEngine(self):
if self.fContainer.getPluginCount() > 0:
@pyqtSlot()
def slot_engineStop(self):
if self.host.get_current_plugin_count() > 0:
ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n" ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n"
"Do you want to do this now?"), "Do you want to do this now?"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
@@ -550,7 +562,10 @@ class HostWindow(QMainWindow):


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------


def handleEngineStarted(self):
@pyqtSlot(str)
def slot_handleEngineStartedCallback(self, processMode, transportMode, driverName):
self.fSampleRate = self.host.get_sample_rate()

check = self.host.is_engine_running() check = self.host.is_engine_running()
self.ui.menu_PluginMacros.setEnabled(check) self.ui.menu_PluginMacros.setEnabled(check)
self.ui.menu_Canvas.setEnabled(check) self.ui.menu_Canvas.setEnabled(check)
@@ -572,7 +587,12 @@ class HostWindow(QMainWindow):
self.refreshTransport(True) self.refreshTransport(True)
self.fContainer.engineStarted() self.fContainer.engineStarted()


def handleEngineStopped(self):
self.startTimers()

@pyqtSlot()
def slot_handleEngineStoppedCallback(self):
self.killTimers()

# just in case # just in case
self.ui.act_plugin_remove_all.setEnabled(False) self.ui.act_plugin_remove_all.setEnabled(False)
self.fContainer.removeAllPlugins() self.fContainer.removeAllPlugins()
@@ -596,62 +616,80 @@ class HostWindow(QMainWindow):
self.fTextTransport = "" self.fTextTransport = ""
self.fContainer.engineStopped() self.fContainer.engineStopped()


self.fSampleRate = 0.0

@pyqtSlot(float)
def slot_handleSampleRateChangedCallback(self, newSampleRate):
self.fSampleRate = newSampleRate
self.refreshTransport(True)

# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
# Internal stuff (plugins)


@pyqtSlot() @pyqtSlot()
def slot_engineStart(self):
self.startEngine()
#self.handleEngineStarted()
def slot_pluginAdd(self, pluginToReplace = -1):
dialog = PluginDatabaseW(self, self.host)


@pyqtSlot()
def slot_engineStop(self):
self.stopEngine()
#self.handleEngineStopped()
if not dialog.exec_():
return


# --------------------------------------------------------------------------------------------------------
if not self.host.is_engine_running():
QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped"))
return


@pyqtSlot(str)
def slot_handleEngineStartedCallback(self, processMode, transportMode, driverName):
self.fSampleRate = self.host.get_sample_rate()
self.handleEngineStarted()
self.startTimers()
btype = dialog.fRetPlugin['build']
ptype = dialog.fRetPlugin['type']
filename = dialog.fRetPlugin['filename']
label = dialog.fRetPlugin['label']
uniqueId = dialog.fRetPlugin['uniqueId']
extraPtr = self.getExtraPtr(dialog.fRetPlugin)

if pluginToReplace >= 0:
if not self.host.replace_plugin(pluginToReplace):
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to replace plugin"), self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
return

ok = self.host.add_plugin(btype, ptype, filename, None, label, uniqueId, extraPtr)

if pluginToReplace >= 0:
self.host.replace_plugin(self.host.get_max_plugin_number())

if not ok:
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)


@pyqtSlot() @pyqtSlot()
def slot_handleEngineStoppedCallback(self):
self.killTimers()
self.handleEngineStopped()
self.fSampleRate = 0.0
def slot_pluginRemoveAll(self):
self.ui.act_plugin_remove_all.setEnabled(False)


# --------------------------------------------------------------------------------------------------------
# Internal stuff (timers)
count = self.host.get_current_plugin_count()


def startTimers(self):
if self.fIdleTimerFast == 0:
self.fIdleTimerFast = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL])
if count == 0:
return


if self.fIdleTimerSlow == 0:
self.fIdleTimerSlow = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL]*4)
self.fContainer.projectLoadingStarted()


def restartTimersIfNeeded(self):
if self.fIdleTimerFast != 0:
self.killTimer(self.fIdleTimerFast)
self.fIdleTimerFast = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL])
app = QApplication.instance()
for i in range(count):
app.processEvents()
self.host.remove_plugin(count-i-1)


if self.fIdleTimerSlow != 0:
self.killTimer(self.fIdleTimerSlow)
self.fIdleTimerSlow = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL]*4)
self.fContainer.projectLoadingFinished()


def killTimers(self):
if self.fIdleTimerFast != 0:
self.killTimer(self.fIdleTimerFast)
self.fIdleTimerFast = 0
#self.fContainer.removeAllPlugins()
#self.host.remove_all_plugins()


if self.fIdleTimerSlow != 0:
self.killTimer(self.fIdleTimerSlow)
self.fIdleTimerSlow = 0
# --------------------------------------------------------------------------------------------------------


# -----------------------------------------------------------------
# Internal stuff (plugins)
@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0)

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0)

# --------------------------------------------------------------------------------------------------------
# Internal stuff (plugin data)


def getExtraPtr(self, plugin): def getExtraPtr(self, plugin):
ptype = plugin['type'] ptype = plugin['type']
@@ -696,11 +734,35 @@ class HostWindow(QMainWindow):


frLadspa.close() frLadspa.close()


# FIXME - put above?
def setLoadRDFsNeeded(self):
self.fLadspaRdfNeedsUpdate = True
# --------------------------------------------------------------------------------------------------------
# Internal stuff (timers)


# -----------------------------------------------------------------
def startTimers(self):
if self.fIdleTimerFast == 0:
self.fIdleTimerFast = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL])

if self.fIdleTimerSlow == 0:
self.fIdleTimerSlow = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL]*4)

def restartTimersIfNeeded(self):
if self.fIdleTimerFast != 0:
self.killTimer(self.fIdleTimerFast)
self.fIdleTimerFast = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL])

if self.fIdleTimerSlow != 0:
self.killTimer(self.fIdleTimerSlow)
self.fIdleTimerSlow = self.startTimer(self.fSavedSettings[CARLA_KEY_MAIN_REFRESH_INTERVAL]*4)

def killTimers(self):
if self.fIdleTimerFast != 0:
self.killTimer(self.fIdleTimerFast)
self.fIdleTimerFast = 0

if self.fIdleTimerSlow != 0:
self.killTimer(self.fIdleTimerSlow)
self.fIdleTimerSlow = 0

# --------------------------------------------------------------------------------------------------------
# Internal stuff (transport) # Internal stuff (transport)


def refreshTransport(self, forced = False): def refreshTransport(self, forced = False):
@@ -708,8 +770,8 @@ class HostWindow(QMainWindow):
return return


timeInfo = self.host.get_transport_info() timeInfo = self.host.get_transport_info()
playing = bool(timeInfo['playing'])
frame = int(timeInfo['frame'])
playing = timeInfo['playing']
frame = timeInfo['frame']


if playing != self.fLastTransportState or forced: if playing != self.fLastTransportState or forced:
if playing: if playing:
@@ -741,6 +803,48 @@ class HostWindow(QMainWindow):
self.ui.act_transport_forwards.setEnabled(enabled) self.ui.act_transport_forwards.setEnabled(enabled)
self.ui.menu_Transport.setEnabled(enabled) self.ui.menu_Transport.setEnabled(enabled)


@pyqtSlot(bool)
def slot_transportPlayPause(self, toggled):
if not self.host.is_engine_running():
return

if toggled:
self.host.transport_play()
else:
self.host.transport_pause()

self.refreshTransport()

@pyqtSlot()
def slot_transportStop(self):
if not self.host.is_engine_running():
return

self.host.transport_pause()
self.host.transport_relocate(0)

self.refreshTransport()

@pyqtSlot()
def slot_transportBackwards(self):
if not self.host.is_engine_running():
return

newFrame = self.host.get_current_transport_frame() - 100000

if newFrame < 0:
newFrame = 0

self.host.transport_relocate(newFrame)

@pyqtSlot()
def slot_transportForwards(self):
if not self.host.is_engine_running():
return

newFrame = self.host.get_current_transport_frame() + 100000
self.host.transport_relocate(newFrame)

# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Internal stuff (settings) # Internal stuff (settings)


@@ -818,131 +922,6 @@ class HostWindow(QMainWindow):
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Internal stuff (gui) # Internal stuff (gui)


@pyqtSlot()
def slot_pluginAdd(self, pluginToReplace = -1):
dialog = PluginDatabaseW(self, self.host)

if not dialog.exec_():
return

if not self.host.is_engine_running():
QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped"))
return

btype = dialog.fRetPlugin['build']
ptype = dialog.fRetPlugin['type']
filename = dialog.fRetPlugin['filename']
label = dialog.fRetPlugin['label']
uniqueId = dialog.fRetPlugin['uniqueId']
extraPtr = self.getExtraPtr(dialog.fRetPlugin)

if pluginToReplace >= 0:
if not self.host.replace_plugin(pluginToReplace):
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to replace plugin"), self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
return

ok = self.host.add_plugin(btype, ptype, filename, None, label, uniqueId, extraPtr)

if pluginToReplace >= 0:
self.host.replace_plugin(self.fContainer.getPluginCount())

if not ok:
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

@pyqtSlot()
def slot_pluginRemoveAll(self):
self.ui.act_plugin_remove_all.setEnabled(False)

count = self.fContainer.getPluginCount()

if count == 0:
return

self.fContainer.projectLoadingStarted()

app = QApplication.instance()
for i in range(count):
app.processEvents()
self.host.remove_plugin(count-i-1)

self.fContainer.projectLoadingFinished()

#self.fContainer.removeAllPlugins()
#self.host.remove_all_plugins()

# -----------------------------------------------------------------

# TODO clear this, move them into containers
@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
self.fContainer.addPlugin(pluginId, self.fIsProjectLoading)

# FIXME ask host directly for plugin count
if self.fContainer.getPluginCount() == 1:
self.ui.act_plugin_remove_all.setEnabled(True)

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
self.fContainer.removePlugin(pluginId)

# FIXME ask host directly for plugin count
if self.fContainer.getPluginCount() == 0:
self.ui.act_plugin_remove_all.setEnabled(False)

@pyqtSlot(int, str)
def slot_handlePluginRenamedCallback(self, pluginId, newName):
self.fContainer.renamePlugin(pluginId, newName)

@pyqtSlot(int, str)
def slot_handlePluginUnavailableCallback(self, pluginId, errorMsg):
self.fContainer.disablePlugin(pluginId, errorMsg)

# -----------------------------------------------------------------

@pyqtSlot(bool)
def slot_transportPlayPause(self, toggled):
if not self.host.is_engine_running():
return

if toggled:
self.host.transport_play()
else:
self.host.transport_pause()

self.refreshTransport()

@pyqtSlot()
def slot_transportStop(self):
if not self.host.is_engine_running():
return

self.host.transport_pause()
self.host.transport_relocate(0)

self.refreshTransport()

@pyqtSlot()
def slot_transportBackwards(self):
if not self.host.is_engine_running():
return

newFrame = self.host.get_current_transport_frame() - 100000

if newFrame < 0:
newFrame = 0

self.host.transport_relocate(newFrame)

@pyqtSlot()
def slot_transportForwards(self):
if not self.host.is_engine_running():
return

newFrame = self.host.get_current_transport_frame() + 100000
self.host.transport_relocate(newFrame)

# -----------------------------------------------------------------

@pyqtSlot() @pyqtSlot()
def slot_aboutCarla(self): def slot_aboutCarla(self):
CarlaAboutW(self, self.host).exec_() CarlaAboutW(self, self.host).exec_()
@@ -1008,16 +987,6 @@ class HostWindow(QMainWindow):
@pyqtSlot(int, int, int, float, str) @pyqtSlot(int, int, int, float, str)
def slot_handleDebugCallback(self, pluginId, value1, value2, value3, valueStr): def slot_handleDebugCallback(self, pluginId, value1, value2, value3, valueStr):
print("DEBUG:", pluginId, value1, value2, value3, valueStr) print("DEBUG:", pluginId, value1, value2, value3, valueStr)
#self.ui.pte_log.appendPlainText(valueStr.replace("", "DEBUG: ").replace("", "ERROR: ").replace("", "").replace("\n", ""))

# -----------------------------------------------------------------

@pyqtSlot(float)
def slot_handleSampleRateChangedCallback(self, newSampleRate):
self.fSampleRate = newSampleRate
self.refreshTransport(True)

# -----------------------------------------------------------------


@pyqtSlot(str) @pyqtSlot(str)
def slot_handleInfoCallback(self, info): def slot_handleInfoCallback(self, info):
@@ -1029,19 +998,7 @@ class HostWindow(QMainWindow):


@pyqtSlot() @pyqtSlot()
def slot_handleQuitCallback(self): def slot_handleQuitCallback(self):
pass

# -----------------------------------------------------------------

@pyqtSlot()
def slot_handleSIGUSR1(self):
print("Got SIGUSR1 -> Saving project now")
self.slot_fileSave()

@pyqtSlot()
def slot_handleSIGTERM(self):
print("Got SIGTERM -> Closing now")
self.close()
pass # TODO


# ----------------------------------------------------------------- # -----------------------------------------------------------------


@@ -1082,7 +1039,7 @@ class HostWindow(QMainWindow):
elif self.host.is_engine_running(): elif self.host.is_engine_running():
self.host.set_engine_about_to_close() self.host.set_engine_about_to_close()


count = self.fContainer.getPluginCount()
count = self.host.get_current_plugin_count()


if count > 0: if count > 0:
# simulate project loading, to disable container # simulate project loading, to disable container
@@ -1099,7 +1056,7 @@ class HostWindow(QMainWindow):
#self.fContainer.removeAllPlugins() #self.fContainer.removeAllPlugins()
#self.host.remove_all_plugins() #self.host.remove_all_plugins()


self.stopEngine()
self.slot_engineStop()


QMainWindow.closeEvent(self, event) QMainWindow.closeEvent(self, event)




+ 23
- 1
source/carla_patchbay.py View File

@@ -231,6 +231,10 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta):


parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)


host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
host.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback)
host.PluginUnavailableCallback.connect(self.slot_handlePluginUnavailableCallback)
host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback)
host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback)
host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback)
@@ -677,6 +681,24 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
self.addPlugin(pluginId, self.fParent.isProjectLoading())

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
self.removePlugin(pluginId)

@pyqtSlot(int, str)
def slot_handlePluginRenamedCallback(self, pluginId, newName):
self.renamePlugin(pluginId, newName)

@pyqtSlot(int, str)
def slot_handlePluginUnavailableCallback(self, pluginId, errorMsg):
self.disablePlugin(pluginId, errorMsg)

# -----------------------------------------------------------------

@pyqtSlot(int, int, float) @pyqtSlot(int, int, float)
def slot_handleParameterValueChangedCallback(self, pluginId, index, value): def slot_handleParameterValueChangedCallback(self, pluginId, index, value):
if pluginId >= self.fPluginCount: if pluginId >= self.fPluginCount:
@@ -911,7 +933,7 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta):
if pluginId < 0: if pluginId < 0:
return return
if pluginId >= self.fPluginCount: if pluginId >= self.fPluginCount:
print("sorry, can't map this plugin to canvas client", pluginId, self.getPluginCount())
print("sorry, can't map this plugin to canvas client", pluginId, self.fPluginCount)
return return


patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI)) patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI))


+ 24
- 5
source/carla_rack.py View File

@@ -84,6 +84,7 @@ class CarlaRackList(QListWidget):
if False: if False:
# kdevelop likes this :) # kdevelop likes this :)
host = CarlaHostMeta() host = CarlaHostMeta()
self.host = host


# ------------------------------------------------------------- # -------------------------------------------------------------


@@ -210,6 +211,7 @@ class CarlaRackW(QFrame):
if False: if False:
# kdevelop likes this :) # kdevelop likes this :)
host = CarlaHostMeta() host = CarlaHostMeta()
self.host = host


# ------------------------------------------------------------- # -------------------------------------------------------------


@@ -305,6 +307,10 @@ class CarlaRackW(QFrame):


parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)


host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
host.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback)
host.PluginUnavailableCallback.connect(self.slot_handlePluginUnavailableCallback)
host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback)
host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback)
host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback)
@@ -323,11 +329,6 @@ class CarlaRackW(QFrame):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


def getPluginCount(self):
return self.fPluginCount

# -----------------------------------------------------------------

def addPlugin(self, pluginId, isProjectLoading): def addPlugin(self, pluginId, isProjectLoading):
pitem = CarlaRackItem(self.fRack, pluginId) pitem = CarlaRackItem(self.fRack, pluginId)


@@ -542,6 +543,24 @@ class CarlaRackW(QFrame):


# ----------------------------------------------------------------- # -----------------------------------------------------------------


@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
self.addPlugin(pluginId, self.fParent.isProjectLoading())

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
self.removePlugin(pluginId)

@pyqtSlot(int, str)
def slot_handlePluginRenamedCallback(self, pluginId, newName):
self.renamePlugin(pluginId, newName)

@pyqtSlot(int, str)
def slot_handlePluginUnavailableCallback(self, pluginId, errorMsg):
self.disablePlugin(pluginId, errorMsg)

# -----------------------------------------------------------------

@pyqtSlot(int, int, float) @pyqtSlot(int, int, float)
def slot_handleParameterValueChangedCallback(self, pluginId, index, value): def slot_handleParameterValueChangedCallback(self, pluginId, index, value):
if pluginId >= self.fPluginCount: if pluginId >= self.fPluginCount:


Loading…
Cancel
Save