public void play(String name, String version, String vendor, String desc) throws Exception { Info port = null; for (Info info : MidiSystem.getMidiDeviceInfo()) { if (name == null && version == null && vendor == null && desc == null) { System.err.println( "At least one of name, version, vendor, or description must be specified."); break; } if (name != null && !info.getName().equals(name)) { continue; } if (vendor != null && !info.getVendor().equals(vendor)) { continue; } if (version != null && !info.getVersion().equals(version)) { continue; } if (desc != null && !info.getDescription().equals(desc)) { continue; } try (MidiDevice dev = MidiSystem.getMidiDevice(info)) { Receiver r = null; try { r = dev.getReceiver(); } catch (Exception e) { r = null; } if (r == null) { continue; } } if (port != null) { System.err.println( "Multiple MIDI ports match the given parameters. Please be more specific."); port = null; break; } port = info; continue; } if (port == null) { System.err.println("Unable to locate MIDI port"); System.err.println("Available ports:"); for (Info info : MidiSystem.getMidiDeviceInfo()) { try (MidiDevice dev = MidiSystem.getMidiDevice(info)) { Receiver r = null; try { r = dev.getReceiver(); } catch (Exception e) { r = null; } if (r == null) { continue; } } System.out.println( "Device [name=" + info.getName() + ", version=" + info.getVersion() + ", vendor=" + info.getVendor() + ", desc=" + info.getDescription() + "]"); } return; } System.out.println( "Using device [name=" + port.getName() + ", version=" + port.getVersion() + ", vendor=" + port.getVendor() + ", desc=" + port.getDescription() + "]"); try (MidiDevice dev = MidiSystem.getMidiDevice(port)) { int channel = CHANNEL_RAW_STEREO; dev.open(); try (Receiver rx = dev.getReceiver()) { rxCleanup = rx; try (DataInputStream dis = new DataInputStream(new FileInputStream(ymz))) { resetController(rx, channel, registers); long startTime = System.nanoTime(); // read a buffer long prevClock = 0; while (true) { long clock = dis.readLong(); byte register = dis.readByte(); byte value = dis.readByte(); if (prevClock != clock) { sendAll(rx, channel, registers); prevClock = clock; } sleepUntil(startTime, clock); System.out.println( "Clock: " + clock + " register: " + register + ", value: " + (value & 0xff)); if (register < 0 || register > 13) { System.err.println("Invalid register " + register + " found, ignoring."); continue; } registers[register] = value; } } catch (EOFException e) { System.err.println("EOF reached"); } finally { resetController(rx, channel, registers); rxCleanup = null; } } } }