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 #endif


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


#include "CarlaNative.hpp" #include "CarlaNative.hpp"


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


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


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


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


CarlaEngineNativeThread(CarlaEngine* const engine)
CarlaEngineNativeUI(CarlaEngine* const engine)
: fEngine(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; 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: 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 else
{ {
// Kill
fUiState = UiCrashed;
carla_stderr("CarlaEngineNativeThread::run() - GUI crashed while running");
carla_stderr("msgReceived : %s", msg);
} }
#endif
} }


private: private:
CarlaEngine* const fEngine; 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), fIsPatchbay(isPatchbay),
fIsActive(false), fIsActive(false),
fIsRunning(false), fIsRunning(false),
fThread(this)
fUiServer(this)
{ {
carla_debug("CarlaEngineNative::CarlaEngineNative()"); carla_debug("CarlaEngineNative::CarlaEngineNative()");


@@ -179,25 +182,7 @@ public:
init("Carla-Rack"); 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 ~CarlaEngineNative() override
@@ -263,6 +248,32 @@ protected:
CarlaEngine::sampleRateChanged(newSampleRate); 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 // Plugin parameter calls


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


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


void uiShow(const bool show) override
void uiShow(const bool show)
{ {
if (show) if (show)
{ {
fThread.start();
fUiServer.setData("/home/falktx/FOSS/GIT-mine/Carla/source/carla-plugin", pData->sampleRate, pHost->uiName);
fUiServer.start();
} }
else 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(); CarlaEngine::idle();
fUiServer.idle();


switch(fThread.getUiState())
switch (fUiServer.getAndResetUiState())
{ {
case CarlaEngineNativeThread::UiNone:
case CarlaEngineNativeThread::UiShow:
case CarlaEngineNativeUI::UiNone:
case CarlaEngineNativeUI::UiShow:
break; break;
case CarlaEngineNativeThread::UiCrashed:
hostUiUnavailable();
case CarlaEngineNativeUI::UiCrashed:
pHost->dispatcher(pHost->handle, HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
break; break;
case CarlaEngineNativeThread::UiHide:
uiClosed();
case CarlaEngineNativeUI::UiHide:
pHost->ui_closed(pHost->handle);
break; 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 // Plugin state calls
@@ -823,6 +795,16 @@ public:
handlePtr->setMidiProgram(channel, bank, program); 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) static void _activate(NativePluginHandle handle)
{ {
handlePtr->activate(); handlePtr->activate();
@@ -876,6 +858,15 @@ public:
(void)ptr; (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 #undef handlePtr


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


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


CarlaPlugin* _getFirstPlugin() const noexcept CarlaPlugin* _getFirstPlugin() const noexcept
{ {
@@ -928,8 +919,8 @@ static const NativePluginDescriptor carlaRackDesc = {
CarlaEngineNative::_set_parameter_value, CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program, CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr, /* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
CarlaEngineNative::_ui_show,
CarlaEngineNative::_ui_idle,
/* _ui_set_parameter_value */ nullptr, /* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr, /* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ nullptr, /* _ui_set_custom_data */ nullptr,
@@ -967,8 +958,8 @@ static const NativePluginDescriptor carlaPatchbayDesc = {
CarlaEngineNative::_set_parameter_value, CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program, CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr, /* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
CarlaEngineNative::_ui_show,
CarlaEngineNative::_ui_idle,
/* _ui_set_parameter_value */ nullptr, /* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr, /* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ 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()); QString name(fPlugin->getName());
QStringList arguments;


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


QStringList arguments;

switch (fMode) switch (fMode)
{ {
case PLUGIN_THREAD_NULL: 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 # For a full copy of the GNU General Public License see the GPL.txt file


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

from time import sleep

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


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


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


self.fParent = None

self.fSupportedFileExts = ""
self.fBufferSize = 0 self.fBufferSize = 0
self.fSampleRate = 0.0
self.fSampleRate = sampleRate
self.fLastError = "" 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): 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): def engine_init(self, driverName, clientName):
return True return True
@@ -50,8 +78,15 @@ class PluginHost(object):
def engine_close(self): def engine_close(self):
return True return True


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

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

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


def set_engine_about_to_close(self): def set_engine_about_to_close(self):
pass pass
@@ -59,197 +94,243 @@ class PluginHost(object):
def set_engine_callback(self, func): def set_engine_callback(self, func):
pass 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 return True


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


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


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

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


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


def patchbay_refresh(self): def patchbay_refresh(self):
self.fParent.send(["patchbay_refresh"])
Carla.gui.send(["patchbay_refresh"])
return True 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 return True


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


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


def rename_plugin(self, pluginId, newName): 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): def clone_plugin(self, pluginId):
self.fParent.send(["clone_plugin", pluginId])
Carla.gui.send(["clone_plugin", pluginId])
return True return True


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


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


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

def load_plugin_state(self, pluginId, filename): 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 return True


def save_plugin_state(self, pluginId, filename): 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 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): 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): def get_buffer_size(self):
return self.fBufferSize return self.fBufferSize
@@ -257,11 +338,14 @@ class PluginHost(object):
def get_sample_rate(self): def get_sample_rate(self):
return self.fSampleRate 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 # Main Window
@@ -271,10 +355,6 @@ class CarlaMiniW(HostWindow, ExternalUI):
HostWindow.__init__(self, None) HostWindow.__init__(self, None)
ExternalUI.__init__(self) ExternalUI.__init__(self)


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

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


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


self.fIdleTimer = self.startTimer(50)

self.showUiIfTesting() self.showUiIfTesting()


# ------------------------------------------------------------------- # -------------------------------------------------------------------
@@ -308,17 +386,54 @@ class CarlaMiniW(HostWindow, ExternalUI):
# ------------------------------------------------------------------- # -------------------------------------------------------------------
# Qt events # 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): def closeEvent(self, event):
self.closeExternalUI() self.closeExternalUI()
HostWindow.closeEvent(self, event) 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 # Main


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


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


Carla.isControl = False Carla.isControl = False
Carla.isLocal = False
Carla.isLocal = True
Carla.isPlugin = 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 # App-Loop


+ 10
- 7
source/carla_host.py View File

@@ -154,7 +154,8 @@ class HostWindow(QMainWindow):
# ------------------------------------------------------------- # -------------------------------------------------------------
# Set callback, TODO put somewhere else # 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 # Internal stuff
@@ -220,9 +221,11 @@ class HostWindow(QMainWindow):
# Set up GUI (right panel) # Set up GUI (right panel)


self.fDirModel = QFileSystemModel(self) self.fDirModel = QFileSystemModel(self)
self.fDirModel.setNameFilters(Carla.host.get_supported_file_extensions().split(";"))
self.fDirModel.setRootPath(HOME) 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.setModel(self.fDirModel)
self.ui.fileTreeView.setRootIndex(self.fDirModel.index(HOME)) self.ui.fileTreeView.setRootIndex(self.fDirModel.index(HOME))
self.ui.fileTreeView.setColumnHidden(1, True) self.ui.fileTreeView.setColumnHidden(1, True)
@@ -508,9 +511,9 @@ class HostWindow(QMainWindow):
if rdfItem.UniqueID == uniqueId: if rdfItem.UniqueID == uniqueId:
return pointer(rdfItem) 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)"): if plugin['name'].lower().endswith(" (16 outputs)"):
return c_char_p("true")
return c_char_p("true".encode("utf-8"))


return None return None


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


def timerEvent(self, event): def timerEvent(self, event):
if event.timerId() == self.fIdleTimerFast: 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() 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_posix32 = findTool("discovery", "carla-discovery-posix32")
Carla.discovery_posix64 = findTool("discovery", "carla-discovery-posix64") Carla.discovery_posix64 = findTool("discovery", "carla-discovery-posix64")


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

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


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


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


+ 5
- 5
source/carla_widgets.py View File

@@ -560,13 +560,13 @@ class PluginEdit(QDialog):
self.ui.le_type.setText("VST") self.ui.le_type.setText("VST")
elif pluginType == PLUGIN_AU: elif pluginType == PLUGIN_AU:
self.ui.le_type.setText("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") self.ui.le_type.setText("GIG")
elif pluginType == PLUGIN_SF2:
elif pluginType == PLUGIN_FILE_SF2:
self.ui.le_type.setText("SF2") self.ui.le_type.setText("SF2")
elif pluginType == PLUGIN_SFZ:
elif pluginType == PLUGIN_FILE_SFZ:
self.ui.le_type.setText("SFZ") self.ui.le_type.setText("SFZ")
else: else:
self.ui.le_type.setText(self.tr("Unknown")) 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): elif isinstance(line, float):
line2 = "%.10f" % line line2 = "%.10f" % line
else: else:
return
try:
line2 = str(line)
except:
print("unknown data type to send:", type(line2))
return


self.fPipeSend.write(line2 + "\n") self.fPipeSend.write(line2 + "\n")
self.fPipeSend.flush() 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)); 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 // LV2 MIDI Out and Open/Save are not implemented yet
if (desc->midiOuts > 0 || (desc->hints & PLUGIN_NEEDS_UI_OPEN_SAVE) != 0) if (desc->midiOuts > 0 || (desc->hints & PLUGIN_NEEDS_UI_OPEN_SAVE) != 0)
continue; continue;


Loading…
Cancel
Save