Browse Source

Introducing "Cancelable actions"

We can now timeout forever, as we let the user cancel when he wants to

Signed-off-by: falkTX <falktx@gmail.com>
tags/v2.1-alpha2
falkTX 6 years ago
parent
commit
e9dffc601e
Signed by: falkTX <falktx@gmail.com> GPG Key ID: 2D3445A829213837
14 changed files with 220 additions and 76 deletions
  1. +15
    -7
      source/backend/CarlaBackend.h
  2. +11
    -0
      source/backend/CarlaEngine.hpp
  3. +6
    -0
      source/backend/CarlaHost.h
  4. +6
    -0
      source/backend/CarlaStandalone.cpp
  5. +76
    -8
      source/backend/engine/CarlaEngine.cpp
  6. +1
    -0
      source/backend/engine/CarlaEngineInternal.cpp
  7. +2
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  8. +4
    -0
      source/backend/engine/CarlaEngineNative.cpp
  9. +14
    -23
      source/backend/plugin/CarlaPluginBridge.cpp
  10. +12
    -29
      source/backend/plugin/CarlaPluginJack.cpp
  11. +28
    -6
      source/frontend/carla_backend.py
  12. +1
    -0
      source/frontend/carla_backend_qt.py
  13. +42
    -3
      source/frontend/carla_host.py
  14. +2
    -0
      source/utils/CarlaBackendUtils.hpp

+ 15
- 7
source/backend/CarlaBackend.h View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -941,40 +941,48 @@ typedef enum {
*/
ENGINE_CALLBACK_SAMPLE_RATE_CHANGED = 34,

/*!
* A cancelable action has been started or stopped.
* @a pluginId Plugin Id the action relates to, -1 for none
* @a value1 1 for action started, 0 for stopped
* @a valueStr Action name
*/
ENGINE_CALLBACK_CANCELABLE_ACTION = 35,

/*!
* Project has finished loading.
*/
ENGINE_CALLBACK_PROJECT_LOAD_FINISHED = 35,
ENGINE_CALLBACK_PROJECT_LOAD_FINISHED = 36,

/*!
* NSM callback.
* (Work in progress, values are not defined yet)
*/
ENGINE_CALLBACK_NSM = 36,
ENGINE_CALLBACK_NSM = 37,

/*!
* Idle frontend.
* This is used by the engine during long operations that might block the frontend,
* giving it the possibility to idle while the operation is still in place.
*/
ENGINE_CALLBACK_IDLE = 37,
ENGINE_CALLBACK_IDLE = 38,

/*!
* Show a message as information.
* @a valueStr The message
*/
ENGINE_CALLBACK_INFO = 38,
ENGINE_CALLBACK_INFO = 39,

/*!
* Show a message as an error.
* @a valueStr The message
*/
ENGINE_CALLBACK_ERROR = 39,
ENGINE_CALLBACK_ERROR = 40,

/*!
* The engine has crashed or malfunctioned and will no longer work.
*/
ENGINE_CALLBACK_QUIT = 40
ENGINE_CALLBACK_QUIT = 41

} EngineCallbackOpcode;



+ 11
- 0
source/backend/CarlaEngine.hpp View File

@@ -1065,6 +1065,17 @@ public:
bool isLoadingProject() const noexcept;
#endif

/*!
* Tell the engine to stop the current cancelable action.
* @see ENGINE_CALLBACK_CANCELABLE_ACTION
*/
void setActionCanceled(const bool canceled) noexcept;

/*!
* Check wherever the last cancelable action was indeed canceled or not.
*/
bool wasActionCanceled() const noexcept;

// -------------------------------------------------------------------
// Options



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

@@ -353,6 +353,12 @@ CARLA_EXPORT void carla_engine_idle();
*/
CARLA_EXPORT bool carla_is_engine_running();

/*!
* Tell the engine to stop the current cancelable action.
* @see ENGINE_CALLBACK_CANCELABLE_ACTION
*/
CARLA_EXPORT void carla_cancel_engine_action();

