Browse Source

More work for carla-plugin; misc fixing

tags/1.9.4
falkTX 11 years ago
parent
commit
20682eb040
8 changed files with 405 additions and 295 deletions
  1. +136
    -145
      source/backend/engine/CarlaEngineNative.cpp
  2. +2
    -1
      source/backend/plugin/CarlaPluginThread.cpp
  3. +241
    -131
      source/carla-plugin
  4. +10
    -7
      source/carla_host.py
  5. +5
    -2
      source/carla_shared.py
  6. +5
    -5
      source/carla_widgets.py
  7. +5
    -1
      source/externalui.py
  8. +1
    -3
      source/plugin/carla-native-base.cpp

+ 136
- 145
source/backend/engine/CarlaEngineNative.cpp View File

@@ -20,18 +20,18 @@
#endif

#include "CarlaEngineInternal.hpp"
#include "CarlaPipeUtils.hpp"
#include "CarlaStateUtils.hpp"

#include "CarlaNative.hpp"

#include <QtCore/QProcess>
#include <QtCore/QTextStream>

CARLA_BACKEND_START_NAMESPACE

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

class CarlaEngineNativeThread : public CarlaThread
class CarlaEngineNativeUI : public CarlaPipeServer
{
public:
enum UiState {
@@ -41,107 +41,110 @@ public:
UiCrashed
};

CarlaEngineNativeThread(CarlaEngine* const engine)
CarlaEngineNativeUI(CarlaEngine* const engine)
: fEngine(engine),
fProcess(nullptr)/*,*/
//fUiState(UiNone)
fUiState(UiNone)
{
carla_debug("CarlaEngineNativeThread::CarlaEngineNativeThread(%p)", engine);
carla_debug("CarlaEngineNativeUI::CarlaEngineNativeUI(%p)", engine);
}

~CarlaEngineNativeThread() override
~CarlaEngineNativeUI() override
{
//CARLA_ASSERT_INT(fUiState == UiNone, fUiState);
carla_debug("CarlaEngineNativeThread::~CarlaEngineNativeThread()");

if (fProcess != nullptr)
{
delete fProcess;
fProcess = nullptr;
}
CARLA_ASSERT_INT(fUiState == UiNone, fUiState);
carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()");
}

#if 0
void setOscData(const char* const binary)
void setData(const char* const filename, const double sampleRate, const char* const uiTitle)
{
fBinary = binary;
fFilename = filename;
fSampleRate = CarlaString(sampleRate);
fUiTitle = uiTitle;
}

UiState getUiState()
UiState getAndResetUiState() noexcept
{
const UiState state(fUiState);
const UiState uiState(fUiState);
fUiState = UiNone;

return state;
return uiState;
}

void stop()
void start()
{
if (fProcess == nullptr)
return;

fUiState = UiNone;
fProcess->kill();
//fProcess->close();
CarlaPipeServer::start(fFilename, fSampleRate, fUiTitle);
writeMsg("show\n", 5);
}
#endif

protected:
void run() override
{
carla_debug("CarlaEngineNativeThread::run() - binary:\"%s\"", (const char*)fBinary);

#if 0
if (fProcess == nullptr)
void msgReceived(const char* const msg) override
{
/*
* TODO:
* load_file load_project save_project patchbay_connect patchbay_disconnect patchbay_refresh
* transport_play transport_pause transport_relocate
* *add_plugin* remove_plugin remove_all_plugins rename_plugin clone_plugin replace_plugin switch_plugins
* load_plugin_state save_plugin_state
* set_option *set_active* set_drywet set_volume set_balance_left set_balance_right set_panning set_ctrl_channel
* set_parameter_value set_parameter_midi_channel set_parameter_midi_cc set_program set_midi_program set_custom_data set_chunk_data
* prepare_for_save send_midi_note show_custom_ui
*/

if (std::strcmp(msg, "exiting") == 0)
{
fProcess = new QProcess(nullptr);
fProcess->setProcessChannelMode(QProcess::ForwardedChannels);
waitChildClose();
fUiState = UiHide;
}
else if (fProcess->state() == QProcess::Running)
else if (std::strcmp(msg, "set_engine_option") == 0)
{
carla_stderr("CarlaEngineNativeThread::run() - already running, giving up...");

fUiState = UiCrashed;
fProcess->terminate();
//kEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, kPlugin->id(), -1, 0, 0.0f, nullptr);
// TODO: tell master to hide UI
return;
}
int option, value;
const char* valueStr;

QStringList arguments;
arguments << kEngine->getOscServerPathTCP();
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(option),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(value),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(valueStr),);

fProcess->start((const char*)fBinary, arguments);
fProcess->waitForStarted();

fUiState = UiShow;
fEngine->setOption((EngineOption)option, value, valueStr);
}
else if (std::strcmp(msg, "add_plugin") == 0)
{
int btype, ptype;
const char* filename;
const char* name;
const char* label;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(btype),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(ptype),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(name),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(label),);

fEngine->addPlugin((BinaryType)btype, (PluginType)ptype, filename, name, label);
}
else if (std::strcmp(msg, "set_active") == 0)
{
int pluginId;
bool onOff;

fProcess->waitForFinished(-1);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(onOff),);

