1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.midiscope; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import android.media.midi.MidiDeviceInfo; 20*90c8c64dSAndroid Build Coastguard Worker import android.media.midi.MidiDeviceInfo.PortInfo; 21*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle; 22*90c8c64dSAndroid Build Coastguard Worker 23*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.midi.MidiConstants; 24*90c8c64dSAndroid Build Coastguard Worker 25*90c8c64dSAndroid Build Coastguard Worker /** 26*90c8c64dSAndroid Build Coastguard Worker * Format a MIDI message for printing. 27*90c8c64dSAndroid Build Coastguard Worker */ 28*90c8c64dSAndroid Build Coastguard Worker public class MidiPrinter { 29*90c8c64dSAndroid Build Coastguard Worker 30*90c8c64dSAndroid Build Coastguard Worker public static final String[] CHANNEL_COMMAND_NAMES = { "NoteOff", "NoteOn", 31*90c8c64dSAndroid Build Coastguard Worker "PolyTouch", "Control", "Program", "Pressure", "Bend" }; 32*90c8c64dSAndroid Build Coastguard Worker public static final String[] SYSTEM_COMMAND_NAMES = { "SysEx", // F0 33*90c8c64dSAndroid Build Coastguard Worker "TimeCode", // F1 34*90c8c64dSAndroid Build Coastguard Worker "SongPos", // F2 35*90c8c64dSAndroid Build Coastguard Worker "SongSel", // F3 36*90c8c64dSAndroid Build Coastguard Worker "F4", // F4 37*90c8c64dSAndroid Build Coastguard Worker "F5", // F5 38*90c8c64dSAndroid Build Coastguard Worker "TuneReq", // F6 39*90c8c64dSAndroid Build Coastguard Worker "EndSysex", // F7 40*90c8c64dSAndroid Build Coastguard Worker "TimingClock", // F8 41*90c8c64dSAndroid Build Coastguard Worker "F9", // F9 42*90c8c64dSAndroid Build Coastguard Worker "Start", // FA 43*90c8c64dSAndroid Build Coastguard Worker "Continue", // FB 44*90c8c64dSAndroid Build Coastguard Worker "Stop", // FC 45*90c8c64dSAndroid Build Coastguard Worker "FD", // FD 46*90c8c64dSAndroid Build Coastguard Worker "ActiveSensing", // FE 47*90c8c64dSAndroid Build Coastguard Worker "Reset" // FF 48*90c8c64dSAndroid Build Coastguard Worker }; 49*90c8c64dSAndroid Build Coastguard Worker getName(int status)50*90c8c64dSAndroid Build Coastguard Worker public static String getName(int status) { 51*90c8c64dSAndroid Build Coastguard Worker if (status >= 0xF0) { 52*90c8c64dSAndroid Build Coastguard Worker int index = status & 0x0F; 53*90c8c64dSAndroid Build Coastguard Worker return SYSTEM_COMMAND_NAMES[index]; 54*90c8c64dSAndroid Build Coastguard Worker } else if (status >= 0x80) { 55*90c8c64dSAndroid Build Coastguard Worker int index = (status >> 4) & 0x07; 56*90c8c64dSAndroid Build Coastguard Worker return CHANNEL_COMMAND_NAMES[index]; 57*90c8c64dSAndroid Build Coastguard Worker } else { 58*90c8c64dSAndroid Build Coastguard Worker return "data"; 59*90c8c64dSAndroid Build Coastguard Worker } 60*90c8c64dSAndroid Build Coastguard Worker } 61*90c8c64dSAndroid Build Coastguard Worker formatBytes(byte[] data, int offset, int count)62*90c8c64dSAndroid Build Coastguard Worker public static String formatBytes(byte[] data, int offset, int count) { 63*90c8c64dSAndroid Build Coastguard Worker StringBuilder sb = new StringBuilder(); 64*90c8c64dSAndroid Build Coastguard Worker for (int i = 0; i < count; i++) { 65*90c8c64dSAndroid Build Coastguard Worker sb.append(String.format(" %02X", data[offset + i])); 66*90c8c64dSAndroid Build Coastguard Worker } 67*90c8c64dSAndroid Build Coastguard Worker return sb.toString(); 68*90c8c64dSAndroid Build Coastguard Worker } 69*90c8c64dSAndroid Build Coastguard Worker formatMessage(byte[] data, int offset, int count)70*90c8c64dSAndroid Build Coastguard Worker public static String formatMessage(byte[] data, int offset, int count) { 71*90c8c64dSAndroid Build Coastguard Worker StringBuilder sb = new StringBuilder(); 72*90c8c64dSAndroid Build Coastguard Worker byte statusByte = data[offset++]; 73*90c8c64dSAndroid Build Coastguard Worker int status = statusByte & 0xFF; 74*90c8c64dSAndroid Build Coastguard Worker sb.append(getName(status)).append("("); 75*90c8c64dSAndroid Build Coastguard Worker int numData = MidiConstants.getBytesPerMessage(statusByte) - 1; 76*90c8c64dSAndroid Build Coastguard Worker if ((status >= 0x80) && (status < 0xF0)) { // channel message 77*90c8c64dSAndroid Build Coastguard Worker int channel = status & 0x0F; 78*90c8c64dSAndroid Build Coastguard Worker // Add 1 for humans who think channels are numbered 1-16. 79*90c8c64dSAndroid Build Coastguard Worker sb.append((channel + 1)).append(", "); 80*90c8c64dSAndroid Build Coastguard Worker } 81*90c8c64dSAndroid Build Coastguard Worker for (int i = 0; i < numData; i++) { 82*90c8c64dSAndroid Build Coastguard Worker if (i > 0) { 83*90c8c64dSAndroid Build Coastguard Worker sb.append(", "); 84*90c8c64dSAndroid Build Coastguard Worker } 85*90c8c64dSAndroid Build Coastguard Worker sb.append(data[offset++]); 86*90c8c64dSAndroid Build Coastguard Worker } 87*90c8c64dSAndroid Build Coastguard Worker sb.append(")"); 88*90c8c64dSAndroid Build Coastguard Worker return sb.toString(); 89*90c8c64dSAndroid Build Coastguard Worker } 90*90c8c64dSAndroid Build Coastguard Worker formatDeviceInfo(MidiDeviceInfo info)91*90c8c64dSAndroid Build Coastguard Worker public static String formatDeviceInfo(MidiDeviceInfo info) { 92*90c8c64dSAndroid Build Coastguard Worker StringBuilder sb = new StringBuilder(); 93*90c8c64dSAndroid Build Coastguard Worker if (info != null) { 94*90c8c64dSAndroid Build Coastguard Worker Bundle properties = info.getProperties(); 95*90c8c64dSAndroid Build Coastguard Worker for (String key : properties.keySet()) { 96*90c8c64dSAndroid Build Coastguard Worker Object value = properties.get(key); 97*90c8c64dSAndroid Build Coastguard Worker sb.append(key).append(" = ").append(value).append('\n'); 98*90c8c64dSAndroid Build Coastguard Worker } 99*90c8c64dSAndroid Build Coastguard Worker for (PortInfo port : info.getPorts()) { 100*90c8c64dSAndroid Build Coastguard Worker sb.append((port.getType() == PortInfo.TYPE_INPUT) ? "input" 101*90c8c64dSAndroid Build Coastguard Worker : "output"); 102*90c8c64dSAndroid Build Coastguard Worker sb.append("[").append(port.getPortNumber()).append("] = \"").append(port.getName() 103*90c8c64dSAndroid Build Coastguard Worker + "\"\n"); 104*90c8c64dSAndroid Build Coastguard Worker } 105*90c8c64dSAndroid Build Coastguard Worker } 106*90c8c64dSAndroid Build Coastguard Worker return sb.toString(); 107*90c8c64dSAndroid Build Coastguard Worker } 108*90c8c64dSAndroid Build Coastguard Worker } 109