Browse Source

More work for carla-plugin, rack mode now kinda working

tags/1.9.4
falkTX 11 years ago
parent
commit
cd0705b13c
4 changed files with 795 additions and 59 deletions
  1. +475
    -13
      source/backend/engine/CarlaEngineNative.cpp
  2. +273
    -30
      source/carla-plugin
  3. +5
    -6
      source/externalui.py
  4. +42
    -10
      source/utils/CarlaPipeUtils.hpp

+ 475
- 13
source/backend/engine/CarlaEngineNative.cpp View File

@@ -77,17 +77,6 @@ public:
protected:
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)
{
waitChildClose();
@@ -103,21 +92,196 @@ protected:
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(valueStr),);

fEngine->setOption((EngineOption)option, value, valueStr);

delete[] valueStr;
}
else if (std::strcmp(msg, "load_file") == 0)
{
const char* filename;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);

fEngine->loadFile(filename);

delete[] filename;
}
else if (std::strcmp(msg, "load_project") == 0)
{
const char* filename;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);

fEngine->loadProject(filename);

delete[] filename;
}
else if (std::strcmp(msg, "save_project") == 0)
{
const char* filename;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);

fEngine->saveProject(filename);

delete[] filename;
}
else if (std::strcmp(msg, "patchbay_connect") == 0)
{
int portA, portB;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(portA),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(portB),);

fEngine->patchbayConnect(portA, portB);
}
else if (std::strcmp(msg, "patchbay_disconnect") == 0)
{
int connectionId;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(connectionId),);

fEngine->patchbayDisconnect(connectionId);
}
else if (std::strcmp(msg, "patchbay_refresh") == 0)
{
fEngine->patchbayRefresh();
}
else if (std::strcmp(msg, "transport_play") == 0)
{
fEngine->transportPlay();
}
else if (std::strcmp(msg, "transport_pause") == 0)
{
fEngine->transportPause();
}
else if (std::strcmp(msg, "transport_relocate") == 0)
{
long frame;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsLong(frame),);

fEngine->transportRelocate((uint64_t)frame);
}
else if (std::strcmp(msg, "add_plugin") == 0)
{
int btype, ptype;
const char* filename;
const char* filename = nullptr;
const char* name;
const char* label;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(btype),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(ptype),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);
readNextLineAsString(filename); // can be null
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(name),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(label),);

if (filename != nullptr && std::strcmp(filename, "(null)") == 0)
{
delete[] filename;
filename = nullptr;
}

if (std::strcmp(name, "(null)") == 0)
{
delete[] name;
name = nullptr;
}

fEngine->addPlugin((BinaryType)btype, (PluginType)ptype, filename, name, label);

if (filename != nullptr)
delete[] filename;
if (name != nullptr)
delete[] name;
delete[] label;
}
else if (std::strcmp(msg, "remove_plugin") == 0)
{
int pluginId;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);

fEngine->removePlugin(pluginId);
}
else if (std::strcmp(msg, "remove_all_plugins") == 0)
{
fEngine->removeAllPlugins();
}
else if (std::strcmp(msg, "rename_plugin") == 0)
{
int pluginId;
const char* newName;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName),);

/*const char* name =*/ fEngine->renamePlugin(pluginId, newName);

delete[] newName;
}
else if (std::strcmp(msg, "clone_plugin") == 0)
{
int pluginId;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);

fEngine->clonePlugin(pluginId);
}
else if (std::strcmp(msg, "replace_plugin") == 0)
{
int pluginId;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);

fEngine->replacePlugin(pluginId);
}
else if (std::strcmp(msg, "switch_plugins") == 0)
{
int pluginIdA, pluginIdB;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginIdA),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginIdB),);