if (fProcess->exitCode() == 0)
{
// Hide
fUiState = UiHide;
carla_stdout("CarlaEngineNativeThread::run() - GUI closed");
if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setActive(onOff, true, false);
}
else
{
// Kill
fUiState = UiCrashed;
carla_stderr("CarlaEngineNativeThread::run() - GUI crashed while running");
carla_stderr("msgReceived : %s", msg);
}
#endif
}

private:
CarlaEngine* const fEngine;

CarlaString fBinary;
QProcess* fProcess;
CarlaString fFilename;
CarlaString fSampleRate;
CarlaString fUiTitle;
UiState fUiState;

// UiState fUiState;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeThread)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeUI)
};

// -----------------------------------------------------------------------
@@ -155,7 +158,7 @@ public:
fIsPatchbay(isPatchbay),
fIsActive(false),
fIsRunning(false),
fThread(this)
fUiServer(this)
{
carla_debug("CarlaEngineNative::CarlaEngineNative()");

@@ -179,25 +182,7 @@ public:
init("Carla-Rack");
}

// TESTING
//if (! addPlugin(PLUGIN_INTERNAL, nullptr, "Ping Pong Pan", "PingPongPan"))
// carla_stdout("TESTING PLUG3 ERROR:\n%s", getLastError());

#if 0
// set control thread binary
CarlaString threadBinary(getResourceDir());
threadBinary += "/../";
threadBinary += "carla_control.py";

fThread.setOscData(threadBinary);

// if (! addPlugin(PLUGIN_INTERNAL, nullptr, "MIDI Transpose", "midiTranspose"))
// carla_stdout("TESTING PLUG1 ERROR:\n%s", getLastError());
// if (! addPlugin(PLUGIN_INTERNAL, nullptr, "ZynAddSubFX", "zynaddsubfx"))
// carla_stdout("TESTING PLUG2 ERROR:\n%s", getLastError());
// if (! addPlugin(PLUGIN_INTERNAL, nullptr, "Ping Pong Pan", "PingPongPan"))
// carla_stdout("TESTING PLUG3 ERROR:\n%s", getLastError());
#endif
setCallback(_ui_server_callback, this);
}

~CarlaEngineNative() override
@@ -263,6 +248,32 @@ protected:
CarlaEngine::sampleRateChanged(newSampleRate);
}

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

void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr)
{
if (! fIsRunning)
return;

char strBuf[STR_MAX+1];
std::sprintf(strBuf, "ENGINE_CALLBACK_%i\n", int(action));
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "%u\n", pluginId);
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "%i\n", value1);
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "%i\n", value2);
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "%f\n", value3);
fUiServer.writeMsg(strBuf);

fUiServer.writeAndFixMsg(valueStr);
}

// -------------------------------------------------------------------
// Plugin parameter calls

@@ -590,79 +601,40 @@ protected:
runPendingRtEvents();
}

#if 0
// -------------------------------------------------------------------
// Plugin UI calls

void uiShow(const bool show) override
void uiShow(const bool show)
{
if (show)
{
fThread.start();
fUiServer.setData("/home/falktx/FOSS/GIT-mine/Carla/source/carla-plugin", pData->sampleRate, pHost->uiName);
fUiServer.start();
}
else
{
#if 0
for (uint32_t i=0; i < pData->curPluginCount; ++i)
{
CarlaPlugin* const plugin(pData->plugins[i].plugin);

if (plugin == nullptr || ! plugin->enabled())
continue;

plugin->showGui(false);
}
#endif

fThread.stop();
fUiServer.stop();
}
}

