Merge "MIDI: fix running status parser" into mnc-dev
This commit is contained in:
@@ -55,18 +55,30 @@ public final class MidiConstants {
|
|||||||
public final static int SYSTEM_BYTE_LENGTHS[] = { 1, 2, 3, 2, 1, 1, 1, 1, 1,
|
public final static int SYSTEM_BYTE_LENGTHS[] = { 1, 2, 3, 2, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1 };
|
1, 1, 1, 1, 1, 1, 1 };
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
public static int getBytesPerMessage(int command) {
|
/**
|
||||||
if ((command < 0x80) || (command > 0xFF)) {
|
* MIDI messages, except for SysEx, are 1,2 or 3 bytes long.
|
||||||
return 0;
|
* You can tell how long a MIDI message is from the first status byte.
|
||||||
} else if (command >= 0xF0) {
|
* Do not call this for SysEx, which has variable length.
|
||||||
return SYSTEM_BYTE_LENGTHS[command & 0x0F];
|
* @param statusByte
|
||||||
|
* @return number of bytes in a complete message or zero if data byte passed
|
||||||
|
*/
|
||||||
|
public static int getBytesPerMessage(byte statusByte) {
|
||||||
|
// Java bytes are signed so we need to mask off the high bits
|
||||||
|
// to get a value between 0 and 255.
|
||||||
|
int statusInt = statusByte & 0xFF;
|
||||||
|
if (statusInt >= 0xF0) {
|
||||||
|
// System messages use low nibble for size.
|
||||||
|
return SYSTEM_BYTE_LENGTHS[statusInt & 0x0F];
|
||||||
|
} else if(statusInt >= 0x80) {
|
||||||
|
// Channel voice messages use high nibble for size.
|
||||||
|
return CHANNEL_BYTE_LENGTHS[(statusInt >> 4) - 8];
|
||||||
} else {
|
} else {
|
||||||
return CHANNEL_BYTE_LENGTHS[(command >> 4) - 8];
|
return 0; // data byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param msg
|
* @param msg
|
||||||
* @param offset
|
* @param offset
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package com.android.internal.midi;
|
package com.android.internal.midi;
|
||||||
|
|
||||||
import android.media.midi.MidiReceiver;
|
import android.media.midi.MidiReceiver;
|
||||||
import android.util.Log;
|
//import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
private MidiReceiver mReceiver;
|
private MidiReceiver mReceiver;
|
||||||
private byte[] mBuffer = new byte[3];
|
private byte[] mBuffer = new byte[3];
|
||||||
private int mCount;
|
private int mCount;
|
||||||
private int mRunningStatus;
|
private byte mRunningStatus;
|
||||||
private int mNeeded;
|
private int mNeeded;
|
||||||
private boolean mInSysEx;
|
private boolean mInSysEx;
|
||||||
|
|
||||||
@@ -59,22 +59,22 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public void onSend(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));
|
|
||||||
int sysExStartOffset = (mInSysEx ? offset : -1);
|
int sysExStartOffset = (mInSysEx ? offset : -1);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int b = data[offset] & 0xFF;
|
final byte currentByte = data[offset];
|
||||||
if (b >= 0x80) { // status byte?
|
final int currentInt = currentByte & 0xFF;
|
||||||
if (b < 0xF0) { // channel message?
|
if (currentInt >= 0x80) { // status byte?
|
||||||
mRunningStatus = (byte) b;
|
if (currentInt < 0xF0) { // channel message?
|
||||||
|
mRunningStatus = currentByte;
|
||||||
mCount = 1;
|
mCount = 1;
|
||||||
mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
|
mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1;
|
||||||
} else if (b < 0xF8) { // system common?
|
} else if (currentInt < 0xF8) { // system common?
|
||||||
if (b == 0xF0 /* SysEx Start */) {
|
if (currentInt == 0xF0 /* SysEx Start */) {
|
||||||
// Log.i(TAG, "SysEx Start");
|
// Log.i(TAG, "SysEx Start");
|
||||||
mInSysEx = true;
|
mInSysEx = true;
|
||||||
sysExStartOffset = offset;
|
sysExStartOffset = offset;
|
||||||
} else if (b == 0xF7 /* SysEx End */) {
|
} else if (currentInt == 0xF7 /* SysEx End */) {
|
||||||
// Log.i(TAG, "SysEx End");
|
// Log.i(TAG, "SysEx End");
|
||||||
if (mInSysEx) {
|
if (mInSysEx) {
|
||||||
mReceiver.send(data, sysExStartOffset,
|
mReceiver.send(data, sysExStartOffset,
|
||||||
@@ -83,10 +83,10 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
sysExStartOffset = -1;
|
sysExStartOffset = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mBuffer[0] = (byte) b;
|
mBuffer[0] = currentByte;
|
||||||
mRunningStatus = 0;
|
mRunningStatus = 0;
|
||||||
mCount = 1;
|
mCount = 1;
|
||||||
mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
|
mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1;
|
||||||
}
|
}
|
||||||
} else { // real-time?
|
} else { // real-time?
|
||||||
// Single byte message interleaved with other data.
|
// Single byte message interleaved with other data.
|
||||||
@@ -98,12 +98,11 @@ public class MidiFramer extends MidiReceiver {
|
|||||||
mReceiver.send(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.
|
|
||||||
if (!mInSysEx) {
|
if (!mInSysEx) {
|
||||||
mBuffer[mCount++] = (byte) b;
|
mBuffer[mCount++] = currentByte;
|
||||||
if (--mNeeded == 0) {
|
if (--mNeeded == 0) {
|
||||||
if (mRunningStatus != 0) {
|
if (mRunningStatus != 0) {
|
||||||
mBuffer[0] = (byte) mRunningStatus;
|
mBuffer[0] = mRunningStatus;
|
||||||
}
|
}
|
||||||
mReceiver.send(mBuffer, 0, mCount, timestamp);
|
mReceiver.send(mBuffer, 0, mCount, timestamp);
|
||||||
mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
|
mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user