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