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 
getName(int status)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 
formatBytes(byte[] data, int offset, int count)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 
formatMessage(byte[] data, int offset, int count)70     public static String formatMessage(byte[] data, int offset, int count) {
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 
formatDeviceInfo(MidiDeviceInfo info)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"
101                         : "output");
102                 sb.append("[").append(port.getPortNumber()).append("] = \"").append(port.getName()
103                         + "\"\n");
104             }
105         }
106         return sb.toString();
107     }
108 }
109