-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Note: this post has been rewritten for clarity.
Say you have two physical devices (same manufacturer, same model). It is very difficult to figure out which MIDIDevice.Info belongs to which device. Oracle Java's midi implementation does not include enough information so you're left to guess or rely on the order that the information is retrieved. CoreMidi4J loses some information but adds a unique id (via casting).
I had written a similar library to CoreMidi4J that exposed all of the OSX MIDIDeviceRef to the Java world. However, I'd like to switch to CoreMidi4J and propose the following in order to do so:
OSX properly models the midi devices via MIDIDeviceRef. At the top level, it has:
uniqueID
manufacturer
model
name : the one that's user modifiable via Audio Midi
entities : midi ports that can have sources and destinations. The entity, entity.source, entity.destination have uniqueIDs and names. The names are retrieved from the device and are not changeable unless the entity is something like an IAC - e.g. a virtual device.
Unfortunately, Oracle's java doesn't map these very well. Java provides MidiDevice.Info with:
name
vendor
description
An Info object usually corresponds to a {midiDeviceRef}.entities.{entity}.(source|destination). So Java has essentially flattened the sources and destinations into a list of infos. The class name MidiDevice is misleading to me since it doesn't represent the physical device but rather the source or destination of a midi device.
On Oracle JDK on the OSX you end up with the following mapping:
name -> {midiDeviceRef}.entities.{entity}.(destination|source).name
vendor -> {midiDeviceRef}.manufacturer
description -> {midiDeviceRef}.name + {midiDeviceRef}.entities.{entity}.(destination|source).name
Arg! The description unnecessarily contains the Info.name. Well, ok, it's easy enough to get the {midiDeviceInfo}.name from the description which is what I'm after. Without it I am unable to differentiate between like kind hardware.
In CoreMidi4J with Oracle JDK on OSX you end up with the following mapping:
name -> "CoreMIDI4J - " + {midiDeviceRef}.entities.{entity}.(destination|source).name
vendor -> {midiDeviceRef}.manufacturer
description -> {midiDeviceRef}.model
Arg again! I no longer have access to {midiDeviceRef}.name. What's better about CoreMidi4J though is that CoreMidiDeviceInfo contains:
uniqueID -> {midiDeviceRef}.entities.{entity}.(destination|source).uniqueID
endPointReference -> not needed in this context
Solution?
Model MIDIDeviceRef, Entity, Source, Destination in Java:
...
public List<Entity> getEntities();
}
public interface Entity {
...
public List<Source> getSources();
public List<Destination> getDestinations();
public MIDIDevice getMIDIDevice();
}
public interface Endpoint {
...
public Entity getEntity();
}
public interface Source extends Endpoint
public interface Destination extends Endpoint
have CoreMidiDeviceInfo implement Endpoint, MidiDevice.Info
introduce two more classes:
public class CoreMidiDeviceInfoSource extends CoreMidiDeviceInfo implements Source
public class CoreMidiDeviceInfoDestination extends CoreMidiDeviceInfo implements Destination
When returning CoreMidiDeviceInfo's via MidiSystem.getMidiDeviceInfo() or CoreMidiDeviceProvider.getMidiDeviceInfo() make sure that the MIDIDevice model is built fully and only return objects that are consistent with the model. In other words, if two info objects belong to the same device, then the following would be true:
coreMidiDeviceInfoSource.getEntity().getMIDIDeviceInfo() == coreMidiDeviceInfoDestination.getEntity().getMIDIDeviceInfo()