diff --git a/src/main/java/sh/ball/audio/midi/MidiCommunicator.java b/src/main/java/sh/ball/audio/midi/MidiCommunicator.java new file mode 100644 index 0000000..ee93e12 --- /dev/null +++ b/src/main/java/sh/ball/audio/midi/MidiCommunicator.java @@ -0,0 +1,71 @@ +package sh.ball.audio.midi;// Java program showing the implementation of a simple record + +import javax.sound.midi.*; + +import java.util.ArrayList; +import java.util.List; + +public class MidiCommunicator implements Runnable { + + private final List devices = new ArrayList<>(); + private final List listeners = new ArrayList<>(); + + public static void main(String[] args) { + MidiCommunicator communicator = new MidiCommunicator(); + communicator.run(); + } + + @Override + public void run() { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (MidiDevice.Info info : infos) { + try { + MidiDevice device = MidiSystem.getMidiDevice(info); + List transmitters = device.getTransmitters(); + + transmitters.forEach(t -> t.setReceiver( + new MidiInputReceiver(this) + )); + + Transmitter trans = device.getTransmitter(); + trans.setReceiver(new MidiInputReceiver(this)); + + device.open(); + devices.add(device); + System.out.println(device.getDeviceInfo() + " Was Opened"); + + + } catch (MidiUnavailableException ignored) { + } + } + } + + public void addListener(MidiListener listener) { + listeners.add(listener); + } + + private void notifyListeners(int status, MidiNote note, int pressure) { + for (MidiListener listener : listeners) { + listener.sendMidiMessage(status, note, pressure); + } + System.out.println(status); + System.out.println(note); + System.out.println(pressure); + } + + public void stop() { + devices.forEach(MidiDevice::close); + } + + private record MidiInputReceiver( + MidiCommunicator communicator) implements Receiver { + + public void send(MidiMessage message, long timeStamp) { + byte[] rawMessage = message.getMessage(); + communicator.notifyListeners(message.getStatus(), new MidiNote(rawMessage[1]), rawMessage[2]); + } + + public void close() { + } + } +} \ No newline at end of file diff --git a/src/main/java/sh/ball/audio/midi/MidiListener.java b/src/main/java/sh/ball/audio/midi/MidiListener.java new file mode 100644 index 0000000..960ea78 --- /dev/null +++ b/src/main/java/sh/ball/audio/midi/MidiListener.java @@ -0,0 +1,6 @@ +package sh.ball.audio.midi; + +public interface MidiListener { + + void sendMidiMessage(int status, MidiNote note, int pressure); +} diff --git a/src/main/java/sh/ball/audio/midi/MidiNote.java b/src/main/java/sh/ball/audio/midi/MidiNote.java new file mode 100644 index 0000000..f6a58fd --- /dev/null +++ b/src/main/java/sh/ball/audio/midi/MidiNote.java @@ -0,0 +1,41 @@ +package sh.ball.audio.midi; + +import java.util.Objects; + +public class MidiNote { + + private static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; + + private final String name; + private final int key; + private final int octave; + + public MidiNote(int key) { + this.key = key; + this.octave = (key / 12)-1; + int note = key % 12; + this.name = NOTE_NAMES[note]; + } + + public int getKey() { + return key; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MidiNote midiNote = (MidiNote) o; + return key == midiNote.key && octave == midiNote.octave && name.equals(midiNote.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, key, octave); + } + + @Override + public String toString() { + return "Note -> " + this.name + this.octave + " key=" + this.key; + } +}