1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package javax.sound.midi;
19
20import java.util.ArrayList;
21import java.util.List;
22
23import java.io.File;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.OutputStream;
27import java.net.URL;
28
29import javax.sound.midi.MidiDevice.Info;
30import javax.sound.midi.spi.MidiDeviceProvider;
31import javax.sound.midi.spi.MidiFileReader;
32import javax.sound.midi.spi.MidiFileWriter;
33import javax.sound.midi.spi.SoundbankReader;
34
35import org.apache.harmony.sound.utils.ProviderService;
36
37public class MidiSystem {
38    //path to javax.sound.midi.spi.MidiDeviceProvider file in the jar-file
39    private final static String midiDeviceProviderPath =
40        "META-INF/services/javax.sound.midi.spi.MidiDeviceProvider";
41
42    //path to javax.sound.midi.spi.MidiFileReader file in the jar-file
43    private final static String midiFileReaderPath =
44        "META-INF/services/javax.sound.midi.spi.MidiFileReader";
45
46    //path to javax.sound.midi.spi.MidiFileWriter file in the jar-file
47    private final static String midiFileWriterPath =
48        "META-INF/services/javax.sound.midi.spi.MidiFileWriter";
49
50    //path to javax.sound.midi.spi.SoundbankReader file in the jar-file
51    private final static String soundbankReaderPath =
52        "META-INF/services/javax.sound.midi.spi.SoundbankReader";
53
54    //key to find default receiver in the sound.properties file
55    private final static String receiverName = "javax.sound.midi.Receiver";
56
57    //key to find default sequencer in the sound.properties file
58    private final static String sequencerName = "javax.sound.midi.Sequencer";
59
60    //key to find default synthesizer in the sound.properties file
61    private final static String synthesizerName = "javax.sound.midi.Synthesizer";
62
63    //key to find default transmitter in the sound.properties file
64    private final static String transmitterName = "javax.sound.midi.Transmitter";
65
66    public static MidiDevice getMidiDevice(MidiDevice.Info info)
67            throws MidiUnavailableException {
68        //FIXME
69        /*
70         * this method must to throw out MidiUnavailableException if requested device
71         * is not available
72         */
73
74        /*
75         * obtain the list of MidiDeviceProviders
76         */
77        List<?> deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
78        /*
79         * find device that describes by parameter info and return it
80         */
81        for (int i = 0; i < deviceProviders.size(); i++) {
82            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
83            for (Info element : deviceInfo) {
84                if (element.equals(info)) {
85                    return ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(info);
86                }
87            }
88        }
89        /*
90         * if we can't find device with requested info, we throw out IllegalArgumentException
91         */
92        throw new IllegalArgumentException("Requested device not installed: " + info.getName());
93    }
94
95    public static MidiDevice.Info[] getMidiDeviceInfo() {
96        /*
97         * obtain the list of MidiDeviceProviders
98         */
99        List<?> deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
100        //variable to save MidiDevice.Info
101        List<MidiDevice.Info> infos = new ArrayList<MidiDevice.Info>();
102        /*
103         * look through list of providers and save info of devices
104         */
105        for (int i = 0; i < deviceProviders.size(); i++) {
106            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
107            for (Info element : deviceInfo) {
108                infos.add(element);
109            }
110        }
111
112        MidiDevice.Info[] temp = new MidiDevice.Info[infos.size()];
113        return infos.toArray(temp);
114    }
115
116    public static MidiFileFormat getMidiFileFormat(File file) throws InvalidMidiDataException,
117            IOException {
118        /*
119         * obtain the list of MidiFileReaderProviders
120         */
121        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
122        if (fileReaderProviders.size() == 0) {
123            //FIXME
124            /*
125             * I don't understand what type of exception we should throw out if we haven't
126             * appropriate providers...
127             * Maybe here is should be MidiUnavailableException
128             */
129            throw new Error("There is no MidiFileReaderProviders on your system!!!");
130        }
131        /*
132         * It's not determine what provider for this service I should to use, and so
133         * I use the first one
134         */
135        return ((MidiFileReader) fileReaderProviders.get(0)).getMidiFileFormat(file);
136    }
137
138    public static MidiFileFormat getMidiFileFormat(InputStream stream) throws InvalidMidiDataException,
139            IOException {
140        /*
141         * obtain the list of MidiFileReaderProviders
142         */
143        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
144        if (fileReaderProviders.size() == 0) {
145            //FIXME
146            /*
147             * I don't understand what type of exception we should throw out if we haven't
148             * appropriate providers...
149             * Maybe here is should be MidiUnavailableException
150             */
151            throw new Error("There is no MidiFileReaderProviders on your system!!!");
152        }
153        /*
154         * It's not determine what provider for this service I should to use, and so
155         * I use the first one
156         */
157        return ((MidiFileReader) fileReaderProviders.get(0)).getMidiFileFormat(stream);
158    }
159
160    public static MidiFileFormat getMidiFileFormat(URL url) throws InvalidMidiDataException,
161            IOException {
162        /*
163         * obtain the list of MidiFileReaderProviders
164         */
165        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
166        if (fileReaderProviders.size() == 0) {
167            //FIXME
168            /*
169             * I don't understand what type of exception we should throw out if we haven't
170             * appropriate providers...
171             * Maybe here is should be MidiUnavailableException
172             */
173            throw new Error("There is no MidiFileReaderProviders on your system!!!");
174        }
175        /*
176         * It's not determine what provider for this service I should to use, and so
177         * I use the first one
178         */
179        return ((MidiFileReader) fileReaderProviders.get(0)).getMidiFileFormat(url);
180    }
181
182    public static int[] getMidiFileTypes() {
183        /*
184         * obtain the list of MidiFileWriterProviders
185         */
186        List<?> fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
187        if (fileWriterProviders.size() == 0) {
188            //FIXME
189            /*
190             * I don't understand what type of exception we should throw out if we haven't
191             * appropriate providers...
192             * Maybe here is should be MidiUnavailableException
193             */
194            throw new Error("There is no MidiFileWriterProviders on your system!!!");
195        }
196        /*
197         * It's not determine what provider for this service I should to use, and so
198         * I use the first one
199         */
200        return ((MidiFileWriter) fileWriterProviders.get(0)).getMidiFileTypes();
201    }
202
203    public static int[] getMidiFileTypes(Sequence sequence) {
204        /*
205         * obtain the list of MidiFileWriterProviders
206         */
207        List<?> fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
208        if (fileWriterProviders.size() == 0) {
209            //FIXME
210            /*
211             * I don't understand what type of exception we should throw out if we haven't
212             * appropriate providers...
213             * Maybe here is should be MidiUnavailableException
214             */
215            throw new Error("There is no MidiFileWriterProviders on your system!!!");
216        }
217        /*
218         * It's not determine what provider for this service I should to use, and so
219         * I use the first one
220         */
221        return ((MidiFileWriter) fileWriterProviders.get(0)).getMidiFileTypes(sequence);
222    }
223
224    public static Receiver getReceiver() throws MidiUnavailableException {
225        /*
226         * description of the default device for javax.sound.midi.Receiver
227         */
228        List<String> defaultDevice = ProviderService.getDefaultDeviceDescription(receiverName);
229        /*
230         * obtain the list of MidiDeviceProviders
231         */
232        List<?> deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
233        String provName;
234        int deviceNum = -1;
235        /*
236         * defaultDevice.get(0) --> provider
237         * defaultDevice.get(1) --> name
238         */
239        if (defaultDevice.size() != 0) {
240            /*
241             * obtain the provider number in the list of deviceProviders that is provider for default device
242             */
243            for (int i = 0; i < deviceProviders.size(); i++) {
244                provName = deviceProviders.get(i).toString();
245                if (provName.substring(0, provName.indexOf("@")).equals(defaultDevice.get(0))) {
246                    deviceNum = i;
247                    break;
248                }
249            }
250            /*
251             * the first case: find the same provider and name that describes by default device
252             */
253            if (deviceNum != -1) {
254                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDeviceInfo();
255                for (Info element : deviceInfo) {
256                    if (element.getName().equals(defaultDevice.get(1))) {
257                        try {
258                            return ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element).getReceiver();
259                        } catch (MidiUnavailableException e) {}
260                    }
261                }
262            for (Info element : deviceInfo) {
263                    try {
264                        return ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element).getReceiver();
265                    } catch (MidiUnavailableException e) {}
266                }
267            }
268            /*
269             * if we don't find again, find any receivers describe by name
270             */
271            for (int i = 0; i < deviceProviders.size(); i++) {
272                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
273                for (Info element : deviceInfo) {
274                    if (element.getName().equals(defaultDevice.get(1))) {
275                        try {
276                            return ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element).getReceiver();
277                        } catch (MidiUnavailableException e) {}
278                    }
279                }
280            }
281        }
282        /*
283         * in the last case we look throw all providers and find any receiver
284         */
285        for (int i = 0; i < deviceProviders.size(); i++) {
286            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
287            for (Info element : deviceInfo) {
288                try {
289                    return ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element).getReceiver();
290                } catch (MidiUnavailableException e) {}
291            }
292        }
293        /*
294         * if we don't find anyway, we throw out MidiUnavailableException
295         */
296        throw new MidiUnavailableException("There are no Recivers installed on your system!");
297    }
298
299    public static Sequence getSequence(File file) throws InvalidMidiDataException, IOException {
300        /*
301         * obtain the list of MidiFileReaderProviders
302         */
303        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
304        // BEGIN android-added
305        try {
306            ((List)fileReaderProviders).add((Object)Class.forName("com.android.internal.sound.midi.AndroidMidiFileReader").newInstance());
307        } catch (Exception ex) {
308            // Ignore
309        }
310        // END android-added
311        if (fileReaderProviders.size() == 0) {
312            //FIXME
313            /*
314             * I don't understand what type of exception we should throw out if we haven't
315             * appropriate providers...
316             * Maybe here is should be MidiUnavailableException
317             */
318            throw new Error("There is no MidiFileReaderProviders on your system!!!");
319        }
320        /*
321         * It's not determine what provider for this service I should to use, and so
322         * I use the first one
323         */
324        return ((MidiFileReader) fileReaderProviders.get(0)).getSequence(file);
325    }
326
327    public static Sequence getSequence(InputStream stream) throws InvalidMidiDataException,
328            IOException {
329        /*
330         * obtain the list of MidiFileReaderProviders
331         */
332        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
333        // BEGIN android-added
334        try {
335            ((List)fileReaderProviders).add(Class.forName("com.android.internal.sound.midi.AndroidMidiFileReader").newInstance());
336        } catch (Exception ex) {
337            // Ignore
338        }
339        // END android-added
340        if (fileReaderProviders.size() == 0) {
341            //FIXME
342            /*
343             * I don't understand what type of exception we should throw out if we haven't
344             * appropriate providers...
345             * Maybe here is should be MidiUnavailableException
346             */
347            throw new Error("There is no MidiFileReaderProviders on your system!!!");
348        }
349        /*
350         * It's not determine what provider for this service I should to use, and so
351         * I use the first one
352         */
353        return ((MidiFileReader) fileReaderProviders.get(0)).getSequence(stream);
354    }
355
356    public static Sequence getSequence(URL url) throws InvalidMidiDataException, IOException {
357        /*
358         * obtain the list of MidiFileReaderProviders
359         */
360        List<?> fileReaderProviders = ProviderService.getProviders(midiFileReaderPath);
361        // BEGIN android-added
362        try {
363            ((List)fileReaderProviders).add(Class.forName("com.android.internal.sound.midi.AndroidMidiFileReader").newInstance());
364        } catch (Exception ex) {
365            // Ignore
366        }
367        // END android-added
368        if (fileReaderProviders.size() == 0) {
369            //FIXME
370            /*
371             * I don't understand what type of exception we should throw out if we haven't
372             * appropriate providers...
373             * Maybe here is should be MidiUnavailableException
374             */
375            throw new Error("There is no MidiFileReaderProviders on your system!!!");
376        }
377        /*
378         * It's not determine what provider for this service I should to use, and so
379         * I use the first one
380         */
381        return ((MidiFileReader) fileReaderProviders.get(0)).getSequence(url);
382    }
383
384    public static Sequencer getSequencer() throws MidiUnavailableException {
385        /*
386         * this method is equals to method MidiSystem.getSequencer(true)
387         */
388        return getSequencer(true);
389    }
390
391    public static Sequencer getSequencer(boolean connected) throws MidiUnavailableException {
392        /*
393         * description of the default device for javax.sound.midi.Sequencer
394         */
395        List<String> defaultDevice = ProviderService.getDefaultDeviceDescription(sequencerName);
396        /*
397         * obtain the list of MidiDeviceProviders
398         */
399        List<?>  deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
400
401        Sequencer sequencer;
402        Transmitter seqTrans;
403        Synthesizer synth;
404        Receiver recv;
405        String provName;
406        int deviceNum = -1;
407        /*
408         * defaultDevice.get(0) --> provider
409         * defaultDevice.get(1) --> name
410         */
411        if (defaultDevice.size() != 0) {
412            /*
413             * obtain the provider number in the list of deviceProviders that is provider for default device
414             */
415            for (int i = 0; i < deviceProviders.size(); i++) {
416                provName = deviceProviders.get(i).toString();
417                if (provName.substring(0, provName.indexOf("@")).equals(defaultDevice.get(0))) {
418                    deviceNum = i;
419                    break;
420                }
421            }
422            /*
423             * the first case: find the same provider and name that describes by default device
424             */
425            if (deviceNum != -1) {
426                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDeviceInfo();
427                for (Info element : deviceInfo) {
428                    if (element.getName().equals(defaultDevice.get(1))) {
429                        if (((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element) instanceof Sequencer) {
430                            if (connected) {
431                                sequencer = (Sequencer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
432                                seqTrans = sequencer.getTransmitter();
433                                try {
434                                    synth = MidiSystem.getSynthesizer();
435                                    recv = synth.getReceiver();
436                                } catch (MidiUnavailableException e) {
437                                    /*
438                                     * if we haven't Synthesizer in the system, we use default receiver
439                                     */
440                                    recv = MidiSystem.getReceiver();
441                                }
442                                seqTrans.setReceiver(recv);
443                                return sequencer;
444                            }
445                            return (Sequencer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
446                        }
447                    }
448                }
449                for (Info element : deviceInfo) {
450                    if (((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element) instanceof Sequencer) {
451                        if (connected) {
452                            sequencer = (Sequencer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
453                            seqTrans = sequencer.getTransmitter();
454                            try {
455                                synth = MidiSystem.getSynthesizer();
456                                recv = synth.getReceiver();
457                            } catch (MidiUnavailableException e) {
458                                /*
459                                 * if we haven't Synthesizer in the system, we use default receiver
460                                 */
461                                recv = MidiSystem.getReceiver();
462                            }
463                            seqTrans.setReceiver(recv);
464                            return sequencer;
465                        }
466                        return (Sequencer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
467                    }
468                }
469            }
470            /*
471             * if we don't find again, find any receivers describe by name
472             */
473            for (int i = 0; i < deviceProviders.size(); i++) {
474                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
475                for (Info element : deviceInfo) {
476                    if (element.getName().equals(defaultDevice.get(1))) {
477                        if (((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element) instanceof Sequencer) {
478                            if (connected) {
479                                sequencer = (Sequencer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
480                                seqTrans = sequencer.getTransmitter();
481                                try {
482                                    synth = MidiSystem.getSynthesizer();
483                                    recv = synth.getReceiver();
484                                } catch (MidiUnavailableException e) {
485                                    /*
486                                     * if we haven't Synthesizer in the system, we use default receiver
487                                     */
488                                    recv = MidiSystem.getReceiver();
489                                }
490                                seqTrans.setReceiver(recv);
491                                return sequencer;
492                            }
493                            return (Sequencer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
494                        }
495                    }
496                }
497            }
498        }
499        /*
500         * in the last case we look throw all providers and find any receiver
501         */
502        for (int i = 0; i < deviceProviders.size(); i++) {
503            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
504            for (Info element : deviceInfo) {
505                if (((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element) instanceof Sequencer) {
506                    if (connected) {
507                        sequencer = (Sequencer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
508                        seqTrans = sequencer.getTransmitter();
509                        try {
510                            synth = MidiSystem.getSynthesizer();
511                            recv = synth.getReceiver();
512                        } catch (MidiUnavailableException e) {
513                            /*
514                             * if we haven't Synthesizer in the system, we use default receiver
515                             */
516                            recv = MidiSystem.getReceiver();
517                        }
518                        seqTrans.setReceiver(recv);
519                        return sequencer;
520                    }
521                    return (Sequencer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
522                }
523            }
524        }
525        // BEGIN android-added
526        try {
527            return (Sequencer)(Class.forName("com.android.internal.sound.midi.AndroidSequencer").newInstance());
528        } catch (Exception ex) {
529            // Ignore
530        }
531        // END android-added
532        /*
533         * if we don't find anyway, we throw out MidiUnavailableException
534         */
535        throw new MidiUnavailableException("There are no Synthesizers installed on your system!");
536    }
537
538    public static Soundbank getSoundbank(File file) throws InvalidMidiDataException,
539            IOException {
540        /*
541         * obtain the list of SoundbankReaderProviders
542         */
543        List<?> soundbankReaderProviders = ProviderService.getProviders(soundbankReaderPath);
544        if (soundbankReaderProviders.size() == 0) {
545            //FIXME
546            /*
547             * I don't understand what type of exception we should throw out if we haven't
548             * appropriate providers...
549             * Maybe here is should be MidiUnavailableException
550             */
551            throw new Error("There is no SoundbankReaderProviders on your system!!!");
552        }
553        /*
554         * It's not determine what provider for this service I should to use, and so
555         * I use the first one
556         */
557        return ((SoundbankReader) soundbankReaderProviders.get(0)).getSoundbank(file);
558    }
559
560    public static Soundbank getSoundbank(InputStream stream) throws InvalidMidiDataException, IOException {
561        /*
562         * obtain the list of SoundbankReaderProviders
563         */
564        List<?> soundbankReaderProviders = ProviderService.getProviders(soundbankReaderPath);
565        if (soundbankReaderProviders.size() == 0) {
566            //FIXME
567            /*
568             * I don't understand what type of exception we should throw out if we haven't
569             * appropriate providers...
570             * Maybe here is should be MidiUnavailableException
571             */
572            throw new Error("There is no SoundbankReaderProviders on your system!!!");
573        }
574        /*
575         * It's not determine what provider for this service I should to use, and so
576         * I use the first one
577         */
578        return ((SoundbankReader) soundbankReaderProviders.get(0)).getSoundbank(stream);
579    }
580
581    public static Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException {
582        /*
583         * obtain the list of SoundbankReaderProviders
584         */
585        List<?> soundbankReaderProviders = ProviderService.getProviders(soundbankReaderPath);
586        if (soundbankReaderProviders.size() == 0) {
587            //FIXME
588            /*
589             * I don't understand what type of exception we should throw out if we haven't
590             * appropriate providers...
591             * Maybe here is should be MidiUnavailableException
592             */
593            throw new Error("There is no SoundbankReaderProviders on your system!!!");
594        }
595        /*
596         * It's not determine what provider for this service I should to use, and so
597         * I use the first one
598         */
599        return ((SoundbankReader) soundbankReaderProviders.get(0)).getSoundbank(url);
600    }
601
602    public static Synthesizer getSynthesizer() throws MidiUnavailableException {
603        /*
604         * description of the default device for javax.sound.midi.Synthesizer
605         */
606        List<String> defaultDevice = ProviderService.getDefaultDeviceDescription(synthesizerName);
607        /*
608         * obtain the list of MidiDeviceProviders
609         */
610        List<?> deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
611        String provName;
612        int deviceNum = -1;
613
614        /*
615         * defaultDevice.get(0) --> provider
616         * defaultDevice.get(1) --> name
617         */
618        if (defaultDevice.size() != 0) {
619            /*
620             * obtain the provider number in the list of deviceProviders that is provider for default device
621             */
622            for (int i = 0; i < deviceProviders.size(); i++) {
623                provName = deviceProviders.get(i).toString();
624                if (provName.substring(0, provName.indexOf("@")).equals(defaultDevice.get(0))) {
625                    deviceNum = i;
626                    break;
627                }
628            }
629            /*
630             * the first case: find the same provider and name that describes by default device
631             */
632            if (deviceNum != -1) {
633                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDeviceInfo();
634                for (Info element : deviceInfo) {
635                    if (element.getName().equals(defaultDevice.get(1))) {
636                        if (((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element) instanceof Synthesizer) {
637                            return (Synthesizer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
638                        }
639                    }
640                }
641                for (Info element : deviceInfo) {
642                    if (((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element) instanceof Synthesizer) {
643                        return (Synthesizer) ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element);
644                    }
645                }
646            }
647            /*
648             * if we don't find again, find any receivers describe by name
649             */
650            for (int i = 0; i < deviceProviders.size(); i++) {
651                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
652                for (Info element : deviceInfo) {
653                    if (element.getName().equals(defaultDevice.get(1))) {
654                        if (((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element) instanceof Synthesizer) {
655                            return (Synthesizer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
656                        }
657                    }
658                }
659            }
660        }
661        /*
662         * in the last case we look throw all providers and find any receiver
663         */
664        for (int i = 0; i < deviceProviders.size(); i++) {
665            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
666            for (Info element : deviceInfo) {
667                if (((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element) instanceof Synthesizer) {
668                    return (Synthesizer) ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element);
669                }
670            }
671        }
672        /*
673         * if we don't find anyway, we throw out MidiUnavailableException
674         */
675        throw new MidiUnavailableException("There are no Synthesizers installed on your system!");
676    }
677
678    public static Transmitter getTransmitter() throws MidiUnavailableException {
679        /*
680         * description of the default device for javax.sound.midi.Transmitter
681         */
682        List<String> defaultDevice = ProviderService.getDefaultDeviceDescription(transmitterName);
683        /*
684         * obtain the list of MidiDeviceProviders
685         */
686        List<?> deviceProviders = ProviderService.getProviders(midiDeviceProviderPath);
687        String provName;
688        int deviceNum = -1;
689        /*
690         * defaultDevice.get(0) --> provider
691         * defaultDevice.get(1) --> name
692         */
693        if (defaultDevice.size() != 0) {
694            /*
695             * obtain the provider number in the list of deviceProviders that is provider for default device
696             */
697            for (int i = 0; i < deviceProviders.size(); i++) {
698                provName = deviceProviders.get(i).toString();
699                if (provName.substring(0, provName.indexOf("@")).equals(defaultDevice.get(0))) {
700                    deviceNum = i;
701                    break;
702                }
703            }
704            /*
705             * the first case: find the same provider and name that describes by default device
706             */
707            if (deviceNum != -1) {
708                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDeviceInfo();
709                for (Info element : deviceInfo) {
710                    if (element.getName().equals(defaultDevice.get(1))) {
711                        try {
712                            return ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element).getTransmitter();
713                        } catch (MidiUnavailableException e) {}
714                    }
715                }
716                for (Info element : deviceInfo) {
717                    try {
718                        return ((MidiDeviceProvider) deviceProviders.get(deviceNum)).getDevice(element).getTransmitter();
719                    } catch (MidiUnavailableException e) {}
720                }
721            }
722            /*
723             * if we don't find again, find any receivers describe by name
724             */
725            for (int i = 0; i < deviceProviders.size(); i++) {
726                MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
727                for (Info element : deviceInfo) {
728                    if (element.getName().equals(defaultDevice.get(1))) {
729                        try {
730                            return ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element).getTransmitter();
731                        } catch (MidiUnavailableException e) {}
732                    }
733                }
734            }
735        }
736        /*
737         * in the last case we look throw all providers and find any receiver
738         */
739        for (int i = 0; i < deviceProviders.size(); i++) {
740            MidiDevice.Info[] deviceInfo = ((MidiDeviceProvider) deviceProviders.get(i)).getDeviceInfo();
741            for (Info element : deviceInfo) {
742                try {
743                    return ((MidiDeviceProvider) deviceProviders.get(i)).getDevice(element).getTransmitter();
744                } catch (MidiUnavailableException e) {}
745            }
746        }
747        /*
748         * if we don't find anyway, we throw out MidiUnavailableException
749         */
750        throw new MidiUnavailableException("There are no Transmitters installed on your system!");
751    }
752
753    public static boolean isFileTypeSupported(int fileType) {
754        /*
755         * obtain the list of MidiFileWriterProviders;
756         * if we already obtain the list of providers, we don't obtain it again
757         */
758        List<?> fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
759        if (fileWriterProviders.size() == 0) {
760            //FIXME
761            /*
762             * I don't understand what type of exception we should throw out if we haven't
763             * appropriate providers...
764             * Maybe here is should be MidiUnavailableException
765             */
766            throw new Error("There is no MidiFileWriterProviders on your system!!!");
767        }
768        /*
769         * It's not determine what provider for this service I should to use, and so
770         * I use the first one
771         */
772        return ((MidiFileWriter) fileWriterProviders.get(0)).isFileTypeSupported(fileType);
773    }
774
775    public static boolean isFileTypeSupported(int fileType, Sequence sequence) {
776        /*
777         * obtain the list of MidiFileWriterProviders
778         */
779        List<?> fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
780        if (fileWriterProviders.size() == 0) {
781            //FIXME
782            /*
783             * I don't understand what type of exception we should throw out if we haven't
784             * appropriate providers...
785             * Maybe here is should be MidiUnavailableException
786             */
787            throw new Error("There is no MidiFileWriterProviders on your system!!!");
788        }
789        /*
790         * It's not determine what provider for this service I should to use, and so
791         * I use the first one
792         */
793        return ((MidiFileWriter) fileWriterProviders.get(0)).isFileTypeSupported(fileType, sequence);
794    }
795
796    public static int write(Sequence in, int type, File out) throws IOException {
797        /*
798         * obtain the list of MidiFileWriterProviders
799         */
800        List<?>  fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
801        if (fileWriterProviders.size() == 0) {
802            //FIXME
803            /*
804             * I don't understand what type of exception we should throw out if we haven't
805             * appropriate providers...
806             * Maybe here is should be MidiUnavailableException
807             */
808            throw new Error("There is no MidiFileWriterProviders on your system!!!");
809        }
810        /*
811         * It's not determine what provider for this service I should to use, and so
812         * I use the first one
813         */
814        return ((MidiFileWriter) fileWriterProviders.get(0)).write(in, type, out);
815    }
816
817    public static int write(Sequence in, int fileType, OutputStream out) throws IOException {
818        /*
819         * obtain the list of MidiFileWriterProviders
820         */
821        List<?>  fileWriterProviders = ProviderService.getProviders(midiFileWriterPath);
822        if (fileWriterProviders.size() == 0) {
823            //FIXME
824            /*
825             * I don't understand what type of exception we should throw out if we haven't
826             * appropriate providers...
827             * Maybe here is should be MidiUnavailableException
828             */
829            throw new Error("There is no MidiFileWriterProviders on your system!!!");
830        }
831        /*
832         * It's not determine what provider for this service I should to use, and so
833         * I use the first one
834         */
835        return ((MidiFileWriter) fileWriterProviders.get(0)).write(in, fileType, out);
836    }
837}
838