fEngine->switchPlugins(pluginIdA, pluginIdB);
}
else if (std::strcmp(msg, "load_plugin_state") == 0)
{
int pluginId;
const char* filename;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->loadStateFromFile(filename);

delete[] filename;
}
else if (std::strcmp(msg, "save_plugin_state") == 0)
{
int pluginId;
const char* filename;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->saveStateToFile(filename);

delete[] filename;
}
else if (std::strcmp(msg, "set_option") == 0)
{
int pluginId;
int option;
bool yesNo;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(option),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setOption(option, yesNo);
}
else if (std::strcmp(msg, "set_active") == 0)
{
@@ -130,6 +294,198 @@ protected:
if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setActive(onOff, true, false);
}
else if (std::strcmp(msg, "set_drywet") == 0)
{
int pluginId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setDryWet(value, true, false);
}
else if (std::strcmp(msg, "set_volume") == 0)
{
int pluginId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setVolume(value, true, false);
}
else if (std::strcmp(msg, "set_balance_left") == 0)
{
int pluginId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setBalanceLeft(value, true, false);
}
else if (std::strcmp(msg, "set_balance_right") == 0)
{
int pluginId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setBalanceRight(value, true, false);
}
else if (std::strcmp(msg, "set_panning") == 0)
{
int pluginId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setPanning(value, true, false);
}
else if (std::strcmp(msg, "set_ctrl_channel") == 0)
{
int pluginId;
int channel;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel),);
CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setCtrlChannel(int8_t(channel), true, false);
}
else if (std::strcmp(msg, "set_parameter_value") == 0)
{
int pluginId;
int parameterId;
float value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(parameterId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setParameterValue(parameterId, value, true, true, false);
}
else if (std::strcmp(msg, "set_parameter_midi_channel") == 0)
{
int pluginId;
int parameterId;
int channel;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(parameterId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel),);
CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS,);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setParameterMidiChannel(parameterId, uint8_t(channel), true, false);
}
else if (std::strcmp(msg, "set_parameter_midi_cc") == 0)
{
int pluginId;
int parameterId;
int cc;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(parameterId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(cc),);
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < 0x5F,);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setParameterMidiCC(parameterId, int16_t(cc), true, false);
}
else if (std::strcmp(msg, "set_program") == 0)
{
int pluginId;
int index;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setProgram(index, true, true, false);
}
else if (std::strcmp(msg, "set_midi_program") == 0)
{
int pluginId;
int index;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setMidiProgram(index, true, true, false);
}
else if (std::strcmp(msg, "set_custom_data") == 0)
{
int pluginId;
const char* type;
const char* key;
const char* value;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(type),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setCustomData(type, key, value, true);
}
else if (std::strcmp(msg, "set_chunk_data") == 0)
{
int pluginId;
const char* cdata;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(cdata),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->setChunkData(cdata);
}
else if (std::strcmp(msg, "prepare_for_save") == 0)
{
int pluginId;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->prepareForSave();
}
else if (std::strcmp(msg, "send_midi_note") == 0)
{
int pluginId;
int channel, note, velocity;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(note),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(velocity),);
CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS,);
CARLA_SAFE_ASSERT_RETURN(note >= 0 && channel < MAX_MIDI_VALUE,);
CARLA_SAFE_ASSERT_RETURN(velocity >= 0 && channel < MAX_MIDI_VALUE,);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->sendMidiSingleNote(uint8_t(channel), uint8_t(note), uint8_t(velocity), true, true, false);
}
else if (std::strcmp(msg, "show_custom_ui") == 0)
{
int pluginId;
bool yesNo;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(pluginId),);
CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo),);

