Browse Source

Continue work on patchbay

tags/1.9.4
falkTX 11 years ago
parent
commit
3e2d817b39
5 changed files with 280 additions and 22 deletions
  1. +12
    -0
      source/backend/CarlaBackend.hpp
  2. +215
    -4
      source/backend/engine/CarlaEngineJack.cpp
  3. +31
    -18
      source/carla.py
  4. +6
    -0
      source/carla_shared.py
  5. +16
    -0
      source/utils/CarlaBackendUtils.hpp

+ 12
- 0
source/backend/CarlaBackend.hpp View File

@@ -97,6 +97,18 @@ const unsigned int PARAMETER_USES_SCALEPOINTS = 0x40; //!< Parameter uses scalep
const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText()
/**@}*/

/*!
* @defgroup PatchbayPortHints Patchbay Port Hints
*
* Various patchbay port hints.
* @{
*/
const unsigned int PATCHBAY_PORT_IS_INPUT = 0x1; //!< Patchbay port is input.
const unsigned int PATCHBAY_PORT_IS_OUTPUT = 0x2; //!< Patchbay port is output.
const unsigned int PATCHBAY_PORT_IS_AUDIO = 0x4; //!< Patchbay port is of Audio type.
const unsigned int PATCHBAY_PORT_IS_MIDI = 0x8; //!< Patchbay port is of MIDI type.
/**@}*/

