--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+}