| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.example.android.midiscope; |
| |
| import android.media.midi.MidiDeviceInfo; |
| import android.media.midi.MidiDeviceInfo.PortInfo; |
| import android.os.Bundle; |
| |
| import com.example.android.common.midi.MidiConstants; |
| |
| /** |
| * Format a MIDI message for printing. |
| */ |
| public class MidiPrinter { |
| |
| public static final String[] CHANNEL_COMMAND_NAMES = { "NoteOff", "NoteOn", |
| "PolyTouch", "Control", "Program", "Pressure", "Bend" }; |
| public static final String[] SYSTEM_COMMAND_NAMES = { "SysEx", // F0 |
| "TimeCode", // F1 |
| "SongPos", // F2 |
| "SongSel", // F3 |
| "F4", // F4 |
| "F5", // F5 |
| "TuneReq", // F6 |
| "EndSysex", // F7 |
| "TimingClock", // F8 |
| "F9", // F9 |
| "Start", // FA |
| "Continue", // FB |
| "Stop", // FC |
| "FD", // FD |
| "ActiveSensing", // FE |
| "Reset" // FF |
| }; |
| |
| public static String getName(int status) { |
| if (status >= 0xF0) { |
| int index = status & 0x0F; |
| return SYSTEM_COMMAND_NAMES[index]; |
| } else if (status >= 0x80) { |
| int index = (status >> 4) & 0x07; |
| return CHANNEL_COMMAND_NAMES[index]; |
| } else { |
| return "data"; |
| } |
| } |
| |
| public static String formatBytes(byte[] data, int offset, int count) { |
| StringBuilder sb = new StringBuilder(); |
| for (int i = 0; i < count; i++) { |
| sb.append(String.format(" %02X", data[offset + i])); |
| } |
| return sb.toString(); |
| } |
| |
| public static String formatMessage(byte[] data, int offset, int count) { |
| StringBuilder sb = new StringBuilder(); |
| byte statusByte = data[offset++]; |
| int status = statusByte & 0xFF; |
| sb.append(getName(status)).append("("); |
| int numData = MidiConstants.getBytesPerMessage(statusByte) - 1; |
| if ((status >= 0x80) && (status < 0xF0)) { // channel message |
| int channel = status & 0x0F; |
| // Add 1 for humans who think channels are numbered 1-16. |
| sb.append((channel + 1)).append(", "); |
| } |
| for (int i = 0; i < numData; i++) { |
| if (i > 0) { |
| sb.append(", "); |
| } |
| sb.append(data[offset++]); |
| } |
| sb.append(")"); |
| return sb.toString(); |
| } |
| |
| public static String formatDeviceInfo(MidiDeviceInfo info) { |
| StringBuilder sb = new StringBuilder(); |
| if (info != null) { |
| Bundle properties = info.getProperties(); |
| for (String key : properties.keySet()) { |
| Object value = properties.get(key); |
| sb.append(key).append(" = ").append(value).append('\n'); |
| } |
| for (PortInfo port : info.getPorts()) { |
| sb.append((port.getType() == PortInfo.TYPE_INPUT) ? "input" |
| : "output"); |
| sb.append("[").append(port.getPortNumber()).append("] = \"").append(port.getName() |
| + "\"\n"); |
| } |
| } |
| return sb.toString(); |
| } |
| } |