Browse Source

Initial code for patchbay state support

tags/1.9.4
falkTX 11 years ago
parent
commit
19404bbd28
5 changed files with 252 additions and 13 deletions
  1. +6
    -0
      source/backend/CarlaEngine.hpp
  2. +157
    -12
      source/backend/engine/CarlaEngine.cpp
  3. +86
    -0
      source/backend/engine/CarlaEngineInternal.cpp
  4. +2
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  5. +1
    -1
      source/backend/engine/CarlaEngineRtAudio.cpp

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

@@ -1055,6 +1055,12 @@ protected:
virtual bool disconnectRackMidiInPort(const int) { return false; }
virtual bool disconnectRackMidiOutPort(const int) { return false; }

/*!
* Virtual functions for handling patchbay state.
*/
virtual const char* const* getPatchbayConnections() const;
virtual void restorePatchbayConnection(const char* const sourcePort, const char* const targetPort);

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

private:


+ 157
- 12
source/backend/engine/CarlaEngine.cpp View File

@@ -1352,6 +1352,7 @@ bool CarlaEngine::loadProject(const char* const filename)
return false;
}

// handle plugins first
for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling())
{
if (isPreset || node.toElement().tagName().compare("plugin", Qt::CaseInsensitive) == 0)
@@ -1382,7 +1383,40 @@ bool CarlaEngine::loadProject(const char* const filename)
}

if (isPreset)
return true;
}

// now connections
for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling())
{
if (node.toElement().tagName().compare("patchbay", Qt::CaseInsensitive) == 0)
{
CarlaString sourcePort, targetPort;

for (QDomNode patchNode = node.firstChild(); ! patchNode.isNull(); patchNode = patchNode.nextSibling())
{
sourcePort.clear();
targetPort.clear();

if (patchNode.toElement().tagName().compare("connection", Qt::CaseInsensitive) != 0)
continue;

for (QDomNode connNode = patchNode.firstChild(); ! connNode.isNull(); connNode = connNode.nextSibling())
{
const QString tag(connNode.toElement().tagName());
const QString text(connNode.toElement().text().trimmed());

if (tag.compare("source", Qt::CaseInsensitive) == 0)
sourcePort = text.toUtf8().constData();
else if (tag.compare("target", Qt::CaseInsensitive) == 0)
targetPort = text.toUtf8().constData();
}

if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
restorePatchbayConnection(sourcePort.getBuffer(), targetPort.getBuffer());
}
break;
}
}

return true;
@@ -1433,6 +1467,30 @@ bool CarlaEngine::saveProject(const char* const filename)
}
}

if (const char* const* patchbayConns = getPatchbayConnections())
{
out << " <Patchbay>\n";

for (int i=0; patchbayConns[i] != nullptr && patchbayConns[i+1] != nullptr; ++i, ++i )
{
const char* const connSource(patchbayConns[i]);
const char* const connTarget(patchbayConns[i+1]);

CARLA_SAFE_ASSERT_CONTINUE(connSource != nullptr && connSource[0] != '\0');
CARLA_SAFE_ASSERT_CONTINUE(connTarget != nullptr && connTarget[0] != '\0');

out << " <Connection>\n";
out << " <Source>" << connSource << "</Source>\n";
out << " <Target>" << connTarget << "</Target>\n";
out << " </Connection>\n";

delete[] connSource;
delete[] connTarget;
}

out << " </Patchbay>\n";
}

out << "</CARLA-PROJECT>\n";

file.close();
@@ -1646,24 +1704,28 @@ bool CarlaEngine::patchbayDisconnect(const uint connectionId)

if (connection.id == connectionId)
{
const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn);
const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut);
const int otherPort((connection.portOut >= 0) ? connection.portOut : connection.portIn);
const int carlaPort((otherPort == connection.portOut) ? connection.portIn : connection.portOut);

if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
{
const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_IN, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
disconnectRackMidiInPort(portId);
}
else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
else if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
{
const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_OUT, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);
disconnectRackMidiOutPort(portId);
}
else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false);

const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);

rack->connectLock.lock();

@@ -1674,11 +1736,11 @@ bool CarlaEngine::patchbayDisconnect(const uint connectionId)

