/* * 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(); } }