PatchBay.java

1
package com.github.dakusui.symfonion.cli.subcommands;
2
3
import com.github.dakusui.symfonion.cli.Cli;
4
import com.github.dakusui.symfonion.cli.MidiRouteRequest;
5
import com.github.dakusui.symfonion.cli.Subcommand;
6
import com.github.dakusui.symfonion.exceptions.CliException;
7
import com.github.dakusui.symfonion.exceptions.SymfonionException;
8
import com.github.dakusui.symfonion.utils.midi.MidiDeviceManager;
9
import com.github.dakusui.symfonion.utils.midi.MidiDeviceRecord;
10
import com.github.dakusui.symfonion.utils.midi.MidiDeviceReportFormatter;
11
12
import javax.sound.midi.MidiDevice;
13
import javax.sound.midi.MidiUnavailableException;
14
import javax.sound.midi.Receiver;
15
import javax.sound.midi.Transmitter;
16
import java.io.IOException;
17
import java.io.InputStream;
18
import java.io.PrintStream;
19
import java.util.Map;
20
import java.util.function.Predicate;
21
import java.util.regex.Pattern;
22
23
import static com.github.dakusui.symfonion.cli.CliUtils.composeErrMsg;
24
import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.failedToRetrieveTransmitterFromMidiIn;
25
import static com.github.dakusui.symfonion.utils.midi.MidiDeviceManager.isMidiDeviceForInput;
26
import static com.github.dakusui.symfonion.utils.midi.MidiDeviceManager.matchesPortNameInDefinitions;
27
import static com.github.dakusui.valid8j_pcond.forms.Predicates.and;
28
import static java.lang.String.format;
29
30
public class PatchBay implements Subcommand {
31
  @Override
32
  public void invoke(Cli cli, PrintStream ps, InputStream inputStream) throws SymfonionException, IOException {
33
    MidiRouteRequest route = cli.routeRequest();
34
35
    String inPortName = route.in();
36
    Map<String, Pattern> midiInDefinitions = requireMidiInDefinitionsContainsInputPortName(cli.midiInRegexPatterns(), inPortName);
37
38
    String outPortName = route.out();
39
    Map<String, Pattern> midiOutDefinitions = requireMidiOutDefinitionsContainsOutputPortName(cli.midiOutRegexPatterns(), outPortName);
40
41
    MidiDeviceManager midiDeviceManager = MidiDeviceManager.from(MidiDeviceReportFormatter.createDefaultInstance());
42
43
    MidiDeviceRecord midiInDevice = MidiDeviceManager.lookUpMidiDevice(isInputPortAndMatchesPortName(inPortName, midiInDefinitions), midiDeviceManager);
44
    MidiDeviceRecord midiOutDevice = MidiDeviceManager.lookUpMidiDevice(isOutputPortAndMatchesPortName(outPortName, midiOutDefinitions), midiDeviceManager);
45
46 1 1. invoke : removed call to com/github/dakusui/symfonion/cli/subcommands/PatchBay::route → KILLED
    route(midiInDevice, midiOutDevice, midiDeviceManager, ps, inputStream);
47
  }
48
49
  private static Predicate<MidiDeviceRecord> isOutputPortAndMatchesPortName(String outPortName, Map<String, Pattern> midiOutDefinitions) {
50 1 1. isOutputPortAndMatchesPortName : replaced return value with null for com/github/dakusui/symfonion/cli/subcommands/PatchBay::isOutputPortAndMatchesPortName → KILLED
    return and(MidiDeviceManager.isMidiDeviceForOutput(), matchesPortNameInDefinitions(outPortName, midiOutDefinitions));
51
  }
52
53
  private static Predicate<MidiDeviceRecord> isInputPortAndMatchesPortName(String inPortName, Map<String, Pattern> midiInDefinitions) {
54 1 1. isInputPortAndMatchesPortName : replaced return value with null for com/github/dakusui/symfonion/cli/subcommands/PatchBay::isInputPortAndMatchesPortName → KILLED
    return and(isMidiDeviceForInput(), matchesPortNameInDefinitions(inPortName, midiInDefinitions));
55
  }
56
57
  public static void route(MidiDeviceRecord input, MidiDeviceRecord output, MidiDeviceManager deviceManager, PrintStream ps, InputStream inputStream) {
58
    try (MidiDevice outMidiDevice = deviceManager.openMidiDevice(output)) {
59
      try (MidiDevice inMidiDevice = deviceManager.openMidiDevice(input)) {
60
        try (Receiver r = outMidiDevice.getReceiver()) {
61
          try (Transmitter t = inMidiDevice.getTransmitter()) {
62 1 1. route : removed call to javax/sound/midi/Transmitter::setReceiver → SURVIVED
            t.setReceiver(r);
63 1 1. route : removed call to java/io/PrintStream::println → KILLED
            ps.println("Now in MIDI patch-bay mode. Hit enter to quit.");
64
            //noinspection ResultOfMethodCallIgnored
65
            inputStream.read();
66
          } catch (IOException e) {
67
            ps.println("quitting due to an error.");
68
          } finally {
69
            ps.println("closing transmitter");
70
          }
71
        } catch (MidiUnavailableException e) {
72
          throw failedToRetrieveTransmitterFromMidiIn(e, inMidiDevice.getDeviceInfo());
73
        } finally {
74
          ps.println("closing receiver");
75
        }
76
      }
77
    }
78
  }
79
80
81
  private static Map<String, Pattern> requireMidiInDefinitionsContainsInputPortName(Map<String, Pattern> midiOutDefinitions, String inPortName) {
82 1 1. requireMidiInDefinitionsContainsInputPortName : negated conditional → KILLED
    if (!midiOutDefinitions.containsKey(inPortName)) {
83
      throw new CliException(composeErrMsg(format("MIDI-in port '%s' is specified, but it is not defined by '-I' option.", inPortName), "r", "--route"));
84
    }
85 1 1. requireMidiInDefinitionsContainsInputPortName : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/cli/subcommands/PatchBay::requireMidiInDefinitionsContainsInputPortName → KILLED
    return midiOutDefinitions;
86
  }
87
88
  private static Map<String, Pattern> requireMidiOutDefinitionsContainsOutputPortName(Map<String, Pattern> midiOutDefinitions, String outPortName) {
89 1 1. requireMidiOutDefinitionsContainsOutputPortName : negated conditional → KILLED
    if (!midiOutDefinitions.containsKey(outPortName)) {
90
      throw new CliException(composeErrMsg(format("MIDI-out port '%s' is specified, but it is not defined by '-O' option.", outPortName), "r", "route"));
91
    }
92 1 1. requireMidiOutDefinitionsContainsOutputPortName : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/cli/subcommands/PatchBay::requireMidiOutDefinitionsContainsOutputPortName → KILLED
    return midiOutDefinitions;
93
  }
94
}

