diff --git a/CoreMIDI4J/Native/CoreMidi4J/CoreMidiInputPort.cpp b/CoreMIDI4J/Native/CoreMidi4J/CoreMidiInputPort.cpp index 4785a25..bf24a89 100644 --- a/CoreMIDI4J/Native/CoreMidi4J/CoreMidiInputPort.cpp +++ b/CoreMIDI4J/Native/CoreMidi4J/CoreMidiInputPort.cpp @@ -23,13 +23,11 @@ /* * The native callback that is called when a MIDI message is received * - * @param packets A list of MIDI packets that have been received. - * @param readProcRefCon The refCon passed to MIDIInputPortCreate - * @param srcConnRefCon The refCon passed to MIDIPortConnectSource + * @param packets A list of MIDI packets that have been received. + * @param callbackParameters Context of the JVM * */ - -void MIDIInput(const MIDIPacketList *packets, void *readProcRefCon, void *srcConnRefCon) { +void sendMidiToCallback(const MIDIPacketList *packets, const MIDI_CALLBACK_PARAMETERS *callbackParameters) { static mach_timebase_info_data_t sTimebaseInfo; // Will hold conversion factor for timestamps JNIEnv *env; @@ -39,13 +37,10 @@ void MIDIInput(const MIDIPacketList *packets, void *readProcRefCon, void *srcCon // uninitialised because it makes no sense to have a zero // denominator in a fraction. if ( sTimebaseInfo.denom == 0 ) { - + (void) mach_timebase_info(&sTimebaseInfo); - - } - // Cast the supplied reference to the correct data type - MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) srcConnRefCon; + } // Get a JNIEnv reference from the cached JVM int getEnvStat = callbackParameters->jvm->GetEnv((void **) &env, NULL); @@ -114,6 +109,33 @@ void MIDIInput(const MIDIPacketList *packets, void *readProcRefCon, void *srcCon } +/* + * The native callback that is called when a MIDI message is received + * + * @param packets A list of MIDI packets that have been received. + * @param readProcRefCon The refCon passed to MIDIInputPortCreate + * @param srcConnRefCon The refCon passed to MIDIPortConnectSource + * + */ +void MIDIInput(const MIDIPacketList *packets, void *readProcRefCon, void *srcConnRefCon) { + MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) srcConnRefCon; + sendMidiToCallback(packets, callbackParameters); +} + +/* + * The native callback that is called when a MIDI message is received for a virtual device + * + * @param packets A list of MIDI packets that have been received. + * @param readProcRefCon The readProcRefCon passed to MIDIDestinationCreate + * @param srcConnRefCon The srcConnRefCon (always NULL) + * + */ +void MIDIInputVirtual(const MIDIPacketList *packets, void *readProcRefCon, void *srcConnRefCon) { + MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) readProcRefCon; + sendMidiToCallback(packets, callbackParameters); +} + + ///////////////////////////////////////////////////////// // Native functions for CoreMidiInputPort ///////////////////////////////////////////////////////// @@ -207,6 +229,7 @@ JNIEXPORT jlong JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPo // Get the endpoint reference from the info object int sourceEndPointReference = env->GetIntField(info, env->GetFieldID(env->GetObjectClass(info),"endPointReference","I")); + std::cout << "midiPortConnectSource" << std::endl; // Connect the input port to the source endpoint. status = MIDIPortConnectSource(inputPortReference, sourceEndPointReference, callbackParameters); @@ -268,3 +291,89 @@ JNIEXPORT void JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPor } } + +/* + * Creates the virtual MIDI Input Port + * + * Class: com_coremidi4j_CoreMidiInputPort + * Method: createVirtualPort + * Signature: (ILjava/lang/String;)Iuk/co/xfactorylibrarians/coremidi4j/CoreMidiSource;)V + * + * @param env The JNI environment + * @param obj The reference to the java object instance that called this native method + * @param clientReference The MIDI Client used to create the port + * @param portName The name of the input port + * @param sourceDevice The reference of the source device + * + * @return A reference to the created virtual input port + * + * @throws CoreMidiException if the virtual input port cannot be created + * + */ + +JNIEXPORT jint JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_createVirtualPort(JNIEnv *env, jobject obj, jint clientReference, jstring portName, jobject sourceDevice) { + + OSStatus status; + + // Allocate memory for the callback parameters + MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) malloc(sizeof(MIDI_CALLBACK_PARAMETERS)); + + // Throw exception if memory allocation failed + if ( callbackParameters == NULL ) { + + ThrowException(env,CFSTR("MIDIPortCreateVirtual"),-1); + + } + + // Cache the information needed for the callback, noting that we obtain a l=global reference for the CoreMidiInputPortObject + callbackParameters->object = env->NewGlobalRef(sourceDevice); + callbackParameters->methodID = env->GetMethodID(env->GetObjectClass(sourceDevice), "messageCallback", "(JI[B)V"); + jint result = env->GetJavaVM(&callbackParameters->jvm); + + // Ensure that the last call succeeded + assert (result == JNI_OK); + + MIDIPortRef portRef; + // Create a CFStringRef from the portName jstring + const char *portNameString = env->GetStringUTFChars(portName,0); + CFStringRef cfPortName = CFStringCreateWithCString(NULL,portNameString,kCFStringEncodingMacRoman); + + status = MIDIDestinationCreate( clientReference, cfPortName, MIDIInputVirtual, callbackParameters, &portRef ); + + if ( status != 0) { + + ThrowException(env,CFSTR("MIDIPortCreateVirtual"),status); + + } + + return portRef; + +} + +/* + * Disposes a virtual source or destination your client created. + * + * Class: com_coremidi4j_CoreMidiInputPort + * Method: disposeVirtualPort + * Signature: (IL + * + * @param env The JNI environment + * @param obj The reference to the java object instance that called this native method + * @param inputPortReference The reference of the input point that we wish to dispose + * + * @throws CoreMidiException if the input port cannot be disposed + * + */ +JNIEXPORT void JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_disposeVirtualPort(JNIEnv *env, jobject obj, jint inputPortReference) { + + OSStatus status; + + status = MIDIEndpointDispose( inputPortReference ); + + if ( status != 0) { + + ThrowException(env,CFSTR("MIDIPortDisposeVirtual"),status); + + } + +} diff --git a/CoreMIDI4J/Native/CoreMidi4J/jni/uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort.h b/CoreMIDI4J/Native/CoreMidi4J/jni/uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort.h index 0a4fcbd..28fbbc2 100644 --- a/CoreMIDI4J/Native/CoreMidi4J/jni/uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort.h +++ b/CoreMIDI4J/Native/CoreMidi4J/jni/uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort.h @@ -15,6 +15,22 @@ extern "C" { JNIEXPORT jint JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_createInputPort (JNIEnv *, jobject, jint, jstring); +/* + * Class: uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort + * Method: createVirtualPort + * Signature: (ILjava/lang/String;Luk/co/xfactorylibrarians/coremidi4j/CoreMidiSource;)I + */ +JNIEXPORT jint JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_createVirtualPort + (JNIEnv *, jobject, jint, jstring, jobject); + +/* + * Class: uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort + * Method: disposeVirtualPort + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_disposeVirtualPort + (JNIEnv *, jobject, jint); + /* * Class: uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort * Method: midiPortConnectSource diff --git a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiClient.java b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiClient.java index 3ec7c23..6711a43 100644 --- a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiClient.java +++ b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiClient.java @@ -5,11 +5,11 @@ * Company: x.factory Librarians * * @author Derek Cook - * + * * CoreMIDI4J is an open source Service Provider Interface for supporting external MIDI devices on MAC OS X - * + * * CREDITS - This library uses principles established by OSXMIDI4J, but converted so it operates at the JNI level with no additional libraries required - * + * */ package uk.co.xfactorylibrarians.coremidi4j; @@ -26,11 +26,11 @@ public class CoreMidiClient { /** * Constructor for class - * - * @param name The name of the client - * + * + * @param name The name of the client + * * @throws CoreMidiException if the client cannot be initialized - * + * */ public CoreMidiClient(String name) throws CoreMidiException { @@ -41,30 +41,32 @@ public CoreMidiClient(String name) throws CoreMidiException { /** * Creates a new CoreMidiInputPort - * + * * @param name The name of the port - * + * + * @param createVirtual If true, create a virtual input port + * * @return A new CoreMidiInputPort - * + * * @throws CoreMidiException if the port cannot be created - * + * */ - public CoreMidiInputPort inputPortCreate(final String name) throws CoreMidiException { + public CoreMidiInputPort inputPortCreate(final String name, final boolean createVirtual) throws CoreMidiException { - return new CoreMidiInputPort(midiClientReference,name); + return new CoreMidiInputPort(midiClientReference,name,createVirtual); } /** * Creates a new CoreMidiOutputPort - * + * * @param name The name of the port - * + * * @return A new CoreMidiOutputPort - * + * * @throws CoreMidiException if the port cannot be created - * + * */ public CoreMidiOutputPort outputPortCreate(final String name) throws CoreMidiException { @@ -75,9 +77,9 @@ public CoreMidiOutputPort outputPortCreate(final String name) throws CoreMidiExc /** * The message callback for receiving notifications about changes in the MIDI environment from the JNI code - * + * * @throws CoreMidiException if a problem occurs passing along the notification - * + * */ public void notifyCallback() throws CoreMidiException { @@ -115,11 +117,11 @@ public void notifyCallback() throws CoreMidiException { /** * Creates the MIDI Client - * + * * @param clientName The name of the client - * + * * @return A reference to the MIDI client - * + * * @throws CoreMidiException if the client cannot be created * */ @@ -128,11 +130,11 @@ public void notifyCallback() throws CoreMidiException { /** * Disposes of a CoreMIDI Client - * + * * @param clientReference The reference of the client to dispose of - * + * * @throws CoreMidiException if there is a problem disposing of the client - * + * */ private native void disposeClient(int clientReference) throws CoreMidiException; diff --git a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo.java b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo.java index 95b52cf..a364481 100644 --- a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo.java +++ b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo.java @@ -5,11 +5,11 @@ * Company: x.factory Librarians * * @author Derek Cook - * + * * CoreMIDI4J is an open source Service Provider Interface for supporting external MIDI devices on MAC OS X - * + * * CREDITS - This library uses principles established by OSXMIDI4J, but converted so it operates at the JNI level with no additional libraries required - * + * */ package uk.co.xfactorylibrarians.coremidi4j; @@ -40,9 +40,9 @@ public class CoreMidiDeviceInfo extends MidiDevice.Info { * * @param value The value which may be null * @param fallback The value to use if value is null - * + * * @return The value string, or the fallback string if the value is null - * + * */ private static String defaultForNull(final String value, final String fallback) { @@ -59,61 +59,61 @@ private static String defaultForNull(final String value, final String fallback) /** * Constructs a CoreMidiDeviceInfo object from the parameters - * + * * @param name The name of the device * @param vendor The manufacturer of the device * @param description A description of the device * @param version The version number of the device driver - * @param deviceName The raw name of the device + * @param deviceName The raw name of the device * @param deviceReference The device reference * @param deviceUniqueID The OS X unique identifier for the device - * @param entityName The raw name of the entity + * @param entityName The raw name of the entity * @param entityReference The entity reference - * @param entityUniqueID The OS X unique identifier for the entity - * @param endPointName The raw name of the end point + * @param entityUniqueID The OS X unique identifier for the entity + * @param endPointName The raw name of the end point * @param endPointReference The end point reference - * @param endPointUniqueID The OS X unique identifier for the end point - * + * @param endPointUniqueID The OS X unique identifier for the end point + * */ - public CoreMidiDeviceInfo(final String name, - final String vendor, - final String description, - final String version, - final String deviceName, - final int deviceReference, - final int deviceUniqueID, - final String entityName, - final int entityReference, - final int entityUniqueID, - final String endPointName, - final int endPointReference, + public CoreMidiDeviceInfo(final String name, + final String vendor, + final String description, + final String version, + final String deviceName, + final int deviceReference, + final int deviceUniqueID, + final String entityName, + final int entityReference, + final int entityUniqueID, + final String endPointName, + final int endPointReference, final int endPointUniqueID) { super("CoreMIDI4J - " + name, defaultForNull(vendor, ""), defaultForNull(description, name), version); this.deviceName = deviceName; this.deviceReference = deviceReference; - this.deviceUniqueID = deviceUniqueID; + this.deviceUniqueID = deviceUniqueID; this.entityName = entityName; this.entityReference = entityReference; - this.entityUniqueID = entityUniqueID; + this.entityUniqueID = entityUniqueID; this.endPointName = endPointName; this.endPointReference = endPointReference; this.endPointUniqueID = endPointUniqueID; - + } /** * Gets a string describing the device - * + * * @return A string describing the device - * + * */ public String getInformationString() { - return getVendor() + ": " + getName(); + return getVendor() + ": " + getName(); } @@ -127,9 +127,9 @@ public String getInformationString() { public String getEndPointName() { return endPointName; - + } - + /** * Gets the endPointReference value * @@ -140,14 +140,14 @@ public String getEndPointName() { public int getEndPointReference() { return endPointReference; - + } - + /** * Gets the OS X unique identifier for the end point - * + * * @return The OS X unique identifier for the end point - * + * */ public int getEndPointUniqueID() { @@ -166,9 +166,9 @@ public int getEndPointUniqueID() { public String getEntityName() { return entityName; - + } - + /** * Gets the entityReference value * @@ -179,14 +179,14 @@ public String getEntityName() { public int getEntityReference() { return entityReference; - + } - + /** * Gets the OS X unique identifier for the entity - * + * * @return The OS X unique identifier for the entity - * + * */ public int getEntityUniqueID() { @@ -205,9 +205,9 @@ public int getEntityUniqueID() { public String getDeviceName() { return deviceName; - + } - + /** * Gets the deviceReference value * @@ -218,14 +218,14 @@ public String getDeviceName() { public int getDeviceReference() { return deviceReference; - + } - + /** * Gets the OS X unique identifier for the device - * + * * @return The OS X unique identifier for the device - * + * */ public int getdeviceUniqueID() { diff --git a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiInputPort.java b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiInputPort.java index b1a685e..a8b2c8d 100644 --- a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiInputPort.java +++ b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiInputPort.java @@ -5,15 +5,17 @@ * Company: x.factory Librarians * * @author Derek Cook - * + * * CoreMIDI4J is an open source Service Provider Interface for supporting external MIDI devices on MAC OS X - * + * * CREDITS - This library uses principles established by OSXMIDI4J, but converted so it operates at the JNI level with no additional libraries required - * + * */ package uk.co.xfactorylibrarians.coremidi4j; +import javax.sound.midi.MidiDevice.Info; + /** * Wraps a native macOS Core MIDI input port. * @@ -21,54 +23,106 @@ public class CoreMidiInputPort { + private final boolean isVirtual; + /** The OSX MIDI port reference */ - private final int midiPortReference; + private int midiPortReference; /** For each connection to an OSX EndPoint, some data is allocated on the native side. This handle tracks the allocation so that it can be returned when this port is disconnected */ private long memoryHandle; + /** The client reference */ + private final int clientReference; + + /** The port name */ + private final String portName; + /** * Constructor - * + * * @param clientReference The client reference * @param portName The name of the input port + * @param isVirtual If true, create a virtual endpoint instead of connecting a real device * @throws CoreMidiException if the input port cannot be created - * + * */ - public CoreMidiInputPort(final int clientReference, String portName) throws CoreMidiException { + public CoreMidiInputPort(final int clientReference, String portName, boolean isVirtual) throws CoreMidiException { - this.midiPortReference = this.createInputPort(clientReference, portName); + this.isVirtual = isVirtual; + + this.portName = portName; + + this.midiPortReference = isVirtual ? 0 : this.createInputPort(clientReference, portName); + + this.clientReference = clientReference; } /** * Connects a source to this input port - * + * * @param sourceDevice The source device that wishes to connect to the port - * + * * @throws CoreMidiException if there is a problem establishing the connection - * + * */ public void connectSource(final CoreMidiSource sourceDevice) throws CoreMidiException { - memoryHandle = midiPortConnectSource(midiPortReference, sourceDevice); + if (isVirtual) { + + midiPortReference = createVirtualPort(clientReference, portName, sourceDevice); + + // This is kind of ugly: read the device info from the CoreMidiDeviceProvider + CoreMidiDeviceProvider provider = new CoreMidiDeviceProvider(); + + provider.midiSystemUpdated(); + + for (Info info : provider.getDeviceInfo()) { + + if (info instanceof CoreMidiDeviceInfo) { + + if (((CoreMidiDeviceInfo) info).getEndPointReference() == midiPortReference) { + + sourceDevice.updateDeviceInfo((CoreMidiDeviceInfo)info); + + break; + + } + + } + + } + + } else { + + memoryHandle = midiPortConnectSource(midiPortReference, sourceDevice); + + } } /** * Disconnects a source from input port - * + * * @param sourceDevice The source device that wishes to disconnect from the port - * + * * @throws CoreMidiException if there is a problem removing the connection - * + * */ public void disconnectSource(final CoreMidiSource sourceDevice) throws CoreMidiException { - midiPortDisconnectSource(midiPortReference, memoryHandle, sourceDevice); + if (isVirtual) { + + disposeVirtualPort(midiPortReference); + + } else { + + midiPortDisconnectSource(midiPortReference, memoryHandle, sourceDevice); + + } } @@ -97,41 +151,67 @@ public void disconnectSource(final CoreMidiSource sourceDevice) throws CoreMidiE /** * Creates a CoreMIDI input port - * + * * @param clientReference The MIDI client reference * @param portName The name of the output port - * + * * @return A reference to the created input port - * + * * @throws CoreMidiException if the port cannot be created - * + * */ private native int createInputPort(int clientReference, String portName) throws CoreMidiException; + /** + * Creates a CoreMIDI virtusal input port + * + * @param clientReference The MIDI client reference + * @param portName The name of the input port + * @param sourceDevice The virtual source device that receives the MIDI data + * + * @return A reference to the created virtual input port + * + * @throws CoreMidiException if the port cannot be created + * + */ + + private native int createVirtualPort(int clientReference, String portName, CoreMidiSource sourceDevice) throws CoreMidiException; + + + /** + * Disposes a virtual port + * + * @param inputPortReference The reference to an virtual input port + * + * @throws CoreMidiException if there is a problem disconnecting the source + * + */ + private native void disposeVirtualPort(int inputPortReference) throws CoreMidiException; + /** * Connects a source end point to a MIDI input - * + * * @param inputPortReference The reference to an input port * @param sourceDevice The source device that wishes to connect to the port - * - * @return A memory handle for the parameters the native side has associated with this call - * + * + * @return A memory handle for the parameters the native side has associated with this call + * * @throws CoreMidiException if there is a problem connecting the source - * + * */ private native long midiPortConnectSource(int inputPortReference, CoreMidiSource sourceDevice) throws CoreMidiException; /** * Disconnects a source end point to a MIDI input - * + * * @param inputPortReference The reference to an input port * @param memoryReference The memory handle that can now be released. * @param sourceDevice The source device that wishes to disconnect from the port - * + * * @throws CoreMidiException if there is a problem disconnecting the source - * + * */ private native void midiPortDisconnectSource(int inputPortReference, long memoryReference, CoreMidiSource sourceDevice) throws CoreMidiException; diff --git a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiSource.java b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiSource.java index 29393f2..a75d115 100644 --- a/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiSource.java +++ b/CoreMIDI4J/src/uk/co/xfactorylibrarians/coremidi4j/CoreMidiSource.java @@ -5,11 +5,11 @@ * Company: x.factory Librarians * * @author Derek Cook, James Elliott - * + * * CoreMIDI4J is an open source Service Provider Interface for supporting external MIDI devices on MAC OS X - * + * * CREDITS - This library uses principles established by OSXMIDI4J, but converted so it operates at the JNI level with no additional libraries required - * + * */ package uk.co.xfactorylibrarians.coremidi4j; @@ -48,6 +48,18 @@ public class CoreMidiSource implements MidiDevice { private int sysexMessageLength = 0; // Tracks the total SYSEX data length accumulated. private long startTime; // The system time in microseconds when the port was opened + /** + * Create a new virtual input device with the given name. + * @param name name of the MIDI device + * @return newly created CoreMidiSource with proper device info + * @throws MidiUnavailableException + */ + public static CoreMidiSource createVirtualDevice(String name) throws MidiUnavailableException { + CoreMidiSource source = new CoreMidiSource(null); + source.open(name, true); + return source; + } + /** * Default constructor. * @@ -67,7 +79,7 @@ public class CoreMidiSource implements MidiDevice { * Gets the MIDI Info object * * @return the MIDI Info object, which provides details about the interface - * + * */ @Override @@ -79,11 +91,11 @@ public Info getDeviceInfo() { /** * Changes the MIDI Info object; can only be done by this package as a result of a MIDI environment change event. - * + * * @param info The CoreMidiDeviceInfo to update - * + * */ - + void updateDeviceInfo(CoreMidiDeviceInfo info) { this.info = info; @@ -94,11 +106,20 @@ void updateDeviceInfo(CoreMidiDeviceInfo info) { * Opens the Core MIDI Device * * @throws MidiUnavailableException if the MIDI system cannot be used - * + * */ - @Override public void open() throws MidiUnavailableException { + open("Core Midi Provider Input", false); + } + + /** + * Opens the Core MIDI Device + * + * @throws MidiUnavailableException if the MIDI s ystem cannot be used + * + */ + public void open(String name, boolean createVirtual) throws MidiUnavailableException { if (isOpen.compareAndSet(false, true)) { @@ -107,7 +128,7 @@ public void open() throws MidiUnavailableException { // Create the input port if not already created if (input.get() == null) { - input.set(CoreMidiDeviceProvider.getMIDIClient().inputPortCreate("Core Midi Provider Input")); + input.set(CoreMidiDeviceProvider.getMIDIClient().inputPortCreate(name, createVirtual)); } @@ -130,7 +151,7 @@ public void open() throws MidiUnavailableException { /** * Closes the Core MIDI Device, which also closes all its transmitters - * + * */ @Override @@ -189,9 +210,9 @@ void deviceDisappeared() { * Checks to see if the MIDI Device is open * * @return true if the device is open, otherwise false; - * + * * @see javax.sound.midi.MidiDevice#isOpen() - * + * */ @Override @@ -205,9 +226,9 @@ public boolean isOpen() { * Obtains the time in microseconds that has elapsed since this MIDI Device was opened. * * @return the time in microseconds that has elapsed since this MIDI Device was opened. - * + * * @see javax.sound.midi.MidiDevice#getMicrosecondPosition() - * + * */ @Override @@ -222,9 +243,9 @@ public long getMicrosecondPosition() { * Gets the maximum number of receivers that can be attached to this device. * * @return the maximum number of receivers that can be attached to this device. This is always 0 as a CoreMidiSource has no receivers - * + * * @see javax.sound.midi.MidiDevice#getMaxReceivers() - * + * */ @Override @@ -239,9 +260,9 @@ public int getMaxReceivers() { * Gets the maximum number of transmitters that can be attached to this device. * * @return the maximum number of transmitters that can be attached to this device. -1 is returned to indicate that the number is unlimited - * + * * @see javax.sound.midi.MidiDevice#getMaxTransmitters() - * + * */ @Override @@ -256,9 +277,9 @@ public int getMaxTransmitters() { * Creates and returns a MIDI Receiver for use with this Device * * @return the created receiver - * + * * @see javax.sound.midi.MidiDevice#getReceiver() - * + * */ @Override @@ -272,9 +293,9 @@ public Receiver getReceiver() throws MidiUnavailableException { * Gets a list of receivers connected to the device * * @return an empty list - we do not maintain a list of receivers - * + * * @see javax.sound.midi.MidiDevice#getReceivers() - * + * */ @Override @@ -289,9 +310,9 @@ public List getReceivers() { * Gets a transmitter for this device (which is also added to the internal list) * * @return a transmitter for this device - * + * * @see javax.sound.midi.MidiDevice#getTransmitter() - * + * */ @Override @@ -324,9 +345,9 @@ void transmitterClosed(CoreMidiTransmitter transmitter) { * Gets the list of transmitters registered with this MIDI device * * @return The list of transmitters created from this MIDI device that are still open - * + * * @see javax.sound.midi.MidiDevice#getTransmitters() - * + * */ @Override @@ -380,10 +401,10 @@ private boolean isRunningStatusMessage (int status) { switch( status & 0xF0 ) { case ShortMessage.NOTE_OFF: - case ShortMessage.NOTE_ON: + case ShortMessage.NOTE_ON: case ShortMessage.POLY_PRESSURE: case ShortMessage.CONTROL_CHANGE: - case ShortMessage.PROGRAM_CHANGE: + case ShortMessage.PROGRAM_CHANGE: case ShortMessage.CHANNEL_PRESSURE: case ShortMessage.PITCH_BEND: return true; @@ -414,21 +435,21 @@ private int expectedDataLength (byte status) throws InvalidMidiDataException { case ShortMessage.END_OF_EXCLUSIVE: // System real-time messages - case ShortMessage.TIMING_CLOCK: + case ShortMessage.TIMING_CLOCK: case 0xF9: // Undefined - case ShortMessage.START: - case ShortMessage.CONTINUE: - case ShortMessage.STOP: + case ShortMessage.START: + case ShortMessage.CONTINUE: + case ShortMessage.STOP: case 0xFD: // Undefined - case ShortMessage.ACTIVE_SENSING: - case ShortMessage.SYSTEM_RESET: + case ShortMessage.ACTIVE_SENSING: + case ShortMessage.SYSTEM_RESET: return 0; case ShortMessage.MIDI_TIME_CODE: - case ShortMessage.SONG_SELECT: + case ShortMessage.SONG_SELECT: return 1; - case ShortMessage.SONG_POSITION_POINTER: + case ShortMessage.SONG_POSITION_POINTER: return 2; default: // Fall through to next switch @@ -438,15 +459,15 @@ private int expectedDataLength (byte status) throws InvalidMidiDataException { // channel voice and mode messages switch( status & 0xF0 ) { - case ShortMessage.NOTE_OFF: - case ShortMessage.NOTE_ON: + case ShortMessage.NOTE_OFF: + case ShortMessage.NOTE_ON: case ShortMessage.POLY_PRESSURE: - case ShortMessage.CONTROL_CHANGE: - case ShortMessage.PITCH_BEND: + case ShortMessage.CONTROL_CHANGE: + case ShortMessage.PITCH_BEND: return 2; - case ShortMessage.PROGRAM_CHANGE: - case ShortMessage.CHANNEL_PRESSURE: + case ShortMessage.PROGRAM_CHANGE: + case ShortMessage.CHANNEL_PRESSURE: return 1; default: @@ -458,13 +479,13 @@ private int expectedDataLength (byte status) throws InvalidMidiDataException { /** * The message callback for receiving midi data from the JNI code - * + * * @param coreTimestamp The time in microseconds since boot at which the messages should take effect * @param packetlength The length of the packet of messages * @param data The data array that holds the messages - * + * * @throws InvalidMidiDataException if the message contained values that could not be interpreted as valid MIDI - * + * */ public void messageCallback(long coreTimestamp, int packetlength, byte data[]) throws InvalidMidiDataException { @@ -511,9 +532,9 @@ public void messageCallback(long coreTimestamp, int packetlength, byte data[]) t // We have just received the first data byte of a message which needs two. firstDataByte = data[offset++]; wasFirstByteReceived = true; - + } - + } } else { @@ -586,9 +607,9 @@ public void messageCallback(long coreTimestamp, int packetlength, byte data[]) t * detected in the most recent message gathered, indicating the end of the SYSEX. * * @return The constructed SYSEX message - * + * * @throws InvalidMidiDataException if the data is not properly formed - * + * */ private SysexMessage constructSysexMessage() throws InvalidMidiDataException { @@ -634,9 +655,9 @@ private SysexMessage constructSysexMessage() throws InvalidMidiDataException { * @param timestamp The message timestamp * * @return The number of bytes consumed from the packet by the SYSEX message - * + * * @throws InvalidMidiDataException if the data is not properly formed - * + * */ private int processSysexData(int packetLength, byte sourceData[], int startOffset, long timestamp) @@ -728,7 +749,7 @@ private int processSysexData(int packetLength, byte sourceData[], int startOffse * * @param message the message to send * @param timestamp the time stamp - * + * */ private void transmitMessage(final MidiMessage message, long timestamp) { @@ -760,9 +781,9 @@ private void transmitMessage(final MidiMessage message, long timestamp) { * Formats the provided data into a HEX string, which is useful for debugging * * @param aByteArray The data to format - * + * * @return The formatted HEX string - * + * */ private String getHexString(byte[] aByteArray) { @@ -782,7 +803,7 @@ private String getHexString(byte[] aByteArray) { return new String(sbuf).trim(); } - + ////////////////////////////// ///// JNI Interfaces ////////////////////////////// @@ -810,7 +831,7 @@ private String getHexString(byte[] aByteArray) { * Obtains the current system time in microseconds. * * @return The current system time in microseconds. - * + * */ private native long getMicroSecondTime();