1 /*
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.media.sound;
27
28 import java.util.ArrayList;
29
30 import javax.sound.midi.MetaMessage;
31 import javax.sound.midi.MidiDevice;
32 import javax.sound.midi.MidiEvent;
33 import javax.sound.midi.MidiMessage;
34 import javax.sound.midi.Sequence;
35 import javax.sound.midi.Track;
36
37 // TODO:
38 // - define and use a global symbolic constant for 60000000 (see convertTempo)
39
40 /**
41 * Some utilities for MIDI (some stuff is used from javax.sound.midi)
42 *
43 * @author Florian Bomers
44 */
45 public final class MidiUtils {
46
47 public static final int DEFAULT_TEMPO_MPQ = 500000; // 120bpm
48 public static final int META_END_OF_TRACK_TYPE = 0x2F;
49 public static final int META_TEMPO_TYPE = 0x51;
50
51 /**
52 * Suppresses default constructor, ensuring non-instantiability.
53 */
54 private MidiUtils() {
55 }
56
57 /**
58 * Returns an exception which should be thrown if MidiDevice is unsupported.
59 *
60 * @param info an info object that describes the desired device
61 * @return an exception instance
62 */
63 static RuntimeException unsupportedDevice(final MidiDevice.Info info) {
64 return new IllegalArgumentException(String.format(
65 "MidiDevice %s not supported by this provider", info));
66 }
67
68 /** return true if the passed message is Meta End Of Track */
69 public static boolean isMetaEndOfTrack(MidiMessage midiMsg) {
70 // first check if it is a META message at all
71 if (midiMsg.getLength() != 3
72 || midiMsg.getStatus() != MetaMessage.META) {
73 return false;
74 }
75 // now get message and check for end of track
76 byte[] msg = midiMsg.getMessage();
77 return ((msg[1] & 0xFF) == META_END_OF_TRACK_TYPE) && (msg[2] == 0);
78 }
79
80 /** return if the given message is a meta tempo message */
81 public static boolean isMetaTempo(MidiMessage midiMsg) {
82 // first check if it is a META message at all
83 if (midiMsg.getLength() != 6
84 || midiMsg.getStatus() != MetaMessage.META) {
85 return false;
86 }
87 // now get message and check for tempo
|
1 /*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.media.sound;
27
28 import java.util.ArrayList;
29
30 import javax.sound.midi.InvalidMidiDataException;
31 import javax.sound.midi.MetaMessage;
32 import javax.sound.midi.MidiDevice;
33 import javax.sound.midi.MidiEvent;
34 import javax.sound.midi.MidiMessage;
35 import javax.sound.midi.Sequence;
36 import javax.sound.midi.Track;
37
38 import static javax.sound.midi.SysexMessage.SPECIAL_SYSTEM_EXCLUSIVE;
39 import static javax.sound.midi.SysexMessage.SYSTEM_EXCLUSIVE;
40
41 // TODO:
42 // - define and use a global symbolic constant for 60000000 (see convertTempo)
43
44 /**
45 * Some utilities for MIDI (some stuff is used from javax.sound.midi)
46 *
47 * @author Florian Bomers
48 */
49 public final class MidiUtils {
50
51 public static final int DEFAULT_TEMPO_MPQ = 500000; // 120bpm
52 public static final int META_END_OF_TRACK_TYPE = 0x2F;
53 public static final int META_TEMPO_TYPE = 0x51;
54
55 /**
56 * Suppresses default constructor, ensuring non-instantiability.
57 */
58 private MidiUtils() {
59 }
60
61 /**
62 * Returns an exception which should be thrown if MidiDevice is unsupported.
63 *
64 * @param info an info object that describes the desired device
65 * @return an exception instance
66 */
67 static RuntimeException unsupportedDevice(final MidiDevice.Info info) {
68 return new IllegalArgumentException(String.format(
69 "MidiDevice %s not supported by this provider", info));
70 }
71
72 /**
73 * Checks the status byte for the system exclusive message.
74 *
75 * @param data the system exclusive message data
76 * @param length the length of the valid message data in the array
77 * @throws InvalidMidiDataException if the status byte is invalid for a
78 * system exclusive message
79 */
80 public static void checkSysexStatus(final byte[] data, final int length)
81 throws InvalidMidiDataException {
82 if (data.length == 0 || length == 0) {
83 throw new InvalidMidiDataException("Status byte is missing");
84 }
85 checkSysexStatus(data[0] & 0xFF);
86 }
87
88 /**
89 * Checks the status byte for the system exclusive message.
90 *
91 * @param status the status byte for the message (0xF0 or 0xF7)
92 * @throws InvalidMidiDataException if the status byte is invalid for a
93 * system exclusive message
94 */
95 public static void checkSysexStatus(final int status)
96 throws InvalidMidiDataException {
97 if (status != SYSTEM_EXCLUSIVE && status != SPECIAL_SYSTEM_EXCLUSIVE) {
98 throw new InvalidMidiDataException(String.format(
99 "Invalid status byte for sysex message: 0x%X", status));
100 }
101 }
102
103 /** return true if the passed message is Meta End Of Track */
104 public static boolean isMetaEndOfTrack(MidiMessage midiMsg) {
105 // first check if it is a META message at all
106 if (midiMsg.getLength() != 3
107 || midiMsg.getStatus() != MetaMessage.META) {
108 return false;
109 }
110 // now get message and check for end of track
111 byte[] msg = midiMsg.getMessage();
112 return ((msg[1] & 0xFF) == META_END_OF_TRACK_TYPE) && (msg[2] == 0);
113 }
114
115 /** return if the given message is a meta tempo message */
116 public static boolean isMetaTempo(MidiMessage midiMsg) {
117 // first check if it is a META message at all
118 if (midiMsg.getLength() != 6
119 || midiMsg.getStatus() != MetaMessage.META) {
120 return false;
121 }
122 // now get message and check for tempo
|