/* * MidiSystem.java * * This file is part of Tritonus: http://www.tritonus.org/ */ /* * Copyright (c) 1999 - 2004 by Matthias Pfisterer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* |<--- this code is formatted to fit into 80 columns --->| */ package javax.sound.midi; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.Iterator; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.spi.MidiDeviceProvider; import javax.sound.midi.spi.MidiFileReader; import javax.sound.midi.spi.MidiFileWriter; import org.tritonus.core.TMidiConfig; import org.tritonus.share.TDebug; import org.tritonus.share.ArraySet; public class MidiSystem { private static final MidiDevice.Info[] EMPTY_MIDIDEVICE_INFO_ARRAY = new MidiDevice.Info[0]; public static MidiDevice.Info[] getMidiDeviceInfo() { List<MidiDevice.Info> deviceInfos = new ArrayList<MidiDevice.Info>(); Iterator providers = TMidiConfig.getMidiDeviceProviders(); while (providers.hasNext()) { MidiDeviceProvider provider = (MidiDeviceProvider) providers.next(); MidiDevice.Info[] infos = provider.getDeviceInfo(); deviceInfos.addAll(Arrays.asList(infos)); } return deviceInfos.toArray(EMPTY_MIDIDEVICE_INFO_ARRAY); } public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavailableException { Iterator providers = TMidiConfig.getMidiDeviceProviders(); while (providers.hasNext()) { MidiDeviceProvider provider = (MidiDeviceProvider) providers.next(); if (provider.isDeviceSupported(info)) { return provider.getDevice(info); } } throw new IllegalArgumentException("no device found for " + info); } public static Receiver getReceiver() throws MidiUnavailableException { MidiDevice.Info info = TMidiConfig.getDefaultMidiOutDeviceInfo(); MidiDevice device = getMidiDevice(info); // to florian: try to comment out the following block if (!device.isOpen()) { device.open(); } // end of block to comment out Receiver receiver = device.getReceiver(); return receiver; } public static Transmitter getTransmitter() throws MidiUnavailableException { MidiDevice.Info info = TMidiConfig.getDefaultMidiInDeviceInfo(); MidiDevice device = getMidiDevice(info); // to florian: try to comment out the following block if (!device.isOpen()) { device.open(); } // end of block to comment out Transmitter transmitter = device.getTransmitter(); return transmitter; } public static Synthesizer getSynthesizer() throws MidiUnavailableException { MidiDevice.Info info = TMidiConfig.getDefaultSynthesizerInfo(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.getSynthesizer(): using default synthesizer info: " + info); } Synthesizer synthesizer = (Synthesizer) getMidiDevice(info); return synthesizer; } public static Sequencer getSequencer() throws MidiUnavailableException { return getSequencer(true); } public static Sequencer getSequencer(boolean bConnected) throws MidiUnavailableException { MidiDevice.Info info = TMidiConfig.getDefaultSequencerInfo(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.getSequencer(): using: " + info); } Sequencer sequencer = (Sequencer) getMidiDevice(info); if (bConnected) { Synthesizer synth = getSynthesizer(); synth.open(); sequencer.getTransmitter().setReceiver(synth.getReceiver()); } return sequencer; } public static Soundbank getSoundbank(InputStream inputStream) throws InvalidMidiDataException, IOException { return null; //TMidiConfig.getSoundbank(inputStream); } public static Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException { return null; //TMidiConfig.getSoundbank(inputStream); } public static Soundbank getSoundbank(File file) throws InvalidMidiDataException, IOException { return null; //TMidiConfig.getSoundbank(inputStream); } public static MidiFileFormat getMidiFileFormat(InputStream inputStream) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); try { return reader.getMidiFileFormat(inputStream); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new InvalidMidiDataException(); } public static MidiFileFormat getMidiFileFormat(URL url) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); try { return reader.getMidiFileFormat(url); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new InvalidMidiDataException(); } public static MidiFileFormat getMidiFileFormat(File file) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); try { return reader.getMidiFileFormat(file); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new InvalidMidiDataException(); } public static Sequence getSequence(InputStream inputStream) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); try { return reader.getSequence(inputStream); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new InvalidMidiDataException(); } public static Sequence getSequence(URL url) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); try { return reader.getSequence(url); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new InvalidMidiDataException(); } public static Sequence getSequence(File file) throws InvalidMidiDataException, IOException { Iterator readers = TMidiConfig.getMidiFileReaders(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.getSequence(File): got readers: " + readers); } while (readers.hasNext()) { MidiFileReader reader = (MidiFileReader) readers.next(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.getSequence(File): Trying MidiFileReader " + reader); } try { return reader.getSequence(file); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.getSequence(File): no appropriate MidiFileReader found, throwing exception"); } throw new InvalidMidiDataException(); } public static int[] getMidiFileTypes() { Set<Integer> fileTypes = new ArraySet<Integer>(); Iterator<MidiFileWriter> writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = writers.next(); int[] anTypes = writer.getMidiFileTypes(); for (int i = 0; i < anTypes.length; i++) { fileTypes.add(anTypes[i]); } } int[] anTypes = new int[fileTypes.size()]; Iterator<Integer> types = fileTypes.iterator(); int nIndex = 0; while (types.hasNext()) { Integer type = types.next(); anTypes[nIndex] = type.intValue(); nIndex++; } return anTypes; } public static boolean isFileTypeSupported(int nFileType) { Iterator<MidiFileWriter> writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = writers.next(); boolean bIsSupported = writer.isFileTypeSupported(nFileType); if (bIsSupported) { return true; } } return false; } public static int[] getMidiFileTypes(Sequence sequence) { Set<Integer> fileTypes = new ArraySet<Integer>(); Iterator<MidiFileWriter> writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = writers.next(); int[] anTypes = writer.getMidiFileTypes(sequence); for (int i = 0; i < anTypes.length; i++) { fileTypes.add(anTypes[i]); } } int[] anTypes = new int[fileTypes.size()]; Iterator<Integer> types = fileTypes.iterator(); int nIndex = 0; while (types.hasNext()) { Integer type = types.next(); anTypes[nIndex] = type.intValue(); nIndex++; } return anTypes; } public static boolean isFileTypeSupported(int nFileType, Sequence sequence) { Iterator<MidiFileWriter> writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = writers.next(); boolean bIsSupported = writer.isFileTypeSupported(nFileType, sequence); if (bIsSupported) { return true; } } return false; } /** MidiFileWriterAction for write(). */ private static class WriteMidiFileWriterAction implements MidiFileWriterAction { private Sequence m_sequence; private int m_fileType; private Object m_destination; private int m_nWritten; public WriteMidiFileWriterAction( Sequence sequence, int fileType, Object destination) { m_sequence = sequence; m_fileType = fileType; m_destination = destination; m_nWritten = -1; } public boolean handleMidiFileWriter( MidiFileWriter midiFileWriter) throws IOException { int nWritten = -1; // $$fb 2000-04-02: need to check whether this audioFileWriter is actually // capable of handling this file type ! if (!midiFileWriter.isFileTypeSupported(m_fileType)) { // do not interrupt the iteration return false; } try { if (m_destination instanceof OutputStream) { nWritten = midiFileWriter.write( m_sequence, m_fileType, (OutputStream) m_destination); } else if (m_destination instanceof File) { nWritten = midiFileWriter.write( m_sequence, m_fileType, (File) m_destination); } else { // TODO: debug message } m_nWritten = nWritten; // interrupt the iteration return true; } catch (IllegalArgumentException e) { if (TDebug.TraceMidiSystem || TDebug.TraceAllExceptions) { TDebug.out(e); } } // continue the iteration return false; } public int getWritten() { return m_nWritten; } } public static int write(Sequence sequence, int fileType, OutputStream outputStream) throws IOException { return writeImpl(sequence, fileType, outputStream); } public static int write(Sequence sequence, int fileType, File file) throws IOException { return writeImpl(sequence, fileType, file); } private static int writeImpl(Sequence sequence, int fileType, Object destination) throws IOException { WriteMidiFileWriterAction action = new WriteMidiFileWriterAction( sequence, fileType, destination); doMidiFileWriterIteration(action); int nWritten = action.getWritten(); if (nWritten == -1) { throw new IllegalArgumentException("format not supported"); } else { return nWritten; } } /* public static int write(Sequence sequence, int nFileType, OutputStream outputStream) throws IOException { Iterator writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = (MidiFileWriter) writers.next(); try { return writer.write(sequence, nFileType, outputStream); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new IllegalArgumentException (); } public static int write(Sequence sequence, int nFileType, File file) throws IOException { Iterator writers = TMidiConfig.getMidiFileWriters(); while (writers.hasNext()) { MidiFileWriter writer = (MidiFileWriter) writers.next(); try { return writer.write(sequence, nFileType, file); } catch (IllegalArgumentException e) { if (TDebug.TraceAllExceptions) { TDebug.out(e); } } } throw new IllegalArgumentException (); } */ //---------------------------------------------------------- private static interface MidiFileReaderAction { public boolean handleMidiFileReader(MidiFileReader audioFileReader) throws IOException; } /** Iterates over the available MidiFileReaders. * For each MidiFileReader, the mathod handleMidiFileReader() of * the passed MidiFileReaderAction is called with the MidiFileReader * in question as the only argument. */ private static void doMidiFileReaderIteration( MidiFileReaderAction action) throws IOException { Iterator<MidiFileReader> audioFileReaders = TMidiConfig.getMidiFileReaders(); boolean bCompleted = false; while (audioFileReaders.hasNext() && ! bCompleted) { MidiFileReader audioFileReader = audioFileReaders.next(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.doMidiFileReaderIteration(): handling MidiFileReader: " + audioFileReader); } bCompleted = action.handleMidiFileReader(audioFileReader); } } private static interface MidiFileWriterAction { public boolean handleMidiFileWriter(MidiFileWriter audioFileWriter) throws IOException; } /** Iterates over the available MidiFileWriters. * For each MidiFileWriter, the mathod handleMidiFileWriter() of * the passed MidiFileWriterAction is called with the MidiFileWriter * in question as the only argument. */ private static void doMidiFileWriterIteration( MidiFileWriterAction action) throws IOException { Iterator<MidiFileWriter> audioFileWriters = TMidiConfig.getMidiFileWriters(); boolean bCompleted = false; while (audioFileWriters.hasNext() && ! bCompleted) { MidiFileWriter audioFileWriter = audioFileWriters.next(); if (TDebug.TraceMidiSystem) { TDebug.out("MidiSystem.doMidiFileWriterIteration(): handling MidiFileWriter: " + audioFileWriter); } bCompleted = action.handleMidiFileWriter(audioFileWriter); } } } /*** MidiSystem.java ***/