Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/sound/midi/Devices/IOLoop.java
41152 views
1
/*
2
* Copyright (c) 2002, 2016, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.io.ByteArrayOutputStream;
25
26
import javax.sound.midi.MidiDevice;
27
import javax.sound.midi.MidiMessage;
28
import javax.sound.midi.MidiSystem;
29
import javax.sound.midi.Receiver;
30
import javax.sound.midi.ShortMessage;
31
import javax.sound.midi.SysexMessage;
32
import javax.sound.midi.Transmitter;
33
34
/**
35
* @test
36
* @bug 4782924
37
* @bug 4812168
38
* @bug 4356787
39
* @summary MIDI i/o. This is an interactive test! Start it and follow the
40
* instructions.
41
* @run main/manual IOLoop
42
*/
43
public class IOLoop {
44
private static final int LONG_SYSEX_LENGTH = 2000;
45
46
private static Receiver receiver;
47
private static Transmitter transmitter;
48
private static MidiMessage receivedMessage;
49
private static ByteArrayOutputStream baos;
50
private static int expectedBytes;
51
private static int receivedBytes;
52
private static Object lock = new Object();
53
private static long lastTimestamp;
54
55
public static void main(String[] args) throws Exception {
56
ShortMessage sMsg = new ShortMessage();
57
SysexMessage syMsg = new SysexMessage();
58
boolean isTestPassed = true;
59
boolean sysExTestPassed = true;
60
boolean isTestExecuted = true;
61
62
out("To run this test successfully, you need to have attached");
63
out(" your MIDI out port with the MIDI in port.");
64
65
MidiDevice inDev = null;
66
MidiDevice outDev = null;
67
68
// setup
69
try {
70
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
71
72
int devNum = Integer.decode(args[0]).intValue();
73
out("-> opening Transmitter from "+infos[devNum]);
74
inDev = MidiSystem.getMidiDevice(infos[devNum]);
75
inDev.open();
76
transmitter = inDev.getTransmitter();
77
Receiver testReceiver = new TestReceiver();
78
transmitter.setReceiver(testReceiver);
79
80
devNum = Integer.decode(args[1]).intValue();
81
out("-> opening Receiver from "+infos[devNum]);
82
outDev = MidiSystem.getMidiDevice(infos[devNum]);
83
outDev.open();
84
receiver = outDev.getReceiver();
85
86
} catch (Exception e) {
87
System.out.println(e);
88
System.out.println("Cannot test!");
89
return;
90
}
91
92
// test
93
sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 27, 100);
94
isTestPassed &= testMessage(sMsg);
95
sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 0, 0);
96
isTestPassed &= testMessage(sMsg);
97
sMsg.setMessage(ShortMessage.NOTE_OFF | 15, 127, 127);
98
isTestPassed &= testMessage(sMsg);
99
sMsg.setMessage(ShortMessage.NOTE_ON | 4, 27, 0);
100
isTestPassed &= testMessage(sMsg);
101
sMsg.setMessage(ShortMessage.NOTE_ON | 0, 0, 0);
102
isTestPassed &= testMessage(sMsg);
103
sMsg.setMessage(ShortMessage.NOTE_ON | 15, 127, 127);
104
isTestPassed &= testMessage(sMsg);
105
sMsg.setMessage(ShortMessage.POLY_PRESSURE | 11, 98, 99);
106
isTestPassed &= testMessage(sMsg);
107
sMsg.setMessage(ShortMessage.POLY_PRESSURE | 0, 0, 0);
108
isTestPassed &= testMessage(sMsg);
109
sMsg.setMessage(ShortMessage.POLY_PRESSURE | 15, 127, 127);
110
isTestPassed &= testMessage(sMsg);
111
sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 13, 1, 63);
112
isTestPassed &= testMessage(sMsg);
113
sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 0, 0, 0);
114
isTestPassed &= testMessage(sMsg);
115
sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 15, 127, 127);
116
isTestPassed &= testMessage(sMsg);
117
sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 2, 120, 0);
118
isTestPassed &= testMessage(sMsg);
119
sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 0, 0, 0);
120
isTestPassed &= testMessage(sMsg);
121
sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 15, 127, 0);
122
isTestPassed &= testMessage(sMsg);
123
sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 6, 30, 0);
124
isTestPassed &= testMessage(sMsg);
125
sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 0, 0, 0);
126
isTestPassed &= testMessage(sMsg);
127
sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 15, 127, 0);
128
isTestPassed &= testMessage(sMsg);
129
130
sMsg.setMessage(ShortMessage.PITCH_BEND | 6, 56, 4);
131
isTestPassed &= testMessage(sMsg);
132
sMsg.setMessage(ShortMessage.PITCH_BEND | 0, 0, 0);
133
isTestPassed &= testMessage(sMsg);
134
sMsg.setMessage(ShortMessage.PITCH_BEND | 15, 127, 127);
135
isTestPassed &= testMessage(sMsg);
136
137
sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 0, 0);
138
isTestPassed &= testMessage(sMsg);
139
sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 127, 0);
140
isTestPassed &= testMessage(sMsg);
141
sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 1, 77);
142
isTestPassed &= testMessage(sMsg);
143
sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 0, 0);
144
isTestPassed &= testMessage(sMsg);
145
sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 127, 127);
146
isTestPassed &= testMessage(sMsg);
147
sMsg.setMessage(ShortMessage.SONG_SELECT, 51, 0);
148
isTestPassed &= testMessage(sMsg);
149
sMsg.setMessage(ShortMessage.SONG_SELECT, 0, 0);
150
isTestPassed &= testMessage(sMsg);
151
sMsg.setMessage(ShortMessage.SONG_SELECT, 127, 0);
152
isTestPassed &= testMessage(sMsg);
153
sMsg.setMessage(ShortMessage.TUNE_REQUEST);
154
isTestPassed &= testMessage(sMsg);
155
156
sMsg.setMessage(ShortMessage.TIMING_CLOCK);
157
isTestPassed &= testMessage(sMsg);
158
sMsg.setMessage(ShortMessage.START);
159
isTestPassed &= testMessage(sMsg);
160
sMsg.setMessage(ShortMessage.CONTINUE);
161
isTestPassed &= testMessage(sMsg);
162
sMsg.setMessage(ShortMessage.STOP);
163
isTestPassed &= testMessage(sMsg);
164
sMsg.setMessage(ShortMessage.ACTIVE_SENSING);
165
isTestPassed &= testMessage(sMsg);
166
sMsg.setMessage(ShortMessage.SYSTEM_RESET);
167
isTestPassed &= testMessage(sMsg);
168
169
syMsg.setMessage(new byte[]{(byte) 0xF0, (byte) 0xF7}, 2);
170
isTestPassed &= testMessage(syMsg);
171
syMsg.setMessage(new byte[]{(byte) 0xF0, 0x01, (byte) 0xF7}, 3);
172
isTestPassed &= testMessage(syMsg);
173
syMsg.setMessage(new byte[]{(byte) 0xF0, 0x02, 0x03, (byte) 0xF7}, 4);
174
isTestPassed &= testMessage(syMsg);
175
syMsg.setMessage(new byte[]{(byte) 0xF0, 0x04, 0x05, 0x06, (byte) 0xF7}, 5);
176
isTestPassed &= testMessage(syMsg);
177
178
if (isTestPassed) {
179
byte[] sysexArray = new byte[LONG_SYSEX_LENGTH];
180
sysexArray[0] = (byte) 0xF0;
181
for (int i = 1; i < sysexArray.length; i++) {
182
sysexArray[i] = (byte) (i % 0x80);
183
}
184
// syMsg.setMessage(new byte[]{(byte) 0xF7, (byte) ShortMessage.START}, 2);
185
// sMsg.setMessage(ShortMessage.START);
186
// isTestPassed &= testMessage(syMsg, sMsg, DEFAULT_SLEEP_INTERVALL);
187
for (int trial = sysexArray.length; trial > 4; trial -= 1234) {
188
sleep(500);
189
sysexArray[trial - 1] = (byte) 0xF7;
190
syMsg.setMessage(sysexArray, trial);
191
sysExTestPassed &= testMessage(syMsg);
192
break;
193
}
194
}
195
196
// cleanup
197
receiver.close();
198
transmitter.close();
199
inDev.close();
200
outDev.close();
201
202
if (isTestExecuted) {
203
if (isTestPassed && sysExTestPassed) {
204
205
out("Test PASSED.");
206
} else {
207
if (isTestPassed
208
&& !sysExTestPassed
209
&& (System.getProperty("os.name").startsWith("Windows"))) {
210
out("Some Windows MIDI i/o drivers have a problem with larger ");
211
out("sys ex messages. The failing sys ex cases are OK, therefore.");
212
out("Test PASSED.");
213
} else {
214
throw new Exception("Test FAILED.");
215
}
216
}
217
} else {
218
out("Test NOT FAILED");
219
}
220
}
221
222
private static boolean testMessage(MidiMessage message) {
223
receivedMessage = null;
224
baos = new ByteArrayOutputStream();
225
expectedBytes = message.getLength();
226
receivedBytes = 0;
227
System.out.print("Sending message " + getMessageString(message.getMessage())+"...");
228
receiver.send(message, -1);
229
/* sending 3 bytes can roughly be done in 1 millisecond,
230
* so this estimate waits at max 3 times longer than the message takes,
231
* plus a little offset to allow the MIDI subsystem some processing time
232
*/
233
int offset = 300; // standard offset 100 millis
234
if (message instanceof SysexMessage) {
235
// add a little processing time to sysex messages
236
offset += 1000;
237
}
238
if (receivedBytes < expectedBytes) {
239
sleep(expectedBytes + offset);
240
}
241
boolean equal;
242
byte[] data = baos.toByteArray();
243
if (data.length > 0) {
244
equal = messagesEqual(message.getMessage(), data);
245
} else {
246
equal = messagesEqual(message, receivedMessage);
247
if (receivedMessage != null) {
248
data = receivedMessage.getMessage();
249
} else {
250
data = null;
251
}
252
}
253
if (!equal) {
254
if ((message.getStatus() & 0xF0) == ShortMessage.PITCH_BEND) {
255
out("NOT failed (may expose a bug in ALSA)");
256
equal = true;
257
sleep(100);
258
}
259
if ((message.getStatus() == 0xF6) && (message.getLength() == 1)) {
260
out("NOT failed (may expose an issue on Solaris)");
261
equal = true;
262
sleep(100);
263
}
264
else if ((message.getStatus()) == 0xF0 && message.getLength() < 4) {
265
out("NOT failed (not a correct sys ex message)");
266
equal = true;
267
sleep(200);
268
} else {
269
out("FAILED:");
270
out(" received as " + getMessageString(data));
271
}
272
} else {
273
System.out.println("OK");
274
}
275
return equal;
276
}
277
278
private static void sleep(int milliseconds) {
279
synchronized(lock) {
280
try {
281
lock.wait(milliseconds);
282
} catch (InterruptedException e) {
283
}
284
}
285
}
286
287
private static String getMessageString(byte[] data) {
288
String s;
289
if (data == null) {
290
s = "<null>";
291
} else if (data.length == 0) {
292
s = "0-sized array";
293
} else {
294
int status = data[0] & 0xFF;
295
if (data.length <= 3) {
296
if (status < 240) {
297
s = "command 0x" + Integer.toHexString(status & 0xF0) + " channel " + (status & 0x0F);
298
} else {
299
s = "status 0x" + Integer.toHexString(status);
300
}
301
if (data.length > 1) {
302
s += " data 0x" + Integer.toHexString(data[1] & 0xFF);
303
if (data.length > 2) {
304
s += " 0x" + Integer.toHexString(data[2] & 0xFF);
305
}
306
}
307
} else {
308
s = "status " + Integer.toHexString(status)+" and length "+data.length+" bytes";
309
}
310
}
311
return s;
312
}
313
314
private static boolean messagesEqual(MidiMessage m1, MidiMessage m2) {
315
if (m1 == null || m2 == null) {
316
return false;
317
}
318
if (m1.getLength() != m2.getLength()) {
319
return false;
320
}
321
byte[] array1 = m1.getMessage();
322
byte[] array2 = m2.getMessage();
323
return messagesEqual(array1, array2);
324
}
325
326
private static boolean messagesEqual(byte[] a1, byte[] a2) {
327
if (a1.length != a2.length) return false;
328
for (int i = 0; i < a1.length; i++) {
329
if (a1[i] != a2[i]) {
330
return false;
331
}
332
}
333
return true;
334
}
335
336
private static void out(String s) {
337
System.out.println(s);
338
System.out.flush();
339
}
340
341
private static String canIn(MidiDevice dev) {
342
if (dev.getMaxTransmitters() != 0) {
343
return "IN ";
344
}
345
return " ";
346
}
347
348
private static String canOut(MidiDevice dev) {
349
if (dev.getMaxReceivers() != 0) {
350
return "OUT ";
351
}
352
return " ";
353
}
354
355
356
private static void checkTimestamp(long timestamp) {
357
// out("checking timestamp...");
358
if (timestamp < 1) {
359
out("timestamp 0 or negative!");
360
}
361
if (timestamp < lastTimestamp) {
362
out("timestamp not progressive!");
363
}
364
lastTimestamp = timestamp;
365
}
366
367
private static class TestReceiver implements Receiver {
368
public void send(MidiMessage message, long timestamp) {
369
//System.out.print(""+message.getLength()+"..");
370
checkTimestamp(timestamp);
371
try {
372
receivedMessage = message;
373
if (message.getStatus() == 0xF0
374
|| (message.getLength() > 3 && message.getStatus() != 0xF7)) {
375
// sys ex message
376
byte[] data = message.getMessage();
377
baos.write(data);
378
receivedBytes += data.length;
379
}
380
else if (message.getStatus() == 0xF7) {
381
// sys ex cont'd message
382
byte[] data = message.getMessage();
383
// ignore the prepended 0xF7
384
baos.write(data, 1, data.length-1);
385
receivedBytes += (data.length - 1);
386
} else {
387
receivedBytes += message.getLength();
388
}
389
if (receivedBytes >= expectedBytes) {
390
synchronized(lock) {
391
lock.notify();
392
}
393
}
394
System.out.print(""+receivedBytes+"..");
395
396
} catch (Exception e) {
397
e.printStackTrace();
398
}
399
}
400
401
public void close() {
402
}
403
}
404
}
405
406