/*!
* Tell the engine it's about to close.
* This is used to prevent the engine thread(s) from reactivating.


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

@@ -537,6 +537,12 @@ bool carla_is_engine_running()
return (gStandalone.engine != nullptr && gStandalone.engine->isRunning());
}

void carla_cancel_engine_action()
{
if (gStandalone.engine != nullptr)
gStandalone.engine->setActionCanceled(true);
}

bool carla_set_engine_about_to_close()
{
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, true);


+ 76
- 8
source/backend/engine/CarlaEngine.cpp View File

@@ -1390,6 +1390,16 @@ bool CarlaEngine::isLoadingProject() const noexcept
}
#endif

void CarlaEngine::setActionCanceled(const bool canceled) noexcept
{
pData->actionCanceled = canceled;
}

bool CarlaEngine::wasActionCanceled() const noexcept
{
return pData->actionCanceled;
}

// -----------------------------------------------------------------------
// Global options

@@ -2053,17 +2063,28 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
return false;
}

pData->actionCanceled = false;
callback(ENGINE_CALLBACK_CANCELABLE_ACTION, 0, 1, 0, 0.0f, "Loading project");

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
const ScopedValueSetter<bool> _svs(pData->loadingProject, true, false);
const ScopedValueSetter<bool> _svs2(pData->loadingProject, true, false);
#endif

// completely load file
xmlElement = xmlDoc.getDocumentElement(false);
CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to completely parse project file");

callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);

if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}

const bool isPlugin(getType() == kEngineTypePlugin);

// load engine settings first of all
@@ -2177,10 +2198,18 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)

setOption(static_cast<EngineOption>(option), value, valueStr);
}
}

if (pData->aboutToClose)
return true;
callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);

if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}
}

// now setup transport
if (XmlElement* const elem = (isPreset || isPlugin) ? nullptr : xmlElement->getChildByName("Transport"))
@@ -2193,12 +2222,20 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
// some sane limits
if (bpm >= 20.0 && bpm < 400.0)
pData->time.setBPM(bpm);

callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);

if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}
}
}

if (pData->aboutToClose)
return true;

// and we handle plugins
for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement())
{
@@ -2214,6 +2251,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}

CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr);

#ifndef BUILD_BRIDGE
@@ -2232,6 +2275,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}

String lsState;
lsState << "0.35\n";
lsState << "18 0 Chromatic\n";
@@ -2377,6 +2426,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}

// deactivate bridge client-side ping check, since some plugins block during load
if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && ! isPreset)
plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "__CarlaPingOnOff__", "false", false);
@@ -2411,6 +2466,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
if (isPreset)
{
callback(ENGINE_CALLBACK_PROJECT_LOAD_FINISHED, 0, 0, 0, 0.0f, nullptr);
callback(ENGINE_CALLBACK_CANCELABLE_ACTION, 0, 0, 0, 0.0f, "Loading project");
return true;
}
}
@@ -2430,6 +2486,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}

bool hasInternalConnections = false;

// and now we handle connections (internal)
@@ -2471,6 +2533,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)

if (pData->aboutToClose)
return true;

if (pData->actionCanceled)
{
setLastError("Project load canceled");
return false;
}
}
}

@@ -2541,10 +2609,10 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
break;
}
}

#endif

callback(ENGINE_CALLBACK_PROJECT_LOAD_FINISHED, 0, 0, 0, 0.0f, nullptr);
callback(ENGINE_CALLBACK_CANCELABLE_ACTION, 0, 0, 0, 0.0f, "Loading project");
return true;
}



+ 1
- 0
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -372,6 +372,7 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept
callbackPtr(nullptr),
fileCallback(nullptr),
fileCallbackPtr(nullptr),
actionCanceled(false),
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
loadingProject(false),
#endif


+ 2
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -219,6 +219,8 @@ struct CarlaEngine::ProtectedData {
FileCallbackFunc fileCallback;
void* fileCallbackPtr;

bool actionCanceled;

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
bool loadingProject;
#endif


+ 4
- 0
source/backend/engine/CarlaEngineNative.cpp View File

@@ -152,6 +152,10 @@ protected:
if (valueStr != nullptr)
delete[] valueStr;
}
else if (std::strcmp(msg, "cancel_engine_action") == 0)
{
fEngine->setActionCanceled(true);
}
else if (std::strcmp(msg, "load_file") == 0)
{
const char* filename;


+ 14
- 23
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -387,7 +387,6 @@ public:
fTimedError(false),
fBufferSize(engine->getBufferSize()),
fProcWaitTime(0),
fLastPongTime(-1),
fBridgeBinary(),
fBridgeThread(engine, this),
fShmAudioPool(),
@@ -1790,9 +1789,6 @@ public:
carla_debug("CarlaPluginBridge::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode));
}
#endif
if (opcode != kPluginBridgeNonRtServerNull && fLastPongTime > 0)
fLastPongTime = Time::currentTimeMillis();

switch (opcode)
{
case kPluginBridgeNonRtServerNull:
@@ -2436,8 +2432,6 @@ private:
uint fBufferSize;
uint fProcWaitTime;

int64_t fLastPongTime;

CarlaString fBridgeBinary;
CarlaPluginBridgeThread fBridgeThread;

@@ -2664,24 +2658,18 @@ private:

fBridgeThread.startThread();

fLastPongTime = Time::currentTimeMillis();
CARLA_SAFE_ASSERT(fLastPongTime > 0);

static bool sFirstInit = true;

int64_t timeoutEnd = 5000;
const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
const bool needsCancelableAction = ! pData->engine->isLoadingProject();

if (sFirstInit)
timeoutEnd *= 2;
#ifndef CARLA_OS_WIN
if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
timeoutEnd *= 2;
if (needsCancelableAction)
{
pData->engine->setActionCanceled(false);
pData->engine->callback(ENGINE_CALLBACK_CANCELABLE_ACTION, pData->id, 1, 0, 0.0f, "Loading JACK application");
}
#endif
sFirstInit = false;

const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;

for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();)
for (;fBridgeThread.isThreadRunning();)
{
pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);

@@ -2692,13 +2680,16 @@ private:

if (fInitiated)
break;
if (pData->engine->isAboutToClose())
if (pData->engine->isAboutToClose() || pData->engine->wasActionCanceled())
break;

carla_msleep(5);
}

fLastPongTime = -1;
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
if (needsCancelableAction)
pData->engine->callback(ENGINE_CALLBACK_CANCELABLE_ACTION, pData->id, 0, 0, 0.0f, "Loading JACK application");
#endif

if (fInitError || ! fInitiated)
{


+ 12
- 29
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -205,7 +205,6 @@ public:
fProcCanceled(false),
fBufferSize(engine->getBufferSize()),
fProcWaitTime(0),
fLastPingTime(-1),
fBridgeThread(engine, this),
fShmAudioPool(),
fShmRtClientControl(),
@@ -426,14 +425,6 @@ public:
try {
handleNonRtData();
} CARLA_SAFE_EXCEPTION("handleNonRtData");

if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000)
{
carla_stderr("Did not receive ping message from server for 30 secs, closing...");
// TODO
//threadShouldExit();
//callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
}
}
else if (fInitiated)
{
@@ -1132,9 +1123,6 @@ public:
carla_debug("CarlaPluginJack::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode));
}
//#endif
if (opcode != kPluginBridgeNonRtServerNull && fLastPingTime > 0)
fLastPingTime = Time::currentTimeMillis();

switch (opcode)
{
case kPluginBridgeNonRtServerNull:
@@ -1372,8 +1360,6 @@ private:
uint fBufferSize;
uint fProcWaitTime;

int64_t fLastPingTime;

CarlaPluginJackThread fBridgeThread;

BridgeAudioPool fShmAudioPool;
@@ -1486,20 +1472,16 @@ private:

fBridgeThread.startThread();

fLastPingTime = Time::currentTimeMillis();
CARLA_SAFE_ASSERT(fLastPingTime > 0);

static bool sFirstInit = true;

int64_t timeoutEnd = 5000;

if (sFirstInit)
timeoutEnd *= 2;
sFirstInit = false;

const bool needsCancelableAction = ! pData->engine->isLoadingProject();
const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;

for (; Time::currentTimeMillis() < fLastPingTime + timeoutEnd && fBridgeThread.isThreadRunning();)
if (needsCancelableAction)
{
pData->engine->setActionCanceled(false);
pData->engine->callback(ENGINE_CALLBACK_CANCELABLE_ACTION, pData->id, 1, 0, 0.0f, "Loading JACK application");
}

for (;fBridgeThread.isThreadRunning();)
{
pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);

@@ -1510,13 +1492,14 @@ private:

if (fInitiated)
break;
if (pData->engine->isAboutToClose())
if (pData->engine->isAboutToClose() || pData->engine->wasActionCanceled())
break;

carla_msleep(20);
carla_msleep(5);
}

fLastPingTime = -1;
if (needsCancelableAction)
pData->engine->callback(ENGINE_CALLBACK_CANCELABLE_ACTION, pData->id, 0, 0, 0.0f, "Loading JACK application");

if (fInitError || ! fInitiated)
{


+ 28
- 6
source/frontend/carla_backend.py View File

@@ -691,28 +691,34 @@ ENGINE_CALLBACK_BUFFER_SIZE_CHANGED = 33
# @a value3 New sample rate
ENGINE_CALLBACK_SAMPLE_RATE_CHANGED = 34

# A cancelable action has been started or stopped.
# @a pluginId Plugin Id the action relates to, -1 for none
# @a value1 1 for action started, 0 for stopped
# @a valueStr Action name
ENGINE_CALLBACK_CANCELABLE_ACTION = 35

# Project has finished loading.
ENGINE_CALLBACK_PROJECT_LOAD_FINISHED = 35
ENGINE_CALLBACK_PROJECT_LOAD_FINISHED = 36

# NSM callback.
# (Work in progress, values are not defined yet)
ENGINE_CALLBACK_NSM = 36
ENGINE_CALLBACK_NSM = 37

# Idle frontend.
# This is used by the engine during long operations that might block the frontend,
# giving it the possibility to idle while the operation is still in place.
ENGINE_CALLBACK_IDLE = 37
ENGINE_CALLBACK_IDLE = 38

# Show a message as information.
# @a valueStr The message
ENGINE_CALLBACK_INFO = 38
ENGINE_CALLBACK_INFO = 39

# Show a message as an error.
# @a valueStr The message
ENGINE_CALLBACK_ERROR = 39
ENGINE_CALLBACK_ERROR = 40

# The engine has crashed or malfunctioned and will no longer work.
ENGINE_CALLBACK_QUIT = 40
ENGINE_CALLBACK_QUIT = 41

# ------------------------------------------------------------------------------------------------------------
# Engine Option
@@ -1330,6 +1336,10 @@ class CarlaHostMeta(object):
def is_engine_running(self):
raise NotImplementedError

@abstractmethod
def cancel_engine_action(self):
raise NotImplementedError

# Tell the engine it's about to close.
# This is used to prevent the engine thread(s) from reactivating.
@abstractmethod
@@ -1934,6 +1944,9 @@ class CarlaHostNull(CarlaHostMeta):
def is_engine_running(self):
return self.fEngineRunning

def cancel_engine_action(self):
return

def set_engine_about_to_close(self):
return True

@@ -2219,6 +2232,9 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_is_engine_running.argtypes = None
self.lib.carla_is_engine_running.restype = c_bool

self.lib.carla_cancel_engine_action.argtypes = None
self.lib.carla_cancel_engine_action.restype = None

self.lib.carla_set_engine_about_to_close.argtypes = None
self.lib.carla_set_engine_about_to_close.restype = c_bool

@@ -2494,6 +2510,9 @@ class CarlaHostDLL(CarlaHostMeta):
def is_engine_running(self):
return bool(self.lib.carla_is_engine_running())

def cancel_engine_action(self):
return self.lib.carla_cancel_engine_action()

def set_engine_about_to_close(self):
return bool(self.lib.carla_set_engine_about_to_close())

@@ -2839,6 +2858,9 @@ class CarlaHostPlugin(CarlaHostMeta):
def get_engine_driver_device_info(self, index, name):
return PyEngineDriverDeviceInfo

def cancel_engine_action(self):
self.sendMsg(["cancel_engine_action"])

def set_engine_callback(self, func):
return # TODO



+ 1
- 0
source/frontend/carla_backend_qt.py View File

@@ -66,6 +66,7 @@ class CarlaHostSignals(QObject):
TransportModeChangedCallback = pyqtSignal(int, str)
BufferSizeChangedCallback = pyqtSignal(int)
SampleRateChangedCallback = pyqtSignal(float)
CancelableActionCallback = pyqtSignal(int, bool, str)
ProjectLoadFinishedCallback = pyqtSignal()
NSMCallback = pyqtSignal(int, int, str)
InfoCallback = pyqtSignal(str)


+ 42
- 3
source/frontend/carla_host.py View File

@@ -148,6 +148,9 @@ class HostWindow(QMainWindow):
if MACOS:
self.fMacClosingHelper = True

# CancelableActionCallback Box
self.fCancelableActionBox = None

# run a custom action after engine is properly closed
self.fCustomStopAction = self.CUSTOM_ACTION_NONE

@@ -492,6 +495,7 @@ class HostWindow(QMainWindow):
host.EngineStoppedCallback.connect(self.slot_handleEngineStoppedCallback)
host.TransportModeChangedCallback.connect(self.slot_handleTransportModeChangedCallback)
host.SampleRateChangedCallback.connect(self.slot_handleSampleRateChangedCallback)
host.CancelableActionCallback.connect(self.slot_handleCancelableActionCallback)
host.ProjectLoadFinishedCallback.connect(self.slot_handleProjectLoadFinishedCallback)

host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
@@ -659,9 +663,14 @@ class HostWindow(QMainWindow):

self.projectLoadingStarted()
self.fIsProjectLoading = True
self.host.load_project(self.fProjectFilename)

# Project finished loading is sent by engine
if not self.host.load_project(self.fProjectFilename):
self.fIsProjectLoading = False
self.projectLoadingFinished()

CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load project"),
self.host.get_last_error(),
QMessageBox.Ok, QMessageBox.Ok)

def loadProjectLater(self, filename):
self.fProjectFilename = QFileInfo(filename).absoluteFilePath()
@@ -672,7 +681,11 @@ class HostWindow(QMainWindow):
if not self.fProjectFilename:
return qCritical("ERROR: saving project without filename set")

self.host.save_project(self.fProjectFilename)
if not self.host.save_project(self.fProjectFilename):
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to save project"),
self.host.get_last_error(),
QMessageBox.Ok, QMessageBox.Ok)
return

if not self.fWithCanvas:
return
@@ -943,6 +956,29 @@ class HostWindow(QMainWindow):
self.fSampleRate = newSampleRate
self.refreshTransport(True)

@pyqtSlot(int, bool, str)
def slot_handleCancelableActionCallback(self, pluginId, started, action):
if self.fCancelableActionBox is not None:
self.fCancelableActionBox.close()

if started:
self.fCancelableActionBox = QMessageBox(self)
self.fCancelableActionBox.setIcon(QMessageBox.Critical)
self.fCancelableActionBox.setWindowTitle(self.tr("Action in progress"))
self.fCancelableActionBox.setText(action)
self.fCancelableActionBox.setInformativeText(self.tr("An action is in progress, please wait..."))
self.fCancelableActionBox.setStandardButtons(QMessageBox.Cancel)
self.fCancelableActionBox.setDefaultButton(QMessageBox.Cancel)
self.fCancelableActionBox.buttonClicked.connect(self.slot_canlableActionBoxClicked)
self.fCancelableActionBox.show()

else:
self.fCancelableActionBox = None

@pyqtSlot()
def slot_canlableActionBoxClicked(self):
self.host.cancel_engine_action()

@pyqtSlot()
def slot_handleProjectLoadFinishedCallback(self):
self.fIsProjectLoading = False
@@ -2577,7 +2613,10 @@ def engineCallback(host, action, pluginId, value1, value2, value3, valueStr):
host.BufferSizeChangedCallback.emit(value1)
elif action == ENGINE_CALLBACK_SAMPLE_RATE_CHANGED:
host.SampleRateChangedCallback.emit(value3)
elif action == ENGINE_CALLBACK_CANCELABLE_ACTION:
host.CancelableActionCallback.emit(pluginId, bool(value1 != 0), valueStr)
elif action == ENGINE_CALLBACK_PROJECT_LOAD_FINISHED:
print("ProjectLoadFinishedCallback")
host.ProjectLoadFinishedCallback.emit()
elif action == ENGINE_CALLBACK_NSM:
host.NSMCallback.emit(value1, value2, valueStr)


+ 2
- 0
source/utils/CarlaBackendUtils.hpp View File

@@ -270,6 +270,8 @@ const char* EngineCallbackOpcode2Str(const EngineCallbackOpcode opcode) noexcept
return "ENGINE_CALLBACK_BUFFER_SIZE_CHANGED";
case ENGINE_CALLBACK_SAMPLE_RATE_CHANGED:
return "ENGINE_CALLBACK_SAMPLE_RATE_CHANGED";
case ENGINE_CALLBACK_CANCELABLE_ACTION:
return "ENGINE_CALLBACK_CANCELABLE_ACTION";
case ENGINE_CALLBACK_PROJECT_LOAD_FINISHED:
return "ENGINE_CALLBACK_PROJECT_LOAD_FINISHED";
case ENGINE_CALLBACK_NSM:


Loading…
Cancel
Save