void uiIdle() override
void uiIdle()
{
CarlaEngine::idle();
fUiServer.idle();

switch(fThread.getUiState())
switch (fUiServer.getAndResetUiState())
{
case CarlaEngineNativeThread::UiNone:
case CarlaEngineNativeThread::UiShow:
case CarlaEngineNativeUI::UiNone:
case CarlaEngineNativeUI::UiShow:
break;
case CarlaEngineNativeThread::UiCrashed:
hostUiUnavailable();
case CarlaEngineNativeUI::UiCrashed:
pHost->dispatcher(pHost->handle, HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
break;
case CarlaEngineNativeThread::UiHide:
uiClosed();
case CarlaEngineNativeUI::UiHide:
pHost->ui_closed(pHost->handle);
break;
}
}
#endif

#if 0
void uiSetParameterValue(const uint32_t index, const float value) override
{
if (index >= getParameterCount())
return;

CarlaPlugin* const plugin(pData->plugins[0].plugin);

if (plugin == nullptr || ! plugin->isEnabled())
return;

plugin->uiParameterChange(index, value);
}

void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override
{
return;

// TODO

// unused
(void)channel;
(void)bank;
(void)program;
}
#endif

// -------------------------------------------------------------------
// Plugin state calls
@@ -823,6 +795,16 @@ public:
handlePtr->setMidiProgram(channel, bank, program);
}

static void _ui_show(NativePluginHandle handle, bool show)
{
handlePtr->uiShow(show);
}

static void _ui_idle(NativePluginHandle handle)
{
handlePtr->uiIdle();
}

static void _activate(NativePluginHandle handle)
{
handlePtr->activate();
@@ -876,6 +858,15 @@ public:
(void)ptr;
}

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

static void _ui_server_callback(void* handle, EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr)
{
handlePtr->uiServerCallback(action, pluginId, value1, value2, value3, valueStr);
}

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

#undef handlePtr

private:
@@ -883,7 +874,7 @@ private:

const bool fIsPatchbay; // rack if false
bool fIsActive, fIsRunning;
CarlaEngineNativeThread fThread;
CarlaEngineNativeUI fUiServer;

