# HG changeset patch # User František Kučera # Date 1602168350 -7200 # Node ID 326935d1bfab1df006a6ee07471fceb98683978f # Parent e8aae4d42c01d3cc6c8d9b378bc17c069a86e620 add option --list-connections for listing JACK connections the output can be later sent to the relpipe-out-jack to restore the connection graph diff -r e8aae4d42c01 -r 326935d1bfab bash-completion.sh --- a/bash-completion.sh Wed Oct 07 22:29:38 2020 +0200 +++ b/bash-completion.sh Thu Oct 08 16:45:50 2020 +0200 @@ -43,6 +43,7 @@ elif [[ "$w1" == "--connect-to" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports)" -- "$w0")) elif [[ "$w1" == "--required-connections" && "x$w0" == "x" ]]; then COMPREPLY=("0") elif [[ "$w1" == "--list-ports" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) + elif [[ "$w1" == "--list-connections" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) elif [[ "$w1" == "--list-midi-messages" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) else OPTIONS=( @@ -51,6 +52,7 @@ "--connect-to" "--required-connections" "--list-ports" + "--list-connections" "--list-midi-messages" ) COMPREPLY=($(compgen -W "${OPTIONS[*]}" -- "$w0")) diff -r e8aae4d42c01 -r 326935d1bfab src/CLIParser.h --- a/src/CLIParser.h Wed Oct 07 22:29:38 2020 +0200 +++ b/src/CLIParser.h Thu Oct 08 16:45:50 2020 +0200 @@ -53,6 +53,7 @@ static const relpipe::common::type::StringX OPTION_CONNECT_TO; static const relpipe::common::type::StringX OPTION_REQUIRED_CONNECTIONS; static const relpipe::common::type::StringX OPTION_LIST_PORTS; + static const relpipe::common::type::StringX OPTION_LIST_CONNECTIONS; static const relpipe::common::type::StringX OPTION_LIST_MIDI_MESSAGES; Configuration parse(const std::vector& arguments) { @@ -71,6 +72,8 @@ c.requiredConnections = std::stoi(readNext(arguments, i)); } else if (option == OPTION_LIST_PORTS) { c.listPorts = parseBoolean(readNext(arguments, i)); + } else if (option == OPTION_LIST_CONNECTIONS) { + c.listConnections = parseBoolean(readNext(arguments, i)); } else if (option == OPTION_LIST_MIDI_MESSAGES) { c.listMidiMessages = parseBoolean(readNext(arguments, i)); } else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); @@ -88,6 +91,7 @@ const relpipe::common::type::StringX CLIParser::OPTION_CONNECT_TO = L"--connect-to"; const relpipe::common::type::StringX CLIParser::OPTION_REQUIRED_CONNECTIONS = L"--required-connections"; const relpipe::common::type::StringX CLIParser::OPTION_LIST_PORTS = L"--list-ports"; +const relpipe::common::type::StringX CLIParser::OPTION_LIST_CONNECTIONS = L"--list-connections"; const relpipe::common::type::StringX CLIParser::OPTION_LIST_MIDI_MESSAGES = L"--list-midi-messages"; } diff -r e8aae4d42c01 -r 326935d1bfab src/Configuration.h --- a/src/Configuration.h Wed Oct 07 22:29:38 2020 +0200 +++ b/src/Configuration.h Thu Oct 08 16:45:50 2020 +0200 @@ -39,6 +39,7 @@ std::vector connectTo; int requiredConnections = 0; relpipe::common::type::Boolean listPorts = false; + relpipe::common::type::Boolean listConnections = false; relpipe::common::type::Boolean listMidiMessages = true; virtual ~Configuration() { diff -r e8aae4d42c01 -r 326935d1bfab src/JackCommand.h --- a/src/JackCommand.h Wed Oct 07 22:29:38 2020 +0200 +++ b/src/JackCommand.h Thu Oct 08 16:45:50 2020 +0200 @@ -187,7 +187,7 @@ writer->startRelation(L"port", metadata, true); const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0); - + std::regex midiTypePattern(".*midi$"); for (const char** portName = portNames; *portName; portName++) { @@ -216,6 +216,36 @@ jack_free(portNames); } + void listConnections(std::shared_ptr writer) { + using namespace relpipe::writer; + vector metadata; + + metadata.push_back({L"event", TypeId::STRING}); + metadata.push_back({L"source_port", TypeId::STRING}); + metadata.push_back({L"destination_port", TypeId::STRING}); + writer->startRelation(L"connection", metadata, true); + + const relpipe::common::type::StringX event = L"connect"; + + const char** sourcePortNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, JackPortFlags::JackPortIsOutput); + + for (const char** sourcePortName = sourcePortNames; *sourcePortName; sourcePortName++) { + jack_port_t* sourcePort = jack_port_by_name(realTimeContext.jackClient, *sourcePortName); + + const char** destinationPortNames = jack_port_get_all_connections(realTimeContext.jackClient, sourcePort); + + for (const char** destinationPortName = destinationPortNames; destinationPortNames && *destinationPortName; destinationPortName++) { + writer->writeAttribute(event); + writer->writeAttribute(convertor.from_bytes(*sourcePortName)); + writer->writeAttribute(convertor.from_bytes(*destinationPortName)); + } + + jack_free(destinationPortNames); + } + + jack_free(sourcePortNames); + } + static void jackErrorCallback(const char * message) { std::wstring_convert < std::codecvt_utf8> convertor; // TODO: local system encoding std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl; @@ -282,6 +312,7 @@ vector metadata; if (configuration.listPorts) listPorts(writer); + if (configuration.listConnections) listConnections(writer); if (!configuration.listMidiMessages) return; metadata.push_back({L"event", TypeId::STRING});