if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
plugin->showCustomUI(yesNo);
}
else
{
carla_stderr("msgReceived : %s", msg);
@@ -256,6 +612,97 @@ protected:
return;

char strBuf[STR_MAX+1];

switch (action)
{
case ENGINE_CALLBACK_PLUGIN_ADDED:
if (CarlaPlugin* const plugin = getPlugin(pluginId))
{
CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);

std::sprintf(strBuf, "PLUGIN_INFO_%i\n", pluginId);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%i:%i:%i:%li\n", plugin->getType(), plugin->getCategory(), plugin->getHints(), plugin->getUniqueId());
fUiServer.writeMsg(strBuf);
plugin->getRealName(strBuf);
fUiServer.writeAndFixMsg(strBuf);
std::sprintf(strBuf, "%s", plugin->getName());
fUiServer.writeAndFixMsg(strBuf);
plugin->getLabel(strBuf);
fUiServer.writeAndFixMsg(strBuf);
plugin->getMaker(strBuf);
fUiServer.writeAndFixMsg(strBuf);
plugin->getCopyright(strBuf);
fUiServer.writeAndFixMsg(strBuf);

std::sprintf(strBuf, "AUDIO_COUNT_%i\n", pluginId);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%i:%i\n", plugin->getAudioInCount(), plugin->getAudioOutCount());
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "MIDI_COUNT_%i\n", pluginId);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%i:%i\n", plugin->getMidiInCount(), plugin->getMidiOutCount());
fUiServer.writeMsg(strBuf);

uint32_t ins, outs, count;
std::sprintf(strBuf, "PARAMETER_COUNT_%i\n", pluginId);
fUiServer.writeMsg(strBuf);
plugin->getParameterCountInfo(ins, outs);
count = plugin->getParameterCount();
std::sprintf(strBuf, "%i:%i:%i\n", ins, outs, count);
fUiServer.writeMsg(strBuf);

for (uint32_t i=0; i<count; ++i)
{
const ParameterData& paramData(plugin->getParameterData(i));
const ParameterRanges& paramRanges(plugin->getParameterRanges(i));

std::sprintf(strBuf, "PARAMETER_DATA_%i:%i\n", pluginId, i);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%i:%i\n", paramData.type, paramData.hints);
fUiServer.writeMsg(strBuf);
plugin->getParameterName(i, strBuf);
fUiServer.writeAndFixMsg(strBuf);
plugin->getParameterUnit(i, strBuf);
fUiServer.writeAndFixMsg(strBuf);

std::sprintf(strBuf, "PARAMETER_MIDI_STUFF_%i:%i\n", pluginId, i);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%i:%i\n", paramData.midiChannel, paramData.midiCC);
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "PARAMETER_RANGES_%i:%i\n", pluginId, i);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%f:%f:%f:%f:%f:%f\n", paramRanges.def, paramRanges.min, paramRanges.max, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
fUiServer.writeMsg(strBuf);

std::sprintf(strBuf, "PARAMETER_VALUE_%i:%i\n", pluginId, i);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%f\n", plugin->getParameterValue(i));
fUiServer.writeMsg(strBuf);
}
}
break;

case ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
std::sprintf(strBuf, "PARAMETER_VALUE_%i:%i\n", pluginId, value1);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%f\n", value3);
fUiServer.writeMsg(strBuf);
break;

case ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED:
std::sprintf(strBuf, "PARAMETER_DEFAULT_%i:%i\n", pluginId, value1);
fUiServer.writeMsg(strBuf);
std::sprintf(strBuf, "%f\n", value3);
fUiServer.writeMsg(strBuf);
break;

default:
break;
}

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

@@ -622,6 +1069,19 @@ protected:
CarlaEngine::idle();
fUiServer.idle();

char strBuf[STR_MAX+1];

for (uint i=0; i < pData->curPluginCount; ++i)
{
const EnginePluginData& plugData(pData->plugins[i]);

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

std::sprintf(strBuf, "%f:%f:%f:%f\n", plugData.insPeak[0], plugData.insPeak[1], plugData.outsPeak[0], plugData.outsPeak[1]);
fUiServer.writeMsg(strBuf);
}