rack->connectLock.unlock();
}
else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false);

const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);

rack->connectLock.lock();

@@ -1697,11 +1759,12 @@ bool CarlaEngine::patchbayDisconnect(const uint connectionId)
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr);

rack->usedConnections.remove(it);
break;
return true;
}
}

return true;
setLastError("Failed to find connection");
return false;
}

bool CarlaEngine::patchbayRefresh()
@@ -1973,6 +2036,88 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak
pluginData.outsPeak[1] = outPeaks[1];
}

// -----------------------------------------------------------------------
// Patchbay stuff

const char* const* CarlaEngine::getPatchbayConnections() const
{
carla_debug("CarlaEngine::getPatchbayConnections()");

if (pData->bufAudio.usePatchbay)
{
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.patchbay != nullptr, nullptr);
return pData->bufAudio.patchbay->getConnections();
}
else
{
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.rack != nullptr, nullptr);
return pData->bufAudio.rack->getConnections();
}
}

static int getCarlaPortIdFromName(const char* const shortname) noexcept
{
if (std::strcmp(shortname, "AudioIn1") == 0)
return RACK_PATCHBAY_PORT_AUDIO_IN1;
if (std::strcmp(shortname, "AudioIn2") == 0)
return RACK_PATCHBAY_PORT_AUDIO_IN2;
if (std::strcmp(shortname, "AudioOut1") == 0)
return RACK_PATCHBAY_PORT_AUDIO_OUT1;
if (std::strcmp(shortname, "AudioOut2") == 0)
return RACK_PATCHBAY_PORT_AUDIO_OUT2;
if (std::strcmp(shortname, "MidiIn") == 0)
return RACK_PATCHBAY_PORT_MIDI_IN;
if (std::strcmp(shortname, "MidiOut") == 0)
return RACK_PATCHBAY_PORT_MIDI_OUT;
return RACK_PATCHBAY_PORT_MAX;
}

void CarlaEngine::restorePatchbayConnection(const char* const connSource, const char* const connTarget)
{
carla_debug("CarlaEngine::restorePatchbayConnection(\"%s\", \"%s\")", connSource, connTarget);

CARLA_SAFE_ASSERT_RETURN(connSource != nullptr && connSource[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(connTarget != nullptr && connTarget[0] != '\0',);

if (pData->bufAudio.usePatchbay)
{
// TODO
}
else
{
int sourcePort, targetPort;

if (std::strncmp(connSource, "Carla:", 6) == 0)
sourcePort = getCarlaPortIdFromName(connSource+6);
else if (std::strncmp(connSource, "AudioIn:", 8) == 0)
sourcePort = std::atoi(connSource+8) + RACK_PATCHBAY_GROUP_AUDIO_IN*1000 - 1;
else if (std::strncmp(connSource, "AudioOut:", 9) == 0)
sourcePort = std::atoi(connSource+9) + RACK_PATCHBAY_GROUP_AUDIO_OUT*1000 - 1;
else if (std::strncmp(connSource, "MidiIn:", 7) == 0)
sourcePort = std::atoi(connSource+7) + RACK_PATCHBAY_GROUP_MIDI_IN*1000 - 1;
else if (std::strncmp(connSource, "MidiOut:", 8) == 0)
sourcePort = std::atoi(connSource+8) + RACK_PATCHBAY_GROUP_MIDI_OUT*1000 - 1;
else
sourcePort = RACK_PATCHBAY_PORT_MAX;

if (std::strncmp(connTarget, "Carla:", 6) == 0)
targetPort = getCarlaPortIdFromName(connTarget+6);
else if (std::strncmp(connTarget, "AudioIn:", 8) == 0)
targetPort = std::atoi(connTarget+8) + RACK_PATCHBAY_GROUP_AUDIO_IN*1000 - 1;
else if (std::strncmp(connTarget, "AudioOut:", 9) == 0)
targetPort = std::atoi(connTarget+9) + RACK_PATCHBAY_GROUP_AUDIO_OUT*1000 - 1;
else if (std::strncmp(connTarget, "MidiIn:", 7) == 0)
targetPort = std::atoi(connTarget+7) + RACK_PATCHBAY_GROUP_MIDI_IN*1000 - 1;
else if (std::strncmp(connTarget, "MidiOut:", 8) == 0)
targetPort = std::atoi(connTarget+8) + RACK_PATCHBAY_GROUP_MIDI_OUT*1000 - 1;
else
targetPort = RACK_PATCHBAY_PORT_MAX;

if (sourcePort != RACK_PATCHBAY_PORT_MAX && targetPort != RACK_PATCHBAY_PORT_MAX)
patchbayConnect(targetPort, sourcePort);
}
}

// -----------------------------------------------------------------------
// Bridge/Controller OSC stuff



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

@@ -347,6 +347,87 @@ void EngineRackBuffers::resize(const uint32_t bufferSize)
}
}

