/* * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package com.sun.media.sound;import javax.sound.midi.MidiDevice;import javax.sound.midi.spi.MidiDeviceProvider;/** * Super class for MIDI input or output device provider. * * @author Florian Bomers */public abstract class AbstractMidiDeviceProvider extends MidiDeviceProvider { private static boolean enabled; /** * Create objects representing all MIDI output devices on the system. */ static { if (Printer.trace) Printer.trace("AbstractMidiDeviceProvider: static"); Platform.initialize(); enabled = Platform.isMidiIOEnabled(); if (Printer.trace) Printer.trace("AbstractMidiDeviceProvider: enabled: " + enabled); // $$fb number of MIDI devices may change with time // also for memory's sake, do not initialize the arrays here } synchronized void readDeviceInfos() { Info[] infos = getInfoCache(); MidiDevice[] devices = getDeviceCache(); if (!enabled) { if (infos == null || infos.length != 0) { setInfoCache(new Info[0]); } if (devices == null || devices.length != 0) { setDeviceCache(new MidiDevice[0]); } return; } int oldNumDevices = (infos==null)?-1:infos.length; int newNumDevices = getNumDevices(); if (oldNumDevices != newNumDevices) { if (Printer.trace) Printer.trace(getClass().toString() +": readDeviceInfos: old numDevices: "+oldNumDevices +" newNumDevices: "+ newNumDevices); // initialize the arrays Info[] newInfos = new Info[newNumDevices]; MidiDevice[] newDevices = new MidiDevice[newNumDevices]; for (int i = 0; i < newNumDevices; i++) { Info newInfo = createInfo(i); // in case that we are re-reading devices, try to find // the previous one and reuse it if (infos != null) { for (int ii = 0; ii < infos.length; ii++) { Info info = infos[ii]; if (info != null && info.equalStrings(newInfo)) { // new info matches the still existing info. Use old one newInfos[i] = info; info.setIndex(i); infos[ii] = null; // prevent re-use newDevices[i] = devices[ii]; devices[ii] = null; break; } } } if (newInfos[i] == null) { newInfos[i] = newInfo; } } // the remaining MidiDevice.Info instances in the infos array // have become obsolete. if (infos != null) { for (int i = 0; i < infos.length; i++) { if (infos[i] != null) { // disable this device info infos[i].setIndex(-1); } // what to do with the MidiDevice instances that are left // in the devices array ?? Close them ? } } // commit new list of infos. setInfoCache(newInfos); setDeviceCache(newDevices); } } public MidiDevice.Info[] getDeviceInfo() { readDeviceInfos(); Info[] infos = getInfoCache(); MidiDevice.Info[] localArray = new MidiDevice.Info[infos.length]; System.arraycopy(infos, 0, localArray, 0, infos.length); return localArray; } public MidiDevice getDevice(MidiDevice.Info info) { if (info instanceof Info) { readDeviceInfos(); MidiDevice[] devices = getDeviceCache(); Info[] infos = getInfoCache(); Info thisInfo = (Info) info; int index = thisInfo.getIndex(); if (index >= 0 && index < devices.length && infos[index] == info) { if (devices[index] == null) { devices[index] = createDevice(thisInfo); } if (devices[index] != null) { return devices[index]; } } } throw new IllegalArgumentException("MidiDevice " + info.toString() + " not supported by this provider."); } // INNER CLASSES /** * Info class for MidiDevices. Adds an index value for * making native references to a particular device. */ static class Info extends MidiDevice.Info { private int index; Info(String name, String vendor, String description, String version, int index) { super(name, vendor, description, version); this.index = index; } boolean equalStrings(Info info) { return (info != null && getName().equals(info.getName()) && getVendor().equals(info.getVendor()) && getDescription().equals(info.getDescription()) && getVersion().equals(info.getVersion())); } int getIndex() { return index; } void setIndex(int index) { this.index = index; } } // class Info // ABSTRACT METHODS abstract int getNumDevices(); abstract MidiDevice[] getDeviceCache(); abstract void setDeviceCache(MidiDevice[] devices); abstract Info[] getInfoCache(); abstract void setInfoCache(Info[] infos); abstract Info createInfo(int index); abstract MidiDevice createDevice(Info info);}
/*
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.media.sound;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.spi.MidiDeviceProvider;
/**
* Super class for MIDI input or output device provider.
*
* @author Florian Bomers
*/
public abstract class AbstractMidiDeviceProvider extends MidiDeviceProvider {
private static boolean enabled;
/**
* Create objects representing all MIDI output devices on the system.
*/
static {
if (Printer.trace) Printer.trace("AbstractMidiDeviceProvider: static");
Platform.initialize();
enabled = Platform.isMidiIOEnabled();
if (Printer.trace) Printer.trace("AbstractMidiDeviceProvider: enabled: " + enabled);
// $$fb number of MIDI devices may change with time
// also for memory's sake, do not initialize the arrays here
}
synchronized void readDeviceInfos() {
Info[] infos = getInfoCache();
MidiDevice[] devices = getDeviceCache();
if (!enabled) {
if (infos == null || infos.length != 0) {
setInfoCache(new Info[0]);
}
if (devices == null || devices.length != 0) {
setDeviceCache(new MidiDevice[0]);
}
return;
}
int oldNumDevices = (infos==null)?-1:infos.length;
int newNumDevices = getNumDevices();
if (oldNumDevices != newNumDevices) {
if (Printer.trace) Printer.trace(getClass().toString()
+": readDeviceInfos: old numDevices: "+oldNumDevices
+" newNumDevices: "+ newNumDevices);
// initialize the arrays
Info[] newInfos = new Info[newNumDevices];
MidiDevice[] newDevices = new MidiDevice[newNumDevices];
for (int i = 0; i < newNumDevices; i++) {
Info newInfo = createInfo(i);
// in case that we are re-reading devices, try to find
// the previous one and reuse it
if (infos != null) {
for (int ii = 0; ii < infos.length; ii++) {
Info info = infos[ii];
if (info != null && info.equalStrings(newInfo)) {
// new info matches the still existing info. Use old one
newInfos[i] = info;
info.setIndex(i);
infos[ii] = null; // prevent re-use
newDevices[i] = devices[ii];
devices[ii] = null;
break;
}
}
}
if (newInfos[i] == null) {
newInfos[i] = newInfo;
}
}
// the remaining MidiDevice.Info instances in the infos array
// have become obsolete.
if (infos != null) {
for (int i = 0; i < infos.length; i++) {
if (infos[i] != null) {
// disable this device info
infos[i].setIndex(-1);
}
// what to do with the MidiDevice instances that are left
// in the devices array ?? Close them ?
}
}
// commit new list of infos.
setInfoCache(newInfos);
setDeviceCache(newDevices);
}
}
public MidiDevice.Info[] getDeviceInfo() {
readDeviceInfos();
Info[] infos = getInfoCache();
MidiDevice.Info[] localArray = new MidiDevice.Info[infos.length];
System.arraycopy(infos, 0, localArray, 0, infos.length);
return localArray;
}
public MidiDevice getDevice(MidiDevice.Info info) {
if (info instanceof Info) {
readDeviceInfos();
MidiDevice[] devices = getDeviceCache();
Info[] infos = getInfoCache();
Info thisInfo = (Info) info;
int index = thisInfo.getIndex();
if (index >= 0 && index < devices.length && infos[index] == info) {
if (devices[index] == null) {
devices[index] = createDevice(thisInfo);
}
if (devices[index] != null) {
return devices[index];
}
}
}
throw new IllegalArgumentException("MidiDevice " + info.toString()
+ " not supported by this provider.");
}
// INNER CLASSES
/**
* Info class for MidiDevices. Adds an index value for
* making native references to a particular device.
*/
static class Info extends MidiDevice.Info {
private int index;
Info(String name, String vendor, String description, String version, int index) {
super(name, vendor, description, version);
this.index = index;
}
boolean equalStrings(Info info) {
return (info != null
&& getName().equals(info.getName())
&& getVendor().equals(info.getVendor())
&& getDescription().equals(info.getDescription())
&& getVersion().equals(info.getVersion()));
}
int getIndex() {
return index;
}
void setIndex(int index) {
this.index = index;
}
} // class Info
// ABSTRACT METHODS
abstract int getNumDevices();
abstract MidiDevice[] getDeviceCache();
abstract void setDeviceCache(MidiDevice[] devices);
abstract Info[] getInfoCache();
abstract void setInfoCache(Info[] infos);
abstract Info createInfo(int index);
abstract MidiDevice createDevice(Info info);
}