switch (fUiServer.getAndResetUiState())
{
case CarlaEngineNativeUI::UiNone:
@@ -876,6 +1336,8 @@ private:
bool fIsActive, fIsRunning;
CarlaEngineNativeUI fUiServer;

CarlaMutex fWriteLock;

CarlaPlugin* _getFirstPlugin() const noexcept
{
if (pData->curPluginCount == 0 || pData->plugins == nullptr)


+ 273
- 30
source/carla-plugin View File

@@ -27,6 +27,30 @@ from time import sleep
from carla_host import *
from externalui import ExternalUI

# ------------------------------------------------------------------------------------------------------------
# Helper object

class PluginStoreInfo(object):
__slots__ = [
'pluginInfo',
'pluginRealName',
'audioCountInfo',
'midiCountInfo',
'parameterCount',
'parameterCountInfo',
'parameterInfoS',
'parameterDataS',
'parameterRangeS',
'parameterValueS',
'programCount',
'programCurrent',
'programNameS',
'midiProgramCount',
'midiProgramCurrent',
'midiProgramDataS',
'peaks'
]

# ------------------------------------------------------------------------------------------------------------
# Host Plugin object

@@ -40,6 +64,126 @@ class PluginHost(object):
self.fLastError = ""
self.fIsRunning = True

self.fPluginsInfo = []

def _add(self, pluginId):
if len(self.fPluginsInfo) != pluginId:
return

info = PluginStoreInfo()
info.pluginInfo = PyCarlaPluginInfo
info.pluginRealName = ""
info.audioCountInfo = PyCarlaPortCountInfo
info.midiCountInfo = PyCarlaPortCountInfo
info.parameterCount = 0
info.parameterCountInfo = PyCarlaPortCountInfo
info.parameterInfoS = []
info.parameterDataS = []
info.parameterRangeS = []
info.parameterValueS = []
info.programCount = 0
info.programCurrent = -1
info.programNameS = []
info.midiProgramCount = 0
info.midiProgramCurrent = -1
info.midiProgramDataS = []
info.peaks = [0.0, 0.0, 0.0, 0.0]
self.fPluginsInfo.append(info)

def _set_pluginInfo(self, pluginId, info):
self.fPluginsInfo[pluginId].pluginInfo = info

def _set_pluginRealName(self, pluginId, realName):
self.fPluginsInfo[pluginId].pluginRealName = realName

def _set_audioCountInfo(self, pluginId, info):
self.fPluginsInfo[pluginId].audioCountInfo = info

def _set_midiCountInfo(self, pluginId, info):
self.fPluginsInfo[pluginId].midiCountInfo = info

def _set_parameterCountInfo(self, pluginId, count, info):
self.fPluginsInfo[pluginId].parameterCount = count
self.fPluginsInfo[pluginId].parameterCountInfo = info

# clear
self.fPluginsInfo[pluginId].parameterInfoS = []
self.fPluginsInfo[pluginId].parameterDataS = []
self.fPluginsInfo[pluginId].parameterRangeS = []
self.fPluginsInfo[pluginId].parameterValueS = []

# add placeholders
for x in range(count):
self.fPluginsInfo[pluginId].parameterInfoS.append(PyCarlaParameterInfo)
self.fPluginsInfo[pluginId].parameterDataS.append(PyParameterData)
self.fPluginsInfo[pluginId].parameterRangeS.append(PyParameterRanges)
self.fPluginsInfo[pluginId].parameterValueS.append(0.0)

def _set_programCount(self, pluginId, count):
self.fPluginsInfo[pluginId].programCount = count

# clear
self.fPluginsInfo[pluginId].programNameS = []

# add placeholders
for x in range(count):
self.fPluginsInfo[pluginId].programNameS.append("")

def _set_midiProgramCount(self, pluginId, count):
self.fPluginsInfo[pluginId].midiProgramCount = count

# clear
self.fPluginsInfo[pluginId].midiProgramDataS = []

# add placeholders
for x in range(count):
self.fPluginsInfo[pluginId].midiProgramDataS.append(PyMidiProgramData)

def _set_parameterInfoS(self, pluginId, paramIndex, info):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterInfoS[paramIndex] = info

def _set_parameterDataS(self, pluginId, paramIndex, data):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterDataS[paramIndex] = data

def _set_parameterRangeS(self, pluginId, paramIndex, ranges):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterRangeS[paramIndex] = ranges

def _set_parameterValueS(self, pluginId, paramIndex, value):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterValueS[paramIndex] = value

def _set_parameterDefaultValue(self, pluginId, paramIndex, value):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterRangeS[paramIndex]['def'] = value

def _set_parameterMidiChannel(self, pluginId, paramIndex, channel):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterDataS[paramIndex]['midiChannel'] = channel

def _set_parameterMidiCC(self, pluginId, paramIndex, cc):
if paramIndex < self.fPluginsInfo[pluginId].parameterCount:
self.fPluginsInfo[pluginId].parameterDataS[paramIndex]['midiCC'] = cc

def _set_currentProgram(self, pluginId, pIndex):
self.fPluginsInfo[pluginId].programCurrent = pIndex

def _set_currentMidiProgram(self, pluginId, mpIndex):
self.fPluginsInfo[pluginId].midiProgramCurrent = mpIndex

def _set_programNameS(self, pluginId, pIndex, name):
if pIndex < self.fPluginsInfo[pluginId].programCount:
self.fPluginsInfo[pluginId].programNameS[pIndex] = name

def _set_midiProgramDataS(self, pluginId, mpIndex, data):
if mpIndex < self.fPluginsInfo[pluginId].midiProgramCount:
self.fPluginsInfo[pluginId].midiProgramDataS[mpIndex] = data

def _set_peaks(self, pluginId, in1, in2, out1, out2):
self.fPluginsInfo[pluginId].peaks = [in1, in2, out1, out2]

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

def get_complete_license_text(self):
@@ -65,7 +209,7 @@ class PluginHost(object):
# -------------------------------------------------------------------

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

def get_internal_plugin_info(self, index):
return None
@@ -188,19 +332,19 @@ class PluginHost(object):
# -------------------------------------------------------------------

def get_plugin_info(self, pluginId):
return PyCarlaPluginInfo
return self.fPluginsInfo[pluginId].pluginInfo

def get_audio_port_count_info(self, pluginId):
return PyCarlaPortCountInfo
return self.fPluginsInfo[pluginId].audioCountInfo

def get_midi_port_count_info(self, pluginId):
return PyCarlaPortCountInfo
return self.fPluginsInfo[pluginId].midiCountInfo

def get_parameter_count_info(self, pluginId):
return PyCarlaPortCountInfo
return self.fPluginsInfo[pluginId].parameterCountInfo

def get_parameter_info(self, pluginId, parameterId):
return PyCarlaParameterInfo
return self.fPluginsInfo[pluginId].parameterInfoS[parameterId]

def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
return PyCarlaScalePointInfo
@@ -208,13 +352,13 @@ class PluginHost(object):
# -------------------------------------------------------------------

def get_parameter_data(self, pluginId, parameterId):
return PyParameterData
return self.fPluginsInfo[pluginId].parameterDataS[parameterId]

def get_parameter_ranges(self, pluginId, parameterId):
return PyParameterRanges
return self.fPluginsInfo[pluginId].parameterRangeS[parameterId]

def get_midi_program_data(self, pluginId, midiProgramId):
return PyMidiProgramData
return self.fPluginsInfo[pluginId].midiProgramDataS[midiProgramId]

def get_custom_data(self, pluginId, customDataId):
return PyCustomData
@@ -225,13 +369,13 @@ class PluginHost(object):
# -------------------------------------------------------------------

def get_parameter_count(self, pluginId):
return 0
return self.fPluginsInfo[pluginId].parameterCount

def get_program_count(self, pluginId):
return 0
return self.fPluginsInfo[pluginId].programCount

def get_midi_program_count(self, pluginId):
return 0
return self.fPluginsInfo[pluginId].midiProgramCount

def get_custom_data_count(self, pluginId):
return 0
@@ -242,33 +386,33 @@ class PluginHost(object):
return ""

def get_program_name(self, pluginId, programId):
return ""
return self.fPluginsInfo[pluginId].programNameS[programId]

def get_midi_program_name(self, pluginId, midiProgramId):
return ""
return self.fPluginsInfo[pluginId].midiProgramDataS[midiProgramId]['label']

def get_real_plugin_name(self, pluginId):
return ""
return self.fPluginsInfo[pluginId].pluginRealName

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

def get_current_program_index(self, pluginId):
return 0
return self.fPluginsInfo[pluginId].programCurrent

def get_current_midi_program_index(self, pluginId):
return 0
return self.fPluginsInfo[pluginId].midiProgramCurrent

def get_default_parameter_value(self, pluginId, parameterId):
return 0.0
return self.fPluginsInfo[pluginId].parameterRangeS[parameterId]['def']

def get_current_parameter_value(self, pluginId, parameterId):
return 0.0
return self.fPluginsInfo[pluginId].parameterValueS[parameterId]

def get_input_peak_value(self, pluginId, isLeft):
return 0.0
return self.fPluginsInfo[pluginId].peaks[0 if isLeft else 1]

def get_output_peak_value(self, pluginId, isLeft):
return 0.0
return self.fPluginsInfo[pluginId].peaks[2 if isLeft else 3]

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

@@ -406,6 +550,114 @@ class CarlaMiniW(HostWindow, ExternalUI):
if not msg:
return True

elif msg.startswith("PEAKS_"):
pluginId = int(msg.replace("PEAKS_", ""))
in1, in2, out1, out2 = [float(i) for i in self.fPipeRecv.readline().strip().split(":")]
Carla.host._set_peaks(pluginId, in1, in2, out1, out2)

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

elif msg.startswith("PLUGIN_INFO_"):
pluginId = int(msg.replace("PLUGIN_INFO_", ""))
Carla.host._add(pluginId)

type_, category, hints, uniqueId = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
realName = self.fPipeRecv.readline().strip().replace("\r", "\n")
name = self.fPipeRecv.readline().strip().replace("\r", "\n")
label = self.fPipeRecv.readline().strip().replace("\r", "\n")
maker = self.fPipeRecv.readline().strip().replace("\r", "\n")
copyright = self.fPipeRecv.readline().strip().replace("\r", "\n")

pinfo = {
'type': type_,
'category': category,
'hints': hints,
'optionsAvailable': 0x0, # TODO
'optionsEnabled': 0x0, # TODO
'filename': "", # TODO
'name': name,
'label': label,
'maker': maker,
'copyright': copyright,
'iconName': None, # TODO
'patchbayClientId': 0,
'uniqueId': uniqueId
}

Carla.host._set_pluginInfo(pluginId, pinfo)
Carla.host._set_pluginRealName(pluginId, realName)

elif msg.startswith("AUDIO_COUNT_"):
pluginId = int(msg.replace("AUDIO_COUNT_", ""))
ins, outs = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
Carla.host._set_audioCountInfo(pluginId, {'ins': ins, 'outs': outs})

elif msg.startswith("MIDI_COUNT_"):
pluginId = int(msg.replace("MIDI_COUNT_", ""))
ins, outs = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
Carla.host._set_midiCountInfo(pluginId, {'ins': ins, 'outs': outs})

elif msg.startswith("PARAMETER_COUNT_"):
pluginId = int(msg.replace("PARAMETER_COUNT_", ""))
ins, outs, count = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
Carla.host._set_parameterCountInfo(pluginId, count, {'ins': ins, 'outs': outs})

elif msg.startswith("PARAMETER_DATA_"):
pluginId, paramId = [int(i) for i in msg.replace("PARAMETER_DATA_", "").split(":")]
paramType, paramHints = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
paramName = self.fPipeRecv.readline().strip().replace("\r", "\n")
paramUnit = self.fPipeRecv.readline().strip().replace("\r", "\n")

paramInfo = {
'name': paramName,
'symbol': "",
'unit': paramUnit,
'scalePointCount': 0,
}
Carla.host._set_parameterInfoS(pluginId, paramId, paramInfo)

paramData = {
'type': paramType,
'hints': paramHints,
'index': paramId,
'rindex': -1,
'midiCC': -1,
'midiChannel': 0
}
Carla.host._set_parameterDataS(pluginId, paramId, paramData)

elif msg.startswith("PARAMETER_MIDI_STUFF_"):
pluginId, paramId = [int(i) for i in msg.replace("PARAMETER_MIDI_STUFF_", "").split(":")]
midiChannel, midiCC = [int(i) for i in self.fPipeRecv.readline().strip().split(":")]
Carla.host._set_parameterMidiChannel(pluginId, paramId, midiChannel)
Carla.host._set_parameterMidiCC(pluginId, paramId, midiCC)

elif msg.startswith("PARAMETER_RANGES_"):
pluginId, paramId = [int(i) for i in msg.replace("PARAMETER_RANGES_", "").split(":")]
def_, min_, max_, step, stepSmall, stepLarge = [float(i) for i in self.fPipeRecv.readline().strip().split(":")]

paramRanges = {
'def': def_,
'min': min_,
'max': max_,
'step': step,
'stepSmall': stepSmall,
'stepLarge': stepLarge
}
Carla.host._set_parameterRangeS(pluginId, paramId, paramRanges)

elif msg.startswith("PARAMETER_VALUE_"):
pluginId, paramId = [int(i) for i in msg.replace("PARAMETER_VALUE_", "").split(":")]
paramValue = float(self.fPipeRecv.readline().strip())
Carla.host._set_parameterValueS(pluginId, paramId, paramValue)

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

@@ -420,15 +672,6 @@ class CarlaMiniW(HostWindow, ExternalUI):
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 + "\"")



+ 5
- 6
source/externalui.py View File

@@ -182,7 +182,9 @@ class ExternalUI(object):
return

for line in lines:
if isinstance(line, str):
if line is None:
line2 = "(null)"
elif isinstance(line, str):
line2 = line.replace("\n", "\r")
else:
if isinstance(line, bool):
@@ -192,11 +194,8 @@ class ExternalUI(object):
elif isinstance(line, float):
line2 = "%.10f" % line
else:
try:
line2 = str(line)
except:
print("unknown data type to send:", type(line2))
return
print("unknown data type to send:", type(line))
return

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

+ 42
- 10
source/utils/CarlaPipeUtils.hpp View File

@@ -309,6 +309,20 @@ public:
return false;
}