CarlaPlugin* _getFirstPlugin() const noexcept
{
@@ -928,8 +919,8 @@ static const NativePluginDescriptor carlaRackDesc = {
CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
CarlaEngineNative::_ui_show,
CarlaEngineNative::_ui_idle,
/* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ nullptr,
@@ -967,8 +958,8 @@ static const NativePluginDescriptor carlaPatchbayDesc = {
CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
CarlaEngineNative::_ui_show,
CarlaEngineNative::_ui_idle,
/* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ nullptr,


+ 2
- 1
source/backend/plugin/CarlaPluginThread.cpp View File

@@ -115,11 +115,12 @@ void CarlaPluginThread::run()
}

QString name(fPlugin->getName());
QStringList arguments;

if (name.isEmpty())
name = "(none)";

QStringList arguments;

switch (fMode)
{
case PLUGIN_THREAD_NULL:


+ 241
- 131
source/carla-plugin View File

@@ -16,6 +16,11 @@
#
# For a full copy of the GNU General Public License see the GPL.txt file

# ------------------------------------------------------------------------------------------------------------
# Imports (Global)

from time import sleep

# ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff)

@@ -26,23 +31,46 @@ from externalui import ExternalUI
# Host Plugin object

class PluginHost(object):
def __init__(self):
def __init__(self, sampleRate):
object.__init__(self)

self.fParent = None

self.fSupportedFileExts = ""
self.fBufferSize = 0
self.fSampleRate = 0.0
self.fSampleRate = sampleRate
self.fLastError = ""
self.fSupportedFileTypes = ""
self.fIsRunning = True

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

def get_complete_license_text(self):
return ""

def get_supported_file_extensions(self):
return self.fSupportedFileExts

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

def get_engine_driver_count(self):
return 0
return 1

def get_supported_file_types(self):
return self.fSupportedFileTypes
def get_engine_driver_name(self, index):
return "Plugin"

def get_engine_driver_device_names(self, index):
return []

def get_engine_driver_device_info(self, index, name):
return PyEngineDriverDeviceInfo

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

def get_internal_plugin_count(self):
return int(self.lib.carla_get_internal_plugin_count())

def get_internal_plugin_info(self, index):
return None

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

def engine_init(self, driverName, clientName):
return True
@@ -50,8 +78,15 @@ class PluginHost(object):
def engine_close(self):
return True

def engine_idle(self):
if Carla.gui.idleExternalUI():
return

self.fIsRunning = False
Carla.gui.d_uiQuit()

def is_engine_running(self):
return True
return self.fIsRunning

def set_engine_about_to_close(self):
pass
@@ -59,197 +94,243 @@ class PluginHost(object):
def set_engine_callback(self, func):
pass

def load_filename(self, filename):
self.fParent.send(["load_filename", filename])
def set_engine_option(self, option, value, valueStr):
Carla.gui.send(["set_engine_option", option, value, valueStr])

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

def set_file_callback(self, func):
pass

def load_file(self, filename):
Carla.gui.send(["load_file", filename])
return True

def load_project(self, filename):
self.fParent.send(["load_project", filename])
Carla.gui.send(["load_project", filename])
return True

def save_project(self, filename):
self.fParent.send(["save_project", filename])
Carla.gui.send(["save_project", filename])
return True

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

def patchbay_connect(self, portIdA, portIdB):
self.fParent.send(["patchbay_connect", portIdA, portIdB])
Carla.gui.send(["patchbay_connect", portIdA, portIdB])
return True

def patchbay_disconnect(self, connectionId):
self.fParent.send(["patchbay_disconnect", connectionId])
Carla.gui.send(["patchbay_disconnect", connectionId])
return True

def patchbay_refresh(self):
self.fParent.send(["patchbay_refresh"])
Carla.gui.send(["patchbay_refresh"])
return True

def add_plugin(self, btype, ptype, filename, name, label, extraStuff):
self.fParent.send(["add_plugin", btype, ptype, filename, name, label])
# -------------------------------------------------------------------

def transport_play(self):
Carla.gui.send(["transport_play"])

def transport_pause(self):
Carla.gui.send(["transport_pause"])

def transport_relocate(self, frame):
Carla.gui.send(["transport_relocate"])

def get_current_transport_frame(self):
return 0

def get_transport_info(self):
return PyCarlaTransportInfo

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

def add_plugin(self, btype, ptype, filename, name, label, extraPtr):
Carla.gui.send(["add_plugin", btype, ptype, filename, name, label])
return True

def remove_plugin(self, pluginId):
self.fParent.send(["remove_plugin", pluginId])
Carla.gui.send(["remove_plugin", pluginId])
return True

def remove_all_plugins(self):
self.fParent.send(["remove_all_plugins"])
Carla.gui.send(["remove_all_plugins"])
return True

def rename_plugin(self, pluginId, newName):
self.fParent.send(["rename_plugin", pluginId, newName])
return True
Carla.gui.send(["rename_plugin", pluginId, newName])
return newName

def clone_plugin(self, pluginId):
self.fParent.send(["clone_plugin", pluginId])
Carla.gui.send(["clone_plugin", pluginId])
return True

def replace_plugin(self, pluginId):
self.fParent.send(["replace_plugin", pluginId])
Carla.gui.send(["replace_plugin", pluginId])
return True

def switch_plugins(self, pluginIdA, pluginIdB):
self.fParent.send(["switch_plugins", pluginIdA, pluginIdB])
Carla.gui.send(["switch_plugins", pluginIdA, pluginIdB])
return True

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

def load_plugin_state(self, pluginId, filename):
self.fParent.send(["load_plugin_state", pluginId, filename])
Carla.gui.send(["load_plugin_state", pluginId, filename])
return True

def save_plugin_state(self, pluginId, filename):
self.fParent.send(["save_plugin_state", pluginId, filename])
Carla.gui.send(["save_plugin_state", pluginId, filename])
return True

#def get_plugin_info(self, pluginId):
#return structToDict(self.lib.carla_get_plugin_info(pluginId).contents)
# -------------------------------------------------------------------

def get_plugin_info(self, pluginId):
return PyCarlaPluginInfo

#def get_audio_port_count_info(self, pluginId):
#return structToDict(self.lib.carla_get_audio_port_count_info(pluginId).contents)
def get_audio_port_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_midi_port_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_parameter_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_parameter_info(self, pluginId, parameterId):
return PyCarlaParameterInfo

def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
return PyCarlaScalePointInfo

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

#def get_midi_port_count_info(self, pluginId):
#return structToDict(self.lib.carla_get_midi_port_count_info(pluginId).contents)
def get_parameter_data(self, pluginId, parameterId):
return PyParameterData

#def get_parameter_count_info(self, pluginId):
#return structToDict(self.lib.carla_get_parameter_count_info(pluginId).contents)
def get_parameter_ranges(self, pluginId, parameterId):
return PyParameterRanges

#def get_parameter_info(self, pluginId, parameterId):
#return structToDict(self.lib.carla_get_parameter_info(pluginId, parameterId).contents)
def get_midi_program_data(self, pluginId, midiProgramId):
return PyMidiProgramData

#def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
#return structToDict(self.lib.carla_get_parameter_scalepoint_info(pluginId, parameterId, scalePointId).contents)
def get_custom_data(self, pluginId, customDataId):
return PyCustomData

#def get_parameter_data(self, pluginId, parameterId):
#return structToDict(self.lib.carla_get_parameter_data(pluginId, parameterId).contents)
def get_chunk_data(self, pluginId):
return ""

#def get_parameter_ranges(self, pluginId, parameterId):
#return structToDict(self.lib.carla_get_parameter_ranges(pluginId, parameterId).contents)
# -------------------------------------------------------------------

#def get_midi_program_data(self, pluginId, midiProgramId):
#return structToDict(self.lib.carla_get_midi_program_data(pluginId, midiProgramId).contents)
def get_parameter_count(self, pluginId):
return 0

#def get_custom_data(self, pluginId, customDataId):
#return structToDict(self.lib.carla_get_custom_data(pluginId, customDataId).contents)
def get_program_count(self, pluginId):
return 0

#def get_chunk_data(self, pluginId):
#return self.lib.carla_get_chunk_data(pluginId)
def get_midi_program_count(self, pluginId):
return 0

#def get_parameter_count(self, pluginId):
#return self.lib.carla_get_parameter_count(pluginId)
def get_custom_data_count(self, pluginId):
return 0

#def get_program_count(self, pluginId):
#return self.lib.carla_get_program_count(pluginId)
# -------------------------------------------------------------------

#def get_midi_program_count(self, pluginId):
#return self.lib.carla_get_midi_program_count(pluginId)
def get_parameter_text(self, pluginId, parameterId, value):
return ""

#def get_custom_data_count(self, pluginId):
#return self.lib.carla_get_custom_data_count(pluginId)
def get_program_name(self, pluginId, programId):
return ""

#def get_parameter_text(self, pluginId, parameterId):
#return self.lib.carla_get_parameter_text(pluginId, parameterId)
def get_midi_program_name(self, pluginId, midiProgramId):
return ""

#def get_program_name(self, pluginId, programId):
#return self.lib.carla_get_program_name(pluginId, programId)
def get_real_plugin_name(self, pluginId):
return ""

#def get_midi_program_name(self, pluginId, midiProgramId):
#return self.lib.carla_get_midi_program_name(pluginId, midiProgramId)
# -------------------------------------------------------------------

#def get_real_plugin_name(self, pluginId):
#return self.lib.carla_get_real_plugin_name(pluginId)
def get_current_program_index(self, pluginId):
return 0

#def get_current_program_index(self, pluginId):
#return self.lib.carla_get_current_program_index(pluginId)
def get_current_midi_program_index(self, pluginId):
return 0

#def get_current_midi_program_index(self, pluginId):
#return self.lib.carla_get_current_midi_program_index(pluginId)
def get_default_parameter_value(self, pluginId, parameterId):
return 0.0

#def get_default_parameter_value(self, pluginId, parameterId):
#return self.lib.carla_get_default_parameter_value(pluginId, parameterId)
def get_current_parameter_value(self, pluginId, parameterId):
return 0.0

#def get_current_parameter_value(self, pluginId, parameterId):
#return self.lib.carla_get_current_parameter_value(pluginId, parameterId)
def get_input_peak_value(self, pluginId, isLeft):
return 0.0

#def get_input_peak_value(self, pluginId, portId):
#return self.lib.carla_get_input_peak_value(pluginId, portId)
def get_output_peak_value(self, pluginId, isLeft):
return 0.0

#def get_output_peak_value(self, pluginId, portId):
#return self.lib.carla_get_output_peak_value(pluginId, portId)
# -------------------------------------------------------------------

def set_option(self, pluginId, option, yesNo):
self.fParent.send(["set_option", pluginId, option, yesNo])
Carla.gui.send(["set_option", pluginId, option, yesNo])

def set_active(self, pluginId, onOff):
self.fParent.send(["set_active", pluginId, onOff])
Carla.gui.send(["set_active", pluginId, onOff])

def set_drywet(self, pluginId, value):
self.fParent.send(["set_drywet", pluginId, value])
Carla.gui.send(["set_drywet", pluginId, value])

def set_volume(self, pluginId, value):
self.fParent.send(["set_volume", pluginId, value])
Carla.gui.send(["set_volume", pluginId, value])

def set_balance_left(self, pluginId, value):
self.fParent.send(["set_balance_left", pluginId, value])
Carla.gui.send(["set_balance_left", pluginId, value])

def set_balance_right(self, pluginId, value):
self.fParent.send(["set_balance_right", pluginId, value])
Carla.gui.send(["set_balance_right", pluginId, value])

def set_panning(self, pluginId, value):
self.fParent.send(["set_panning", pluginId, value])
Carla.gui.send(["set_panning", pluginId, value])

def set_ctrl_channel(self, pluginId, channel):
self.fParent.send(["set_ctrl_channel", pluginId, channel])
Carla.gui.send(["set_ctrl_channel", pluginId, channel])

def set_parameter_value(self, pluginId, parameterId, value):
self.fParent.send(["set_parameter_value", pluginId, parameterId, value])
# -------------------------------------------------------------------

def set_parameter_midi_cc(self, pluginId, parameterId, cc):
self.fParent.send(["set_parameter_midi_cc", pluginId, parameterId, cc])
def set_parameter_value(self, pluginId, parameterId, value):
Carla.gui.send(["set_parameter_value", pluginId, parameterId, value])

def set_parameter_midi_channel(self, pluginId, parameterId, channel):
self.fParent.send(["set_parameter_midi_channel", pluginId, parameterId, channel])
Carla.gui.send(["set_parameter_midi_channel", pluginId, parameterId, channel])

def set_parameter_midi_cc(self, pluginId, parameterId, cc):
Carla.gui.send(["set_parameter_midi_cc", pluginId, parameterId, cc])

def set_program(self, pluginId, programId):
self.fParent.send(["set_program", pluginId, programId])
Carla.gui.send(["set_program", pluginId, programId])

def set_midi_program(self, pluginId, midiProgramId):
self.fParent.send(["set_midi_program", pluginId, midiProgramId])
Carla.gui.send(["set_midi_program", pluginId, midiProgramId])

def set_custom_data(self, pluginId, type_, key, value):
self.fParent.send(["set_custom_data", pluginId, type_, key, value])
Carla.gui.send(["set_custom_data", pluginId, type_, key, value])

def set_chunk_data(self, pluginId, chunkData):
self.fParent.send(["set_chunk_data", pluginId, chunkData])
Carla.gui.send(["set_chunk_data", pluginId, chunkData])

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

def prepare_for_save(self, pluginId):
self.fParent.send(["prepare_for_save", pluginId])
Carla.gui.send(["prepare_for_save", pluginId])

def send_midi_note(self, pluginId, channel, note, velocity):
self.fParent.send(["send_midi_note", pluginId, channel, note, velocity])
Carla.gui.send(["send_midi_note", pluginId, channel, note, velocity])

def show_gui(self, pluginId, yesNo):
self.fParent.send(["show_gui", pluginId, yesNo])
def show_custom_ui(self, pluginId, yesNo):
Carla.gui.send(["show_custom_ui", pluginId, yesNo])

def get_last_error(self):
return self.fLastError
# -------------------------------------------------------------------

def get_buffer_size(self):
return self.fBufferSize
@@ -257,11 +338,14 @@ class PluginHost(object):
def get_sample_rate(self):
return self.fSampleRate

# ------------------------------------------------------------------------------------------------------------
# Init plugin
def get_last_error(self):
return self.fLastError

def get_host_osc_url_tcp(self):
return ""

def initPlugin():
Carla.host = PluginHost()
def get_host_osc_url_udp(self):
return ""

# ------------------------------------------------------------------------------------------------------------
# Main Window
@@ -271,10 +355,6 @@ class CarlaMiniW(HostWindow, ExternalUI):
HostWindow.__init__(self, None)
ExternalUI.__init__(self)

if Carla.host is not None:
Carla.host.fParent = None
Carla.host.fSampleRate = self.d_getSampleRate()

if False:
from carla_patchbay import CarlaPatchbayW
self.fContainer = CarlaPatchbayW(self)
@@ -282,11 +362,9 @@ class CarlaMiniW(HostWindow, ExternalUI):
from carla_rack import CarlaRackW
self.fContainer = CarlaRackW(self)

self.setCentralWidget(self.fContainer)
self.setupContainer(False)
self.setWindowTitle(self.fUiName)

self.fIdleTimer = self.startTimer(50)

self.showUiIfTesting()

# -------------------------------------------------------------------
@@ -308,17 +386,54 @@ class CarlaMiniW(HostWindow, ExternalUI):
# -------------------------------------------------------------------
# Qt events

def timerEvent(self, event):
if event.timerId() == self.fIdleTimer:
if not self.idleExternalUI():
self.d_uiQuit()

HostWindow.timerEvent(self, event)

def closeEvent(self, event):
self.closeExternalUI()
HostWindow.closeEvent(self, event)

# -------------------------------------------------------------------
# Custom idler

def idleExternalUI(self):
while True:
if self.fPipeRecv is None:
return True

try:
msg = self.fPipeRecv.readline().strip()
except IOError:
return False

if not msg:
return True

elif msg == "show":
self.d_uiShow()

elif msg == "hide":
self.d_uiHide()

elif msg == "quit":
self.fQuitReceived = True
self.d_uiQuit()

elif msg == "uiTitle":
uiTitle = self.fPipeRecv.readline().strip().replace("\r", "\n")
self.d_uiTitleChanged(uiTitle)

elif msg.startswith("ENGINE_CALLBACK_"):
action = int(msg.replace("ENGINE_CALLBACK_", ""))
pluginId = int(self.fPipeRecv.readline())
value1 = int(self.fPipeRecv.readline())
value2 = int(self.fPipeRecv.readline())
value3 = float(self.fPipeRecv.readline())
valueStr = self.fPipeRecv.readline().strip().replace("\r", "\n")
engineCallback(None, action, pluginId, value1, value2, value3, valueStr)

else:
print("unknown message: \"" + msg + "\"")

return True

# ------------------------------------------------------------------------------------------------------------
# Main

@@ -334,30 +449,25 @@ if __name__ == '__main__':
setUpSignals()

# -------------------------------------------------------------
# Setup
# Init plugin host data

Carla.isControl = False
Carla.isLocal = False
Carla.isLocal = True
Carla.isPlugin = True

# -------------------------------------------------------------
# Read CLI args

argv = app.arguments()
argc = len(argv)
# Create GUI first

if argc > 1:
pass
Carla.gui = CarlaMiniW()

# -------------------------------------------------------------
# Init plugin backend
# Init plugin host now

initPlugin()
Carla.host = PluginHost(Carla.gui.d_getSampleRate())

# -------------------------------------------------------------
# Create GUI
initHost("Carla-Plugin")

Carla.gui = CarlaMiniW()
engineCallback(None, ENGINE_CALLBACK_ENGINE_STARTED, 0, ENGINE_PROCESS_MODE_CONTINUOUS_RACK, ENGINE_TRANSPORT_MODE_PLUGIN, 0.0, "Plugin")

# -------------------------------------------------------------
# App-Loop


+ 10
- 7
source/carla_host.py View File

@@ -154,7 +154,8 @@ class HostWindow(QMainWindow):
# -------------------------------------------------------------
# Set callback, TODO put somewhere else

Carla.host.set_engine_callback(engineCallback)
if Carla.host is not None:
Carla.host.set_engine_callback(engineCallback)

# -------------------------------------------------------------
# Internal stuff
@@ -220,9 +221,11 @@ class HostWindow(QMainWindow):
# Set up GUI (right panel)

self.fDirModel = QFileSystemModel(self)
self.fDirModel.setNameFilters(Carla.host.get_supported_file_extensions().split(";"))
self.fDirModel.setRootPath(HOME)

if Carla.host is not None:
self.fDirModel.setNameFilters(Carla.host.get_supported_file_extensions().split(";"))

self.ui.fileTreeView.setModel(self.fDirModel)
self.ui.fileTreeView.setRootIndex(self.fDirModel.index(HOME))
self.ui.fileTreeView.setColumnHidden(1, True)
@@ -508,9 +511,9 @@ class HostWindow(QMainWindow):
if rdfItem.UniqueID == uniqueId:
return pointer(rdfItem)

elif ptype in (PLUGIN_GIG, PLUGIN_SF2):
elif ptype in (PLUGIN_FILE_GIG, PLUGIN_FILE_SF2):
if plugin['name'].lower().endswith(" (16 outputs)"):
return c_char_p("true")
return c_char_p("true".encode("utf-8"))

return None

@@ -1061,9 +1064,9 @@ class HostWindow(QMainWindow):

def timerEvent(self, event):
if event.timerId() == self.fIdleTimerFast:
if not Carla.isPlugin:
Carla.host.engine_idle()
self.refreshTransport()
#if not Carla.isPlugin:
Carla.host.engine_idle()
self.refreshTransport()

self.fContainer.idleFast()



+ 5
- 2
source/carla_shared.py View File

@@ -524,7 +524,9 @@ def initHost(appName, libPrefix = None, failError = True):
Carla.discovery_posix32 = findTool("discovery", "carla-discovery-posix32")
Carla.discovery_posix64 = findTool("discovery", "carla-discovery-posix64")

if not libfilename:
# -------------------------------------------------------------

if not (libfilename or Carla.isPlugin):
if failError:
QMessageBox.critical(None, "Error", "Failed to find the carla library, cannot continue")
sys.exit(1)
@@ -533,7 +535,8 @@ def initHost(appName, libPrefix = None, failError = True):
# -------------------------------------------------------------
# Init host

Carla.host = Host(libfilename)
if Carla.host is None:
Carla.host = Host(libfilename)

# -------------------------------------------------------------
# Set binary path


+ 5
- 5
source/carla_widgets.py View File

@@ -560,13 +560,13 @@ class PluginEdit(QDialog):
self.ui.le_type.setText("VST")
elif pluginType == PLUGIN_AU:
self.ui.le_type.setText("AU")
elif pluginType == PLUGIN_CSOUND:
self.ui.le_type.setText("CSOUND")
elif pluginType == PLUGIN_GIG:
elif pluginType == PLUGIN_FILE_CSD:
self.ui.le_type.setText("CSD")
elif pluginType == PLUGIN_FILE_GIG:
self.ui.le_type.setText("GIG")
elif pluginType == PLUGIN_SF2:
elif pluginType == PLUGIN_FILE_SF2:
self.ui.le_type.setText("SF2")
elif pluginType == PLUGIN_SFZ:
elif pluginType == PLUGIN_FILE_SFZ:
self.ui.le_type.setText("SFZ")
else:
self.ui.le_type.setText(self.tr("Unknown"))


+ 5
- 1
source/externalui.py View File

@@ -192,7 +192,11 @@ class ExternalUI(object):
elif isinstance(line, float):
line2 = "%.10f" % line
else:
return
try:
line2 = str(line)
except:
print("unknown data type to send:", type(line2))
return

self.fPipeSend.write(line2 + "\n")
self.fPipeSend.flush()

+ 1
- 3
source/plugin/carla-native-base.cpp View File

@@ -52,9 +52,7 @@ struct PluginListManager {
{
const NativePluginDescriptor* const desc(CarlaBackend::CarlaPlugin::getNativePluginDescriptor(i));

carla_stderr2("PLM: %i/%i : %s", i+1, count, desc->name);

#ifdef CARLA_NATIVE_PLUGIN_LV2
#if 0 //def CARLA_NATIVE_PLUGIN_LV2 // TESTING!!!
// LV2 MIDI Out and Open/Save are not implemented yet
if (desc->midiOuts > 0 || (desc->hints & PLUGIN_NEEDS_UI_OPEN_SAVE) != 0)
continue;


Loading…
Cancel
Save