/*!
* @defgroup CustomDataTypes Custom Data types
*


+ 215
- 4
source/backend/engine/CarlaEngineJack.cpp View File

@@ -497,7 +497,10 @@ public:
#ifdef BUILD_BRIDGE
fHasQuit(false)
#else
fRackPorts{nullptr}
fRackPorts{nullptr},
fLastGroupId(0),
fLastPortId(0),
fLastConnectionId(0)
#endif
{
carla_debug("CarlaEngineJack::CarlaEngineJack()");
@@ -513,6 +516,12 @@ public:
{
carla_debug("CarlaEngineJack::~CarlaEngineJack()");
CARLA_ASSERT(fClient == nullptr);

#ifndef BUILD_BRIDGE
fUsedGroupNames.clear();
fUsedPortNames.clear();
fUsedConnections.clear();
#endif
}

// -------------------------------------------------------------------
@@ -547,6 +556,14 @@ public:
carla_zeroStruct<jack_position_t>(fTransportPos);

#ifndef BUILD_BRIDGE
fLastGroupId = 0;
fLastPortId = 0;
fLastConnectionId = 0;

fUsedGroupNames.clear();
fUsedPortNames.clear();
fUsedConnections.clear();

fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);

if (fClient != nullptr)
@@ -571,6 +588,14 @@ public:
fRackPorts[rackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
}

// TODO - update jackbridge
jack_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
jack_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
jack_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);

if (jack_set_port_rename_callback)
jack_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);

if (jackbridge_activate(fClient) == 0)
{
const char* const jackClientName = jackbridge_get_client_name(fClient);
@@ -639,6 +664,10 @@ public:
setLastError("Failed to deactivate the JACK client");

fClient = nullptr;

fUsedGroupNames.clear();
fUsedPortNames.clear();
fUsedConnections.clear();
#endif
return false;
}
@@ -691,9 +720,6 @@ public:
}
#endif

static int test = 0;
callback(CALLBACK_PATCHBAY_CLIENT_ADDED, 0, test++, 0, 0, plugin->name());

return new CarlaEngineJackClient(kEngineTypeJack, fOptions.processMode, client);
}

@@ -1047,6 +1073,113 @@ protected:
}
}

#ifndef BUILD_BRIDGE
void handleJackClientRegistrationCallback(const char* name, bool reg)
{
if (reg)
{
GroupNameToId groupNameToId;
groupNameToId.id = fLastGroupId;
groupNameToId.name = name;

callback(CALLBACK_PATCHBAY_CLIENT_ADDED, 0, fLastGroupId, 0, 0.0f, name);
fUsedGroupNames.append(groupNameToId);
fLastGroupId++;
}
else
{
for (int i=0, count=fUsedGroupNames.count(); i < count; i++)
{
if (fUsedGroupNames[i].name == name)
{
callback(CALLBACK_PATCHBAY_CLIENT_REMOVED, 0, fUsedGroupNames[i].id, 0, 0.0f, nullptr);
fUsedGroupNames.takeAt(i);
break;
}
}
}
}

void handleJackPortRegistrationCallback(jack_port_id_t port, bool reg)
{
jack_port_t* jackPort = jack_port_by_id(fClient, port);

QString fullName(jack_port_name(jackPort));
QString groupName = fullName.split(":").at(0);
int groupId = getGroupId(groupName);

const char* portName = jack_port_short_name(jackPort);

if (reg)
{
bool portIsInput = (jack_port_flags(jackPort) & JackPortIsInput);
bool portIsAudio = (std::strcmp(jack_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);

unsigned int portFlags = 0x0;
portFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : PATCHBAY_PORT_IS_OUTPUT;
portFlags |= portIsAudio ? PATCHBAY_PORT_IS_AUDIO : PATCHBAY_PORT_IS_MIDI;

PortNameToId portNameToId;
portNameToId.groupId = groupId;
portNameToId.portId = fLastPortId;
portNameToId.name = portName;

fUsedPortNames.append(portNameToId);
callback(CALLBACK_PATCHBAY_PORT_ADDED, 0, groupId, fLastPortId, portFlags, portName);
fLastPortId++;
}
else
{
for (int i=0, count=fUsedPortNames.count(); i < count; i++)
{
if (fUsedPortNames[i].groupId == groupId && fUsedPortNames[i].name == portName)
{
callback(CALLBACK_PATCHBAY_PORT_REMOVED, 0, fUsedPortNames[i].portId, 0, 0.0f, nullptr);
fUsedPortNames.takeAt(i);
break;
}
}
}
}

void handleJackPortConnectCallback(jack_port_id_t a, jack_port_id_t b, bool connect)
{
jack_port_t* jackPortA = jack_port_by_id(fClient, a);
jack_port_t* jackPortB = jack_port_by_id(fClient, b);

int portIdA = getPortId(QString(jack_port_name(jackPortA)));
int portIdB = getPortId(QString(jack_port_name(jackPortB)));

if (connect)
{
ConnectionToId connectionToId;
connectionToId.id = fLastConnectionId;
connectionToId.portOut = portIdA;
connectionToId.portIn = portIdB;

fUsedConnections.append(connectionToId);
callback(CALLBACK_PATCHBAY_CONNECTION_ADDED, 0, fLastConnectionId, portIdA, portIdB, nullptr);
fLastConnectionId++;
}
else
{
for (int i=0, count=fUsedConnections.count(); i < count; i++)
{
if (fUsedConnections[i].portOut == portIdA && fUsedConnections[i].portIn == portIdB)
{
callback(CALLBACK_PATCHBAY_CONNECTION_REMOVED, 0, fUsedConnections[i].id, 0, 0.0f, nullptr);
fUsedConnections.takeAt(i);
break;
}
}
}
}

int handleJackPortRenameCallback(jack_port_id_t port, const char* oldName, const char* newName)
{
}
#endif

void handleJackShutdownCallback()
{
for (unsigned int i=0; i < kData->curPluginCount; i++)
@@ -1085,6 +1218,61 @@ private:
};

jack_port_t* fRackPorts[rackPortCount];

struct GroupNameToId {
int id;
QString name;
};

struct PortNameToId {
int groupId;
int portId;
QString name;
};

struct ConnectionToId {
int id;
int portOut;
int portIn;
};

int fLastGroupId;
int fLastPortId;
int fLastConnectionId ;

QList<GroupNameToId> fUsedGroupNames;
QList<PortNameToId> fUsedPortNames;
QList<ConnectionToId> fUsedConnections;

int getGroupId(QString groupName)
{
for (int i=0, count=fUsedGroupNames.count(); i < count; i++)
{
if (fUsedGroupNames[i].name == groupName)
{
return fUsedGroupNames[i].id;
}
}
return -1;
}

int getPortId(QString fullPortName)
{
QString groupName = fullPortName.split(":").at(0);
QString portName = fullPortName.replace(groupName+":", "");

int groupId = getGroupId(groupName);

for (int i=0, count=fUsedPortNames.count(); i < count; i++)
{
if (fUsedPortNames[i].groupId == groupId && fUsedPortNames[i].name == portName)
{
return fUsedPortNames[i].portId;
}
}

return -1;
}
#endif

// -------------------------------------
@@ -1217,6 +1405,29 @@ private:
handlePtr->handleJackLatencyCallback(mode);
}

#ifndef BUILD_BRIDGE
static void carla_jack_client_registration_callback(const char* name, int reg, void* arg)
{
handlePtr->handleJackClientRegistrationCallback(name, (reg != 0));
}

static void carla_jack_port_registration_callback(jack_port_id_t port, int reg, void* arg)
{
handlePtr->handleJackPortRegistrationCallback(port, (reg != 0));
}

static void carla_jack_port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
{
handlePtr->handleJackPortConnectCallback(a, b, (connect != 0));
}

static int carla_jack_port_rename_callback(jack_port_id_t port, const char* oldName, const char* newName, void* arg)
{
handlePtr->handleJackPortRenameCallback(port, oldName, newName);
return 0;
}
#endif

static void carla_jack_shutdown_callback(void* arg)
{
handlePtr->handleJackShutdownCallback();


+ 31
- 18
source/carla.py View File

@@ -660,11 +660,11 @@ class CarlaMainW(QMainWindow):
self.connect(self, SIGNAL("PatchbayClientAddedCallback(int, QString)"), SLOT("slot_handlePatchbayClientAddedCallback(int, QString)"))
self.connect(self, SIGNAL("PatchbayClientRemovedCallback(int)"), SLOT("slot_handlePatchbayClientRemovedCallback(int)"))
self.connect(self, SIGNAL("PatchbayClientRenamedCallback(int, QString)"), SLOT("slot_handlePatchbayClientRenamedCallback(int, QString)"))
self.connect(self, SIGNAL("PatchbayPortAddedCallback(int, int, QString)"), SLOT("slot_handlePatchbayPortAddedCallback(int, int, QString)"))
self.connect(self, SIGNAL("PatchbayPortAddedCallback(int, int, int, QString)"), SLOT("slot_handlePatchbayPortAddedCallback(int, int, int, QString)"))
self.connect(self, SIGNAL("PatchbayPortRemovedCallback(int)"), SLOT("slot_handlePatchbayPortRemovedCallback(int)"))
self.connect(self, SIGNAL("PatchbayPortRenamedCallback(int, QString)"), SLOT("slot_handlePatchbayPortRenamedCallback(int, QString)"))
self.connect(self, SIGNAL("PatchbayConnectionAddedCallback(int, int)"), SLOT("slot_handlePatchbayConnectionAddedCallback(int, int)"))
self.connect(self, SIGNAL("PatchbayConnectionRemovedCallback(int, int)"), SLOT("slot_handlePatchbayConnectionRemovedCallback(int, int)"))
self.connect(self, SIGNAL("PatchbayConnectionAddedCallback(int, int, int)"), SLOT("slot_handlePatchbayConnectionAddedCallback(int, int, int)"))
self.connect(self, SIGNAL("PatchbayConnectionRemovedCallback(int)"), SLOT("slot_handlePatchbayConnectionRemovedCallback(int)"))
#self.connect(self, SIGNAL("NSM_AnnounceCallback()"), SLOT("slot_handleNSM_AnnounceCallback()"))
#self.connect(self, SIGNAL("NSM_Open1Callback()"), SLOT("slot_handleNSM_Open1Callback()"))
#self.connect(self, SIGNAL("NSM_Open2Callback()"), SLOT("slot_handleNSM_Open2Callback()"))
@@ -839,6 +839,8 @@ class CarlaMainW(QMainWindow):
self.ui.ch_transport.clear()
self.ui.ch_transport.blockSignals(False)

patchcanvas.clear()

def loadProject(self, filename):
self.fProjectFilename = filename
self.setWindowTitle("Carla - %s" % os.path.basename(filename))
@@ -1232,10 +1234,23 @@ class CarlaMainW(QMainWindow):
def slot_handlePatchbayClientRenamedCallback(self, clientId, newClientName):
patchcanvas.renameGroup(clientId, newClientName)

@pyqtSlot(int, int, str)
def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portName):
# FIXME - needs mode and type
patchcanvas.addPort(clientId, portId, portName, 0, 0)
@pyqtSlot(int, int, int, str)
def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portFlags, portName):
if (portFlags & PATCHBAY_PORT_IS_INPUT):
portMode = patchcanvas.PORT_MODE_INPUT
elif (portFlags & PATCHBAY_PORT_IS_OUTPUT):
portMode = patchcanvas.PORT_MODE_OUTPUT
else:
portMode = patchcanvas.PORT_MODE_NULL

if (portFlags & PATCHBAY_PORT_IS_AUDIO):
portType = patchcanvas.PORT_TYPE_AUDIO_JACK
elif (portFlags & PATCHBAY_PORT_IS_MIDI):
portType = patchcanvas.PORT_TYPE_MIDI_JACK
else:
portType = patchcanvas.PORT_TYPE_NULL

patchcanvas.addPort(clientId, portId, portName, portMode, portType)

@pyqtSlot(int)
def slot_handlePatchbayPortRemovedCallback(self, portId):
@@ -1245,14 +1260,13 @@ class CarlaMainW(QMainWindow):
def slot_handlePatchbayPortRenamedCallback(self, portId, newPortName):
patchcanvas.renamePort(portId, newPortName)

@pyqtSlot(int, int)
def slot_handlePatchbayConnectionAddedCallback(self, portOutId, portInId):
patchcanvas.connectPorts(0, portOutId, portInId)
@pyqtSlot(int, int, int)
def slot_handlePatchbayConnectionAddedCallback(self, connectionId, portOutId, portInId):
patchcanvas.connectPorts(connectionId, portOutId, portInId)

@pyqtSlot(int, int)
def slot_handlePatchbayConnectionRemovedCallback(self, portOutId, portInId):
# FIXME
patchcanvas.disconnectPorts(0)
@pyqtSlot(int)
def slot_handlePatchbayConnectionRemovedCallback(self, connectionId):
patchcanvas.disconnectPorts(connectionId)

@pyqtSlot(str)
def slot_handleErrorCallback(self, error):
@@ -1411,7 +1425,6 @@ class CarlaMainW(QMainWindow):

self.stopEngine()

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

# ------------------------------------------------------------------------------------------------
@@ -1464,15 +1477,15 @@ def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr):
elif action == CALLBACK_PATCHBAY_CLIENT_RENAMED:
Carla.gui.emit(SIGNAL("PatchbayClientRenamedCallback(int, QString)"), value1, cString(valueStr))
elif action == CALLBACK_PATCHBAY_PORT_ADDED:
Carla.gui.emit(SIGNAL("PatchbayPortAddedCallback(int, int, QString)"), value1, value2, cString(valueStr))
Carla.gui.emit(SIGNAL("PatchbayPortAddedCallback(int, int, int, QString)"), value1, value2, value3, cString(valueStr))
elif action == CALLBACK_PATCHBAY_PORT_REMOVED:
Carla.gui.emit(SIGNAL("PatchbayPortRemovedCallback(int)"), value1)
elif action == CALLBACK_PATCHBAY_PORT_RENAMED:
Carla.gui.emit(SIGNAL("PatchbayPortRenamedCallback(int, QString)"), value1, cString(valueStr))
elif action == CALLBACK_PATCHBAY_CONNECTION_ADDED:
Carla.gui.emit(SIGNAL("PatchbayConnectionAddedCallback(int, int)"), value1, value2)
Carla.gui.emit(SIGNAL("PatchbayConnectionAddedCallback(int, int, int)"), value1, value2, value3)
elif action == CALLBACK_PATCHBAY_CONNECTION_REMOVED:
Carla.gui.emit(SIGNAL("PatchbayConnectionRemovedCallback(int, int)"), value1, value2)
Carla.gui.emit(SIGNAL("PatchbayConnectionRemovedCallback(int)"), value1)
#elif action == CALLBACK_NSM_ANNOUNCE:
#Carla.gui._nsmAnnounce2str = cString(Carla.host.get_last_error())
#Carla.gui.emit(SIGNAL("NSM_AnnounceCallback()"))


+ 6
- 0
source/carla_shared.py View File

@@ -189,6 +189,12 @@ PARAMETER_USES_SAMPLERATE = 0x20
PARAMETER_USES_SCALEPOINTS = 0x40
PARAMETER_USES_CUSTOM_TEXT = 0x80

# Patchbay Port Hints
PATCHBAY_PORT_IS_INPUT = 0x1
PATCHBAY_PORT_IS_OUTPUT = 0x2
PATCHBAY_PORT_IS_AUDIO = 0x4
PATCHBAY_PORT_IS_MIDI = 0x8

# Custom Data types
CUSTOM_DATA_INVALID = None
CUSTOM_DATA_CHUNK = "http://kxstudio.sf.net/ns/carla/chunk"


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

@@ -295,6 +295,22 @@ const char* CallbackType2Str(const CallbackType& type)
return "CALLBACK_SHOW_GUI";
case CALLBACK_UPDATE:
return "CALLBACK_UPDATE";
case CALLBACK_PATCHBAY_CLIENT_ADDED:
return "CALLBACK_PATCHBAY_CLIENT_ADDED";
case CALLBACK_PATCHBAY_CLIENT_REMOVED:
return "CALLBACK_PATCHBAY_CLIENT_REMOVED";
case CALLBACK_PATCHBAY_CLIENT_RENAMED:
return "CALLBACK_PATCHBAY_CLIENT_RENAMED";
case CALLBACK_PATCHBAY_PORT_ADDED:
return "CALLBACK_PATCHBAY_PORT_ADDED";
case CALLBACK_PATCHBAY_PORT_REMOVED:
return "CALLBACK_PATCHBAY_PORT_REMOVED";
case CALLBACK_PATCHBAY_PORT_RENAMED:
return "CALLBACK_PATCHBAY_PORT_RENAMED";
case CALLBACK_PATCHBAY_CONNECTION_ADDED:
return "CALLBACK_PATCHBAY_CONNECTION_ADDED";
case CALLBACK_PATCHBAY_CONNECTION_REMOVED:
return "CALLBACK_PATCHBAY_CONNECTION_REMOVED";
case CALLBACK_RELOAD_INFO:
return "CALLBACK_RELOAD_INFO";
case CALLBACK_RELOAD_PARAMETERS:


Loading…
Cancel
Save