bool readNextLineAsLong(long& value)
{
CARLA_SAFE_ASSERT_RETURN(fIsReading, false);

if (const char* const msg = readline())
{
value = std::atol(msg);
delete[] msg;
return true;
}

return false;
}

bool readNextLineAsFloat(float& value)
{
CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
@@ -360,22 +374,40 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);

const size_t size(std::strlen(msg));
const size_t size(msg != nullptr ? std::strlen(msg) : 0);

char fixedMsg[size+1];
std::strcpy(fixedMsg, msg);
char fixedMsg[size+2];

for (size_t i=0; i < size; ++i)
if (size > 0)
{
if (fixedMsg[i] == '\n')
fixedMsg[i] = '\r';
}
std::strcpy(fixedMsg, msg);

for (size_t i=0; i < size; ++i)
{
if (fixedMsg[i] == '\n')
fixedMsg[i] = '\r';
}

fixedMsg[size-1] = '\n';
fixedMsg[size] = '\0';
if (fixedMsg[size+1] == '\r')
{
fixedMsg[size-1] = '\n';
fixedMsg[size] = '\0';
fixedMsg[size+1] = '\0';
}
else
{
fixedMsg[size] = '\n';
fixedMsg[size+1] = '\0';
}
}
else
{
fixedMsg[0] = '\n';
fixedMsg[1] = '\0';
}

try {
::write(fPipeSend, fixedMsg, size);
::write(fPipeSend, fixedMsg, size+1);
} catch (...) {}
}



Loading…
Cancel
Save