Skip to content

Commit

Permalink
Fill in placeholders in input port patterns with matches from named r…
Browse files Browse the repository at this point in the history
…egex groups in output port patterns

Signed-off-by: Christopher Arndt <[email protected]>
  • Loading branch information
SpotlightKid committed Oct 21, 2016
1 parent 39a96aa commit 50ff93a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 11 deletions.
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ Automatically connect the first two ports of Fluidsynth to the audio outs::
jack-matchmaker "fluidsynth:l_01" "system:playback_1" \
"fluidsynth:r_01" "system:playback_2"

Both the output port and the input port patterns can be regular expressions.
If a match is found on an output port, the matching port will be connected to
all input ports, which match the corresponding input port pattern::

jack-matchmaker "fluidsynth:l_\d+" "system:playback_[13]" \
"fluidsynth:r_\d+" "system:playback_[24]"

You can also use named regular expression groups in the output port pattern and
fill the strings they match to into placeholders in the input port pattern::

jack-matchmaker "system:midi_capture_(?P<num>\d+)" \
"mydaw:midi_in_track_{num}"

Run ``jack-matchmaker -h`` (or ``--help``) to show help on the available
command line options.

Expand Down
45 changes: 34 additions & 11 deletions jackmatchmaker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import re
import sys

from collections import defaultdict
from itertools import chain

try:
Expand All @@ -34,7 +35,10 @@ def flatten(nestedlist):

class JackMatchmaker(object):
def __init__(self, patterns, name="jack-matchmaker"):
self.patterns = patterns
self.patterns = []
for pair in patterns:
self.add_patterns(*pair)

self.queue = queue.Queue()
status = jacklib.jack_status_t()
self.client = jacklib.client_open("jack-matchmaker", jacklib.JackNoStartServer, status)
Expand All @@ -49,6 +53,14 @@ def close(self):
jacklib.deactivate(self.client)
return jacklib.client_close(self.client)

def add_patterns(self, ptn_output, ptn_input):
try:
ptn_output = re.compile(ptn_output)
except re.error:
log.error("Error in output port pattern '%s': %s", ptn_output, exc)
else:
self.patterns.append((ptn_output, ptn_input))

def reg_callback(self, port_id, action, *args):
if action == 0:
return
Expand All @@ -58,18 +70,29 @@ def reg_callback(self, port_id, action, *args):
outputs = list(flatten(self.get_ports(jacklib.JackPortIsOutput)))
log.debug("Outputs:\n%s", "\n".join(outputs))

for left, right in self.patterns:
for ptn_output, ptn_input in self.patterns:
for output in outputs:
log.debug("Checking output '%s' against pattern '%s'.", output, left)
match = re.match(left, output, re.I)
if match:
log.info("Found matching output port: %s.", output)
log.debug("Checking output '%s' against pattern '%s'.", output, ptn_output)
match_output = ptn_output.match(output)
if match_output:
log.debug("Found matching output port: %s.", output)
for input in inputs:
log.debug("Checking input '%s' against pattern '%s'.", input, right)
match = re.match(right, input, re.I)
if match:
log.info("Found matching input port: %s.", input)
self.queue.put((output, input))
# try to fill-in groups matches from output port
# pattern into input port pattern
subst = defaultdict(str, **match_output.groupdict())
rx_input = ptn_input.format_map(subst)

log.debug("Checking input '%s' against pattern '%s'.", input, ptn_input)

try:
rx_input = re.compile(rx_input)
except re.error:
log.error("Error in input port pattern '%s': %s", rx_input, exc)
else:
match_input = rx_input.match(input)
if match_input:
log.debug("Found matching input port: %s.", input)
self.queue.put((output, input))

def get_ports(self, type_=jacklib.JackPortIsOutput, include_aliases=True):
for port_name in jacklib.get_ports(self.client, '', '', type_):
Expand Down

0 comments on commit 50ff93a

Please sign in to comment.