/* * This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com> * Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/) ** * Comment: not really modified but is a part of JSound "front-end". */ /* * @(#)MidiSystem.java 1.49 03/01/27 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.sound.midi; import java.io.FileInputStream; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.Vector; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.net.URL; import javax.sound.midi.spi.MidiFileWriter; import javax.sound.midi.spi.MidiFileReader; import javax.sound.midi.spi.SoundbankReader; import javax.sound.midi.spi.MidiDeviceProvider; /** * The <code>MidiSystem</code> class provides access to the installed MIDI * system resources, including devices such as synthesizers, sequencers, and * MIDI input and output ports. A typical simple MIDI application might * begin by invoking one or more <code>MidiSystem</code> methods to learn * what devices are installed and to obtain the ones needed in that * application. * <p> * The class also has methods for reading files, streams, and URLs that * contain standard MIDI file data or soundbanks. You can query the * <code>MidiSystem</code> for the format of a specified MIDI file. * <p> * You cannot instantiate a <code>MidiSystem</code>; all the methods are * static. * * @version 1.49, 03/01/27 * @author Kara Kytle */ public class MidiSystem { /** * Private strings for default services class and method */ private static final String defaultServicesClassName = "com.sun.media.sound.DefaultServices"; private static final String jdk13ServicesClassName = "com.sun.media.sound.JDK13Services"; private static final String servicesMethodName = "getProviders"; private static final Class[] servicesParamTypes = new Class[] { String.class }; /** * Private no-args constructor for ensuring against instantiation. */ private MidiSystem() { } /** * Obtains an array of information objects representing * the set of all MIDI devices available on the system. * A returned information object can then be used to obtain the * corresponding device object, by invoking * {@link #getMidiDevice(MidiDevice.Info) getMidiDevice}. * * @return an array of <code>MidiDevice.Info</code> objects, one * for each installed MIDI device. If no such devices are installed, * an array of length 0 is returned. */ public static MidiDevice.Info[] getMidiDeviceInfo() { return getGenericDeviceInfo( MidiDevice.class ); } /** * Obtains the requested MIDI device. * * @param info a device information object representing the desired device. * @return the requested device * @throws MidiUnavailableException if the requested device is not available * due to resource restrictions * @throws IllegalArgumentException if the info object does not represent * a MIDI device installed on the system * @see #getMidiDeviceInfo */ public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavailableException { return (MidiDevice)getGenericDevice( null, info ); } /* * re-deleted */ /* * un-deleted, AbstractPlayer.addPlatformSynth() conflict */ /** * Obtains an array of information objects representing * the set of MIDI devices available on the system that support * one or more receivers. * A returned information object can then be used to obtain a * receiver from the corresponding device object, by invoking * {@link #getReceiver(MidiDevice.Info) getReceiver}. * * @return an array of <code>MidiDevice.Info</code> objects, one * for each installed device that supports one or more * {@link Receiver Receivers}. * If no such devices are installed, an array of length * 0 is returned. */ /* public static MidiDevice.Info[] getReceiverInfo() { return getGenericDeviceInfo( Receiver.class ); } */ /* * re-changed */ /* * un-changed, AbstractPlayer.addPlatformSynth() conflict */ /** * Obtains a MIDI receiver from an external MIDI port * or other default source. * @return the default MIDI receiver * @throws MidiUnavailableException if the default receiver is not * available due to resource restrictions */ public static Receiver getReceiver() throws MidiUnavailableException { return ( ((MidiDevice)getGenericDevice(Receiver.class, null)).getReceiver() ); } /* public static Receiver getReceiver(MidiDevice.Info info) throws MidiUnavailableException { return ( ((MidiDevice)getGenericDevice(Receiver.class, info)).getReceiver() ); } */ /* * deleted */ /** * Obtains an array of information objects representing * the set of MIDI devices available on the system that support * one or more transmitters. * A returned information object can then be used to obtain a * transmitter from the corresponding device object, by invoking * {@link #getTransmitter(MidiDevice.Info) getTransmitter}. * * @return an array of <code>MidiDevice.Info</code> objects, one * for each installed device that supports one or more * {@link Transmitter Transmitters}. * If no such devices are installed, an array of length * 0 is returned. */ /* public static MidiDevice.Info[] getTransmitterInfo() { return getGenericDeviceInfo( Transmitter.class ); } */ /** * Obtains a MIDI transmitter from an external MIDI port * or other default source. * @return the default MIDI transmitter * @throws MidiUnavailableException if the default transmitter is not * available due to resource restrictions */ public static Transmitter getTransmitter() throws MidiUnavailableException { return ( ((MidiDevice)getGenericDevice(Transmitter.class, null)).getTransmitter() ); } /* public static Transmitter getTransmitter(MidiDevice.Info info) throws MidiUnavailableException { return ( ((MidiDevice)getGenericDevice(Transmitter.class, info)).getTransmitter() ); } */ /* * deleted */ /** * Obtains an array of information objects representing * the set of synthesizers available on the system. A * returned information object can then be used to obtain the corresponding * synthesizer, by invoking * {@link #getSynthesizer(MidiDevice.Info) getSynthesizer}. * * @return an array of <code>MidiDevice.Info</code> objects, one * for each installed device that is a {@link Synthesizer}. * If no synthesizers are installed, an array of length * 0 is returned. */ /* public static MidiDevice.Info[] getSynthesizerInfo() { return getGenericDeviceInfo( Synthesizer.class ); } */ /** * Obtains the default synthesizer. * @return the default synthesizer * @throws MidiUnavailableException if the synthesizer is not * available due to resource restrictions */ public static Synthesizer getSynthesizer() throws MidiUnavailableException { return (Synthesizer) getGenericDevice( Synthesizer.class, null ); } /* public static Synthesizer getSynthesizer(MidiDevice.Info info) { return (Synthesizer) getGenericDevice( Synthesizer.class, info ); } */ /* * deleted */ /** * Obtains an array of information objects representing * the set of sequencers available on the system. A * returned information object can then be used to obtain the corresponding * sequencer, by invoking * {@link #getSequencer(MidiDevice.Info) getSequencer}. * * @return an array of <code>MidiDevice.Info</code> objects, one * for each installed device that is a {@link Sequencer}. * If no sequencers are installed, an array of length * 0 is returned. */ /* public static MidiDevice.Info[] getSequencerInfo() { return getGenericDeviceInfo( Sequencer.class ); } */ /** * Obtains the default sequencer. * @return the default sequencer * @throws MidiUnavailableException if the sequencer is not * available due to resource restrictions */ public static Sequencer getSequencer() throws MidiUnavailableException { return (Sequencer) getGenericDevice( Sequencer.class, null ); } /* public static Sequencer getSequencer(MidiDevice.Info info) { return (Sequencer) getGenericDevice( Sequencer.class, info ); } */ /** * Constructs a MIDI sound bank by reading it from the specified stream. * The stream must point to * a valid MIDI soundbank file. In general, MIDI soundbank providers may * need to read some data from the stream before determining whether they * support it. These parsers must * be able to mark the stream, read enough data to determine whether they * support the stream, and, if not, reset the stream's read pointer to * its original position. If the input stream does not support this, * this method may fail with an IOException. * @param stream the source of the sound bank data. * @return the sound bank * @throws InvalidMidiDataException if the stream does not point to * valid MIDI soundbank data recognized by the system * @throws IOException if an I/O error occurred when loading the soundbank * @see InputStream#markSupported * @see InputStream#mark */ public static Soundbank getSoundbank(InputStream stream) throws InvalidMidiDataException, IOException { SoundbankReader sp = null; Soundbank s = null; Vector providers = getSoundbankReaders(); //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.size()-1; i >= 0; i-- ) { sp = (SoundbankReader)providers.elementAt(i); s = sp.getSoundbank(stream); if( s!= null) { return s; } } throw new InvalidMidiDataException("cannot get soundbank from stream"); } /** * Constructs a <code>Soundbank</code> by reading it from the specified URL. * The URL must point to a valid MIDI soundbank file. * * @param url the source of the sound bank data * @return the sound bank * @throws InvalidMidiDataException if the URL does not point to valid MIDI * soundbank data recognized by the system * @throws IOException if an I/O error occurred when loading the soundbank */ public static Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException { SoundbankReader sp = null; Soundbank s = null; Vector providers = getSoundbankReaders(); //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.size()-1; i >= 0; i-- ) { sp = (SoundbankReader)providers.elementAt(i); s = sp.getSoundbank(url); if( s!= null) { return s; } } throw new InvalidMidiDataException("cannot get soundbank from stream"); } /** * Constructs a <code>Soundbank</code> by reading it from the specified * <code>File</code>. * The <code>File</code> must point to a valid MIDI soundbank file. * * @param file the source of the sound bank data * @return the sound bank * @throws InvalidMidiDataException if the <code>File</code> does not * point to valid MIDI soundbank data recognized by the system * @throws IOException if an I/O error occurred when loading the soundbank */ public static Soundbank getSoundbank(File file) throws InvalidMidiDataException, IOException { FileInputStream fis = new FileInputStream( file ); return getSoundbank( fis ); } /** * Obtains the MIDI file format of the data in the specified input stream. * The stream must point to valid MIDI file data for a file type recognized * by the system. * <p> * This method and/or the code it invokes may need to read some data from * the stream to determine whether its data format is supported. The * implementation may therefore * need to mark the stream, read enough data to determine whether it is in * a supported format, and reset the stream's read pointer to its original * position. If the input stream does not permit this set of operations, * this method may fail with an <code>IOException</code>. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while determining the file format. * * @param stream the input stream from which file format information * should be extracted * @return an <code>MidiFileFormat</code> object describing the MIDI file * format * @throws InvalidMidiDataException if the stream does not point to valid * MIDI file data recognized by the system * @throws IOException if an I/O exception occurs while accessing the * stream * @see #getMidiFileFormat(URL) * @see #getMidiFileFormat(File) * @see InputStream#markSupported * @see InputStream#mark */ public static MidiFileFormat getMidiFileFormat(InputStream stream) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); MidiFileFormat format = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { format = providers[i].getMidiFileFormat( stream ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( format==null ) { throw new InvalidMidiDataException("input stream is not a supported file type"); } else { return format; } } /** * Obtains the MIDI file format of the data in the specified URL. The URL * must point to valid MIDI file data for a file type recognized * by the system. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while determining the file format. * * @param url the URL from which file format information should be * extracted * @return a <code>MidiFileFormat</code> object describing the MIDI file * format * @throws InvalidMidiDataException if the URL does not point to valid MIDI * file data recognized by the system * @throws IOException if an I/O exception occurs while accessing the URL * * @see #getMidiFileFormat(InputStream) * @see #getMidiFileFormat(File) */ public static MidiFileFormat getMidiFileFormat(URL url) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); MidiFileFormat format = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { format = providers[i].getMidiFileFormat( url ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( format==null ) { throw new InvalidMidiDataException("url is not a supported file type"); } else { return format; } } /** * Obtains the MIDI file format of the specified <code>File</code>. The * <code>File</code> must point to valid MIDI file data for a file type * recognized by the system. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while determining the file format. * * @param file the <code>File</code> from which file format information * should be extracted * @return a <code>MidiFileFormat</code> object describing the MIDI file * format * @throws InvalidMidiDataException if the <code>File</code> does not point * to valid MIDI file data recognized by the system * @throws IOException if an I/O exception occurs while accessing the file * * @see #getMidiFileFormat(InputStream) * @see #getMidiFileFormat(URL) */ public static MidiFileFormat getMidiFileFormat(File file) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); MidiFileFormat format = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { format = providers[i].getMidiFileFormat( file ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( format==null ) { throw new InvalidMidiDataException("file is not a supported file type"); } else { return format; } } /** * Obtains a MIDI sequence from the specified input stream. The stream must * point to valid MIDI file data for a file type recognized * by the system. * <p> * This method and/or the code it invokes may need to read some data * from the stream to determine whether * its data format is supported. The implementation may therefore * need to mark the stream, read enough data to determine whether it is in * a supported format, and reset the stream's read pointer to its original * position. If the input stream does not permit this set of operations, * this method may fail with an <code>IOException</code>. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while constructing the <code>Sequence</code> * object from the file data. * * @param stream the input stream from which the <code>Sequence</code> * should be constructed * @return a <code>Sequence</code> object based on the MIDI file data * contained in the input stream * @throws InvalidMidiDataException if the stream does not point to * valid MIDI file data recognized by the system * @throws IOException if an I/O exception occurs while accessing the * stream * @see InputStream#markSupported * @see InputStream#mark */ public static Sequence getSequence(InputStream stream) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); Sequence sequence = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { sequence = providers[i].getSequence( stream ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( sequence==null ) { throw new InvalidMidiDataException("could not get sequence from input stream"); } else { return sequence; } } /** * Obtains a MIDI sequence from the specified URL. The URL must * point to valid MIDI file data for a file type recognized * by the system. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while constructing the <code>Sequence</code> * object from the file data. * * @param url the URL from which the <code>Sequence</code> should be * constructed * @return a <code>Sequence</code> object based on the MIDI file data * pointed to by the URL * @throws InvalidMidiDataException if the URL does not point to valid MIDI * file data recognized by the system * @throws IOException if an I/O exception occurs while accessing the URL */ public static Sequence getSequence(URL url) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); Sequence sequence = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { sequence = providers[i].getSequence( url ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( sequence==null ) { throw new InvalidMidiDataException("could not get sequence from URL"); } else { return sequence; } } /** * Obtains a MIDI sequence from the specified <code>File</code>. * The <code>File</code> must point to valid MIDI file data * for a file type recognized by the system. * <p> * This operation can only succeed for files of a type which can be parsed * by an installed file reader. It may fail with an InvalidMidiDataException * even for valid files if no compatible file reader is installed. It * will also fail with an InvalidMidiDataException if a compatible file reader * is installed, but encounters errors while constructing the <code>Sequence</code> * object from the file data. * * @param file the <code>File</code> from which the <code>Sequence</code> * should be constructed * @return a <code>Sequence</code> object based on the MIDI file data * pointed to by the File * @throws InvalidMidiDataException if the File does not point to valid MIDI * file data recognized by the system * @throws IOException if an I/O exception occurs */ public static Sequence getSequence(File file) throws InvalidMidiDataException, IOException { MidiFileReader providers[] = getMidiFileReaders(); Sequence sequence = null; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { try { sequence = providers[i].getSequence( file ); // throws IOException break; } catch (InvalidMidiDataException e) { continue; } } if( sequence==null ) { throw new InvalidMidiDataException("could not get sequence from file"); } else { return sequence; } } /** * Obtains the set of MIDI file types for which file writing support is * provided by the system. * @return array of file types. If no file types are supported, * an array of length 0 is returned. */ public static int[] getMidiFileTypes() { MidiFileWriter providers[] = getMidiFileWriters(); Vector allTypes = new Vector(); int size = 0; int index = 0; int types[] = null; // gather from all the providers for(int i=0; i<providers.length; i++ ) { types = providers[i].getMidiFileTypes(); size += types.length; allTypes.addElement( types ); } // now build a new array int types2[] = new int[size]; for(int i=0; i<allTypes.size(); i++ ) { types = (int [])(allTypes.elementAt(i)); for(int j=0; j<types.length; j++ ) { types2[index++] = types[j]; } } return types2; } /** * Indicates whether file writing support for the specified MIDI file type * is provided by the system. * @param fileType the file type for which write capabilities are queried * @return <code>true</code> if the file type is supported, * otherwise <code>false</code> */ public static boolean isFileTypeSupported(int fileType) { MidiFileWriter providers[] = getMidiFileWriters(); for(int i=0; i<providers.length; i++) { if( providers[i].isFileTypeSupported(fileType) == true ) { return true; } } return false; } /** * Obtains the set of MIDI file types that the system can write from the * sequence specified. * @param sequence the sequence for which MIDI file type support * is queried * @return the set of supported file types. If no file types are supported, * returns an array of length 0. */ public static int[] getMidiFileTypes(Sequence sequence) { MidiFileWriter providers[] = getMidiFileWriters(); int types[][] = new int[ providers.length ][]; int returnTypes[] = null; int numTypes = 0; int index = 0; // Get all supported file types for(int i=0; i < providers.length; i++) { types[i] = providers[i].getMidiFileTypes(sequence); numTypes += types[i].length; } // Now put them in a 1-D array returnTypes = new int[ numTypes ]; for(int i=0; i < providers.length; i++) { for(int j=0; j < types[i].length; j++) { returnTypes[ index ] = types[i][j]; index++; } } return returnTypes; } /** * Indicates whether a MIDI file of the file type specified can be written * from the sequence indicated. * @param fileType the file type for which write capabilities * are queried * @param sequence the sequence for which file writing support is queried * @return <code>true</code> if the file type is supported for this * sequence, otherwise <code>false</code> */ public static boolean isFileTypeSupported(int fileType, Sequence sequence) { MidiFileWriter providers[] = getMidiFileWriters(); for(int i=0; i<providers.length; i++) { if( providers[i].isFileTypeSupported(fileType,sequence) == true ) { return true; } } return false; } /** * Writes a stream of bytes representing a file of the MIDI file type * indicated to the output stream provided. * @param in sequence containing MIDI data to be written to the file * @param fileType the file type of the file to be written to the output stream * @param out stream to which the file data should be written * @return the number of bytes written to the output stream * @throws IOException if an I/O exception occurs * @throws IllegalArgumentException if the file format is not supported by * the system * @see #isFileTypeSupported(int, Sequence) * @see #getMidiFileTypes(Sequence) */ public static int write(Sequence in, int fileType, OutputStream out) throws IOException { MidiFileWriter providers[] = getMidiFileWriters(); //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences int bytesWritten = -2; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { if( providers[i].isFileTypeSupported( fileType, in ) == true ) { bytesWritten = providers[i].write(in, fileType, out); break; } } if (bytesWritten == -2) { throw new IllegalArgumentException("MIDI file type is not supported"); } return bytesWritten; } /** * Writes a stream of bytes representing a file of the MIDI file type * indicated to the external file provided. * @param in sequence containing MIDI data to be written to the file * @param type the file type of the file to be written to the output stream * @param out external file to which the file data should be written * @return the number of bytes written to the file * @throws IOException if an I/O exception occurs * @throws IllegalArgumentException if the file type is not supported by * the system * @see #isFileTypeSupported(int, Sequence) * @see #getMidiFileTypes(Sequence) */ public static int write(Sequence in, int type, File out) throws IOException { MidiFileWriter providers[] = getMidiFileWriters(); //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences int bytesWritten = -2; //$$fb 2001-08-03: reverse this loop to give external providers more priority (Bug #4487550) for(int i = providers.length-1; i >= 0; i-- ) { if( providers[i].isFileTypeSupported( type, in ) == true ) { bytesWritten = providers[i].write(in, type, out); break; } } if (bytesWritten == -2) { throw new IllegalArgumentException("MIDI file type is not supported"); } return bytesWritten; } // HELPER METHODS private static synchronized boolean isA( Class testClass, Class targetClass ) { return (targetClass.isAssignableFrom(testClass)) ? true : false; } private static Vector getMidiDeviceProviders() { Vector providers = null; try { Class.forName( "sun.misc.Service" ); providers = getJDK13Services("javax.sound.midi.spi.MidiDeviceProvider"); } catch (Exception e) { // we're not running with 1.3's SPI mechanism providers = getDefaultServices("javax.sound.midi.spi.MidiDeviceProvider"); } return providers; } private static Vector getSoundbankReaders() { Vector providers = null; try { Class.forName( "sun.misc.Service" ); providers = getJDK13Services("javax.sound.midi.spi.SoundbankReader"); } catch (Exception e) { // we're not running with 1.3's SPI mechanism providers = getDefaultServices("javax.sound.midi.spi.SoundbankReader"); } return providers; } private static MidiFileWriter[] getMidiFileWriters() { Vector v = new Vector(); MidiFileWriter varray[]; try { Class.forName( "sun.misc.Service" ); v = getJDK13Services("javax.sound.midi.spi.MidiFileWriter"); } catch (Exception e) { // we're not running with 1.3's SPI mechanism v = getDefaultServices("javax.sound.midi.spi.MidiFileWriter"); } varray = new MidiFileWriter[ v.size() ]; for( int i=0; i < varray.length; i++ ) { varray[i] = (MidiFileWriter)(v.elementAt(i)); } return varray; } private static MidiFileReader[] getMidiFileReaders() { Vector v = new Vector(); MidiFileReader varray[]; try { Class.forName( "sun.misc.Service" ); v = getJDK13Services("javax.sound.midi.spi.MidiFileReader"); } catch (Exception e) { // we're not running with 1.3's SPI mechanism v = getDefaultServices("javax.sound.midi.spi.MidiFileReader"); } varray = new MidiFileReader[ v.size() ]; for( int i=0; i < varray.length; i++ ) { varray[i] = (MidiFileReader)(v.elementAt(i)); } return varray; } private static MidiDevice.Info[] getGenericDeviceInfo( Class deviceClass ) { int i; int j; Vector v = new Vector(); MidiDevice.Info[] tmpinfo; MidiDevice.Info[] varray; Vector v1; v1 = getMidiDeviceProviders(); for(i = 0; i < v1.size(); i++) { tmpinfo = ((MidiDeviceProvider) v1.elementAt(i)).getDeviceInfo(); for (j = 0; j < tmpinfo.length; j++) { // $$kk: 10.12.99: ugh! i have wrecked this!! //if( isA( tmpinfo[j].getDeviceClass(), deviceClass ) ) { MidiDevice device = ((MidiDeviceProvider) v1.elementAt(i)).getDevice(tmpinfo[j]); if (isA(deviceClass, Receiver.class)) { if(device.getMaxReceivers() != 0) { v.addElement( tmpinfo[j] ); } } else if (isA(deviceClass, Transmitter.class)) { if(device.getMaxTransmitters() != 0) { v.addElement( tmpinfo[j] ); } } else if (deviceClass.isInstance(device)) { v.addElement( tmpinfo[j] ); } } } varray = new MidiDevice.Info[ v.size() ]; for(i = 0; i < varray.length; i++ ) { varray[i] = (MidiDevice.Info)(v.elementAt(i)); } return varray; } /** * Attempts to locate and return the specified device * @throws IllegalArgumentException on failure. */ private static Object getGenericDevice( Class deviceClass, MidiDevice.Info info) { int i; int j; MidiDevice s = null; MidiDevice.Info[] tmpinfo = null; Vector v1 = new Vector(); v1 = getMidiDeviceProviders(); for(i = 0; i < v1.size(); i++) { tmpinfo = ((MidiDeviceProvider) v1.elementAt(i)).getDeviceInfo(); if( info == null ) { // $$jb: 06.04.99: Should we do more to guarantee which // device is the default? for (j = 0; j < tmpinfo.length; j++) { // $$kk: 10.12.99: ugh! i have wrecked this!! //if( isA(tmpinfo[j].getDeviceClass(), deviceClass ) ) { // return ((MidiDeviceProvider) v1.elementAt(i)).getDevice(tmpinfo[j]); //} MidiDevice device = ((MidiDeviceProvider) v1.elementAt(i)).getDevice(tmpinfo[j]); if (isA(deviceClass, Receiver.class)) { if(device.getMaxReceivers() != 0) { return device; } } else if (isA(deviceClass, Transmitter.class)) { if(device.getMaxTransmitters() != 0) { return device; } } else if (deviceClass.isInstance(device)) { return device; } } } else { for (j = 0; j < tmpinfo.length; j++) { if( tmpinfo[j].equals( info ) ) { // $$kk: 10.12.99: ugh! i have wrecked this!! // $$kk: 10.12.99: shouldn't need this check? //if( isA(tmpinfo[j].getDeviceClass(), deviceClass ) ) { // return ((MidiDeviceProvider) v1.elementAt(i)).getDevice(tmpinfo[j]); //} MidiDevice device = ((MidiDeviceProvider) v1.elementAt(i)).getDevice(tmpinfo[j]); if (deviceClass == null) { return device; } if (isA(deviceClass, Receiver.class)) { if(device.getMaxReceivers() != 0) { return device; } } else if (isA(deviceClass, Transmitter.class)) { if(device.getMaxTransmitters() != 0) { return device; } } } } } } throw new IllegalArgumentException("Requested device not installed: " + info); } /** * Obtains the set of services currently installed on the system * using sun.misc.Service, the SPI mechanism in 1.3. * @return a Vector of instances of providers for the requested service. * If no providers are available, a vector of length 0 will be returned. */ private static Vector getJDK13Services( String serviceName ) { Vector v = null; try { Class jdk13Services = Class.forName( jdk13ServicesClassName ); Method m = jdk13Services.getMethod( servicesMethodName, servicesParamTypes); Object[] arguments = new Object[] { serviceName }; v = (Vector) m.invoke(jdk13Services,arguments); } catch(InvocationTargetException e1) { v = new Vector(); } catch(ClassNotFoundException e2) { v = new Vector(); } catch(IllegalAccessException e3) { v = new Vector(); } catch(NoSuchMethodException e4) { v = new Vector(); } return v; } /** * Obtains the default set of services currently installed on the system. * This method is only invoked if sun.misc.Service is not available. * @return a Vector of instances of providers for the requested service. * If no providers are available, a vector of length 0 will be returned. */ private static Vector getDefaultServices( String serviceName ) { Vector v = null; try { Class defaultServices = Class.forName( defaultServicesClassName ); Method m = defaultServices.getMethod( servicesMethodName, servicesParamTypes); Object[] arguments = new Object[] { serviceName }; v = (Vector) m.invoke(defaultServices,arguments); } catch(InvocationTargetException e1) { v = new Vector(); } catch(ClassNotFoundException e2) { v = new Vector(); } catch(IllegalAccessException e3) { v = new Vector(); } catch(NoSuchMethodException e4) { v = new Vector(); } return v; } }