# HG changeset patch # User František Kučera # Date 1602170587 -7200 # Node ID cde9bb07ea0a919171f602e26642f63ea35b15bf # Parent 326935d1bfab1df006a6ee07471fceb98683978f add options --connect-ports and --disconnect-ports to allow connecting and disconnecting arbitrary JACK ports diff -r 326935d1bfab -r cde9bb07ea0a bash-completion.sh --- a/bash-completion.sh Thu Oct 08 16:45:50 2020 +0200 +++ b/bash-completion.sh Thu Oct 08 17:23:07 2020 +0200 @@ -20,7 +20,7 @@ relpipe-in-jack --list-ports true --list-midi-messages false 2>/dev/null \ | relpipe-out-nullbyte \ | while _relpipe_in_jack_completion_read_nullbyte "name" "input" "output" "physical" "terminal" "mine" "midi" "type"; do - if [[ "$midi" = "true" && "$output" = "true" && "$mine" = "false" ]]; then echo "$name"; fi; done + if [[ "$midi" = "true" && "${!1}" = "true" && "$mine" = "false" ]]; then echo "$name"; fi; done fi } @@ -40,7 +40,11 @@ if [[ "$w1" == "--client" && "x$w0" == "x" ]]; then COMPREPLY=("'relpipe-in-jack'") elif [[ "$w1" == "--port" && "x$w0" == "x" ]]; then COMPREPLY=("'midi-in'") - elif [[ "$w1" == "--connect-to" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports)" -- "$w0")) + elif [[ "$w1" == "--connect-to" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports output)" -- "$w0")) + elif [[ "$w1" == "--connect-ports" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports output)" -- "$w0")) + elif [[ "$w2" == "--connect-ports" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports input)" -- "$w0")) + elif [[ "$w1" == "--disconnect-ports" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports output)" -- "$w0")) + elif [[ "$w2" == "--disconnect-ports" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports input)" -- "$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")) @@ -50,6 +54,8 @@ "--client" "--port" "--connect-to" + "--connect-ports" + "--disconnect-ports" "--required-connections" "--list-ports" "--list-connections" diff -r 326935d1bfab -r cde9bb07ea0a src/CLIParser.h --- a/src/CLIParser.h Thu Oct 08 16:45:50 2020 +0200 +++ b/src/CLIParser.h Thu Oct 08 17:23:07 2020 +0200 @@ -51,6 +51,8 @@ static const relpipe::common::type::StringX OPTION_CLIENT; static const relpipe::common::type::StringX OPTION_PORT; static const relpipe::common::type::StringX OPTION_CONNECT_TO; + static const relpipe::common::type::StringX OPTION_CONNECT_PORTS; + static const relpipe::common::type::StringX OPTION_DISCONNECT_PORTS; 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; @@ -68,6 +70,8 @@ c.port = readNext(arguments, i); } else if (option == OPTION_CONNECT_TO) { c.connectTo.push_back(readNext(arguments, i)); + } else if (option == OPTION_CONNECT_PORTS || option == OPTION_DISCONNECT_PORTS) { + c.connectionRecipes.push_back({option == OPTION_CONNECT_PORTS, readNext(arguments, i), readNext(arguments, i)}); } else if (option == OPTION_REQUIRED_CONNECTIONS) { c.requiredConnections = std::stoi(readNext(arguments, i)); } else if (option == OPTION_LIST_PORTS) { @@ -89,6 +93,8 @@ const relpipe::common::type::StringX CLIParser::OPTION_CLIENT = L"--client"; const relpipe::common::type::StringX CLIParser::OPTION_PORT = L"--port"; const relpipe::common::type::StringX CLIParser::OPTION_CONNECT_TO = L"--connect-to"; +const relpipe::common::type::StringX CLIParser::OPTION_CONNECT_PORTS = L"--connect-ports"; +const relpipe::common::type::StringX CLIParser::OPTION_DISCONNECT_PORTS = L"--disconnect-ports"; 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"; diff -r 326935d1bfab -r cde9bb07ea0a src/Configuration.h --- a/src/Configuration.h Thu Oct 08 16:45:50 2020 +0200 +++ b/src/Configuration.h Thu Oct 08 17:23:07 2020 +0200 @@ -28,15 +28,22 @@ class Configuration { public: - - enum class PortType { - MIDI_INPUT, - MIDI_OUTPUT + + class ConnectionRecipe { + public: + bool connected; + relpipe::common::type::StringX sourcePort; + relpipe::common::type::StringX destinationPort; + + ConnectionRecipe(bool connected, relpipe::common::type::StringX sourcePort, relpipe::common::type::StringX destinationPort) : connected(connected), sourcePort(sourcePort), destinationPort(destinationPort) { + } + }; - + relpipe::common::type::StringX client = L"relpipe-in-jack"; relpipe::common::type::StringX port = L"midi-in"; std::vector connectTo; + std::vector connectionRecipes; int requiredConnections = 0; relpipe::common::type::Boolean listPorts = false; relpipe::common::type::Boolean listConnections = false; diff -r 326935d1bfab -r cde9bb07ea0a src/JackCommand.h --- a/src/JackCommand.h Thu Oct 08 16:45:50 2020 +0200 +++ b/src/JackCommand.h Thu Oct 08 17:23:07 2020 +0200 @@ -246,6 +246,14 @@ jack_free(sourcePortNames); } + void applyConnectionRecipes() { + for (Configuration::ConnectionRecipe recipe : configuration.connectionRecipes) { + auto operation = recipe.connected ? jack_connect : jack_disconnect; + int result = operation(realTimeContext.jackClient, convertor.to_bytes(recipe.sourcePort).c_str(), convertor.to_bytes(recipe.destinationPort).c_str()); + if (result != 0 && result != EEXIST) std::wcerr << L"Unable to " << (recipe.connected ? L"connect" : L"disconnect") << L": „" << recipe.sourcePort << L"“ to: „" << recipe.destinationPort << L"“." << std::endl; + } + } + 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; @@ -311,6 +319,8 @@ using namespace relpipe::writer; vector metadata; + applyConnectionRecipes(); + if (configuration.listPorts) listPorts(writer); if (configuration.listConnections) listConnections(writer); if (!configuration.listMidiMessages) return;