* commit 'a29558c5c5001cdadf5f59fed35134bbfffe763b': MidiManager: Address API Council feedback:
This commit is contained in:
@@ -17259,7 +17259,7 @@ package android.media.midi {
|
|||||||
method public int getId();
|
method public int getId();
|
||||||
method public int getInputPortCount();
|
method public int getInputPortCount();
|
||||||
method public int getOutputPortCount();
|
method public int getOutputPortCount();
|
||||||
method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList();
|
method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts();
|
||||||
method public android.os.Bundle getProperties();
|
method public android.os.Bundle getProperties();
|
||||||
method public int getType();
|
method public int getType();
|
||||||
method public boolean isPrivate();
|
method public boolean isPrivate();
|
||||||
@@ -17307,22 +17307,17 @@ package android.media.midi {
|
|||||||
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
|
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
|
||||||
method public void close() throws java.io.IOException;
|
method public void close() throws java.io.IOException;
|
||||||
method public final int getPortNumber();
|
method public final int getPortNumber();
|
||||||
method public void onReceive(byte[], int, int, long) throws java.io.IOException;
|
method public void onSend(byte[], int, int, long) throws java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MidiManager {
|
public final class MidiManager {
|
||||||
method public android.media.midi.MidiDeviceInfo[] getDeviceList();
|
method public android.media.midi.MidiDeviceInfo[] getDevices();
|
||||||
method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler);
|
method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
|
||||||
method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler);
|
method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
|
||||||
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
|
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
|
||||||
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
|
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class MidiManager.BluetoothOpenCallback {
|
|
||||||
ctor public MidiManager.BluetoothOpenCallback();
|
|
||||||
method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MidiManager.DeviceCallback {
|
public static class MidiManager.DeviceCallback {
|
||||||
ctor public MidiManager.DeviceCallback();
|
ctor public MidiManager.DeviceCallback();
|
||||||
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
|
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
|
||||||
@@ -17330,31 +17325,34 @@ package android.media.midi {
|
|||||||
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
|
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class MidiManager.DeviceOpenCallback {
|
public static abstract interface MidiManager.OnDeviceOpenedListener {
|
||||||
ctor public MidiManager.DeviceOpenCallback();
|
method public abstract void onDeviceOpened(android.media.midi.MidiDevice);
|
||||||
method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
|
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
|
||||||
method public void close() throws java.io.IOException;
|
method public void close() throws java.io.IOException;
|
||||||
method public void connect(android.media.midi.MidiReceiver);
|
|
||||||
method public void disconnect(android.media.midi.MidiReceiver);
|
|
||||||
method public final int getPortNumber();
|
method public final int getPortNumber();
|
||||||
|
method public void onConnect(android.media.midi.MidiReceiver);
|
||||||
|
method public void onDisconnect(android.media.midi.MidiReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class MidiReceiver {
|
public abstract class MidiReceiver {
|
||||||
ctor public MidiReceiver();
|
ctor public MidiReceiver();
|
||||||
|
ctor public MidiReceiver(int);
|
||||||
method public void flush() throws java.io.IOException;
|
method public void flush() throws java.io.IOException;
|
||||||
method public int getMaxMessageSize();
|
method public final int getMaxMessageSize();
|
||||||
method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException;
|
method public void onFlush() throws java.io.IOException;
|
||||||
|
method public abstract void onSend(byte[], int, int, long) throws java.io.IOException;
|
||||||
method public void send(byte[], int, int) throws java.io.IOException;
|
method public void send(byte[], int, int) throws java.io.IOException;
|
||||||
method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException;
|
method public void send(byte[], int, int, long) throws java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class MidiSender {
|
public abstract class MidiSender {
|
||||||
ctor public MidiSender();
|
ctor public MidiSender();
|
||||||
method public abstract void connect(android.media.midi.MidiReceiver);
|
method public void connect(android.media.midi.MidiReceiver);
|
||||||
method public abstract void disconnect(android.media.midi.MidiReceiver);
|
method public void disconnect(android.media.midi.MidiReceiver);
|
||||||
|
method public abstract void onConnect(android.media.midi.MidiReceiver);
|
||||||
|
method public abstract void onDisconnect(android.media.midi.MidiReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18562,7 +18562,7 @@ package android.media.midi {
|
|||||||
method public int getId();
|
method public int getId();
|
||||||
method public int getInputPortCount();
|
method public int getInputPortCount();
|
||||||
method public int getOutputPortCount();
|
method public int getOutputPortCount();
|
||||||
method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList();
|
method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts();
|
||||||
method public android.os.Bundle getProperties();
|
method public android.os.Bundle getProperties();
|
||||||
method public int getType();
|
method public int getType();
|
||||||
method public boolean isPrivate();
|
method public boolean isPrivate();
|
||||||
@@ -18610,22 +18610,17 @@ package android.media.midi {
|
|||||||
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
|
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
|
||||||
method public void close() throws java.io.IOException;
|
method public void close() throws java.io.IOException;
|
||||||
method public final int getPortNumber();
|
method public final int getPortNumber();
|
||||||
method public void onReceive(byte[], int, int, long) throws java.io.IOException;
|
method public void onSend(byte[], int, int, long) throws java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MidiManager {
|
public final class MidiManager {
|
||||||
method public android.media.midi.MidiDeviceInfo[] getDeviceList();
|
method public android.media.midi.MidiDeviceInfo[] getDevices();
|
||||||
method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler);
|
method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
|
||||||
method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler);
|
method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
|
||||||
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
|
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
|
||||||
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
|
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class MidiManager.BluetoothOpenCallback {
|
|
||||||
ctor public MidiManager.BluetoothOpenCallback();
|
|
||||||
method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MidiManager.DeviceCallback {
|
public static class MidiManager.DeviceCallback {
|
||||||
ctor public MidiManager.DeviceCallback();
|
ctor public MidiManager.DeviceCallback();
|
||||||
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
|
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
|
||||||
@@ -18633,31 +18628,34 @@ package android.media.midi {
|
|||||||
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
|
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class MidiManager.DeviceOpenCallback {
|
public static abstract interface MidiManager.OnDeviceOpenedListener {
|
||||||
ctor public MidiManager.DeviceOpenCallback();
|
method public abstract void onDeviceOpened(android.media.midi.MidiDevice);
|
||||||
method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
|
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
|
||||||
method public void close() throws java.io.IOException;
|
method public void close() throws java.io.IOException;
|
||||||
method public void connect(android.media.midi.MidiReceiver);
|
|
||||||
method public void disconnect(android.media.midi.MidiReceiver);
|
|
||||||
method public final int getPortNumber();
|
method public final int getPortNumber();
|
||||||
|
method public void onConnect(android.media.midi.MidiReceiver);
|
||||||
|
method public void onDisconnect(android.media.midi.MidiReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class MidiReceiver {
|
public abstract class MidiReceiver {
|
||||||
ctor public MidiReceiver();
|
ctor public MidiReceiver();
|
||||||
|
ctor public MidiReceiver(int);
|
||||||
method public void flush() throws java.io.IOException;
|
method public void flush() throws java.io.IOException;
|
||||||
method public int getMaxMessageSize();
|
method public final int getMaxMessageSize();
|
||||||
method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException;
|
method public void onFlush() throws java.io.IOException;
|
||||||
|
method public abstract void onSend(byte[], int, int, long) throws java.io.IOException;
|
||||||
method public void send(byte[], int, int) throws java.io.IOException;
|
method public void send(byte[], int, int) throws java.io.IOException;
|
||||||
method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException;
|
method public void send(byte[], int, int, long) throws java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class MidiSender {
|
public abstract class MidiSender {
|
||||||
ctor public MidiSender();
|
ctor public MidiSender();
|
||||||
method public abstract void connect(android.media.midi.MidiReceiver);
|
method public void connect(android.media.midi.MidiReceiver);
|
||||||
method public abstract void disconnect(android.media.midi.MidiReceiver);
|
method public void disconnect(android.media.midi.MidiReceiver);
|
||||||
|
method public abstract void onConnect(android.media.midi.MidiReceiver);
|
||||||
|
method public abstract void onDisconnect(android.media.midi.MidiReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
* This class subclasses {@link android.media.midi.MidiReceiver} and dispatches any data it receives
|
* This class subclasses {@link android.media.midi.MidiReceiver} and dispatches any data it receives
|
||||||
* to its receiver list. Any receivers that throw an exception upon receiving data will
|
* to its receiver list. Any receivers that throw an exception upon receiving data will
|
||||||
* be automatically removed from the receiver list, but no IOException will be returned
|
* be automatically removed from the receiver list, but no IOException will be returned
|
||||||
* from the dispatcher's {@link android.media.midi.MidiReceiver#onReceive} in that case.
|
* from the dispatcher's {@link android.media.midi.MidiReceiver#onSend} in that case.
|
||||||
*/
|
*/
|
||||||
public final class MidiDispatcher extends MidiReceiver {
|
public final class MidiDispatcher extends MidiReceiver {
|
||||||
|
|
||||||
@@ -35,21 +35,13 @@ public final class MidiDispatcher extends MidiReceiver {
|
|||||||
= new CopyOnWriteArrayList<MidiReceiver>();
|
= new CopyOnWriteArrayList<MidiReceiver>();
|
||||||
|
|
||||||
private final MidiSender mSender = new MidiSender() {
|
private final MidiSender mSender = new MidiSender() {
|
||||||
/**
|
@Override
|
||||||
* Called to connect a {@link android.media.midi.MidiReceiver} to the sender
|
public void onConnect(MidiReceiver receiver) {
|
||||||
*
|
|
||||||
* @param receiver the receiver to connect
|
|
||||||
*/
|
|
||||||
public void connect(MidiReceiver receiver) {
|
|
||||||
mReceivers.add(receiver);
|
mReceivers.add(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Called to disconnect a {@link android.media.midi.MidiReceiver} from the sender
|
public void onDisconnect(MidiReceiver receiver) {
|
||||||
*
|
|
||||||
* @param receiver the receiver to disconnect
|
|
||||||
*/
|
|
||||||
public void disconnect(MidiReceiver receiver) {
|
|
||||||
mReceivers.remove(receiver);
|
mReceivers.remove(receiver);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -73,10 +65,10 @@ public final class MidiDispatcher extends MidiReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException {
|
public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
|
||||||
for (MidiReceiver receiver : mReceivers) {
|
for (MidiReceiver receiver : mReceivers) {
|
||||||
try {
|
try {
|
||||||
receiver.sendWithTimestamp(msg, offset, count, timestamp);
|
receiver.send(msg, offset, count, timestamp);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// if the receiver fails we remove the receiver but do not propagate the exception
|
// if the receiver fails we remove the receiver but do not propagate the exception
|
||||||
mReceivers.remove(receiver);
|
mReceivers.remove(receiver);
|
||||||
@@ -85,7 +77,7 @@ public final class MidiDispatcher extends MidiReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() throws IOException {
|
public void onFlush() throws IOException {
|
||||||
for (MidiReceiver receiver : mReceivers) {
|
for (MidiReceiver receiver : mReceivers) {
|
||||||
receiver.flush();
|
receiver.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class MidiEventScheduler extends EventScheduler {
|
|||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] msg, int offset, int count, long timestamp)
|
public void onSend(byte[] msg, int offset, int count, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
MidiEvent event = createScheduledEvent(msg, offset, count, timestamp);
|
MidiEvent event = createScheduledEvent(msg, offset, count, timestamp);
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
@@ -45,7 +45,7 @@ public class MidiEventScheduler extends EventScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void onFlush() {
|
||||||
MidiEventScheduler.this.flush();
|
MidiEventScheduler.this.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,10 +54,10 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see android.midi.MidiReceiver#onReceive(byte[], int, int, long)
|
* @see android.midi.MidiReceiver#onSend(byte[], int, int, long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] data, int offset, int count, long timestamp)
|
public void onSend(byte[] data, int offset, int count, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// Log.i(TAG, formatMidiData(data, offset, count));
|
// Log.i(TAG, formatMidiData(data, offset, count));
|
||||||
int sysExStartOffset = (mInSysEx ? offset : -1);
|
int sysExStartOffset = (mInSysEx ? offset : -1);
|
||||||
@@ -77,7 +77,7 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
} else if (b == 0xF7 /* SysEx End */) {
|
} else if (b == 0xF7 /* SysEx End */) {
|
||||||
// Log.i(TAG, "SysEx End");
|
// Log.i(TAG, "SysEx End");
|
||||||
if (mInSysEx) {
|
if (mInSysEx) {
|
||||||
mReceiver.sendWithTimestamp(data, sysExStartOffset,
|
mReceiver.send(data, sysExStartOffset,
|
||||||
offset - sysExStartOffset + 1, timestamp);
|
offset - sysExStartOffset + 1, timestamp);
|
||||||
mInSysEx = false;
|
mInSysEx = false;
|
||||||
sysExStartOffset = -1;
|
sysExStartOffset = -1;
|
||||||
@@ -91,11 +91,11 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
} else { // real-time?
|
} else { // real-time?
|
||||||
// Single byte message interleaved with other data.
|
// Single byte message interleaved with other data.
|
||||||
if (mInSysEx) {
|
if (mInSysEx) {
|
||||||
mReceiver.sendWithTimestamp(data, sysExStartOffset,
|
mReceiver.send(data, sysExStartOffset,
|
||||||
offset - sysExStartOffset, timestamp);
|
offset - sysExStartOffset, timestamp);
|
||||||
sysExStartOffset = offset + 1;
|
sysExStartOffset = offset + 1;
|
||||||
}
|
}
|
||||||
mReceiver.sendWithTimestamp(data, offset, 1, timestamp);
|
mReceiver.send(data, offset, 1, timestamp);
|
||||||
}
|
}
|
||||||
} else { // data byte
|
} else { // data byte
|
||||||
// Save SysEx data for SysEx End marker or end of buffer.
|
// Save SysEx data for SysEx End marker or end of buffer.
|
||||||
@@ -105,7 +105,7 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
if (mRunningStatus != 0) {
|
if (mRunningStatus != 0) {
|
||||||
mBuffer[0] = (byte) mRunningStatus;
|
mBuffer[0] = (byte) mRunningStatus;
|
||||||
}
|
}
|
||||||
mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
|
mReceiver.send(mBuffer, 0, mCount, timestamp);
|
||||||
mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
|
mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
|
||||||
mCount = 1;
|
mCount = 1;
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
|
|
||||||
// send any accumulatedSysEx data
|
// send any accumulatedSysEx data
|
||||||
if (sysExStartOffset >= 0 && sysExStartOffset < offset) {
|
if (sysExStartOffset >= 0 && sysExStartOffset < offset) {
|
||||||
mReceiver.sendWithTimestamp(data, sysExStartOffset,
|
mReceiver.send(data, sysExStartOffset,
|
||||||
offset - sysExStartOffset, timestamp);
|
offset - sysExStartOffset, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import android.os.IBinder;
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
interface IMidiManager
|
interface IMidiManager
|
||||||
{
|
{
|
||||||
MidiDeviceInfo[] getDeviceList();
|
MidiDeviceInfo[] getDevices();
|
||||||
|
|
||||||
// for device creation & removal notifications
|
// for device creation & removal notifications
|
||||||
void registerListener(IBinder token, in IMidiDeviceListener listener);
|
void registerListener(IBinder token, in IMidiDeviceListener listener);
|
||||||
|
|||||||
@@ -136,11 +136,14 @@ public final class MidiDevice implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* Connects the supplied {@link MidiInputPort} to the output port of this device
|
* Connects the supplied {@link MidiInputPort} to the output port of this device
|
||||||
* with the specified port number. Once the connection is made, the MidiInput port instance
|
* with the specified port number. Once the connection is made, the MidiInput port instance
|
||||||
* can no longer receive data via its {@link MidiReceiver#onReceive} method.
|
* can no longer receive data via its {@link MidiReceiver#onSend} method.
|
||||||
* This method returns a {@link MidiDevice.MidiConnection} object, which can be used to close the connection
|
* This method returns a {@link MidiDevice.MidiConnection} object, which can be used
|
||||||
|
* to close the connection.
|
||||||
|
*
|
||||||
* @param inputPort the inputPort to connect
|
* @param inputPort the inputPort to connect
|
||||||
* @param outputPortNumber the port number of the output port to connect inputPort to.
|
* @param outputPortNumber the port number of the output port to connect inputPort to.
|
||||||
* @return {@link MidiDevice.MidiConnection} object if the connection is successful, or null in case of failure
|
* @return {@link MidiDevice.MidiConnection} object if the connection is successful,
|
||||||
|
* or null in case of failure.
|
||||||
*/
|
*/
|
||||||
public MidiConnection connectPorts(MidiInputPort inputPort, int outputPortNumber) {
|
public MidiConnection connectPorts(MidiInputPort inputPort, int outputPortNumber) {
|
||||||
if (outputPortNumber < 0 || outputPortNumber >= mDeviceInfo.getOutputPortCount()) {
|
if (outputPortNumber < 0 || outputPortNumber >= mDeviceInfo.getOutputPortCount()) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's user visible name property.
|
* Bundle key for the device's user visible name property.
|
||||||
|
* The value for this property is of type {@link java.lang.String}.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
|
||||||
* For USB devices, this is a concatenation of the manufacturer and product names.
|
* For USB devices, this is a concatenation of the manufacturer and product names.
|
||||||
*/
|
*/
|
||||||
@@ -56,6 +57,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's manufacturer name property.
|
* Bundle key for the device's manufacturer name property.
|
||||||
|
* The value for this property is of type {@link java.lang.String}.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
|
||||||
* Matches the USB device manufacturer name string for USB MIDI devices.
|
* Matches the USB device manufacturer name string for USB MIDI devices.
|
||||||
*/
|
*/
|
||||||
@@ -63,6 +65,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's product name property.
|
* Bundle key for the device's product name property.
|
||||||
|
* The value for this property is of type {@link java.lang.String}.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
* Matches the USB device product name string for USB MIDI devices.
|
* Matches the USB device product name string for USB MIDI devices.
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +73,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's version property.
|
* Bundle key for the device's version property.
|
||||||
|
* The value for this property is of type {@link java.lang.String}.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
* Matches the USB device version number for USB MIDI devices.
|
* Matches the USB device version number for USB MIDI devices.
|
||||||
*/
|
*/
|
||||||
@@ -77,20 +81,23 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's serial number property.
|
* Bundle key for the device's serial number property.
|
||||||
|
* The value for this property is of type {@link java.lang.String}.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
* Matches the USB device serial number for USB MIDI devices.
|
* Matches the USB device serial number for USB MIDI devices.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_SERIAL_NUMBER = "serial_number";
|
public static final String PROPERTY_SERIAL_NUMBER = "serial_number";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's {@link android.hardware.usb.UsbDevice}.
|
* Bundle key for the device's corresponding USB device.
|
||||||
|
* The value for this property is of type {@link android.hardware.usb.UsbDevice}.
|
||||||
* Only set for USB MIDI devices.
|
* Only set for USB MIDI devices.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_USB_DEVICE = "usb_device";
|
public static final String PROPERTY_USB_DEVICE = "usb_device";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's {@link android.bluetooth.BluetoothDevice}.
|
* Bundle key for the device's corresponding Bluetooth device.
|
||||||
|
* The value for this property is of type {@link android.bluetooth.BluetoothDevice}.
|
||||||
* Only set for Bluetooth MIDI devices.
|
* Only set for Bluetooth MIDI devices.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
*/
|
*/
|
||||||
@@ -98,6 +105,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's ALSA card number.
|
* Bundle key for the device's ALSA card number.
|
||||||
|
* The value for this property is an integer.
|
||||||
* Only set for USB MIDI devices.
|
* Only set for USB MIDI devices.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
*
|
*
|
||||||
@@ -107,6 +115,7 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle key for the device's ALSA device number.
|
* Bundle key for the device's ALSA device number.
|
||||||
|
* The value for this property is an integer.
|
||||||
* Only set for USB MIDI devices.
|
* Only set for USB MIDI devices.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
*
|
*
|
||||||
@@ -115,7 +124,8 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
public static final String PROPERTY_ALSA_DEVICE = "alsa_device";
|
public static final String PROPERTY_ALSA_DEVICE = "alsa_device";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link android.content.pm.ServiceInfo} for the service hosting the device implementation.
|
* ServiceInfo for the service hosting the device implementation.
|
||||||
|
* The value for this property is of type {@link android.content.pm.ServiceInfo}.
|
||||||
* Only set for Virtual MIDI devices.
|
* Only set for Virtual MIDI devices.
|
||||||
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
|
||||||
*
|
*
|
||||||
@@ -249,18 +259,18 @@ public final class MidiDeviceInfo implements Parcelable {
|
|||||||
*
|
*
|
||||||
* @return array of {@link PortInfo}
|
* @return array of {@link PortInfo}
|
||||||
*/
|
*/
|
||||||
public PortInfo[] getPortList() {
|
public PortInfo[] getPorts() {
|
||||||
PortInfo[] portInfoList = new PortInfo[mInputPortCount + mOutputPortCount];
|
PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount];
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < mInputPortCount; i++) {
|
for (int i = 0; i < mInputPortCount; i++) {
|
||||||
portInfoList[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
|
ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mOutputPortCount; i++) {
|
for (int i = 0; i < mOutputPortCount; i++) {
|
||||||
portInfoList[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
|
ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return portInfoList;
|
return ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public final class MidiDeviceStatus implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if an input port is open.
|
* Returns true if an input port is open.
|
||||||
|
* An input port can only be opened by one client at a time.
|
||||||
*
|
*
|
||||||
* @param portNumber the input port's port number
|
* @param portNumber the input port's port number
|
||||||
* @return input port open status
|
* @return input port open status
|
||||||
@@ -78,7 +79,8 @@ public final class MidiDeviceStatus implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the open count for an output port.
|
* Returns the number of clients currently connected to the specified output port.
|
||||||
|
* Unlike input ports, an output port can be opened by multiple clients at the same time.
|
||||||
*
|
*
|
||||||
* @param portNumber the output port's port number
|
* @param portNumber the output port's port number
|
||||||
* @return output port open count
|
* @return output port open count
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public final class MidiInputPort extends MidiReceiver implements Closeable {
|
|||||||
|
|
||||||
/* package */ MidiInputPort(IMidiDeviceServer server, IBinder token,
|
/* package */ MidiInputPort(IMidiDeviceServer server, IBinder token,
|
||||||
ParcelFileDescriptor pfd, int portNumber) {
|
ParcelFileDescriptor pfd, int portNumber) {
|
||||||
|
super(MidiPortImpl.MAX_PACKET_DATA_SIZE);
|
||||||
|
|
||||||
mDeviceServer = server;
|
mDeviceServer = server;
|
||||||
mToken = token;
|
mToken = token;
|
||||||
mParcelFileDescriptor = pfd;
|
mParcelFileDescriptor = pfd;
|
||||||
@@ -71,7 +73,7 @@ public final class MidiInputPort extends MidiReceiver implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException {
|
public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
|
||||||
if (offset < 0 || count < 0 || offset + count > msg.length) {
|
if (offset < 0 || count < 0 || offset + count > msg.length) {
|
||||||
throw new IllegalArgumentException("offset or count out of range");
|
throw new IllegalArgumentException("offset or count out of range");
|
||||||
}
|
}
|
||||||
@@ -89,7 +91,7 @@ public final class MidiInputPort extends MidiReceiver implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() throws IOException {
|
public void onFlush() throws IOException {
|
||||||
synchronized (mBuffer) {
|
synchronized (mBuffer) {
|
||||||
if (mOutputStream == null) {
|
if (mOutputStream == null) {
|
||||||
throw new IOException("MidiInputPort is closed");
|
throw new IOException("MidiInputPort is closed");
|
||||||
@@ -112,11 +114,6 @@ public final class MidiInputPort extends MidiReceiver implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxMessageSize() {
|
|
||||||
return MidiPortImpl.MAX_PACKET_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
synchronized (mGuard) {
|
synchronized (mGuard) {
|
||||||
|
|||||||
@@ -151,29 +151,16 @@ public final class MidiManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback class used for receiving the results of {@link #openDevice}
|
* Listener class used for receiving the results of {@link #openDevice} and
|
||||||
|
* {@link #openBluetoothDevice}
|
||||||
*/
|
*/
|
||||||
abstract public static class DeviceOpenCallback {
|
public interface OnDeviceOpenedListener {
|
||||||
/**
|
/**
|
||||||
* Called to respond to a {@link #openDevice} request
|
* Called to respond to a {@link #openDevice} request
|
||||||
*
|
*
|
||||||
* @param deviceInfo the {@link MidiDeviceInfo} for the device to open
|
|
||||||
* @param device a {@link MidiDevice} for opened device, or null if opening failed
|
* @param device a {@link MidiDevice} for opened device, or null if opening failed
|
||||||
*/
|
*/
|
||||||
abstract public void onDeviceOpened(MidiDeviceInfo deviceInfo, MidiDevice device);
|
abstract public void onDeviceOpened(MidiDevice device);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback class used for receiving the results of {@link #openBluetoothDevice}
|
|
||||||
*/
|
|
||||||
abstract public static class BluetoothOpenCallback {
|
|
||||||
/**
|
|
||||||
* Called to respond to a {@link #openBluetoothDevice} request
|
|
||||||
*
|
|
||||||
* @param bluetoothDevice the {@link android.bluetooth.BluetoothDevice} to open
|
|
||||||
* @param device a {@link MidiDevice} for opened device, or null if opening failed
|
|
||||||
*/
|
|
||||||
abstract public void onDeviceOpened(BluetoothDevice bluetoothDevice, MidiDevice device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,38 +211,25 @@ public final class MidiManager {
|
|||||||
*
|
*
|
||||||
* @return an array of all MIDI devices
|
* @return an array of all MIDI devices
|
||||||
*/
|
*/
|
||||||
public MidiDeviceInfo[] getDeviceList() {
|
public MidiDeviceInfo[] getDevices() {
|
||||||
try {
|
try {
|
||||||
return mService.getDeviceList();
|
return mService.getDevices();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in getDeviceList");
|
Log.e(TAG, "RemoteException in getDevices");
|
||||||
return new MidiDeviceInfo[0];
|
return new MidiDeviceInfo[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendOpenDeviceResponse(final MidiDeviceInfo deviceInfo, final MidiDevice device,
|
private void sendOpenDeviceResponse(final MidiDevice device,
|
||||||
final DeviceOpenCallback callback, Handler handler) {
|
final OnDeviceOpenedListener listener, Handler handler) {
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
callback.onDeviceOpened(deviceInfo, device);
|
listener.onDeviceOpened(device);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
callback.onDeviceOpened(deviceInfo, device);
|
listener.onDeviceOpened(device);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendBluetoothDeviceResponse(final BluetoothDevice bluetoothDevice,
|
|
||||||
final MidiDevice device, final BluetoothOpenCallback callback, Handler handler) {
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
callback.onDeviceOpened(bluetoothDevice, device);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback.onDeviceOpened(bluetoothDevice, device);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,12 +237,13 @@ public final class MidiManager {
|
|||||||
* Opens a MIDI device for reading and writing.
|
* Opens a MIDI device for reading and writing.
|
||||||
*
|
*
|
||||||
* @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
|
* @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
|
||||||
* @param callback a {@link MidiManager.DeviceOpenCallback} to be called to receive the result
|
* @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
|
||||||
|
* to receive the result
|
||||||
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
|
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
|
||||||
* the result. If handler is null, then the thread used for the
|
* the result. If handler is null, then the thread used for the
|
||||||
* callback is unspecified.
|
* listener is unspecified.
|
||||||
*/
|
*/
|
||||||
public void openDevice(MidiDeviceInfo deviceInfo, DeviceOpenCallback callback,
|
public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener,
|
||||||
Handler handler) {
|
Handler handler) {
|
||||||
MidiDevice device = null;
|
MidiDevice device = null;
|
||||||
try {
|
try {
|
||||||
@@ -283,7 +258,7 @@ public final class MidiManager {
|
|||||||
intent.setComponent(new ComponentName(serviceInfo.packageName,
|
intent.setComponent(new ComponentName(serviceInfo.packageName,
|
||||||
serviceInfo.name));
|
serviceInfo.name));
|
||||||
final MidiDeviceInfo deviceInfoF = deviceInfo;
|
final MidiDeviceInfo deviceInfoF = deviceInfo;
|
||||||
final DeviceOpenCallback callbackF = callback;
|
final OnDeviceOpenedListener listenerF = listener;
|
||||||
final Handler handlerF = handler;
|
final Handler handlerF = handler;
|
||||||
if (mContext.bindService(intent,
|
if (mContext.bindService(intent,
|
||||||
new ServiceConnection() {
|
new ServiceConnection() {
|
||||||
@@ -291,8 +266,9 @@ public final class MidiManager {
|
|||||||
public void onServiceConnected(ComponentName name, IBinder binder) {
|
public void onServiceConnected(ComponentName name, IBinder binder) {
|
||||||
IMidiDeviceServer server =
|
IMidiDeviceServer server =
|
||||||
IMidiDeviceServer.Stub.asInterface(binder);
|
IMidiDeviceServer.Stub.asInterface(binder);
|
||||||
MidiDevice device = new MidiDevice(deviceInfoF, server, mContext, this);
|
MidiDevice device = new MidiDevice(deviceInfoF, server, mContext,
|
||||||
sendOpenDeviceResponse(deviceInfoF, device, callbackF, handlerF);
|
this);
|
||||||
|
sendOpenDeviceResponse(device, listenerF, handlerF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -314,21 +290,21 @@ public final class MidiManager {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in openDevice");
|
Log.e(TAG, "RemoteException in openDevice");
|
||||||
}
|
}
|
||||||
sendOpenDeviceResponse(deviceInfo, device, callback, handler);
|
sendOpenDeviceResponse(device, listener, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a Bluetooth MIDI device for reading and writing.
|
* Opens a Bluetooth MIDI device for reading and writing.
|
||||||
*
|
*
|
||||||
* @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device
|
* @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device
|
||||||
* @param callback a {@link MidiManager.BluetoothOpenCallback} to be called to receive the
|
* @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called to receive the
|
||||||
* result
|
* result
|
||||||
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
|
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
|
||||||
* the result. If handler is null, then the thread used for the
|
* the result. If handler is null, then the thread used for the
|
||||||
* callback is unspecified.
|
* listener is unspecified.
|
||||||
*/
|
*/
|
||||||
public void openBluetoothDevice(final BluetoothDevice bluetoothDevice,
|
public void openBluetoothDevice(final BluetoothDevice bluetoothDevice,
|
||||||
final BluetoothOpenCallback callback, final Handler handler) {
|
final OnDeviceOpenedListener listener, final Handler handler) {
|
||||||
Intent intent = new Intent(BLUETOOTH_MIDI_SERVICE_INTENT);
|
Intent intent = new Intent(BLUETOOTH_MIDI_SERVICE_INTENT);
|
||||||
intent.setComponent(new ComponentName(BLUETOOTH_MIDI_SERVICE_PACKAGE,
|
intent.setComponent(new ComponentName(BLUETOOTH_MIDI_SERVICE_PACKAGE,
|
||||||
BLUETOOTH_MIDI_SERVICE_CLASS));
|
BLUETOOTH_MIDI_SERVICE_CLASS));
|
||||||
@@ -343,10 +319,10 @@ public final class MidiManager {
|
|||||||
// fetch MidiDeviceInfo from the server
|
// fetch MidiDeviceInfo from the server
|
||||||
MidiDeviceInfo deviceInfo = server.getDeviceInfo();
|
MidiDeviceInfo deviceInfo = server.getDeviceInfo();
|
||||||
MidiDevice device = new MidiDevice(deviceInfo, server, mContext, this);
|
MidiDevice device = new MidiDevice(deviceInfo, server, mContext, this);
|
||||||
sendBluetoothDeviceResponse(bluetoothDevice, device, callback, handler);
|
sendOpenDeviceResponse(device, listener, handler);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "remote exception in onServiceConnected");
|
Log.e(TAG, "remote exception in onServiceConnected");
|
||||||
sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler);
|
sendOpenDeviceResponse(null, listener, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +334,7 @@ public final class MidiManager {
|
|||||||
Context.BIND_AUTO_CREATE))
|
Context.BIND_AUTO_CREATE))
|
||||||
{
|
{
|
||||||
Log.e(TAG, "Unable to bind service: " + intent);
|
Log.e(TAG, "Unable to bind service: " + intent);
|
||||||
sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler);
|
sendOpenDeviceResponse(null, listener, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public final class MidiOutputPort extends MidiSender implements Closeable {
|
|||||||
long timestamp = MidiPortImpl.getPacketTimestamp(buffer, count);
|
long timestamp = MidiPortImpl.getPacketTimestamp(buffer, count);
|
||||||
|
|
||||||
// dispatch to all our receivers
|
// dispatch to all our receivers
|
||||||
mDispatcher.sendWithTimestamp(buffer, offset, size, timestamp);
|
mDispatcher.send(buffer, offset, size, timestamp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MidiPortImpl.PACKET_TYPE_FLUSH:
|
case MidiPortImpl.PACKET_TYPE_FLUSH:
|
||||||
@@ -114,12 +114,12 @@ public final class MidiOutputPort extends MidiSender implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connect(MidiReceiver receiver) {
|
public void onConnect(MidiReceiver receiver) {
|
||||||
mDispatcher.getSender().connect(receiver);
|
mDispatcher.getSender().connect(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect(MidiReceiver receiver) {
|
public void onDisconnect(MidiReceiver receiver) {
|
||||||
mDispatcher.getSender().disconnect(receiver);
|
mDispatcher.getSender().disconnect(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,19 +22,35 @@ import java.io.IOException;
|
|||||||
* Interface for sending and receiving data to and from a MIDI device.
|
* Interface for sending and receiving data to and from a MIDI device.
|
||||||
*/
|
*/
|
||||||
abstract public class MidiReceiver {
|
abstract public class MidiReceiver {
|
||||||
|
|
||||||
|
private final int mMaxMessageSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Although public, this method should be considered a private implementation
|
* Default MidiReceiver constructor. Maximum message size is set to
|
||||||
* detail. Client code should call {@link #send} or {@link #sendWithTimestamp}
|
* {@link java.lang.Integer#MAX_VALUE}
|
||||||
* instead.
|
*/
|
||||||
*
|
public MidiReceiver() {
|
||||||
* Called to pass MIDI data to the receiver.
|
mMaxMessageSize = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MidiReceiver constructor.
|
||||||
|
* @param maxMessageSize the maximum size of a message this receiver can receive
|
||||||
|
*/
|
||||||
|
public MidiReceiver(int maxMessageSize) {
|
||||||
|
mMaxMessageSize = maxMessageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever the receiver is passed new MIDI data.
|
||||||
|
* Subclasses override this method to receive MIDI data.
|
||||||
* May fail if count exceeds {@link #getMaxMessageSize}.
|
* May fail if count exceeds {@link #getMaxMessageSize}.
|
||||||
*
|
*
|
||||||
* NOTE: the msg array parameter is only valid within the context of this call.
|
* NOTE: the msg array parameter is only valid within the context of this call.
|
||||||
* The msg bytes should be copied by the receiver rather than retaining a reference
|
* The msg bytes should be copied by the receiver rather than retaining a reference
|
||||||
* to this parameter.
|
* to this parameter.
|
||||||
* Also, modifying the contents of the msg array parameter may result in other receivers
|
* Also, modifying the contents of the msg array parameter may result in other receivers
|
||||||
* in the same application receiving incorrect values in their {link #onReceive} method.
|
* in the same application receiving incorrect values in their {link #onSend} method.
|
||||||
*
|
*
|
||||||
* @param msg a byte array containing the MIDI data
|
* @param msg a byte array containing the MIDI data
|
||||||
* @param offset the offset of the first byte of the data in the array to be processed
|
* @param offset the offset of the first byte of the data in the array to be processed
|
||||||
@@ -42,28 +58,37 @@ abstract public class MidiReceiver {
|
|||||||
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
|
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
abstract public void onReceive(byte[] msg, int offset, int count, long timestamp)
|
abstract public void onSend(byte[] msg, int offset, int count, long timestamp)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instructs the receiver to discard all pending events.
|
* Instructs the receiver to discard all pending MIDI data.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
|
onFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the receiver is instructed to discard all pending MIDI data.
|
||||||
|
* Subclasses should override this method if they maintain a list or queue of MIDI data
|
||||||
|
* to be processed in the future.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void onFlush() throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the maximum size of a message this receiver can receive.
|
* Returns the maximum size of a message this receiver can receive.
|
||||||
* Defaults to {@link java.lang.Integer#MAX_VALUE} unless overridden.
|
|
||||||
* @return maximum message size
|
* @return maximum message size
|
||||||
*/
|
*/
|
||||||
public int getMaxMessageSize() {
|
public final int getMaxMessageSize() {
|
||||||
return Integer.MAX_VALUE;
|
return mMaxMessageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to send MIDI data to the receiver
|
* Called to send MIDI data to the receiver
|
||||||
* Data will get split into multiple calls to {@link #onReceive} if count exceeds
|
* Data will get split into multiple calls to {@link #onSend} if count exceeds
|
||||||
* {@link #getMaxMessageSize}.
|
* {@link #getMaxMessageSize}.
|
||||||
*
|
*
|
||||||
* @param msg a byte array containing the MIDI data
|
* @param msg a byte array containing the MIDI data
|
||||||
@@ -72,12 +97,12 @@ abstract public class MidiReceiver {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void send(byte[] msg, int offset, int count) throws IOException {
|
public void send(byte[] msg, int offset, int count) throws IOException {
|
||||||
sendWithTimestamp(msg, offset, count, System.nanoTime());
|
send(msg, offset, count, System.nanoTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to send MIDI data to the receiver to be handled at a specified time in the future
|
* Called to send MIDI data to the receiver to be handled at a specified time in the future
|
||||||
* Data will get split into multiple calls to {@link #onReceive} if count exceeds
|
* Data will get split into multiple calls to {@link #onSend} if count exceeds
|
||||||
* {@link #getMaxMessageSize}.
|
* {@link #getMaxMessageSize}.
|
||||||
*
|
*
|
||||||
* @param msg a byte array containing the MIDI data
|
* @param msg a byte array containing the MIDI data
|
||||||
@@ -86,12 +111,12 @@ abstract public class MidiReceiver {
|
|||||||
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
|
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void sendWithTimestamp(byte[] msg, int offset, int count, long timestamp)
|
public void send(byte[] msg, int offset, int count, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
int messageSize = getMaxMessageSize();
|
int messageSize = getMaxMessageSize();
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
int length = (count > messageSize ? messageSize : count);
|
int length = (count > messageSize ? messageSize : count);
|
||||||
onReceive(msg, offset, length, timestamp);
|
onSend(msg, offset, length, timestamp);
|
||||||
offset += length;
|
offset += length;
|
||||||
count -= length;
|
count -= length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,17 +21,42 @@ package android.media.midi;
|
|||||||
* MidiReceivers to a MIDI device.
|
* MidiReceivers to a MIDI device.
|
||||||
*/
|
*/
|
||||||
abstract public class MidiSender {
|
abstract public class MidiSender {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a {@link MidiReceiver} to the sender
|
||||||
|
*
|
||||||
|
* @param receiver the receiver to connect
|
||||||
|
*/
|
||||||
|
public void connect(MidiReceiver receiver) {
|
||||||
|
if (receiver == null) {
|
||||||
|
throw new NullPointerException("receiver null in MidiSender.connect");
|
||||||
|
}
|
||||||
|
onConnect(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects a {@link MidiReceiver} from the sender
|
||||||
|
*
|
||||||
|
* @param receiver the receiver to disconnect
|
||||||
|
*/
|
||||||
|
public void disconnect(MidiReceiver receiver) {
|
||||||
|
if (receiver == null) {
|
||||||
|
throw new NullPointerException("receiver null in MidiSender.disconnect");
|
||||||
|
}
|
||||||
|
onDisconnect(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to connect a {@link MidiReceiver} to the sender
|
* Called to connect a {@link MidiReceiver} to the sender
|
||||||
*
|
*
|
||||||
* @param receiver the receiver to connect
|
* @param receiver the receiver to connect
|
||||||
*/
|
*/
|
||||||
abstract public void connect(MidiReceiver receiver);
|
abstract public void onConnect(MidiReceiver receiver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to disconnect a {@link MidiReceiver} from the sender
|
* Called to disconnect a {@link MidiReceiver} from the sender
|
||||||
*
|
*
|
||||||
* @param receiver the receiver to disconnect
|
* @param receiver the receiver to disconnect
|
||||||
*/
|
*/
|
||||||
abstract public void disconnect(MidiReceiver receiver);
|
abstract public void onDisconnect(MidiReceiver receiver);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ capabilities, etc.
|
|||||||
messages.
|
messages.
|
||||||
<li> Support transmission of arbitrary length data for SysEx, etc.
|
<li> Support transmission of arbitrary length data for SysEx, etc.
|
||||||
<li> Timestamps to avoid jitter.
|
<li> Timestamps to avoid jitter.
|
||||||
<li> Support direction connection or “patching” of devices for lower latency.
|
<li> Support direction connection or “patching” of devices for lower latency.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 id=transports_supported>Transports Supported</h2>
|
<h2 id=transports_supported>Transports Supported</h2>
|
||||||
|
|
||||||
|
|
||||||
<p>The API is “transport agnostic”. But there are several transports currently
|
<p>The API is “transport agnostic”. But there are several transports currently
|
||||||
supported:</p>
|
supported:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@@ -83,7 +83,7 @@ MidiManager m = (MidiManager)context.getSystemService(Context.MIDI_SERVICE);
|
|||||||
information can be presented to a user, allowing them to choose a device.</p>
|
information can be presented to a user, allowing them to choose a device.</p>
|
||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
MidiDeviceInfo[] infos = m.getDeviceList();
|
MidiDeviceInfo[] infos = m.getDevices();
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@@ -116,9 +116,9 @@ int numOutputs = info.getOutputPortCount();
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
<p>Note that “input” and “output” are from the standpoint of the device. So a
|
<p>Note that “input” and “output” are from the standpoint of the device. So a
|
||||||
synthesizer will have an “input” port that receives messages. A keyboard will
|
synthesizer will have an “input” port that receives messages. A keyboard will
|
||||||
have an “output” port that sends messages.</p>
|
have an “output” port that sends messages.</p>
|
||||||
|
|
||||||
<p>The MidiDeviceInfo has a bundle of properties.</p>
|
<p>The MidiDeviceInfo has a bundle of properties.</p>
|
||||||
|
|
||||||
@@ -148,12 +148,11 @@ you need to provide a callback for completion. You can specify an optional
|
|||||||
Handler if you want the callback to occur on a specific Thread.</p>
|
Handler if you want the callback to occur on a specific Thread.</p>
|
||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
m.openDevice(info, new MidiManager.DeviceOpenCallback() {
|
m.openDevice(info, new MidiManager.OnDeviceOpenedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDeviceOpened(MidiDeviceInfo deviceInfo,
|
public void onDeviceOpened(MidiDevice device) {
|
||||||
MidiDevice device) {
|
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
Log.e(TAG, "could not open " + deviceInfo);
|
Log.e(TAG, "could not open device " + info);
|
||||||
} else {
|
} else {
|
||||||
...
|
...
|
||||||
}, new Handler(Looper.getMainLooper())
|
}, new Handler(Looper.getMainLooper())
|
||||||
@@ -164,7 +163,7 @@ m.openDevice(info, new MidiManager.DeviceOpenCallback() {
|
|||||||
<h2 id=open_a_midi_input_port>Open a MIDI Input Port</h2>
|
<h2 id=open_a_midi_input_port>Open a MIDI Input Port</h2>
|
||||||
|
|
||||||
|
|
||||||
<p>If you want to send a message to a MIDI Device then you need to open an “input”
|
<p>If you want to send a message to a MIDI Device then you need to open an “input”
|
||||||
port with exclusive access.</p>
|
port with exclusive access.</p>
|
||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
@@ -199,7 +198,7 @@ consistent with the other audio and input timers.</p>
|
|||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
long now = System.nanoTime();
|
long now = System.nanoTime();
|
||||||
long future = now + (2 * 1000000000);
|
long future = now + (2 * 1000000000);
|
||||||
inputPort.sendWithTimestamp(buffer, offset, numBytes, future);
|
inputPort.send(buffer, offset, numBytes, future);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@@ -212,7 +211,7 @@ inputPort.flush(); // discard events
|
|||||||
|
|
||||||
|
|
||||||
<p>If there were any MIDI NoteOff message left in the buffer then they will be
|
<p>If there were any MIDI NoteOff message left in the buffer then they will be
|
||||||
discarded and you may get stuck notes. So we recommend sending “all notes off”
|
discarded and you may get stuck notes. So we recommend sending “all notes off”
|
||||||
after doing a flush.</p>
|
after doing a flush.</p>
|
||||||
|
|
||||||
<h2 id=receive_a_note>Receive a Note</h2>
|
<h2 id=receive_a_note>Receive a Note</h2>
|
||||||
@@ -223,7 +222,7 @@ connect your receiver to an output port of the device.</p>
|
|||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
class MyReceiver extends MidiReceiver {
|
class MyReceiver extends MidiReceiver {
|
||||||
public void onReceive(byte[] data, int offset,
|
public void onSend(byte[] data, int offset,
|
||||||
int count, long timestamp) throws IOException {
|
int count, long timestamp) throws IOException {
|
||||||
// parse MIDI or whatever
|
// parse MIDI or whatever
|
||||||
}
|
}
|
||||||
@@ -264,7 +263,7 @@ AndroidManifest.xml file.</p>
|
|||||||
|
|
||||||
|
|
||||||
<p>The details of the resource in this example is stored in
|
<p>The details of the resource in this example is stored in
|
||||||
“res/xml/synth_device_info.xml”.</p>
|
“res/xml/synth_device_info.xml”.</p>
|
||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
<devices>
|
<devices>
|
||||||
@@ -279,7 +278,7 @@ AndroidManifest.xml file.</p>
|
|||||||
|
|
||||||
|
|
||||||
<p>You then define your server by extending android.media.midi.MidiDeviceService.
|
<p>You then define your server by extending android.media.midi.MidiDeviceService.
|
||||||
Let’s assume you have a MySynthEngine class that extends MidiReceiver.</p>
|
Let‘s assume you have a MySynthEngine class that extends MidiReceiver.</p>
|
||||||
|
|
||||||
<pre class=prettyprint>
|
<pre class=prettyprint>
|
||||||
import android.media.midi.MidiDeviceService;
|
import android.media.midi.MidiDeviceService;
|
||||||
|
|||||||
@@ -234,10 +234,10 @@ public final class BluetoothMidiDevice {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mPacketEncoder.sendWithTimestamp(event.data, 0, event.count,
|
mPacketEncoder.send(event.data, 0, event.count,
|
||||||
event.getTimestamp());
|
event.getTimestamp());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "mPacketAccumulator.sendWithTimestamp failed", e);
|
Log.e(TAG, "mPacketAccumulator.send failed", e);
|
||||||
}
|
}
|
||||||
mEventScheduler.addEventToPool(event);
|
mEventScheduler.addEventToPool(event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class BluetoothPacketDecoder extends PacketDecoder {
|
|||||||
if (dataCount > 0) {
|
if (dataCount > 0) {
|
||||||
// send previous message separately since it has a different timestamp
|
// send previous message separately since it has a different timestamp
|
||||||
try {
|
try {
|
||||||
receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp);
|
receiver.send(mBuffer, 0, dataCount, nanoTimestamp);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// ???
|
// ???
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ public class BluetoothPacketDecoder extends PacketDecoder {
|
|||||||
|
|
||||||
if (dataCount > 0) {
|
if (dataCount > 0) {
|
||||||
try {
|
try {
|
||||||
receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp);
|
receiver.send(mBuffer, 0, dataCount, nanoTimestamp);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// ???
|
// ???
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class BluetoothPacketEncoder extends PacketEncoder {
|
|||||||
// This receives normalized data from mMidiFramer and accumulates it into a packet buffer
|
// This receives normalized data from mMidiFramer and accumulates it into a packet buffer
|
||||||
private final MidiReceiver mFramedDataReceiver = new MidiReceiver() {
|
private final MidiReceiver mFramedDataReceiver = new MidiReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] msg, int offset, int count, long timestamp)
|
public void onSend(byte[] msg, int offset, int count, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@@ -130,7 +130,8 @@ public class BluetoothPacketEncoder extends PacketEncoder {
|
|||||||
flushLocked(true);
|
flushLocked(true);
|
||||||
appendHeader(milliTimestamp);
|
appendHeader(milliTimestamp);
|
||||||
}
|
}
|
||||||
mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | (milliTimestamp & 0x7F));
|
mAccumulationBuffer[mAccumulatedBytes++] =
|
||||||
|
(byte)(0x80 | (milliTimestamp & 0x7F));
|
||||||
mAccumulationBuffer[mAccumulatedBytes++] = MidiConstants.STATUS_END_SYSEX;
|
mAccumulationBuffer[mAccumulatedBytes++] = MidiConstants.STATUS_END_SYSEX;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -146,7 +147,8 @@ public class BluetoothPacketEncoder extends PacketEncoder {
|
|||||||
|
|
||||||
// now copy data bytes
|
// now copy data bytes
|
||||||
int dataLength = count - 1;
|
int dataLength = count - 1;
|
||||||
System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes, dataLength);
|
System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes,
|
||||||
|
dataLength);
|
||||||
mAccumulatedBytes += dataLength;
|
mAccumulatedBytes += dataLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +162,8 @@ public class BluetoothPacketEncoder extends PacketEncoder {
|
|||||||
// write header if we are starting a new packet
|
// write header if we are starting a new packet
|
||||||
if (mAccumulatedBytes == 0) {
|
if (mAccumulatedBytes == 0) {
|
||||||
// header byte with timestamp bits 7 - 12
|
// header byte with timestamp bits 7 - 12
|
||||||
mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | ((milliTimestamp >> 7) & 0x3F));
|
mAccumulationBuffer[mAccumulatedBytes++] =
|
||||||
|
(byte)(0x80 | ((milliTimestamp >> 7) & 0x3F));
|
||||||
mPacketTimestamp = milliTimestamp;
|
mPacketTimestamp = milliTimestamp;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -177,10 +180,10 @@ public class BluetoothPacketEncoder extends PacketEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(byte[] msg, int offset, int count, long timestamp)
|
public void onSend(byte[] msg, int offset, int count, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// normalize the data by passing it through a MidiFramer first
|
// normalize the data by passing it through a MidiFramer first
|
||||||
mMidiFramer.sendWithTimestamp(msg, offset, count, timestamp);
|
mMidiFramer.send(msg, offset, count, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ public class MidiService extends IMidiManager.Stub {
|
|||||||
|
|
||||||
private static final MidiDeviceInfo[] EMPTY_DEVICE_INFO_ARRAY = new MidiDeviceInfo[0];
|
private static final MidiDeviceInfo[] EMPTY_DEVICE_INFO_ARRAY = new MidiDeviceInfo[0];
|
||||||
|
|
||||||
public MidiDeviceInfo[] getDeviceList() {
|
public MidiDeviceInfo[] getDevices() {
|
||||||
ArrayList<MidiDeviceInfo> deviceInfos = new ArrayList<MidiDeviceInfo>();
|
ArrayList<MidiDeviceInfo> deviceInfos = new ArrayList<MidiDeviceInfo>();
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user