0N/A/*
3909N/A * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.sound.midi;
0N/A
0N/Aimport java.io.FileInputStream;
0N/Aimport java.io.File;
0N/Aimport java.io.InputStream;
0N/Aimport java.io.OutputStream;
0N/Aimport java.io.IOException;
0N/A
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.List;
0N/Aimport java.util.Set;
0N/A
0N/Aimport java.net.URL;
0N/A
0N/Aimport javax.sound.midi.spi.MidiFileWriter;
0N/Aimport javax.sound.midi.spi.MidiFileReader;
0N/Aimport javax.sound.midi.spi.SoundbankReader;
0N/Aimport javax.sound.midi.spi.MidiDeviceProvider;
0N/A
0N/Aimport com.sun.media.sound.JDK13Services;
0N/Aimport com.sun.media.sound.ReferenceCountingDevice;
0N/Aimport com.sun.media.sound.AutoConnectSequencer;
2719N/Aimport com.sun.media.sound.MidiDeviceReceiverEnvelope;
2719N/Aimport com.sun.media.sound.MidiDeviceTransmitterEnvelope;
0N/A
0N/A
0N/A/**
0N/A * The <code>MidiSystem</code> class provides access to the installed MIDI
0N/A * system resources, including devices such as synthesizers, sequencers, and
0N/A * MIDI input and output ports. A typical simple MIDI application might
0N/A * begin by invoking one or more <code>MidiSystem</code> methods to learn
0N/A * what devices are installed and to obtain the ones needed in that
0N/A * application.
0N/A * <p>
0N/A * The class also has methods for reading files, streams, and URLs that
0N/A * contain standard MIDI file data or soundbanks. You can query the
0N/A * <code>MidiSystem</code> for the format of a specified MIDI file.
0N/A * <p>
0N/A * You cannot instantiate a <code>MidiSystem</code>; all the methods are
0N/A * static.
0N/A *
0N/A * <p>Properties can be used to specify default MIDI devices.
0N/A * Both system properties and a properties file are considered.
0N/A * The properties file is &quot;lib/sound.properties&quot; in the JRE
0N/A * directory. If a property exists both as a system property and in the
0N/A * properties file, the system property takes precedence. If none is
0N/A * specified, a suitable default is chosen among the available devices.
0N/A * The syntax of the properties file is specified in
0N/A * {@link java.util.Properties#load(InputStream) Properties.load}. The
0N/A * following table lists the available property keys and which methods
0N/A * consider them:
0N/A *
0N/A * <table border=0>
0N/A * <tr>
0N/A * <th>Property Key</th>
0N/A * <th>Interface</th>
0N/A * <th>Affected Method</th>
0N/A * </tr>
0N/A * <tr>
0N/A * <td><code>javax.sound.midi.Receiver</code></td>
0N/A * <td>{@link Receiver}</td>
0N/A * <td>{@link #getReceiver}</td>
0N/A * </tr>
0N/A * <tr>
0N/A * <td><code>javax.sound.midi.Sequencer</code></td>
0N/A * <td>{@link Sequencer}</td>
0N/A * <td>{@link #getSequencer}</td>
0N/A * </tr>
0N/A * <tr>
0N/A * <td><code>javax.sound.midi.Synthesizer</code></td>
0N/A * <td>{@link Synthesizer}</td>
0N/A * <td>{@link #getSynthesizer}</td>
0N/A * </tr>
0N/A * <tr>
0N/A * <td><code>javax.sound.midi.Transmitter</code></td>
0N/A * <td>{@link Transmitter}</td>
0N/A * <td>{@link #getTransmitter}</td>
0N/A * </tr>
0N/A * </table>
0N/A *
0N/A * The property value consists of the provider class name
0N/A * and the device name, separated by the hash mark (&quot;#&quot;).
0N/A * The provider class name is the fully-qualified
0N/A * name of a concrete {@link javax.sound.midi.spi.MidiDeviceProvider
0N/A * MIDI device provider} class. The device name is matched against
0N/A * the <code>String</code> returned by the <code>getName</code>
0N/A * method of <code>MidiDevice.Info</code>.
0N/A * Either the class name, or the device name may be omitted.
0N/A * If only the class name is specified, the trailing hash mark
0N/A * is optional.
0N/A *
0N/A * <p>If the provider class is specified, and it can be
0N/A * successully retrieved from the installed providers,
0N/A * the list of
0N/A * <code>MidiDevice.Info</code> objects is retrieved
0N/A * from the provider. Otherwise, or when these devices
0N/A * do not provide a subsequent match, the list is retrieved
0N/A * from {@link #getMidiDeviceInfo} to contain
0N/A * all available <code>MidiDevice.Info</code> objects.
0N/A *
0N/A * <p>If a device name is specified, the resulting list of
0N/A * <code>MidiDevice.Info</code> objects is searched:
0N/A * the first one with a matching name, and whose
0N/A * <code>MidiDevice</code> implements the
0N/A * respective interface, will be returned.
0N/A * If no matching <code>MidiDevice.Info</code> object
0N/A * is found, or the device name is not specified,
0N/A * the first suitable device from the resulting
0N/A * list will be returned. For Sequencer and Synthesizer,
0N/A * a device is suitable if it implements the respective
0N/A * interface; whereas for Receiver and Transmitter, a device is
0N/A * suitable if it
0N/A * implements neither Sequencer nor Synthesizer and provides
0N/A * at least one Receiver or Transmitter, respectively.
0N/A *
0N/A * For example, the property <code>javax.sound.midi.Receiver</code>
0N/A * with a value
0N/A * <code>&quot;com.sun.media.sound.MidiProvider#SunMIDI1&quot;</code>
0N/A * will have the following consequences when
0N/A * <code>getReceiver</code> is called:
0N/A * if the class <code>com.sun.media.sound.MidiProvider</code> exists
0N/A * in the list of installed MIDI device providers,
0N/A * the first <code>Receiver</code> device with name
0N/A * <code>&quot;SunMIDI1&quot;</code> will be returned. If it cannot
0N/A * be found, the first <code>Receiver</code> from that provider
0N/A * will be returned, regardless of name.
0N/A * If there is none, the first <code>Receiver</code> with name
0N/A * <code>&quot;SunMIDI1&quot;</code> in the list of all devices
0N/A * (as returned by <code>getMidiDeviceInfo</code>) will be returned,
0N/A * or, if not found, the first <code>Receiver</code> that can
0N/A * be found in the list of all devices is returned.
0N/A * If that fails, too, a <code>MidiUnavailableException</code>
0N/A * is thrown.
0N/A *
0N/A * @author Kara Kytle
0N/A * @author Florian Bomers
0N/A * @author Matthias Pfisterer
0N/A */
0N/Apublic class MidiSystem {
0N/A
0N/A /**
0N/A * Private no-args constructor for ensuring against instantiation.
0N/A */
0N/A private MidiSystem() {
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains an array of information objects representing
0N/A * the set of all MIDI devices available on the system.
0N/A * A returned information object can then be used to obtain the
0N/A * corresponding device object, by invoking
0N/A * {@link #getMidiDevice(MidiDevice.Info) getMidiDevice}.
0N/A *
0N/A * @return an array of <code>MidiDevice.Info</code> objects, one
0N/A * for each installed MIDI device. If no such devices are installed,
0N/A * an array of length 0 is returned.
0N/A */
0N/A public static MidiDevice.Info[] getMidiDeviceInfo() {
0N/A List allInfos = new ArrayList();
0N/A List providers = getMidiDeviceProviders();
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
0N/A MidiDevice.Info[] tmpinfo = provider.getDeviceInfo();
0N/A for (int j = 0; j < tmpinfo.length; j++) {
0N/A allInfos.add( tmpinfo[j] );
0N/A }
0N/A }
0N/A MidiDevice.Info[] infosArray = (MidiDevice.Info[]) allInfos.toArray(new MidiDevice.Info[0]);
0N/A return infosArray;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the requested MIDI device.
0N/A *
0N/A * @param info a device information object representing the desired device.
0N/A * @return the requested device
0N/A * @throws MidiUnavailableException if the requested device is not available
0N/A * due to resource restrictions
0N/A * @throws IllegalArgumentException if the info object does not represent
0N/A * a MIDI device installed on the system
0N/A * @see #getMidiDeviceInfo
0N/A */
0N/A public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavailableException {
0N/A List providers = getMidiDeviceProviders();
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
0N/A if (provider.isDeviceSupported(info)) {
0N/A MidiDevice device = provider.getDevice(info);
0N/A return device;
0N/A }
0N/A }
0N/A throw new IllegalArgumentException("Requested device not installed: " + info);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains a MIDI receiver from an external MIDI port
0N/A * or other default device.
2719N/A * The returned receiver always implements
2719N/A * the {@code MidiDeviceReceiver} interface.
0N/A *
0N/A * <p>If the system property
0N/A * <code>javax.sound.midi.Receiver</code>
0N/A * is defined or it is defined in the file &quot;sound.properties&quot;,
0N/A * it is used to identify the device that provides the default receiver.
0N/A * For details, refer to the {@link MidiSystem class description}.
0N/A *
0N/A * If a suitable MIDI port is not available, the Receiver is
0N/A * retrieved from an installed synthesizer.
0N/A *
3956N/A * <p>If a native receiver provided by the default device does not implement
3956N/A * the {@code MidiDeviceReceiver} interface, it will be wrapped in a
3956N/A * wrapper class that implements the {@code MidiDeviceReceiver} interface.
3956N/A * The corresponding {@code Receiver} method calls will be forwarded
3956N/A * to the native receiver.
3956N/A *
0N/A * <p>If this method returns successfully, the {@link
0N/A * javax.sound.midi.MidiDevice MidiDevice} the
0N/A * <code>Receiver</code> belongs to is opened implicitly, if it is
0N/A * not already open. It is possible to close an implicitly opened
0N/A * device by calling {@link javax.sound.midi.Receiver#close close}
0N/A * on the returned <code>Receiver</code>. All open <code>Receiver</code>
0N/A * instances have to be closed in order to release system resources
0N/A * hold by the <code>MidiDevice</code>. For a
0N/A * detailed description of open/close behaviour see the class
0N/A * description of {@link javax.sound.midi.MidiDevice MidiDevice}.
0N/A *
0N/A *
0N/A * @return the default MIDI receiver
0N/A * @throws MidiUnavailableException if the default receiver is not
0N/A * available due to resource restrictions,
0N/A * or no device providing receivers is installed in the system
0N/A */
0N/A public static Receiver getReceiver() throws MidiUnavailableException {
0N/A // may throw MidiUnavailableException
0N/A MidiDevice device = getDefaultDeviceWrapper(Receiver.class);
0N/A Receiver receiver;
0N/A if (device instanceof ReferenceCountingDevice) {
0N/A receiver = ((ReferenceCountingDevice) device).getReceiverReferenceCounting();
0N/A } else {
0N/A receiver = device.getReceiver();
0N/A }
2719N/A if (!(receiver instanceof MidiDeviceReceiver)) {
2719N/A receiver = new MidiDeviceReceiverEnvelope(device, receiver);
2719N/A }
0N/A return receiver;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains a MIDI transmitter from an external MIDI port
0N/A * or other default source.
2719N/A * The returned transmitter always implements
2719N/A * the {@code MidiDeviceTransmitter} interface.
0N/A *
0N/A * <p>If the system property
0N/A * <code>javax.sound.midi.Transmitter</code>
0N/A * is defined or it is defined in the file &quot;sound.properties&quot;,
0N/A * it is used to identify the device that provides the default transmitter.
0N/A * For details, refer to the {@link MidiSystem class description}.
0N/A *
3956N/A * <p>If a native transmitter provided by the default device does not implement
3956N/A * the {@code MidiDeviceTransmitter} interface, it will be wrapped in a
3956N/A * wrapper class that implements the {@code MidiDeviceTransmitter} interface.
3956N/A * The corresponding {@code Transmitter} method calls will be forwarded
3956N/A * to the native transmitter.
3956N/A *
3956N/A * <p>If this method returns successfully, the {@link
0N/A * javax.sound.midi.MidiDevice MidiDevice} the
0N/A * <code>Transmitter</code> belongs to is opened implicitly, if it
0N/A * is not already open. It is possible to close an implicitly
0N/A * opened device by calling {@link
0N/A * javax.sound.midi.Transmitter#close close} on the returned
0N/A * <code>Transmitter</code>. All open <code>Transmitter</code>
0N/A * instances have to be closed in order to release system resources
0N/A * hold by the <code>MidiDevice</code>. For a detailed description
0N/A * of open/close behaviour see the class description of {@link
0N/A * javax.sound.midi.MidiDevice MidiDevice}.
0N/A *
0N/A * @return the default MIDI transmitter
0N/A * @throws MidiUnavailableException if the default transmitter is not
0N/A * available due to resource restrictions,
0N/A * or no device providing transmitters is installed in the system
0N/A */
0N/A public static Transmitter getTransmitter() throws MidiUnavailableException {
0N/A // may throw MidiUnavailableException
0N/A MidiDevice device = getDefaultDeviceWrapper(Transmitter.class);
0N/A Transmitter transmitter;
0N/A if (device instanceof ReferenceCountingDevice) {
0N/A transmitter = ((ReferenceCountingDevice) device).getTransmitterReferenceCounting();
0N/A } else {
0N/A transmitter = device.getTransmitter();
0N/A }
3311N/A if (!(transmitter instanceof MidiDeviceTransmitter)) {
2719N/A transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
2719N/A }
0N/A return transmitter;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the default synthesizer.
0N/A *
0N/A * <p>If the system property
0N/A * <code>javax.sound.midi.Synthesizer</code>
0N/A * is defined or it is defined in the file &quot;sound.properties&quot;,
0N/A * it is used to identify the default synthesizer.
0N/A * For details, refer to the {@link MidiSystem class description}.
0N/A *
0N/A * @return the default synthesizer
0N/A * @throws MidiUnavailableException if the synthesizer is not
0N/A * available due to resource restrictions,
0N/A * or no synthesizer is installed in the system
0N/A */
0N/A public static Synthesizer getSynthesizer() throws MidiUnavailableException {
0N/A // may throw MidiUnavailableException
0N/A return (Synthesizer) getDefaultDeviceWrapper(Synthesizer.class);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the default <code>Sequencer</code>, connected to
0N/A * a default device.
0N/A * The returned <code>Sequencer</code> instance is
0N/A * connected to the default <code>Synthesizer</code>,
0N/A * as returned by {@link #getSynthesizer}.
0N/A * If there is no <code>Synthesizer</code>
0N/A * available, or the default <code>Synthesizer</code>
0N/A * cannot be opened, the <code>sequencer</code> is connected
0N/A * to the default <code>Receiver</code>, as returned
0N/A * by {@link #getReceiver}.
0N/A * The connection is made by retrieving a <code>Transmitter</code>
0N/A * instance from the <code>Sequencer</code> and setting its
0N/A * <code>Receiver</code>.
0N/A * Closing and re-opening the sequencer will restore the
0N/A * connection to the default device.
0N/A *
0N/A * <p>This method is equivalent to calling
0N/A * <code>getSequencer(true)</code>.
0N/A *
0N/A * <p>If the system property
0N/A * <code>javax.sound.midi.Sequencer</code>
0N/A * is defined or it is defined in the file &quot;sound.properties&quot;,
0N/A * it is used to identify the default sequencer.
0N/A * For details, refer to the {@link MidiSystem class description}.
0N/A *
0N/A * @return the default sequencer, connected to a default Receiver
0N/A * @throws MidiUnavailableException if the sequencer is not
0N/A * available due to resource restrictions,
0N/A * or there is no <code>Receiver</code> available by any
0N/A * installed <code>MidiDevice</code>,
0N/A * or no sequencer is installed in the system.
0N/A * @see #getSequencer(boolean)
0N/A * @see #getSynthesizer
0N/A * @see #getReceiver
0N/A */
0N/A public static Sequencer getSequencer() throws MidiUnavailableException {
0N/A return getSequencer(true);
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Obtains the default <code>Sequencer</code>, optionally
0N/A * connected to a default device.
0N/A *
0N/A * <p>If <code>connected</code> is true, the returned
0N/A * <code>Sequencer</code> instance is
0N/A * connected to the default <code>Synthesizer</code>,
0N/A * as returned by {@link #getSynthesizer}.
0N/A * If there is no <code>Synthesizer</code>
0N/A * available, or the default <code>Synthesizer</code>
0N/A * cannot be opened, the <code>sequencer</code> is connected
0N/A * to the default <code>Receiver</code>, as returned
0N/A * by {@link #getReceiver}.
0N/A * The connection is made by retrieving a <code>Transmitter</code>
0N/A * instance from the <code>Sequencer</code> and setting its
0N/A * <code>Receiver</code>.
0N/A * Closing and re-opening the sequencer will restore the
0N/A * connection to the default device.
0N/A *
0N/A * <p>If <code>connected</code> is false, the returned
0N/A * <code>Sequencer</code> instance is not connected, it
0N/A * has no open <code>Transmitters</code>. In order to
0N/A * play the sequencer on a MIDI device, or a <code>Synthesizer</code>,
0N/A * it is necessary to get a <code>Transmitter</code> and set its
0N/A * <code>Receiver</code>.
0N/A *
0N/A * <p>If the system property
0N/A * <code>javax.sound.midi.Sequencer</code>
0N/A * is defined or it is defined in the file "sound.properties",
0N/A * it is used to identify the default sequencer.
0N/A * For details, refer to the {@link MidiSystem class description}.
0N/A *
0N/A * @return the default sequencer
0N/A * @throws MidiUnavailableException if the sequencer is not
0N/A * available due to resource restrictions,
0N/A * or no sequencer is installed in the system,
0N/A * or if <code>connected</code> is true, and there is
0N/A * no <code>Receiver</code> available by any installed
0N/A * <code>MidiDevice</code>
0N/A * @see #getSynthesizer
0N/A * @see #getReceiver
0N/A * @since 1.5
0N/A */
0N/A public static Sequencer getSequencer(boolean connected)
0N/A throws MidiUnavailableException {
0N/A Sequencer seq = (Sequencer) getDefaultDeviceWrapper(Sequencer.class);
0N/A
0N/A if (connected) {
0N/A // IMPORTANT: this code needs to be synch'ed with
0N/A // all AutoConnectSequencer instances,
0N/A // (e.g. RealTimeSequencer) because the
0N/A // same algorithm for synth retrieval
0N/A // needs to be used!
0N/A
0N/A Receiver rec = null;
0N/A MidiUnavailableException mue = null;
0N/A
0N/A // first try to connect to the default synthesizer
0N/A try {
0N/A Synthesizer synth = getSynthesizer();
0N/A if (synth instanceof ReferenceCountingDevice) {
0N/A rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
0N/A } else {
0N/A synth.open();
0N/A try {
0N/A rec = synth.getReceiver();
0N/A } finally {
0N/A // make sure that the synth is properly closed
0N/A if (rec == null) {
0N/A synth.close();
0N/A }
0N/A }
0N/A }
0N/A } catch (MidiUnavailableException e) {
0N/A // something went wrong with synth
0N/A if (e instanceof MidiUnavailableException) {
0N/A mue = (MidiUnavailableException) e;
0N/A }
0N/A }
0N/A if (rec == null) {
0N/A // then try to connect to the default Receiver
0N/A try {
0N/A rec = MidiSystem.getReceiver();
0N/A } catch (Exception e) {
0N/A // something went wrong. Nothing to do then!
0N/A if (e instanceof MidiUnavailableException) {
0N/A mue = (MidiUnavailableException) e;
0N/A }
0N/A }
0N/A }
0N/A if (rec != null) {
0N/A seq.getTransmitter().setReceiver(rec);
0N/A if (seq instanceof AutoConnectSequencer) {
0N/A ((AutoConnectSequencer) seq).setAutoConnect(rec);
0N/A }
0N/A } else {
0N/A if (mue != null) {
0N/A throw mue;
0N/A }
0N/A throw new MidiUnavailableException("no receiver available");
0N/A }
0N/A }
0N/A return seq;
0N/A }
0N/A
0N/A
0N/A
0N/A
0N/A /**
0N/A * Constructs a MIDI sound bank by reading it from the specified stream.
0N/A * The stream must point to
0N/A * a valid MIDI soundbank file. In general, MIDI soundbank providers may
0N/A * need to read some data from the stream before determining whether they
0N/A * support it. These parsers must
0N/A * be able to mark the stream, read enough data to determine whether they
0N/A * support the stream, and, if not, reset the stream's read pointer to
0N/A * its original position. If the input stream does not support this,
0N/A * this method may fail with an IOException.
0N/A * @param stream the source of the sound bank data.
0N/A * @return the sound bank
0N/A * @throws InvalidMidiDataException if the stream does not point to
0N/A * valid MIDI soundbank data recognized by the system
0N/A * @throws IOException if an I/O error occurred when loading the soundbank
0N/A * @see InputStream#markSupported
0N/A * @see InputStream#mark
0N/A */
0N/A public static Soundbank getSoundbank(InputStream stream)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A SoundbankReader sp = null;
0N/A Soundbank s = null;
0N/A
0N/A List providers = getSoundbankReaders();
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A sp = (SoundbankReader)providers.get(i);
0N/A s = sp.getSoundbank(stream);
0N/A
0N/A if( s!= null) {
0N/A return s;
0N/A }
0N/A }
0N/A throw new InvalidMidiDataException("cannot get soundbank from stream");
0N/A
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Constructs a <code>Soundbank</code> by reading it from the specified URL.
0N/A * The URL must point to a valid MIDI soundbank file.
0N/A *
0N/A * @param url the source of the sound bank data
0N/A * @return the sound bank
0N/A * @throws InvalidMidiDataException if the URL does not point to valid MIDI
0N/A * soundbank data recognized by the system
0N/A * @throws IOException if an I/O error occurred when loading the soundbank
0N/A */
0N/A public static Soundbank getSoundbank(URL url)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A SoundbankReader sp = null;
0N/A Soundbank s = null;
0N/A
0N/A List providers = getSoundbankReaders();
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A sp = (SoundbankReader)providers.get(i);
0N/A s = sp.getSoundbank(url);
0N/A
0N/A if( s!= null) {
0N/A return s;
0N/A }
0N/A }
0N/A throw new InvalidMidiDataException("cannot get soundbank from stream");
0N/A
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Constructs a <code>Soundbank</code> by reading it from the specified
0N/A * <code>File</code>.
0N/A * The <code>File</code> must point to a valid MIDI soundbank file.
0N/A *
0N/A * @param file the source of the sound bank data
0N/A * @return the sound bank
0N/A * @throws InvalidMidiDataException if the <code>File</code> does not
0N/A * point to valid MIDI soundbank data recognized by the system
0N/A * @throws IOException if an I/O error occurred when loading the soundbank
0N/A */
0N/A public static Soundbank getSoundbank(File file)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A SoundbankReader sp = null;
0N/A Soundbank s = null;
0N/A
0N/A List providers = getSoundbankReaders();
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A sp = (SoundbankReader)providers.get(i);
0N/A s = sp.getSoundbank(file);
0N/A
0N/A if( s!= null) {
0N/A return s;
0N/A }
0N/A }
0N/A throw new InvalidMidiDataException("cannot get soundbank from stream");
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Obtains the MIDI file format of the data in the specified input stream.
0N/A * The stream must point to valid MIDI file data for a file type recognized
0N/A * by the system.
0N/A * <p>
0N/A * This method and/or the code it invokes may need to read some data from
0N/A * the stream to determine whether its data format is supported. The
0N/A * implementation may therefore
0N/A * need to mark the stream, read enough data to determine whether it is in
0N/A * a supported format, and reset the stream's read pointer to its original
0N/A * position. If the input stream does not permit this set of operations,
0N/A * this method may fail with an <code>IOException</code>.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while determining the file format.
0N/A *
0N/A * @param stream the input stream from which file format information
0N/A * should be extracted
0N/A * @return an <code>MidiFileFormat</code> object describing the MIDI file
0N/A * format
0N/A * @throws InvalidMidiDataException if the stream does not point to valid
0N/A * MIDI file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs while accessing the
0N/A * stream
0N/A * @see #getMidiFileFormat(URL)
0N/A * @see #getMidiFileFormat(File)
0N/A * @see InputStream#markSupported
0N/A * @see InputStream#mark
0N/A */
0N/A public static MidiFileFormat getMidiFileFormat(InputStream stream)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A MidiFileFormat format = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A format = reader.getMidiFileFormat( stream ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( format==null ) {
0N/A throw new InvalidMidiDataException("input stream is not a supported file type");
0N/A } else {
0N/A return format;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the MIDI file format of the data in the specified URL. The URL
0N/A * must point to valid MIDI file data for a file type recognized
0N/A * by the system.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while determining the file format.
0N/A *
0N/A * @param url the URL from which file format information should be
0N/A * extracted
0N/A * @return a <code>MidiFileFormat</code> object describing the MIDI file
0N/A * format
0N/A * @throws InvalidMidiDataException if the URL does not point to valid MIDI
0N/A * file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs while accessing the URL
0N/A *
0N/A * @see #getMidiFileFormat(InputStream)
0N/A * @see #getMidiFileFormat(File)
0N/A */
0N/A public static MidiFileFormat getMidiFileFormat(URL url)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A MidiFileFormat format = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A format = reader.getMidiFileFormat( url ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( format==null ) {
0N/A throw new InvalidMidiDataException("url is not a supported file type");
0N/A } else {
0N/A return format;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the MIDI file format of the specified <code>File</code>. The
0N/A * <code>File</code> must point to valid MIDI file data for a file type
0N/A * recognized by the system.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while determining the file format.
0N/A *
0N/A * @param file the <code>File</code> from which file format information
0N/A * should be extracted
0N/A * @return a <code>MidiFileFormat</code> object describing the MIDI file
0N/A * format
0N/A * @throws InvalidMidiDataException if the <code>File</code> does not point
0N/A * to valid MIDI file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs while accessing the file
0N/A *
0N/A * @see #getMidiFileFormat(InputStream)
0N/A * @see #getMidiFileFormat(URL)
0N/A */
0N/A public static MidiFileFormat getMidiFileFormat(File file)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A MidiFileFormat format = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A format = reader.getMidiFileFormat( file ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( format==null ) {
0N/A throw new InvalidMidiDataException("file is not a supported file type");
0N/A } else {
0N/A return format;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains a MIDI sequence from the specified input stream. The stream must
0N/A * point to valid MIDI file data for a file type recognized
0N/A * by the system.
0N/A * <p>
0N/A * This method and/or the code it invokes may need to read some data
0N/A * from the stream to determine whether
0N/A * its data format is supported. The implementation may therefore
0N/A * need to mark the stream, read enough data to determine whether it is in
0N/A * a supported format, and reset the stream's read pointer to its original
0N/A * position. If the input stream does not permit this set of operations,
0N/A * this method may fail with an <code>IOException</code>.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while constructing the <code>Sequence</code>
0N/A * object from the file data.
0N/A *
0N/A * @param stream the input stream from which the <code>Sequence</code>
0N/A * should be constructed
0N/A * @return a <code>Sequence</code> object based on the MIDI file data
0N/A * contained in the input stream
0N/A * @throws InvalidMidiDataException if the stream does not point to
0N/A * valid MIDI file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs while accessing the
0N/A * stream
0N/A * @see InputStream#markSupported
0N/A * @see InputStream#mark
0N/A */
0N/A public static Sequence getSequence(InputStream stream)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A Sequence sequence = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A sequence = reader.getSequence( stream ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( sequence==null ) {
0N/A throw new InvalidMidiDataException("could not get sequence from input stream");
0N/A } else {
0N/A return sequence;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains a MIDI sequence from the specified URL. The URL must
0N/A * point to valid MIDI file data for a file type recognized
0N/A * by the system.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while constructing the <code>Sequence</code>
0N/A * object from the file data.
0N/A *
0N/A * @param url the URL from which the <code>Sequence</code> should be
0N/A * constructed
0N/A * @return a <code>Sequence</code> object based on the MIDI file data
0N/A * pointed to by the URL
0N/A * @throws InvalidMidiDataException if the URL does not point to valid MIDI
0N/A * file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs while accessing the URL
0N/A */
0N/A public static Sequence getSequence(URL url)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A Sequence sequence = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A sequence = reader.getSequence( url ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( sequence==null ) {
0N/A throw new InvalidMidiDataException("could not get sequence from URL");
0N/A } else {
0N/A return sequence;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains a MIDI sequence from the specified <code>File</code>.
0N/A * The <code>File</code> must point to valid MIDI file data
0N/A * for a file type recognized by the system.
0N/A * <p>
0N/A * This operation can only succeed for files of a type which can be parsed
0N/A * by an installed file reader. It may fail with an InvalidMidiDataException
0N/A * even for valid files if no compatible file reader is installed. It
0N/A * will also fail with an InvalidMidiDataException if a compatible file reader
0N/A * is installed, but encounters errors while constructing the <code>Sequence</code>
0N/A * object from the file data.
0N/A *
0N/A * @param file the <code>File</code> from which the <code>Sequence</code>
0N/A * should be constructed
0N/A * @return a <code>Sequence</code> object based on the MIDI file data
0N/A * pointed to by the File
0N/A * @throws InvalidMidiDataException if the File does not point to valid MIDI
0N/A * file data recognized by the system
0N/A * @throws IOException if an I/O exception occurs
0N/A */
0N/A public static Sequence getSequence(File file)
0N/A throws InvalidMidiDataException, IOException {
0N/A
0N/A List providers = getMidiFileReaders();
0N/A Sequence sequence = null;
0N/A
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiFileReader reader = (MidiFileReader) providers.get(i);
0N/A try {
0N/A sequence = reader.getSequence( file ); // throws IOException
0N/A break;
0N/A } catch (InvalidMidiDataException e) {
0N/A continue;
0N/A }
0N/A }
0N/A
0N/A if( sequence==null ) {
0N/A throw new InvalidMidiDataException("could not get sequence from file");
0N/A } else {
0N/A return sequence;
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the set of MIDI file types for which file writing support is
0N/A * provided by the system.
0N/A * @return array of unique file types. If no file types are supported,
0N/A * an array of length 0 is returned.
0N/A */
0N/A public static int[] getMidiFileTypes() {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A Set allTypes = new HashSet();
0N/A
0N/A // gather from all the providers
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A int[] types = writer.getMidiFileTypes();
0N/A for (int j = 0; j < types.length; j++ ) {
0N/A allTypes.add(new Integer(types[j]));
0N/A }
0N/A }
0N/A int resultTypes[] = new int[allTypes.size()];
0N/A int index = 0;
0N/A Iterator iterator = allTypes.iterator();
0N/A while (iterator.hasNext()) {
0N/A Integer integer = (Integer) iterator.next();
0N/A resultTypes[index++] = integer.intValue();
0N/A }
0N/A return resultTypes;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Indicates whether file writing support for the specified MIDI file type
0N/A * is provided by the system.
0N/A * @param fileType the file type for which write capabilities are queried
0N/A * @return <code>true</code> if the file type is supported,
0N/A * otherwise <code>false</code>
0N/A */
0N/A public static boolean isFileTypeSupported(int fileType) {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A if( writer.isFileTypeSupported(fileType)) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the set of MIDI file types that the system can write from the
0N/A * sequence specified.
0N/A * @param sequence the sequence for which MIDI file type support
0N/A * is queried
0N/A * @return the set of unique supported file types. If no file types are supported,
0N/A * returns an array of length 0.
0N/A */
0N/A public static int[] getMidiFileTypes(Sequence sequence) {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A Set allTypes = new HashSet();
0N/A
0N/A // gather from all the providers
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A int[] types = writer.getMidiFileTypes(sequence);
0N/A for (int j = 0; j < types.length; j++ ) {
0N/A allTypes.add(new Integer(types[j]));
0N/A }
0N/A }
0N/A int resultTypes[] = new int[allTypes.size()];
0N/A int index = 0;
0N/A Iterator iterator = allTypes.iterator();
0N/A while (iterator.hasNext()) {
0N/A Integer integer = (Integer) iterator.next();
0N/A resultTypes[index++] = integer.intValue();
0N/A }
0N/A return resultTypes;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Indicates whether a MIDI file of the file type specified can be written
0N/A * from the sequence indicated.
0N/A * @param fileType the file type for which write capabilities
0N/A * are queried
0N/A * @param sequence the sequence for which file writing support is queried
0N/A * @return <code>true</code> if the file type is supported for this
0N/A * sequence, otherwise <code>false</code>
0N/A */
0N/A public static boolean isFileTypeSupported(int fileType, Sequence sequence) {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A if( writer.isFileTypeSupported(fileType,sequence)) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Writes a stream of bytes representing a file of the MIDI file type
0N/A * indicated to the output stream provided.
0N/A * @param in sequence containing MIDI data to be written to the file
0N/A * @param fileType the file type of the file to be written to the output stream
0N/A * @param out stream to which the file data should be written
0N/A * @return the number of bytes written to the output stream
0N/A * @throws IOException if an I/O exception occurs
0N/A * @throws IllegalArgumentException if the file format is not supported by
0N/A * the system
0N/A * @see #isFileTypeSupported(int, Sequence)
0N/A * @see #getMidiFileTypes(Sequence)
0N/A */
0N/A public static int write(Sequence in, int fileType, OutputStream out) throws IOException {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
0N/A int bytesWritten = -2;
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A if( writer.isFileTypeSupported( fileType, in ) ) {
0N/A
0N/A bytesWritten = writer.write(in, fileType, out);
0N/A break;
0N/A }
0N/A }
0N/A if (bytesWritten == -2) {
0N/A throw new IllegalArgumentException("MIDI file type is not supported");
0N/A }
0N/A return bytesWritten;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Writes a stream of bytes representing a file of the MIDI file type
0N/A * indicated to the external file provided.
0N/A * @param in sequence containing MIDI data to be written to the file
0N/A * @param type the file type of the file to be written to the output stream
0N/A * @param out external file to which the file data should be written
0N/A * @return the number of bytes written to the file
0N/A * @throws IOException if an I/O exception occurs
0N/A * @throws IllegalArgumentException if the file type is not supported by
0N/A * the system
0N/A * @see #isFileTypeSupported(int, Sequence)
0N/A * @see #getMidiFileTypes(Sequence)
0N/A */
0N/A public static int write(Sequence in, int type, File out) throws IOException {
0N/A
0N/A List providers = getMidiFileWriters();
0N/A //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
0N/A int bytesWritten = -2;
0N/A
0N/A for (int i = 0; i < providers.size(); i++ ) {
0N/A MidiFileWriter writer = (MidiFileWriter) providers.get(i);
0N/A if( writer.isFileTypeSupported( type, in ) ) {
0N/A
0N/A bytesWritten = writer.write(in, type, out);
0N/A break;
0N/A }
0N/A }
0N/A if (bytesWritten == -2) {
0N/A throw new IllegalArgumentException("MIDI file type is not supported");
0N/A }
0N/A return bytesWritten;
0N/A }
0N/A
0N/A
0N/A
0N/A // HELPER METHODS
0N/A
0N/A private static List getMidiDeviceProviders() {
0N/A return getProviders(MidiDeviceProvider.class);
0N/A }
0N/A
0N/A
0N/A private static List getSoundbankReaders() {
0N/A return getProviders(SoundbankReader.class);
0N/A }
0N/A
0N/A
0N/A private static List getMidiFileWriters() {
0N/A return getProviders(MidiFileWriter.class);
0N/A }
0N/A
0N/A
0N/A private static List getMidiFileReaders() {
0N/A return getProviders(MidiFileReader.class);
0N/A }
0N/A
0N/A
0N/A /** Attempts to locate and return a default MidiDevice of the specified
0N/A * type.
0N/A *
0N/A * This method wraps {@link #getDefaultDevice}. It catches the
0N/A * <code>IllegalArgumentException</code> thrown by
0N/A * <code>getDefaultDevice</code> and instead throws a
0N/A * <code>MidiUnavailableException</code>, with the catched
0N/A * exception chained.
0N/A *
0N/A * @param deviceClass The requested device type, one of Synthesizer.class,
0N/A * Sequencer.class, Receiver.class or Transmitter.class.
0N/A * @throws MidiUnavalableException on failure.
0N/A */
0N/A private static MidiDevice getDefaultDeviceWrapper(Class deviceClass)
0N/A throws MidiUnavailableException{
0N/A try {
0N/A return getDefaultDevice(deviceClass);
0N/A } catch (IllegalArgumentException iae) {
0N/A MidiUnavailableException mae = new MidiUnavailableException();
0N/A mae.initCause(iae);
0N/A throw mae;
0N/A }
0N/A }
0N/A
0N/A
0N/A /** Attempts to locate and return a default MidiDevice of the specified
0N/A * type.
0N/A *
0N/A * @param deviceClass The requested device type, one of Synthesizer.class,
0N/A * Sequencer.class, Receiver.class or Transmitter.class.
0N/A * @throws IllegalArgumentException on failure.
0N/A */
0N/A private static MidiDevice getDefaultDevice(Class deviceClass) {
0N/A List providers = getMidiDeviceProviders();
0N/A String providerClassName = JDK13Services.getDefaultProviderClassName(deviceClass);
0N/A String instanceName = JDK13Services.getDefaultInstanceName(deviceClass);
0N/A MidiDevice device;
0N/A
0N/A if (providerClassName != null) {
0N/A MidiDeviceProvider defaultProvider = getNamedProvider(providerClassName, providers);
0N/A if (defaultProvider != null) {
0N/A if (instanceName != null) {
0N/A device = getNamedDevice(instanceName, defaultProvider, deviceClass);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A device = getFirstDevice(defaultProvider, deviceClass);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* Provider class not specified or cannot be found, or
0N/A provider class specified, and no appropriate device available or
0N/A provider class and instance specified and instance cannot be found or is not appropriate */
0N/A if (instanceName != null) {
0N/A device = getNamedDevice(instanceName, providers, deviceClass);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A
0N/A /* No default are specified, or if something is specified, everything
0N/A failed. */
0N/A device = getFirstDevice(providers, deviceClass);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A throw new IllegalArgumentException("Requested device not installed");
0N/A }
0N/A
0N/A
0N/A
0N/A /** Return a MidiDeviceProcider of a given class from the list of
0N/A MidiDeviceProviders.
0N/A
0N/A @param providerClassName The class name of the provider to be returned.
0N/A @param provider The list of MidiDeviceProviders that is searched.
0N/A @return A MidiDeviceProvider of the requested class, or null if none
0N/A is found.
0N/A */
0N/A private static MidiDeviceProvider getNamedProvider(String providerClassName, List providers) {
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
0N/A if (provider.getClass().getName().equals(providerClassName)) {
0N/A return provider;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** Return a MidiDevice with a given name from a given MidiDeviceProvider.
0N/A @param deviceName The name of the MidiDevice to be returned.
0N/A @param provider The MidiDeviceProvider to check for MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A
0N/A @return A MidiDevice matching the requirements, or null if none is found.
0N/A */
0N/A private static MidiDevice getNamedDevice(String deviceName,
0N/A MidiDeviceProvider provider,
0N/A Class deviceClass) {
0N/A MidiDevice device;
0N/A // try to get MIDI port
0N/A device = getNamedDevice(deviceName, provider, deviceClass,
0N/A false, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A
0N/A if (deviceClass == Receiver.class) {
0N/A // try to get Synthesizer
0N/A device = getNamedDevice(deviceName, provider, deviceClass,
0N/A true, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** Return a MidiDevice with a given name from a given MidiDeviceProvider.
0N/A @param deviceName The name of the MidiDevice to be returned.
0N/A @param provider The MidiDeviceProvider to check for MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A
0N/A @return A MidiDevice matching the requirements, or null if none is found.
0N/A */
0N/A private static MidiDevice getNamedDevice(String deviceName,
0N/A MidiDeviceProvider provider,
0N/A Class deviceClass,
0N/A boolean allowSynthesizer,
0N/A boolean allowSequencer) {
0N/A MidiDevice.Info[] infos = provider.getDeviceInfo();
0N/A for (int i = 0; i < infos.length; i++) {
0N/A if (infos[i].getName().equals(deviceName)) {
0N/A MidiDevice device = provider.getDevice(infos[i]);
0N/A if (isAppropriateDevice(device, deviceClass,
0N/A allowSynthesizer, allowSequencer)) {
0N/A return device;
0N/A }
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** Return a MidiDevice with a given name from a list of
0N/A MidiDeviceProviders.
0N/A @param deviceName The name of the MidiDevice to be returned.
0N/A @param providers The List of MidiDeviceProviders to check for
0N/A MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A Mixer matching the requirements, or null if none is found.
0N/A */
0N/A private static MidiDevice getNamedDevice(String deviceName,
0N/A List providers,
0N/A Class deviceClass) {
0N/A MidiDevice device;
0N/A // try to get MIDI port
0N/A device = getNamedDevice(deviceName, providers, deviceClass,
0N/A false, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A
0N/A if (deviceClass == Receiver.class) {
0N/A // try to get Synthesizer
0N/A device = getNamedDevice(deviceName, providers, deviceClass,
0N/A true, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** Return a MidiDevice with a given name from a list of
0N/A MidiDeviceProviders.
0N/A @param deviceName The name of the MidiDevice to be returned.
0N/A @param providers The List of MidiDeviceProviders to check for
0N/A MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A Mixer matching the requirements, or null if none is found.
0N/A */
0N/A private static MidiDevice getNamedDevice(String deviceName,
0N/A List providers,
0N/A Class deviceClass,
0N/A boolean allowSynthesizer,
0N/A boolean allowSequencer) {
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
0N/A MidiDevice device = getNamedDevice(deviceName, provider,
0N/A deviceClass,
0N/A allowSynthesizer,
0N/A allowSequencer);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** From a given MidiDeviceProvider, return the first appropriate device.
0N/A @param provider The MidiDeviceProvider to check for MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A MidiDevice is considered appropriate, or null if no
0N/A appropriate device is found.
0N/A */
0N/A private static MidiDevice getFirstDevice(MidiDeviceProvider provider,
0N/A Class deviceClass) {
0N/A MidiDevice device;
0N/A // try to get MIDI port
0N/A device = getFirstDevice(provider, deviceClass,
0N/A false, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A
0N/A if (deviceClass == Receiver.class) {
0N/A // try to get Synthesizer
0N/A device = getFirstDevice(provider, deviceClass,
0N/A true, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** From a given MidiDeviceProvider, return the first appropriate device.
0N/A @param provider The MidiDeviceProvider to check for MidiDevices.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A MidiDevice is considered appropriate, or null if no
0N/A appropriate device is found.
0N/A */
0N/A private static MidiDevice getFirstDevice(MidiDeviceProvider provider,
0N/A Class deviceClass,
0N/A boolean allowSynthesizer,
0N/A boolean allowSequencer) {
0N/A MidiDevice.Info[] infos = provider.getDeviceInfo();
0N/A for (int j = 0; j < infos.length; j++) {
0N/A MidiDevice device = provider.getDevice(infos[j]);
0N/A if (isAppropriateDevice(device, deviceClass,
0N/A allowSynthesizer, allowSequencer)) {
0N/A return device;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** From a List of MidiDeviceProviders, return the first appropriate
0N/A MidiDevice.
0N/A @param providers The List of MidiDeviceProviders to search.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A MidiDevice that is considered appropriate, or null
0N/A if none is found.
0N/A */
0N/A private static MidiDevice getFirstDevice(List providers,
0N/A Class deviceClass) {
0N/A MidiDevice device;
0N/A // try to get MIDI port
0N/A device = getFirstDevice(providers, deviceClass,
0N/A false, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A
0N/A if (deviceClass == Receiver.class) {
0N/A // try to get Synthesizer
0N/A device = getFirstDevice(providers, deviceClass,
0N/A true, false);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** From a List of MidiDeviceProviders, return the first appropriate
0N/A MidiDevice.
0N/A @param providers The List of MidiDeviceProviders to search.
0N/A @param deviceClass The requested device type, one of Synthesizer.class,
0N/A Sequencer.class, Receiver.class or Transmitter.class.
0N/A @return A MidiDevice that is considered appropriate, or null
0N/A if none is found.
0N/A */
0N/A private static MidiDevice getFirstDevice(List providers,
0N/A Class deviceClass,
0N/A boolean allowSynthesizer,
0N/A boolean allowSequencer) {
0N/A for(int i = 0; i < providers.size(); i++) {
0N/A MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
0N/A MidiDevice device = getFirstDevice(provider, deviceClass,
0N/A allowSynthesizer,
0N/A allowSequencer);
0N/A if (device != null) {
0N/A return device;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A
0N/A /** Checks if a MidiDevice is appropriate.
0N/A If deviceClass is Synthesizer or Sequencer, a device implementing
0N/A the respective interface is considered appropriate. If deviceClass
0N/A is Receiver or Transmitter, a device is considered appropriate if
0N/A it implements neither Synthesizer nor Transmitter, and if it can
0N/A provide at least one Receiver or Transmitter, respectively.
0N/A
0N/A @param device the MidiDevice to test
0N/A @param allowSynthesizer if true, Synthesizers are considered
0N/A appropriate. Otherwise only pure MidiDevices are considered
0N/A appropriate (unless allowSequencer is true). This flag only has an
0N/A effect for deviceClass Receiver and Transmitter. For other device
0N/A classes (Sequencer and Synthesizer), this flag has no effect.
0N/A @param allowSequencer if true, Sequencers are considered
0N/A appropriate. Otherwise only pure MidiDevices are considered
0N/A appropriate (unless allowSynthesizer is true). This flag only has an
0N/A effect for deviceClass Receiver and Transmitter. For other device
0N/A classes (Sequencer and Synthesizer), this flag has no effect.
0N/A @return true if the device is considered appropriate according to the
0N/A rules given above, false otherwise.
0N/A */
0N/A private static boolean isAppropriateDevice(MidiDevice device,
0N/A Class deviceClass,
0N/A boolean allowSynthesizer,
0N/A boolean allowSequencer) {
0N/A if (deviceClass.isInstance(device)) {
0N/A // This clause is for deviceClass being either Synthesizer
0N/A // or Sequencer.
0N/A return true;
0N/A } else {
0N/A // Now the case that deviceClass is Transmitter or
0N/A // Receiver. If neither allowSynthesizer nor allowSequencer is
0N/A // true, we require device instances to be
0N/A // neither Synthesizer nor Sequencer, since we only want
0N/A // devices representing MIDI ports.
0N/A // Otherwise, the respective type is accepted, too
0N/A if ( (! (device instanceof Sequencer) &&
0N/A ! (device instanceof Synthesizer) ) ||
0N/A ((device instanceof Sequencer) && allowSequencer) ||
0N/A ((device instanceof Synthesizer) && allowSynthesizer)) {
0N/A // And of cource, the device has to be able to provide
0N/A // Receivers or Transmitters.
0N/A if ((deviceClass == Receiver.class &&
0N/A device.getMaxReceivers() != 0) ||
0N/A (deviceClass == Transmitter.class &&
0N/A device.getMaxTransmitters() != 0)) {
0N/A return true;
0N/A }
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Obtains the set of services currently installed on the system
0N/A * using sun.misc.Service, the SPI mechanism in 1.3.
0N/A * @return a List of instances of providers for the requested service.
0N/A * If no providers are available, a List of length 0 will be returned.
0N/A */
0N/A private static List getProviders(Class providerClass) {
0N/A return JDK13Services.getProviders(providerClass);
0N/A }
0N/A}