Mutations

46

1.1
Location : invoke
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
removed call to com/github/dakusui/symfonion/cli/subcommands/PatchBay::route → KILLED

50

1.1
Location : isOutputPortAndMatchesPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
replaced return value with null for com/github/dakusui/symfonion/cli/subcommands/PatchBay::isOutputPortAndMatchesPortName → KILLED

54

1.1
Location : isInputPortAndMatchesPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
replaced return value with null for com/github/dakusui/symfonion/cli/subcommands/PatchBay::isInputPortAndMatchesPortName → KILLED

62

1.1
Location : route
Killed by : none
removed call to javax/sound/midi/Transmitter::setReceiver → SURVIVED

63

1.1
Location : route
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
removed call to java/io/PrintStream::println → KILLED

82

1.1
Location : requireMidiInDefinitionsContainsInputPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
negated conditional → KILLED

85

1.1
Location : requireMidiInDefinitionsContainsInputPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/cli/subcommands/PatchBay::requireMidiInDefinitionsContainsInputPortName → KILLED

89

1.1
Location : requireMidiOutDefinitionsContainsOutputPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
negated conditional → KILLED

92

1.1
Location : requireMidiOutDefinitionsContainsOutputPortName
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.whenPatchBay_thenOutputLooksOk(com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest)
replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/cli/subcommands/PatchBay::requireMidiOutDefinitionsContainsOutputPortName → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.3