const char* const* EngineRackBuffers::getConnections() const
{
if (usedConnections.count() == 0)
return nullptr;

LinkedList<const char*> connList;
char strBuf[STR_MAX+1];

for (LinkedList<ConnectionToId>::Itenerator it=usedConnections.begin(); it.valid(); it.next())
{
const ConnectionToId& connection(it.getValue());

const int otherPort((connection.portOut >= 0) ? connection.portOut : connection.portIn);
const int carlaPort((otherPort == connection.portOut) ? connection.portIn : connection.portOut);

if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
{
CARLA_SAFE_ASSERT_CONTINUE(carlaPort == RACK_PATCHBAY_PORT_MIDI_IN);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);

std::sprintf(strBuf, "MidiOut:%i", portId+1);
connList.append(carla_strdup(strBuf));

connList.append(carla_strdup("Carla:MidiOut"));
}
else if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
{
CARLA_SAFE_ASSERT_CONTINUE(carlaPort == RACK_PATCHBAY_PORT_MIDI_OUT);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);

connList.append(carla_strdup("Carla:MidiIn"));

std::sprintf(strBuf, "MidiIn:%i", portId+1);
connList.append(carla_strdup(strBuf));
}
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
{
CARLA_SAFE_ASSERT_CONTINUE(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2);

const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);

std::sprintf(strBuf, "AudioOut:%i", portId+1);
connList.append(carla_strdup(strBuf));

connList.append(carla_strdup((carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) ? "Carla:AudioOut1" : "Carla:AudioOut2"));
}
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
{
CARLA_SAFE_ASSERT_CONTINUE(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2);

const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);

connList.append(carla_strdup((carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) ? "Carla:AudioIn1" : "Carla:AudioIn2"));

std::sprintf(strBuf, "AudioIn:%i", portId+1);
connList.append(carla_strdup(strBuf));
}
else
{
CARLA_SAFE_ASSERT_RETURN(false, nullptr);
}
}

const size_t connCount(connList.count());

if (connCount == 0)
return nullptr;

const char** const retConns = new const char*[connCount+1];

for (size_t i=0; i < connCount; ++i)
retConns[i] = connList.getAt(i);

retConns[connCount] = nullptr;
connList.clear();

return retConns;
}

// -----------------------------------------------------------------------
// EnginePatchbayBuffers

@@ -368,6 +449,11 @@ void EnginePatchbayBuffers::resize(const uint32_t /*bufferSize*/)
{
}

const char* const* EnginePatchbayBuffers::getConnections() const
{
return nullptr;
}

// -----------------------------------------------------------------------
// InternalAudio



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

@@ -96,6 +96,7 @@ struct EngineRackBuffers {
~EngineRackBuffers();
void clear();
void resize(const uint32_t bufferSize);
const char* const* getConnections() const;

CARLA_DECLARE_NON_COPY_STRUCT(EngineRackBuffers)
};
@@ -109,6 +110,7 @@ struct EnginePatchbayBuffers {
~EnginePatchbayBuffers();
void clear();
void resize(const uint32_t bufferSize);
const char* const* getConnections() const;

CARLA_DECLARE_NON_COPY_STRUCT(EnginePatchbayBuffers)
};


+ 1
- 1
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -890,7 +890,7 @@ protected:
return false;
}

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

private:
RtAudio fAudio;


Loading…
Cancel
Save