From 9c45541e01728bd58414ccd9ea97e768ba1e1668 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 25 Dec 2017 18:50:16 +0000 Subject: [PATCH] libjack: show all system audio and midi ports; Misc changes --- source/libjack/libjack.hpp | 26 +++-- source/libjack/libjack_port-searching.cpp | 128 +++++++++++++++++----- source/libjack/libjack_ports.cpp | 108 +++++++++++------- source/modules/water/text/StringArray.cpp | 15 ++- source/modules/water/text/StringArray.h | 6 +- source/utils/CarlaStringList.hpp | 39 +++++++ 6 files changed, 232 insertions(+), 90 deletions(-) diff --git a/source/libjack/libjack.hpp b/source/libjack/libjack.hpp index d7ffecde5..a560c77d4 100644 --- a/source/libjack/libjack.hpp +++ b/source/libjack/libjack.hpp @@ -100,6 +100,7 @@ struct JackPortState { void* buffer; uint index; uint flags; + jack_uuid_t uuid; bool isMidi : 1; bool isSystem : 1; bool isConnected : 1; @@ -111,34 +112,39 @@ struct JackPortState { buffer(nullptr), index(0), flags(0), + uuid(0), isMidi(false), isSystem(false), isConnected(false), unused(false) {} - JackPortState(const char* const cn, const char* const pn, const uint i, const uint f, + JackPortState(const char* const clientName, const char* const portName, const uint i, const uint f, const bool midi, const bool sys, const bool con) - : name(strdup(pn)), + : name(portName != nullptr ? strdup(portName) : nullptr), fullname(nullptr), buffer(nullptr), index(i), flags(f), + uuid(0), isMidi(midi), isSystem(sys), isConnected(con), unused(false) { - char strBuf[STR_MAX+1]; - snprintf(strBuf, STR_MAX, "%s:%s", cn, pn); - strBuf[STR_MAX] = '\0'; + if (clientName != nullptr && portName != nullptr) + { + char strBuf[STR_MAX+1]; + snprintf(strBuf, STR_MAX, "%s:%s", clientName, portName); + strBuf[STR_MAX] = '\0'; - fullname = strdup(strBuf); + fullname = strdup(strBuf); + } } ~JackPortState() { - free(name); - free(fullname); + std::free(name); + std::free(fullname); } CARLA_DECLARE_NON_COPY_STRUCT(JackPortState) @@ -232,11 +238,13 @@ struct JackClientState { delete jport; } - free(name); + std::free(name); name = nullptr; audioIns.clear(); audioOuts.clear(); + midiIns.clear(); + midiOuts.clear(); } CARLA_DECLARE_NON_COPY_STRUCT(JackClientState) diff --git a/source/libjack/libjack_port-searching.cpp b/source/libjack/libjack_port-searching.cpp index 5a4b2ccb3..542eeff06 100644 --- a/source/libjack/libjack_port-searching.cpp +++ b/source/libjack/libjack_port-searching.cpp @@ -17,10 +17,28 @@ #include "libjack.hpp" +#include "CarlaStringList.hpp" + CARLA_BACKEND_USE_NAMESPACE // -------------------------------------------------------------------------------------------------------------------- +const char* allocate_port_name(const char* const prefix, const uint32_t num) +{ + static CarlaStringList portList; + + char portName[STR_MAX]; + carla_zeroChars(portName, STR_MAX); + std::snprintf(portName, STR_MAX-1, "%s%u", prefix, num+1); + + if (const char* const storedPortName = portList.containsAndReturnString(portName)) + return storedPortName; + + CARLA_SAFE_ASSERT_RETURN(portList.append(portName), nullptr); + + return portList.getLast(); +} + CARLA_EXPORT const char** jack_get_ports(jack_client_t* client, const char* a, const char* b, unsigned long flags) { @@ -29,42 +47,53 @@ const char** jack_get_ports(jack_client_t* client, const char* a, const char* b, JackClientState* const jclient = (JackClientState*)client; CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr); - static const char* capture_1 = "system:capture_1"; - static const char* capture_2 = "system:capture_2"; - static const char* playback_1 = "system:playback_1"; - static const char* playback_2 = "system:playback_2"; + const JackServerState& jserver(jclient->server); + + const uint32_t numIns = jserver.numAudioIns + jserver.numMidiIns; + const uint32_t numOuts = jserver.numAudioOuts + jserver.numMidiOuts; if (flags == 0 || (flags & (JackPortIsInput|JackPortIsOutput)) == (JackPortIsInput|JackPortIsOutput)) { - if (const char** const ret = (const char**)calloc(5, sizeof(const char*))) + if (const char** const ret = (const char**)calloc(numIns+numOuts, sizeof(const char*))) { - ret[0] = capture_1; - ret[1] = capture_2; - ret[2] = playback_1; - ret[3] = playback_2; - ret[4] = nullptr; + uint32_t i=0; + for (uint32_t j=0; jserver); const int commonFlags = JackPortIsPhysical|JackPortIsTerminal; - static const JackPortState capturePorts[] = { - { "system", "capture_1", 0, JackPortIsOutput|commonFlags, false, true, jserver.numAudioIns > 0 }, - { "system", "capture_2", 1, JackPortIsOutput|commonFlags, false, true, jserver.numAudioIns > 1 }, - }; - static const JackPortState playbackPorts[] = { - { "system", "playback_1", 3, JackPortIsInput|commonFlags, false, true, jserver.numAudioOuts > 0 }, - { "system", "playback_2", 4, JackPortIsInput|commonFlags, false, true, jserver.numAudioOuts > 1 }, - }; + static JackPortState retPort( + /* name */ nullptr, + /* fullname */ nullptr, + /* index */ 0, + /* flags */ 0x0, + /* isMidi */ false, + /* isSystem */ true, + /* isConnected */ false + ); if (std::strncmp(name, "system:", 7) == 0) { + std::free(retPort.fullname); + retPort.fullname = strdup(name); + name += 7; + std::free(retPort.name); + retPort.name = strdup(name); + /**/ if (std::strncmp(name, "capture_", 8) == 0) { name += 8; const int index = std::atoi(name)-1; - CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < 2, nullptr); + CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < jserver.numAudioIns, nullptr); - return (jack_port_t*)&capturePorts[index]; + retPort.index = index; + retPort.flags = commonFlags|JackPortIsOutput; + retPort.isMidi = false; + retPort.isConnected = jserver.numAudioIns > index; } else if (std::strncmp(name, "playback_", 9) == 0) { name += 9; const int index = std::atoi(name)-1; - CARLA_SAFE_ASSERT_RETURN(index >= 0, nullptr); + CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < jserver.numAudioOuts, nullptr); + + retPort.index = (jserver.numAudioIns) + index; + retPort.flags = commonFlags|JackPortIsInput; + retPort.isMidi = false; + retPort.isConnected = jserver.numAudioOuts > index; + } + else if (std::strncmp(name, "midi_capture_", 13) == 0) + { + name += 13; + + const int index = std::atoi(name)-1; + CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < jserver.numAudioIns, nullptr); - return (jack_port_t*)&playbackPorts[index]; + retPort.index = index; + retPort.flags = commonFlags|JackPortIsOutput; + retPort.isMidi = true; + retPort.isConnected = jserver.numMidiIns > index; + } + else if (std::strncmp(name, "midi_playback_", 14) == 0) + { + name += 14; + + const int index = std::atoi(name)-1; + CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < jserver.numAudioOuts, nullptr); + + retPort.index = (jserver.numAudioIns) + index; + retPort.flags = commonFlags|JackPortIsInput; + retPort.isMidi = true; + retPort.isConnected = jserver.numMidiOuts > index; } else { carla_stderr2("jack_port_by_name: invalid port short name '%s'", name); return nullptr; } + + return (jack_port_t*)&retPort; } carla_stderr2("jack_port_by_name: invalid port name '%s'", name); diff --git a/source/libjack/libjack_ports.cpp b/source/libjack/libjack_ports.cpp index 08e9239c1..e73d6a205 100644 --- a/source/libjack/libjack_ports.cpp +++ b/source/libjack/libjack_ports.cpp @@ -43,9 +43,11 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co JackPortState* const port = new JackPortState(jclient->name, port_name, index, flags, false, false, index < jserver.numAudioIns); - const CarlaMutexLocker cms(jclient->mutex); + { + const CarlaMutexLocker cms(jclient->mutex); + jclient->audioIns.append(port); + } - jclient->audioIns.append(port); return (jack_port_t*)port; } @@ -55,9 +57,11 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co JackPortState* const port = new JackPortState(jclient->name, port_name, index, flags, false, false, index < jserver.numAudioOuts); - const CarlaMutexLocker cms(jclient->mutex); + { + const CarlaMutexLocker cms(jclient->mutex); + jclient->audioOuts.append(port); + } - jclient->audioOuts.append(port); return (jack_port_t*)port; } @@ -73,9 +77,11 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co JackPortState* const port = new JackPortState(jclient->name, port_name, index, flags, true, false, index < jserver.numMidiIns); - const CarlaMutexLocker cms(jclient->mutex); + { + const CarlaMutexLocker cms(jclient->mutex); + jclient->midiIns.append(port); + } - jclient->midiIns.append(port); return (jack_port_t*)port; } @@ -85,9 +91,11 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co JackPortState* const port = new JackPortState(jclient->name, port_name, index, flags, true, false, index < jserver.numMidiOuts); - const CarlaMutexLocker cms(jclient->mutex); + { + const CarlaMutexLocker cms(jclient->mutex); + jclient->midiOuts.append(port); + } - jclient->midiOuts.append(port); return (jack_port_t*)port; } @@ -108,45 +116,47 @@ int jack_port_unregister(jack_client_t* client, jack_port_t* port) carla_debug("%s(%p, %p)", __FUNCTION__, client, port); JackClientState* const jclient = (JackClientState*)client; - CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1); + CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, EINVAL); JackPortState* const jport = (JackPortState*)port; - CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 1); - CARLA_SAFE_ASSERT_RETURN(! jport->isSystem, 1); + CARLA_SAFE_ASSERT_RETURN(jport != nullptr, EINVAL); + CARLA_SAFE_ASSERT_RETURN(! jport->isSystem, EINVAL); - const CarlaMutexLocker cms(jclient->mutex); - - if (jport->isMidi) { - if (jport->flags & JackPortIsInput) - { - CARLA_SAFE_ASSERT_RETURN(jclient->midiIns.removeOne(jport), 1); - return 0; - } + const CarlaMutexLocker cms(jclient->mutex); - if (jport->flags & JackPortIsOutput) - { - CARLA_SAFE_ASSERT_RETURN(jclient->midiOuts.removeOne(jport), 1); - return 0; - } - } - else - { - if (jport->flags & JackPortIsInput) + if (jport->isMidi) { - CARLA_SAFE_ASSERT_RETURN(jclient->audioIns.removeOne(jport), 1); - return 0; + if (jport->flags & JackPortIsInput) + { + CARLA_SAFE_ASSERT_RETURN(jclient->midiIns.removeOne(jport), ENOENT); + return 0; + } + + if (jport->flags & JackPortIsOutput) + { + CARLA_SAFE_ASSERT_RETURN(jclient->midiOuts.removeOne(jport), ENOENT); + return 0; + } } - - if (jport->flags & JackPortIsOutput) + else { - CARLA_SAFE_ASSERT_RETURN(jclient->audioOuts.removeOne(jport), 1); - return 0; + if (jport->flags & JackPortIsInput) + { + CARLA_SAFE_ASSERT_RETURN(jclient->audioIns.removeOne(jport), ENOENT); + return 0; + } + + if (jport->flags & JackPortIsOutput) + { + CARLA_SAFE_ASSERT_RETURN(jclient->audioOuts.removeOne(jport), ENOENT); + return 0; + } } } carla_stderr2("jack_port_register: invalid port '%s'", jport->name); - return 1; + return EINVAL; } CARLA_EXPORT @@ -163,8 +173,12 @@ void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t) CARLA_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t* port) { - carla_stderr2("%s(%p)", __FUNCTION__, port); - return 0; + carla_debug("%s(%p)", __FUNCTION__, port); + + JackPortState* const jport = (JackPortState*)port; + CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0); + + return jport->uuid; } CARLA_EXPORT @@ -248,7 +262,15 @@ int jack_port_connected(const jack_port_t* port) CARLA_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name) { - carla_stderr2("%s(%p, %s)", __FUNCTION__, port, port_name); + carla_stderr2("%s(%p, %s) WIP", __FUNCTION__, port, port_name); + + JackPortState* const jport = (JackPortState*)port; + CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0); + + if (! jport->isConnected) + return 0; + + // TODO return 1; } @@ -273,15 +295,21 @@ const char** jack_port_get_all_connections(const jack_client_t* client, const ja CARLA_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) { - carla_stderr2("%s(%p, %p)", __FUNCTION__, src, dst); + carla_debug("%s(%p, %p)", __FUNCTION__, src, dst); return ENOSYS; + + // unused + (void)src; (void)dst; } CARLA_EXPORT int jack_port_untie(jack_port_t* port) { - carla_stderr2("%s(%p)", __FUNCTION__, port); + carla_debug("%s(%p)", __FUNCTION__, port); return ENOSYS; + + // unused + (void)port; } // -------------------------------------------------------------------------------------------------------------------- diff --git a/source/modules/water/text/StringArray.cpp b/source/modules/water/text/StringArray.cpp index 2e7537a55..e06875bb3 100644 --- a/source/modules/water/text/StringArray.cpp +++ b/source/modules/water/text/StringArray.cpp @@ -120,21 +120,21 @@ String& StringArray::getReference (const int index) noexcept return strings.getReference (index); } -void StringArray::add (const String& newString) +bool StringArray::add (const String& newString) { - strings.add (newString); + return strings.add (newString); } #if WATER_COMPILER_SUPPORTS_MOVE_SEMANTICS -void StringArray::add (String&& stringToAdd) +bool StringArray::add (String&& stringToAdd) { - strings.add (static_cast (stringToAdd)); + return strings.add (static_cast (stringToAdd)); } #endif -void StringArray::insert (const int index, const String& newString) +bool StringArray::insert (const int index, const String& newString) { - strings.insert (index, newString); + return strings.insert (index, newString); } bool StringArray::addIfNotAlreadyThere (const String& newString, const bool ignoreCase) @@ -142,8 +142,7 @@ bool StringArray::addIfNotAlreadyThere (const String& newString, const bool igno if (contains (newString, ignoreCase)) return false; - add (newString); - return true; + return add (newString); } void StringArray::addArray (const StringArray& otherArray, int startIndex, int numElementsToAdd) diff --git a/source/modules/water/text/StringArray.h b/source/modules/water/text/StringArray.h index e7de81cff..70944384f 100644 --- a/source/modules/water/text/StringArray.h +++ b/source/modules/water/text/StringArray.h @@ -157,11 +157,11 @@ public: //============================================================================== /** Appends a string at the end of the array. */ - void add (const String& stringToAdd); + bool add (const String& stringToAdd); #if WATER_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Appends a string at the end of the array. */ - void add (String&& stringToAdd); + bool add (String&& stringToAdd); #endif /** Inserts a string into the array. @@ -171,7 +171,7 @@ public: If the index is less than zero or greater than the size of the array, the new string will be added to the end of the array. */ - void insert (int index, const String& stringToAdd); + bool insert (int index, const String& stringToAdd); /** Adds a string to the array as long as it's not already in there. The search can optionally be case-insensitive. diff --git a/source/utils/CarlaStringList.hpp b/source/utils/CarlaStringList.hpp index 1df1472a2..d53abb6c0 100644 --- a/source/utils/CarlaStringList.hpp +++ b/source/utils/CarlaStringList.hpp @@ -259,6 +259,26 @@ public: return data->value; } + const char* getFirst() const noexcept + { + CARLA_SAFE_ASSERT_RETURN(fCount > 0, nullptr); + + const Data* const data(list_entry_const(fQueue.next, Data, siblings)); + CARLA_SAFE_ASSERT_RETURN(data != nullptr, nullptr); + + return data->value; + } + + const char* getLast() const noexcept + { + CARLA_SAFE_ASSERT_RETURN(fCount > 0, nullptr); + + const Data* const data(list_entry_const(fQueue.prev, Data, siblings)); + CARLA_SAFE_ASSERT_RETURN(data != nullptr, nullptr); + + return data->value; + } + // ------------------------------------------------------------------- bool contains(const char* const string) noexcept @@ -280,6 +300,25 @@ public: return false; } + const char* containsAndReturnString(const char* const string) noexcept + { + CARLA_SAFE_ASSERT_RETURN(string != nullptr, nullptr); + + if (fCount == 0) + return nullptr; + + for (Itenerator it = begin2(); it.valid(); it.next()) + { + const char* const stringComp(it.getValue(nullptr)); + CARLA_SAFE_ASSERT_CONTINUE(stringComp != nullptr); + + if (std::strcmp(string, stringComp) == 0) + return stringComp; + } + + return nullptr; + } + // ------------------------------------------------------------------- void remove(Itenerator& it) noexcept