Merge "MIDI: fix running status parser" into mnc-dev

This commit is contained in:
Phil Burk
2015-07-27 17:15:04 +00:00
committed by Android (Google) Code Review
2 changed files with 34 additions and 23 deletions

View File

@@ -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

View File

@@ -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;