summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/javax/sound
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/javax/sound')
-rw-r--r--libjava/classpath/gnu/javax/sound/AudioSecurityManager.java112
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java130
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java216
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java515
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java131
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java150
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java171
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java742
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/file/ExtendedMidiFileFormat.java77
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/file/MidiDataInputStream.java83
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/file/MidiDataOutputStream.java114
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/file/MidiFileReader.java378
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/file/MidiFileWriter.java197
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/AU/AUReader.java210
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/WAV/WAVReader.java236
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixer.java248
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixerProvider.java71
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReader.java185
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer.java284
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileWriter.java80
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstInputStream.java119
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstDataLine.java151
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstNativeDataLine.java77
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstPipeline.java415
-rw-r--r--libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstSourceDataLine.java153
25 files changed, 5245 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/sound/AudioSecurityManager.java b/libjava/classpath/gnu/javax/sound/AudioSecurityManager.java
new file mode 100644
index 000000000..1daea2db5
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/AudioSecurityManager.java
@@ -0,0 +1,112 @@
+/* AudioSecurityManager.java -- Manages Security requests for Sound classes.
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound;
+
+import javax.sound.sampled.AudioPermission;
+
+/**
+ * This class handles security requests for classes in the Sound API.
+ *
+ * A class that needs to check against a particular permission type may use this
+ * class to query the <code>SecurityManager</code>.
+ *
+ * For example, to check for a read permission, a class can simply pass the
+ * <code>Permission.READ</code> constant to
+ * {@link #checkPermissions(gnu.javax.sound.AudioSecurityManager.Permission))},
+ * like the following code demonstrates:
+ *
+ * <pre>
+ * AudioSecurityManager.checkPermissions(Permission.PLAY);
+ * </pre>
+ *
+ * If there is need to query for all the defined permissions type, the constant
+ * <code>Permission.ALL</code> can be used. In alternative, the
+ * {@link #checkPermissions()} is presented as a shorthand.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class AudioSecurityManager
+{
+ /**
+ * Defines a common set of permission allowed by the specification.
+ */
+ public static enum Permission
+ {
+ PLAY, RECORD, ALL
+ }
+
+ /**
+ * Shorthand to <code>checkPermissions(Permission.ALL)</code>.
+ */
+ public static final void checkPermissions()
+ {
+ checkPermissions(Permission.ALL);
+ }
+
+ /**
+ * Query the <code>SecurityManager</code> agains the given
+ * <code>Permission</code>.
+ *
+ * @param permission
+ */
+ public static final void checkPermissions(Permission permission)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ String perm = null;
+ switch (permission)
+ {
+ case PLAY:
+ perm = "play";
+ break;
+
+ case RECORD:
+ perm = "record";
+ break;
+
+ case ALL: default:
+ perm = "*";
+ break;
+ }
+
+ sm.checkPermission(new AudioPermission(perm));
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java
new file mode 100644
index 000000000..d37a8fd6b
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java
@@ -0,0 +1,130 @@
+/* AlsaInputPortDevice.java -- ALSA MIDI In Port
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.alsa;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+/**
+ * ALSA MIDI In Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaInputPortDevice extends AlsaPortDevice
+{
+
+ AlsaInputPortDevice (AlsaPortInfo info)
+ {
+ super(info);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ return new AlsaTransmitter();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java
new file mode 100644
index 000000000..33181b6d5
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java
@@ -0,0 +1,216 @@
+/* AlsaMidiDeviceProvider.java -- The ALSA MIDI Device Provider
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.alsa;
+
+import gnu.classpath.Configuration;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * Provide ALSA MIDI devices.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaMidiDeviceProvider extends MidiDeviceProvider
+{
+ /**
+ * Abstract base for ALSA specific MIDI device info.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static abstract class AlsaInfo extends Info
+ {
+ /**
+ * Create an ALSA specific MIDI device info object.
+ *
+ * @param name the device name
+ * @param description the device description
+ */
+ public AlsaInfo(String name, String description)
+ {
+ super(name, "Alsa", description, "0.0");
+ }
+
+ abstract MidiDevice getDevice ();
+ }
+
+ /**
+ * ALSA MIDI Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public static abstract class AlsaPortInfo extends AlsaInfo
+ {
+ long client;
+ long port;
+
+ /**
+ * Create ALSA MIDI In Port.
+ *
+ * @param name the device name
+ * @param description the device description
+ * @param client the client ID
+ * @param port the port ID
+ */
+ public AlsaPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description);
+ this.client = client;
+ this.port = port;
+ }
+ }
+
+ /**
+ * ALSA Sequencer specific info.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaSequencerInfo extends AlsaInfo
+ {
+ public AlsaSequencerInfo(String name, String description)
+ {
+ super(name, description);
+ }
+
+ MidiDevice getDevice()
+ {
+ return AlsaMidiSequencerDevice.getInstance();
+ }
+ }
+
+ /**
+ * ALSA MIDI In Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaInputPortInfo extends AlsaPortInfo
+ {
+ public AlsaInputPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description, client, port);
+ }
+
+ MidiDevice getDevice()
+ {
+ return new AlsaInputPortDevice(this);
+ }
+ }
+
+ /**
+ * ALSA MIDI Out Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaOutputPortInfo extends AlsaPortInfo
+ {
+ public AlsaOutputPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description, client, port);
+ }
+
+ MidiDevice getDevice()
+ {
+ return new AlsaOutputPortDevice(this);
+ }
+ }
+
+ private static AlsaInfo[] infos;
+
+ private static native AlsaInfo[] getInputDeviceInfo_();
+ private static native AlsaInfo[] getOutputDeviceInfo_();
+
+ /**
+ * Initialize the ALSA system
+ */
+ private static native void init_();
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gjsmalsa");
+ }
+
+ init_();
+
+ AlsaInfo inputs[] = getInputDeviceInfo_();
+ AlsaInfo outputs[] = getOutputDeviceInfo_();
+
+ infos = new AlsaInfo[inputs.length + outputs.length + 1];
+ infos[0] = new AlsaSequencerInfo ("/dev/snd/seq", "ALSA Sequencer");
+ System.arraycopy(inputs, 0, infos, 1, inputs.length);
+ System.arraycopy(outputs, 0, infos, 1 + inputs.length, outputs.length);
+ }
+
+ public AlsaMidiDeviceProvider()
+ {
+ // Nothing.
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDeviceInfo()
+ */
+ public Info[] getDeviceInfo()
+ {
+ return infos;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDevice(javax.sound.midi.MidiDevice.Info)
+ */
+ public MidiDevice getDevice(Info info)
+ {
+ for (int i = 0; i < infos.length; i++)
+ {
+ if (info.equals(infos[i]))
+ {
+ return infos[i].getDevice();
+ }
+ }
+ throw new IllegalArgumentException("Don't recognize MIDI device " + info);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
new file mode 100644
index 000000000..3603bb5a7
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
@@ -0,0 +1,515 @@
+/* AlsaMidiSequencerDevice.java -- The ALSA MIDI sequencer device
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.alsa;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.ControllerEventListener;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Track;
+import javax.sound.midi.Transmitter;
+
+/**
+ * The ALSA MIDI sequencer device. This is a singleton device.
+ *
+ * @author green@redhat.com
+ *
+ */
+public class AlsaMidiSequencerDevice implements Sequencer
+{
+ // The singleton instance.
+ public final static AlsaMidiSequencerDevice instance = new AlsaMidiSequencerDevice();
+
+ // A pointer to a native chunk of memory
+ private long nativeState;
+
+ // The sequence to process
+ private Sequence sequence;
+
+ /**
+ * A private constructor. There should only be one instance of this
+ * device.
+ */
+ private AlsaMidiSequencerDevice()
+ {
+ super();
+ }
+
+ /**
+ * Return the sequencer singleton.
+ *
+ * @return the sequencer singleton
+ */
+ public static AlsaMidiSequencerDevice getInstance()
+ {
+ return instance;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSequence(javax.sound.midi.Sequence)
+ */
+ public void setSequence(Sequence seq) throws InvalidMidiDataException
+ {
+ sequence = seq;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSequence(java.io.InputStream)
+ */
+ public void setSequence(InputStream istream) throws IOException,
+ InvalidMidiDataException
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSequence()
+ */
+ public Sequence getSequence()
+ {
+ return sequence;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#start()
+ */
+ public void start()
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#stop()
+ */
+ public void stop()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#isRunning()
+ */
+ public boolean isRunning()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#startRecording()
+ */
+ public void startRecording()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#stopRecording()
+ */
+ public void stopRecording()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#isRecording()
+ */
+ public boolean isRecording()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#recordEnable(javax.sound.midi.Track, int)
+ */
+ public void recordEnable(Track track, int channel)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#recordDisable(javax.sound.midi.Track)
+ */
+ public void recordDisable(Track track)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoInBPM()
+ */
+ public float getTempoInBPM()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoInBPM(float)
+ */
+ public void setTempoInBPM(float bpm)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoInMPQ()
+ */
+ public float getTempoInMPQ()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoInMPQ(float)
+ */
+ public void setTempoInMPQ(float mpq)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoFactor(float)
+ */
+ public void setTempoFactor(float factor)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoFactor()
+ */
+ public float getTempoFactor()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTickLength()
+ */
+ public long getTickLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTickPosition()
+ */
+ public long getTickPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTickPosition(long)
+ */
+ public void setTickPosition(long tick)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMicrosecondLength()
+ */
+ public long getMicrosecondLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setMicrosecondPosition(long)
+ */
+ public void setMicrosecondPosition(long microsecond)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setMasterSyncMode(javax.sound.midi.Sequencer.SyncMode)
+ */
+ public void setMasterSyncMode(SyncMode sync)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMasterSyncMode()
+ */
+ public SyncMode getMasterSyncMode()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMasterSyncModes()
+ */
+ public SyncMode[] getMasterSyncModes()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSlaveSyncMode(javax.sound.midi.Sequencer.SyncMode)
+ */
+ public void setSlaveSyncMode(SyncMode sync)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSlaveSyncMode()
+ */
+ public SyncMode getSlaveSyncMode()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSlaveSyncModes()
+ */
+ public SyncMode[] getSlaveSyncModes()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTrackMute(int, boolean)
+ */
+ public void setTrackMute(int track, boolean mute)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTrackMute(int)
+ */
+ public boolean getTrackMute(int track)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTrackSolo(int, boolean)
+ */
+ public void setTrackSolo(int track, boolean solo)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTrackSolo(int)
+ */
+ public boolean getTrackSolo(int track)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#addMetaEventListener(javax.sound.midi.MetaEventListener)
+ */
+ public boolean addMetaEventListener(MetaEventListener listener)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#removeMetaEventListener(javax.sound.midi.MetaEventListener)
+ */
+ public void removeMetaEventListener(MetaEventListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#addControllerEventListener(javax.sound.midi.ControllerEventListener, int[])
+ */
+ public int[] addControllerEventListener(ControllerEventListener listener,
+ int[] controllers)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#removeControllerEventListener(javax.sound.midi.ControllerEventListener, int[])
+ */
+ public int[] removeControllerEventListener(ControllerEventListener listener,
+ int[] controllers)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getDeviceInfo()
+ */
+ public Info getDeviceInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ synchronized(this)
+ {
+ // Check to see if we're open already.
+ if (nativeState != 0)
+ return;
+
+ nativeState = open_();
+ }
+ }
+
+ /**
+ * Allocate the native state object, and open the sequencer.
+ *
+ * @return a long representation of a pointer to the nativeState.
+ */
+ private native long open_();
+
+ /**
+ * Close the sequencer and free the native state object.
+ */
+ private native void close_(long nativeState);
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ synchronized(this)
+ {
+ close_(nativeState);
+ nativeState = 0;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ synchronized(this)
+ {
+ return (nativeState != 0);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java
new file mode 100644
index 000000000..9140d59ad
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java
@@ -0,0 +1,131 @@
+/* AlsaOutputPortDevice.java -- ALSA MIDI Output Port Device
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.alsa;
+
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+/**
+ * ALSA MIDI Out Device
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaOutputPortDevice extends AlsaPortDevice
+{
+ AlsaOutputPortDevice (AlsaPortInfo info)
+ {
+ super(info);
+ }
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
new file mode 100644
index 000000000..f55941ba5
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
@@ -0,0 +1,150 @@
+/* AlsaPortDevice.java -- ALSA MIDI Port Devices
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.alsa;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+/**
+ * ALSA Port Device
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public abstract class AlsaPortDevice implements MidiDevice
+{
+ /**
+ * The ALSA Receiver class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public class AlsaReceiver implements Receiver
+ {
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
+ */
+ public void send(MidiMessage message, long timeStamp)
+ throws IllegalStateException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ AlsaMidiDeviceProvider.AlsaPortInfo info;
+
+ public AlsaPortDevice (AlsaPortInfo info)
+ {
+ this.info = info;
+ }
+
+ public Info getDeviceInfo()
+ {
+ return info;
+ }
+
+ native void run_receiver_thread_ (long client, long port, Receiver receiver);
+
+ /**
+ * The ALSA Transmitter class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ protected class AlsaTransmitter implements Transmitter, Runnable
+ {
+ private Receiver receiver;
+
+ public void run()
+ {
+ run_receiver_thread_ (info.client, info.port, receiver);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#setReceiver(javax.sound.midi.Receiver)
+ */
+ public void setReceiver(Receiver receiver)
+ {
+ synchronized (this)
+ {
+ this.receiver = receiver;
+ }
+
+ // Create the processing thread
+ new Thread(this).start();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#getReceiver()
+ */
+ public Receiver getReceiver()
+ {
+ synchronized (this)
+ {
+ return receiver;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#close()
+ */
+ public void close()
+ {
+ synchronized (this)
+ {
+ receiver.close();
+ receiver = null;
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java
new file mode 100644
index 000000000..605c6dfb7
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java
@@ -0,0 +1,171 @@
+/* DSSIMidiDeviceProvider.java -- DSSI Device Provider
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.dssi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.FilenameFilter;
+
+import gnu.classpath.Configuration;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * A DSSI MIDI device provider.
+ *
+ * DSSI (pronounced "dizzy") is an API for audio plugins, with particular
+ * application for software synthesis plugins with native user interfaces.
+ *
+ * Read about DSSI at http://dssi.sourceforge.net
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class DSSIMidiDeviceProvider extends MidiDeviceProvider
+{
+ /**
+ * The MidiDevice.Info specialized for DSSI synthesizers.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class DSSIInfo extends Info
+ {
+ String soname;
+ long index;
+
+ public DSSIInfo(String name, String vendor, String description,
+ String version, String soname, long index)
+ {
+ super(name, vendor, description, version);
+ this.soname = soname;
+ this.index = index;
+ }
+ }
+
+ static native long dlopen_(String soname);
+ static native void dlclose_(long sohandle);
+ static native long getDSSIHandle_(long sohandle, long index);
+ static native String getDSSIName_(long handle);
+ static native String getDSSICopyright_(long handle);
+ static native String getDSSIVendor_(long handle);
+ static native String getDSSILabel_(long handle);
+
+ private static List examineLibrary(String soname)
+ {
+ List list = new ArrayList();
+ long index = 0;
+ long handle;
+
+ long sohandle = dlopen_(soname);
+ if (sohandle == 0)
+ return list;
+ do
+ {
+ handle = getDSSIHandle_(sohandle, index);
+ if (handle == 0)
+ break;
+ String name = getDSSILabel_(handle);
+ String copyright = getDSSICopyright_(handle);
+ String label = getDSSIName_(handle);
+ String vendor = getDSSIVendor_(handle);
+ list.add(new DSSIInfo(name, vendor, label,
+ "DSSI-1", soname, index));
+ index++;
+ } while (true);
+
+ // Close the library and free memory
+ dlclose_(sohandle);
+
+ return list;
+ }
+
+ private static DSSIInfo[] infos;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("gjsmdssi");
+
+ File dssidir = new File("/usr/lib/dssi/");
+ String sofiles[] = dssidir.list(new FilenameFilter()
+ {
+ public boolean accept(File dir, String n)
+ {
+ return n.endsWith(".so");
+ }
+ });
+ List ilist = new ArrayList();
+ for (int i = 0; i < sofiles.length; i++)
+ ilist.addAll(examineLibrary(new File(dssidir, sofiles[i]).getAbsolutePath()));
+ infos = (DSSIInfo[]) ilist.toArray(new DSSIInfo[ilist.size()]);
+ }
+
+ public DSSIMidiDeviceProvider()
+ {
+ // Empty.
+ }
+
+ /* Return the Info array.
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDeviceInfo()
+ */
+ public Info[] getDeviceInfo()
+ {
+ return infos;
+ }
+
+ /* Get a MIDI Device for info.
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDevice(javax.sound.midi.MidiDevice.Info)
+ */
+ public MidiDevice getDevice(Info info)
+ {
+ for (int i = 0; i < infos.length; i++)
+ {
+ if (info.equals(infos[i]))
+ {
+ return new DSSISynthesizer(infos[i],
+ infos[i].soname,
+ infos[i].index);
+ }
+ }
+ throw new IllegalArgumentException("Don't recognize MIDI device " + info);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
new file mode 100644
index 000000000..9472ee4ad
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
@@ -0,0 +1,742 @@
+/* DSSISynthesizer.java -- DSSI Synthesizer Provider
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.sound.midi.dssi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Transmitter;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * DSSI soft-synth support.
+ *
+ * All DSSI soft-synths are expected to be installed in /usr/lib/dssi.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class DSSISynthesizer implements Synthesizer
+{
+ /**
+ * The DSSI Instrument class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSIInstrument extends Instrument
+ {
+ DSSIInstrument (Soundbank soundbank, Patch patch, String name)
+ {
+ super (soundbank, patch, name, null);
+ }
+
+ /* @see javax.sound.midi.SoundbankResource#getData()
+ */
+ public Object getData()
+ {
+ return null;
+ }
+
+ }
+
+/**
+ * DSSISoundbank holds all instruments.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSISoundbank implements Soundbank
+ {
+ private String name;
+ private String description;
+ private List instruments = new ArrayList();
+ private List resources = new ArrayList();
+ private String vendor;
+ private String version;
+
+ public DSSISoundbank(String name, String description, String vendor, String version)
+ {
+ this.name = name;
+ this.description = description;
+ this.vendor = vendor;
+ this.version = version;
+ }
+
+ void add(Instrument instrument)
+ {
+ instruments.add(instrument);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getName()
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getVersion()
+ */
+ public String getVersion()
+ {
+ return version;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getVendor()
+ */
+ public String getVendor()
+ {
+ return vendor;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getDescription()
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getResources()
+ */
+ public SoundbankResource[] getResources()
+ {
+ return (SoundbankResource[])
+ resources.toArray(new SoundbankResource[resources.size()]);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getInstruments()
+ */
+ public Instrument[] getInstruments()
+ {
+ return (Instrument[])
+ instruments.toArray(new Instrument[instruments.size()]);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getInstrument(javax.sound.midi.Patch)
+ */
+ public Instrument getInstrument(Patch patch)
+ {
+ Iterator itr = instruments.iterator();
+
+ while (itr.hasNext())
+ {
+ Instrument i = (Instrument) itr.next();
+ if (i.getPatch().equals(patch))
+ return i;
+ }
+
+ return null;
+ }
+ }
+
+/**
+ * The Receiver class receives all MIDI messages from a connected
+ * Transmitter.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSIReceiver implements Receiver
+ {
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
+ */
+ public void send(MidiMessage message, long timeStamp)
+ throws IllegalStateException
+ {
+ if (message instanceof ShortMessage)
+ {
+ ShortMessage smessage = (ShortMessage) message;
+
+ switch (message.getStatus())
+ {
+ case ShortMessage.NOTE_ON:
+ int velocity = smessage.getData2();
+ if (velocity > 0)
+ channels[smessage.getChannel()].noteOn(smessage.getData1(),
+ smessage.getData2());
+ else
+ channels[smessage.getChannel()].noteOff(smessage.getData1());
+ break;
+ case ShortMessage.CONTROL_CHANGE:
+ channels[smessage.getChannel()].controlChange(smessage.getData1(),
+ smessage.getData2());
+ break;
+ default:
+ System.out.println ("Unhandled message: " + message.getStatus());
+ break;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+ }
+
+ }
+
+ static native void noteOn_(long handle, int channel, int noteNumber, int velocity);
+ static native void noteOff_(long handle, int channel, int noteNumber, int velocity);
+ static native void setPolyPressure_(long handle, int channel, int noteNumber, int pressure);
+ static native int getPolyPressure_(long handle, int channel, int noteNumber);
+ static native void controlChange_(long handle, int channel, int control, int value);
+ static native void open_(long handle);
+ static native void close_(long handle);
+ static native String getProgramName_(long handle, int index);
+ static native int getProgramBank_(long handle, int index);
+ static native int getProgramProgram_(long handle, int index);
+ static native void selectProgram_(long handle, int bank, int program);
+
+ /**
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public class DSSIMidiChannel implements MidiChannel
+ {
+ int channel = 0;
+
+ /**
+ * Default contructor.
+ */
+ public DSSIMidiChannel(int channel)
+ {
+ super();
+ this.channel = channel;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOn(int, int)
+ */
+ public void noteOn(int noteNumber, int velocity)
+ {
+ noteOn_(sohandle, channel, noteNumber, velocity);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOff(int, int)
+ */
+ public void noteOff(int noteNumber, int velocity)
+ {
+ noteOff_(sohandle, channel, noteNumber, velocity);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOff(int)
+ */
+ public void noteOff(int noteNumber)
+ {
+ noteOff_(sohandle, channel, noteNumber, -1);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setPolyPressure(int, int)
+ */
+ public void setPolyPressure(int noteNumber, int pressure)
+ {
+ setPolyPressure_(sohandle, channel, noteNumber, pressure);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getPolyPressure(int)
+ */
+ public int getPolyPressure(int noteNumber)
+ {
+ return getPolyPressure_(sohandle, channel, noteNumber);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setChannelPressure(int)
+ */
+ public void setChannelPressure(int pressure)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getChannelPressure()
+ */
+ public int getChannelPressure()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiChannel#controlChange(int, int) */
+ public void controlChange(int controller, int value)
+ {
+ controlChange_(sohandle, channel, controller, value);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getController(int)
+ */
+ public int getController(int controller)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#programChange(int)
+ */
+ public void programChange(int program)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#programChange(int, int)
+ */
+ public void programChange(int bank, int program)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getProgram()
+ */
+ public int getProgram()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setPitchBend(int)
+ */
+ public void setPitchBend(int bend)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getPitchBend()
+ */
+ public int getPitchBend()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#resetAllControllers()
+ */
+ public void resetAllControllers()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#allNotesOff()
+ */
+ public void allNotesOff()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#allSoundOff()
+ */
+ public void allSoundOff()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#localControl(boolean)
+ */
+ public boolean localControl(boolean on)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setMono(boolean)
+ */
+ public void setMono(boolean on)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getMono()
+ */
+ public boolean getMono()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setOmni(boolean)
+ */
+ public void setOmni(boolean on)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getOmni()
+ */
+ public boolean getOmni()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setMute(boolean)
+ */
+ public void setMute(boolean mute)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getMute()
+ */
+ public boolean getMute()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setSolo(boolean)
+ */
+ public void setSolo(boolean solo)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getSolo()
+ */
+ public boolean getSolo()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+ long sohandle;
+ long handle;
+ private Info info;
+
+ MidiChannel channels[] = new MidiChannel[16];
+
+ // The list of known soundbanks, and the default one.
+ List soundbanks = new ArrayList();
+ DSSISoundbank defaultSoundbank;
+
+ /**
+ * Create a DSSI Synthesizer.
+ *
+ * @param info the DSSIInfo for this soft-synth
+ * @param soname the name of the .so file for this DSSI synth
+ * @param index the DSSI index for this soft-synth
+ */
+ public DSSISynthesizer(Info info, String soname, long index)
+ {
+ super();
+ this.info = info;
+ sohandle = DSSIMidiDeviceProvider.dlopen_(soname);
+ handle = DSSIMidiDeviceProvider.getDSSIHandle_(sohandle, index);
+ channels[0] = new DSSIMidiChannel(0);
+ defaultSoundbank = new DSSISoundbank("name", "description",
+ "vendor", "version");
+ soundbanks.add(defaultSoundbank);
+
+ int i = 0;
+ String name;
+ do
+ {
+ name = getProgramName_(sohandle, i);
+ if (name != null)
+ {
+ defaultSoundbank.
+ add(new DSSIInstrument(defaultSoundbank,
+ new Patch(getProgramBank_(sohandle, i),
+ getProgramProgram_(sohandle, i)),
+ name));
+ i++;
+ }
+ } while (name != null);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getMaxPolyphony()
+ */
+ public int getMaxPolyphony()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getLatency()
+ */
+ public long getLatency()
+ {
+ // DSSI and LADSPA provide no way to determine the latency.
+ // Let's just return 0 for now.
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getChannels()
+ */
+ public MidiChannel[] getChannels()
+ {
+ return channels;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getVoiceStatus()
+ */
+ public VoiceStatus[] getVoiceStatus()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#isSoundbankSupported(javax.sound.midi.Soundbank)
+ */
+ public boolean isSoundbankSupported(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#loadInstrument(javax.sound.midi.Instrument)
+ */
+ public boolean loadInstrument(Instrument instrument)
+ {
+ // FIXME: perhaps this isn't quite right. It can probably
+ // be in any soundbank.
+ if (instrument.getSoundbank() != defaultSoundbank)
+ throw new IllegalArgumentException ("Synthesizer doesn't support this instrument's soundbank");
+
+ Patch patch = instrument.getPatch();
+ selectProgram_(sohandle, patch.getBank(), patch.getProgram());
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadInstrument(javax.sound.midi.Instrument)
+ */
+ public void unloadInstrument(Instrument instrument)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#remapInstrument(javax.sound.midi.Instrument, javax.sound.midi.Instrument)
+ */
+ public boolean remapInstrument(Instrument from, Instrument to)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#getDefaultSoundbank()
+ */
+ public Soundbank getDefaultSoundbank()
+ {
+ return defaultSoundbank;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#getAvailableInstruments()
+ */
+ public Instrument[] getAvailableInstruments()
+ {
+ List instruments = new ArrayList();
+ Iterator itr = soundbanks.iterator();
+ while (itr.hasNext())
+ {
+ Soundbank sb = (Soundbank) itr.next();
+ Instrument ins[] = sb.getInstruments();
+ for (int i = 0; i < ins.length; i++)
+ instruments.add(ins[i]);
+ }
+ return (Instrument[])
+ instruments.toArray(new Instrument[instruments.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getLoadedInstruments()
+ */
+ public Instrument[] getLoadedInstruments()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#loadAllInstruments(javax.sound.midi.Soundbank)
+ */
+ public boolean loadAllInstruments(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadAllInstruments(javax.sound.midi.Soundbank)
+ */
+ public void unloadAllInstruments(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#loadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
+ */
+ public boolean loadInstruments(Soundbank soundbank, Patch[] patchList)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
+ */
+ public void unloadInstruments(Soundbank soundbank, Patch[] patchList)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getDeviceInfo()
+ */
+ public Info getDeviceInfo()
+ {
+ return info;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ open_(sohandle);
+ }
+
+ /* @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ close_(sohandle);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ return 1;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ return new DSSIReceiver();
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ return null;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/file/ExtendedMidiFileFormat.java b/libjava/classpath/gnu/javax/sound/midi/file/ExtendedMidiFileFormat.java
new file mode 100644
index 000000000..4b065f3dc
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/file/ExtendedMidiFileFormat.java
@@ -0,0 +1,77 @@
+/* ExtendedMidiFileFormat.java -- extended with track count info.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.midi.file;
+
+/**
+ * ExtendedMidiFileFormat is a package private class that simply
+ * adds the number of MIDI tracks for the MidiFileFormat class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ */
+class ExtendedMidiFileFormat
+ extends javax.sound.midi.MidiFileFormat
+{
+ private int ntracks;
+
+ /**
+ * Get the number of tracks for this MIDI file.
+ *
+ * @return the number of tracks for this MIDI file
+ */
+ public int getNumberTracks()
+ {
+ return ntracks;
+ }
+
+ /**
+ * Create an ExtendedMidiFileFormat object from the given parameters.
+ *
+ * @param type the MIDI file type (0, 1, or 2)
+ * @param divisionType the MIDI file division type
+ * @param resolution the MIDI file timing resolution
+ * @param bytes the MIDI file size in bytes
+ * @param microseconds the MIDI file length in microseconds
+ * @param ntracks the number of tracks
+ */
+ public ExtendedMidiFileFormat(int type, float divisionType, int resolution,
+ int bytes, long microseconds, int ntracks)
+ {
+ super(type, divisionType, resolution, bytes, microseconds);
+ this.ntracks = ntracks;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/file/MidiDataInputStream.java b/libjava/classpath/gnu/javax/sound/midi/file/MidiDataInputStream.java
new file mode 100644
index 000000000..d91970b9f
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/file/MidiDataInputStream.java
@@ -0,0 +1,83 @@
+/* MidiDataInputStream.java -- adds variable length MIDI ints
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.midi.file;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * MidiDataInputStream is simply a DataInputStream with the addition
+ * of special variable length int reading as defined by the MIDI spec.
+ *
+ * @author Anthony Green (green@redhat.com)
+ */
+public class MidiDataInputStream
+ extends DataInputStream
+{
+ /**
+ * Create a MidiDataInputStream.
+ */
+ public MidiDataInputStream(InputStream is)
+ {
+ super(is);
+ }
+
+ /**
+ * Read an int encoded in the MIDI-style variable length
+ * encoding format.
+ *
+ * @return an int
+ */
+ public int readVariableLengthInt()
+ throws IOException
+ {
+ int c, value = readByte();
+
+ if ((value & 0x80) != 0)
+ {
+ value &= 0x7F;
+ do
+ {
+ value = (value << 7) + ((c = readByte()) & 0x7F);
+ } while ((c & 0x80) != 0);
+ }
+
+ return value;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/file/MidiDataOutputStream.java b/libjava/classpath/gnu/javax/sound/midi/file/MidiDataOutputStream.java
new file mode 100644
index 000000000..79c66e8a2
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/file/MidiDataOutputStream.java
@@ -0,0 +1,114 @@
+/* MidiDataOutputStream.java -- adds variable length MIDI ints
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.midi.file;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * MidiDataOutputStream is simply a DataOutputStream with the addition
+ * of special variable length int writing as defined by the MIDI spec.
+ *
+ * @author Anthony Green (green@redhat.com)
+ */
+public class MidiDataOutputStream
+ extends DataOutputStream
+{
+ /**
+ * Create a MidiDataOutputStream.
+ */
+ public MidiDataOutputStream(OutputStream os)
+ {
+ super(os);
+ }
+
+ /**
+ * Return the length of a variable length encoded int without
+ * writing it out.
+ *
+ * @return the length of the encoding
+ */
+ public int variableLengthIntLength (int value)
+ {
+ int length = 0;
+ int buffer = value & 0x7F;
+
+ while ((value >>= 7) != 0)
+ {
+ buffer <<= 8;
+ buffer |= ((value & 0x7F) | 0x80);
+ }
+
+ while (true)
+ {
+ length++;
+ if ((buffer & 0x80) != 0)
+ buffer >>>= 8;
+ else
+ break;
+ }
+
+ return length;
+ }
+
+ /**
+ * Write an int encoded in the MIDI-style variable length
+ * encoding format.
+ */
+ public synchronized void writeVariableLengthInt (int value)
+ throws IOException
+ {
+ int buffer = value & 0x7F;
+
+ while ((value >>= 7) != 0)
+ {
+ buffer <<= 8;
+ buffer |= ((value & 0x7F) | 0x80);
+ }
+
+ while (true)
+ {
+ writeByte(buffer & 0xff);
+ if ((buffer & 0x80) != 0)
+ buffer >>>= 8;
+ else
+ break;
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/file/MidiFileReader.java b/libjava/classpath/gnu/javax/sound/midi/file/MidiFileReader.java
new file mode 100644
index 000000000..fb2a472fa
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/file/MidiFileReader.java
@@ -0,0 +1,378 @@
+/* MidiFileReader.java -- Read MIDI files.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.midi.file;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiFileFormat;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.SysexMessage;
+import javax.sound.midi.Track;
+
+/**
+ * A MIDI file reader.
+ *
+ * This code reads MIDI file types 0 and 1.
+ *
+ * There are many decent documents on the web describing the MIDI file
+ * format. I didn't bother looking for the official document. If it
+ * exists, I'm not even sure if it is freely available. We should
+ * update this comment if we find out anything helpful here.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class MidiFileReader extends javax.sound.midi.spi.MidiFileReader
+{
+ /* Get the MidiFileFormat for the given input stream.
+ * @see javax.sound.midi.spi.MidiFileReader#getMidiFileFormat(java.io.InputStream)
+ */
+ public MidiFileFormat getMidiFileFormat(InputStream in)
+ throws InvalidMidiDataException, IOException
+ {
+ DataInputStream din;
+ if (in instanceof DataInputStream)
+ din = (DataInputStream) in;
+ else
+ din = new DataInputStream(in);
+
+ int type, ntracks, division, resolution, bytes;
+ float divisionType;
+
+ if (din.readInt() != 0x4d546864) // "MThd"
+ throw new InvalidMidiDataException("Invalid MIDI chunk header.");
+
+ bytes = din.readInt();
+ if (bytes < 6)
+ throw new
+ InvalidMidiDataException("Invalid MIDI chunk header length: " + bytes);
+
+ type = din.readShort();
+ if (type < 0 || type > 2)
+ throw new
+ InvalidMidiDataException("Invalid MIDI file type value: " + type);
+
+ ntracks = din.readShort();
+ if (ntracks <= 0)
+ throw new
+ InvalidMidiDataException("Invalid number of MIDI tracks: " + ntracks);
+
+ division = din.readShort();
+ if ((division & 0x8000) != 0)
+ {
+ division = -((division >>> 8) & 0xFF);
+ switch (division)
+ {
+ case 24:
+ divisionType = Sequence.SMPTE_24;
+ break;
+
+ case 25:
+ divisionType = Sequence.SMPTE_25;
+ break;
+
+ case 29:
+ divisionType = Sequence.SMPTE_30DROP;
+ break;
+
+ case 30:
+ divisionType = Sequence.SMPTE_30;
+ break;
+
+ default:
+ throw new
+ InvalidMidiDataException("Invalid MIDI frame division type: "
+ + division);
+ }
+ resolution = division & 0xff;
+ }
+ else
+ {
+ divisionType = Sequence.PPQ;
+ resolution = division & 0x7fff;
+ }
+
+ // If we haven't read every byte in the header now, just skip the rest.
+ din.skip(bytes - 6);
+
+ return new ExtendedMidiFileFormat(type, divisionType, resolution,
+ MidiFileFormat.UNKNOWN_LENGTH,
+ MidiFileFormat.UNKNOWN_LENGTH, ntracks);
+ }
+
+ /* Get the MidiFileFormat from the given URL.
+ * @see javax.sound.midi.spi.MidiFileReader#getMidiFileFormat(java.net.URL)
+ */
+ public MidiFileFormat getMidiFileFormat(URL url)
+ throws InvalidMidiDataException, IOException
+ {
+ InputStream is = url.openStream();
+ try
+ {
+ return getMidiFileFormat(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
+ /* Get the MidiFileFormat from the given file.
+ * @see javax.sound.midi.spi.MidiFileReader#getMidiFileFormat(java.io.File)
+ */
+ public MidiFileFormat getMidiFileFormat(File file)
+ throws InvalidMidiDataException, IOException
+ {
+ InputStream is = new FileInputStream(file);
+ try
+ {
+ return getMidiFileFormat(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
+ /* Get the MIDI Sequence found in this input stream.
+ * @see javax.sound.midi.spi.MidiFileReader#getSequence(java.io.InputStream)
+ */
+ public Sequence getSequence(InputStream is) throws InvalidMidiDataException,
+ IOException
+ {
+ MidiDataInputStream din = new MidiDataInputStream(is);
+ ExtendedMidiFileFormat mff = (ExtendedMidiFileFormat) getMidiFileFormat(din);
+
+ Sequence seq = new Sequence(mff.getDivisionType(), mff.getResolution());
+
+ int ntracks = mff.getNumberTracks();
+
+ while (ntracks-- > 0)
+ {
+ Track track = seq.createTrack();
+ int Mtrk = din.readInt();
+ if (Mtrk != 0x4d54726b)
+ throw new InvalidMidiDataException("Invalid MIDI track header.");
+ int length = din.readInt();
+
+ int runningStatus = -1;
+ int click = 0;
+
+ // Set this to true when we've hit an End of Track meta event.
+ boolean done = false;
+
+ // Read all events.
+ while (! done)
+ {
+ MidiMessage mm;
+ int dtime = din.readVariableLengthInt();
+ click += dtime;
+
+ int sbyte = din.readUnsignedByte();
+
+ if (sbyte < 0xf0)
+ {
+ ShortMessage sm;
+ switch (sbyte & 0xf0)
+ {
+ case ShortMessage.NOTE_OFF:
+ case ShortMessage.NOTE_ON:
+ case ShortMessage.POLY_PRESSURE:
+ case ShortMessage.CONTROL_CHANGE:
+ case ShortMessage.PITCH_BEND:
+ case ShortMessage.SONG_POSITION_POINTER:
+ sm = new ShortMessage();
+ sm.setMessage(sbyte, din.readByte(), din.readByte());
+ runningStatus = sbyte;
+ break;
+
+ case ShortMessage.PROGRAM_CHANGE:
+ case ShortMessage.CHANNEL_PRESSURE:
+ case ShortMessage.SONG_SELECT:
+ case 0xF5: // FIXME: unofficial bus select. Not in spec??
+ sm = new ShortMessage();
+ sm.setMessage(sbyte, din.readByte(), 0);
+ runningStatus = sbyte;
+ break;
+
+ case ShortMessage.TUNE_REQUEST:
+ case ShortMessage.END_OF_EXCLUSIVE:
+ case ShortMessage.TIMING_CLOCK:
+ case ShortMessage.START:
+ case ShortMessage.CONTINUE:
+ case ShortMessage.STOP:
+ case ShortMessage.ACTIVE_SENSING:
+ case ShortMessage.SYSTEM_RESET:
+ sm = new ShortMessage();
+ sm.setMessage(sbyte, 0, 0);
+ runningStatus = sbyte;
+ break;
+
+ default:
+ if (runningStatus != - 1)
+ {
+ switch (runningStatus & 0xf0)
+ {
+ case ShortMessage.NOTE_OFF:
+ case ShortMessage.NOTE_ON:
+ case ShortMessage.POLY_PRESSURE:
+ case ShortMessage.CONTROL_CHANGE:
+ case ShortMessage.PITCH_BEND:
+ case ShortMessage.SONG_POSITION_POINTER:
+ sm = new ShortMessage();
+ sm.setMessage(runningStatus, sbyte, din.readByte());
+ break;
+
+ case ShortMessage.PROGRAM_CHANGE:
+ case ShortMessage.CHANNEL_PRESSURE:
+ case ShortMessage.SONG_SELECT:
+ case 0xF5: // FIXME: unofficial bus select. Not in
+ // spec??
+ sm = new ShortMessage();
+ sm.setMessage(runningStatus, sbyte, 0);
+ continue;
+
+ case ShortMessage.TUNE_REQUEST:
+ case ShortMessage.END_OF_EXCLUSIVE:
+ case ShortMessage.TIMING_CLOCK:
+ case ShortMessage.START:
+ case ShortMessage.CONTINUE:
+ case ShortMessage.STOP:
+ case ShortMessage.ACTIVE_SENSING:
+ case ShortMessage.SYSTEM_RESET:
+ sm = new ShortMessage();
+ sm.setMessage(runningStatus, 0, 0);
+ continue;
+
+ default:
+ throw new
+ InvalidMidiDataException("Invalid Short MIDI Event: "
+ + sbyte);
+ }
+ }
+ else
+ throw new
+ InvalidMidiDataException("Invalid Short MIDI Event: "
+ + sbyte);
+ }
+ mm = sm;
+ }
+ else if (sbyte == 0xf0 || sbyte == 0xf7)
+ {
+ // System Exclusive event
+ int slen = din.readVariableLengthInt();
+ byte sysex[] = new byte[slen];
+ din.readFully(sysex);
+ SysexMessage sm = new SysexMessage();
+ sm.setMessage(sbyte, sysex, slen);
+ mm = sm;
+ runningStatus = - 1;
+ }
+ else if (sbyte == 0xff)
+ {
+ // Meta Message
+ byte mtype = din.readByte();
+ int mlen = din.readVariableLengthInt();
+ byte meta[] = new byte[mlen];
+ din.readFully(meta);
+ MetaMessage metam = new MetaMessage();
+ metam.setMessage(mtype, meta, mlen);
+ mm = metam;
+
+ if (mtype == 0x2f) // End of Track
+ done = true;
+
+ runningStatus = - 1;
+ }
+ else
+ {
+ throw new InvalidMidiDataException("Invalid status byte: "
+ + sbyte);
+ }
+
+ track.add(new MidiEvent(mm, click));
+ }
+ }
+
+ return seq;
+ }
+
+ /* Get the MIDI Sequence found at the given URL.
+ * @see javax.sound.midi.spi.MidiFileReader#getSequence(java.net.URL)
+ */
+ public Sequence getSequence(URL url) throws InvalidMidiDataException,
+ IOException
+ {
+ InputStream is = url.openStream();
+ try
+ {
+ return getSequence(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
+ /* Get the MIDI Sequence found in the given file.
+ * @see javax.sound.midi.spi.MidiFileReader#getSequence(java.io.File)
+ */
+ public Sequence getSequence(File file) throws InvalidMidiDataException,
+ IOException
+ {
+ InputStream is = new FileInputStream(file);
+ try
+ {
+ return getSequence(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/file/MidiFileWriter.java b/libjava/classpath/gnu/javax/sound/midi/file/MidiFileWriter.java
new file mode 100644
index 000000000..5170fc1e7
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/file/MidiFileWriter.java
@@ -0,0 +1,197 @@
+/* MidiFileWriter.java -- Write MIDI files.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.midi.file;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Track;
+
+/**
+ * A MIDI file writer.
+ *
+ * This code writes MIDI file types 0 and 1.
+ *
+ * There are many decent documents on the web describing the MIDI file
+ * format. I didn't bother looking for the official document. If it
+ * exists, I'm not even sure if it is freely available. We should
+ * update this comment if we find out anything helpful here.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class MidiFileWriter
+ extends javax.sound.midi.spi.MidiFileWriter
+{
+ /* Return an array indicating which midi file types are supported.
+ * @see javax.sound.midi.spi.MidiFileWriter#getMidiFileTypes()
+ */
+ public int[] getMidiFileTypes()
+ {
+ return new int[]{0, 1};
+ }
+
+ /* Return an array indicating which midi file types are supported
+ * for a given Sequence.
+ * @see javax.sound.midi.spi.MidiFileWriter#getMidiFileTypes(javax.sound.midi.Sequence)
+ */
+ public int[] getMidiFileTypes(Sequence sequence)
+ {
+ if (sequence.getTracks().length == 1)
+ return new int[]{0};
+ else
+ return new int[]{1};
+ }
+
+ /* Write a sequence to an output stream in standard midi format.
+ * @see javax.sound.midi.spi.MidiFileWriter#write(javax.sound.midi.Sequence, int, java.io.OutputStream)
+ */
+ public int write(Sequence in, int fileType, OutputStream out)
+ throws IOException
+ {
+ MidiDataOutputStream dos = new MidiDataOutputStream (out);
+ Track[] tracks = in.getTracks();
+ dos.writeInt(0x4d546864); // MThd
+ dos.writeInt(6);
+ dos.writeShort(fileType);
+ dos.writeShort(tracks.length);
+ float divisionType = in.getDivisionType();
+ int resolution = in.getResolution();
+ // FIXME: division computation is incomplete.
+ int division = 0;
+ if (divisionType == Sequence.PPQ)
+ division = resolution & 0x7fff;
+ dos.writeShort(division);
+ int length = 14;
+ for (int i = 0; i < tracks.length; i++)
+ length += writeTrack(tracks[i], dos);
+ return length;
+ }
+
+ /**
+ * Compute the length of a track as it will be written to the
+ * output stream.
+ *
+ * @param track the track to measure
+ * @param dos a MidiDataOutputStream used for helper method
+ * @return the length of the track
+ */
+ private int computeTrackLength(Track track, MidiDataOutputStream dos)
+ {
+ int count = 0, length = 0, i = 0, eventCount = track.size();
+ long ptick = 0;
+ while (i < eventCount)
+ {
+ MidiEvent me = track.get(i);
+ long tick = me.getTick();
+ length += dos.variableLengthIntLength((int) (tick - ptick));
+ ptick = tick;
+ length += me.getMessage().getLength();
+ i++;
+ }
+ return length;
+ }
+
+ /**
+ * Write a track to an output stream.
+ *
+ * @param track the track to write
+ * @param dos a MidiDataOutputStream to write to
+ * @return the number of bytes written
+ */
+ private int writeTrack(Track track, MidiDataOutputStream dos)
+ throws IOException
+ {
+ int i = 0, elength = track.size(), trackLength;
+ MidiEvent pme = null;
+ dos.writeInt(0x4d54726b); // "MTrk"
+ trackLength = computeTrackLength(track, dos);
+ dos.writeInt(trackLength);
+ while (i < elength)
+ {
+ MidiEvent me = track.get(i);
+ int dtime = 0;
+ if (pme != null)
+ dtime = (int) (me.getTick() - pme.getTick());
+ dos.writeVariableLengthInt(dtime);
+ // FIXME: use running status byte
+ byte msg[] = me.getMessage().getMessage();
+ dos.write(msg);
+ pme = me;
+ i++;
+ }
+
+ // We're done if the last event was an End of Track meta message.
+ if (pme != null && (pme.getMessage() instanceof MetaMessage))
+ {
+ MetaMessage mm = (MetaMessage) pme.getMessage();
+ if (mm.getType() == 0x2f) // End of Track message
+ return trackLength + 8;
+ }
+
+ // Write End of Track meta message
+ dos.writeVariableLengthInt(0); // Delta time of 0
+ dos.writeByte(0xff); // Meta Message
+ dos.writeByte(0x2f); // End of Track message
+ dos.writeVariableLengthInt(0); // Length of 0
+
+ return trackLength + 8 + 4;
+ }
+
+ /* Write a Sequence to a file.
+ * @see javax.sound.midi.spi.MidiFileWriter#write(javax.sound.midi.Sequence, int, java.io.File)
+ */
+ public int write(Sequence in, int fileType, File out) throws IOException
+ {
+ OutputStream os = new FileOutputStream(out);
+ try
+ {
+ return write(in, fileType, os);
+ }
+ finally
+ {
+ os.close();
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/AU/AUReader.java b/libjava/classpath/gnu/javax/sound/sampled/AU/AUReader.java
new file mode 100644
index 000000000..fe0df6eb1
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/AU/AUReader.java
@@ -0,0 +1,210 @@
+/* AUReader.java -- Read AU files.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.AU;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.spi.AudioFileReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.net.URL;
+import java.nio.ByteBuffer;
+
+public class AUReader extends AudioFileReader
+{
+ private static class AUHeader
+ {
+ // Magic number identifying the file. '.snd'
+ private static final int MAGIC = 0x2e736e64;
+
+ public static final int SIZE = 24; // size of the header
+
+ // Encoding types
+ public static final int ULAW = 1; // 8-bit u-law
+ public static final int PCM8 = 2; // 8-bit PCM
+ public static final int PCM16 = 3; // 16-bit PCM
+ public static final int PCM24 = 4; // 24-bit PCM
+ public static final int PCM32 = 5; // 32-bit PCM
+ public static final int IEEE32 = 6; // 32-bit IEEE f.p.
+ public static final int IEEE64 = 7; // 64-bit IEEE f.p.
+ public static final int G721 = 23;
+ public static final int G722 = 24;
+ public static final int G723 = 25;
+ public static final int G723_5BIT = 26;
+ public static final int ALAW = 27; // 8-bit a-law
+
+ // Header data.
+ public int headerSize;
+ public int fileSize; // this value may not be set.
+ public int encoding;
+ public int sampleRate;
+ public int channels;
+ public int sampleSizeInBits;
+
+ public AUHeader(InputStream stream)
+ throws IOException, UnsupportedAudioFileException
+ {
+ byte[] hdr = new byte[24];
+ stream.read( hdr );
+ ByteBuffer buf = ByteBuffer.wrap(hdr);
+
+ if( buf.getInt() != MAGIC )
+ throw new UnsupportedAudioFileException("Not an AU format audio file.");
+ headerSize = buf.getInt();
+ fileSize = buf.getInt();
+ encoding = buf.getInt();
+ sampleRate = buf.getInt();
+ channels = buf.getInt();
+
+ switch(encoding)
+ {
+ case ULAW:
+ case PCM8:
+ case ALAW:
+ sampleSizeInBits = 8;
+ break;
+ case PCM16:
+ sampleSizeInBits = 16;
+ break;
+ case PCM24:
+ sampleSizeInBits = 24;
+ break;
+ case PCM32:
+ sampleSizeInBits = 32;
+ break;
+ default: // other types exist but are not supported. Yet.
+ throw new UnsupportedAudioFileException("Unsupported encoding.");
+ }
+ }
+
+ public AudioFormat getAudioFormat()
+ {
+ AudioFormat.Encoding encType = AudioFormat.Encoding.PCM_SIGNED;
+ if(encoding == 1)
+ encType = AudioFormat.Encoding.ULAW;
+ if(encoding == 27)
+ encType = AudioFormat.Encoding.ALAW;
+
+ return new AudioFormat(encType,
+ (float)sampleRate,
+ sampleSizeInBits,
+ channels,
+ (sampleSizeInBits >> 3) * channels,
+ (float)sampleRate,
+ true);
+ }
+
+ public AudioFileFormat getAudioFileFormat()
+ {
+ return new AudioFileFormat(new AUFormatType(),
+ getAudioFormat(),
+ AudioSystem.NOT_SPECIFIED);
+ }
+ }
+
+ public static class AUFormatType extends AudioFileFormat.Type
+ {
+ public AUFormatType()
+ {
+ super("AU", ".au");
+ }
+ }
+
+ public AudioFileFormat getAudioFileFormat(File file)
+ throws IOException, UnsupportedAudioFileException
+ {
+ return getAudioFileFormat(new FileInputStream(file));
+ }
+
+ public AudioFileFormat getAudioFileFormat(InputStream stream)
+ throws IOException, UnsupportedAudioFileException
+ {
+ if(!stream.markSupported())
+ throw new IOException("Stream must support marking.");
+
+ stream.mark(25);
+ AUHeader header = new AUHeader(stream);
+ stream.reset();
+
+ return header.getAudioFileFormat();
+ }
+
+ public AudioFileFormat getAudioFileFormat(URL url)
+ throws IOException, UnsupportedAudioFileException
+ {
+ return getAudioFileFormat(new BufferedInputStream(url.openStream()));
+ }
+
+ public AudioInputStream getAudioInputStream(File file)
+ throws IOException, UnsupportedAudioFileException
+ {
+ InputStream stream = new FileInputStream(file);
+ long length = file.length();
+
+ AUHeader header = new AUHeader( stream );
+ if( header.headerSize > AUHeader.SIZE )
+ stream.skip(header.headerSize - AUHeader.SIZE);
+
+ length -= header.headerSize;
+
+ return new AudioInputStream(stream, header.getAudioFormat(), length);
+ }
+
+ public AudioInputStream getAudioInputStream(InputStream stream)
+ throws IOException, UnsupportedAudioFileException
+ {
+ AUHeader header = new AUHeader( stream );
+ if( header.headerSize > AUHeader.SIZE )
+ stream.skip(header.headerSize - AUHeader.SIZE);
+
+ return new AudioInputStream(stream, header.getAudioFormat(),
+ AudioSystem.NOT_SPECIFIED);
+ }
+
+ public AudioInputStream getAudioInputStream(URL url)
+ throws IOException, UnsupportedAudioFileException
+ {
+ return getAudioInputStream(new BufferedInputStream(url.openStream()));
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/WAV/WAVReader.java b/libjava/classpath/gnu/javax/sound/sampled/WAV/WAVReader.java
new file mode 100644
index 000000000..5cd6efe5e
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/WAV/WAVReader.java
@@ -0,0 +1,236 @@
+/* WAVReader.java -- Read WAV files.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.WAV;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * A WAV file reader.
+ *
+ * This code reads WAV files.
+ *
+ * There are many decent documents on the web describing the WAV file
+ * format. I didn't bother looking for the official document. If it
+ * exists, I'm not even sure if it is freely available. We should
+ * update this comment if we find out anything helpful here. I used
+ * http://www.sonicspot.com/guide/wavefiles.html
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class WAVReader extends AudioFileReader
+{
+ private static long readUnsignedIntLE (DataInputStream is)
+ throws IOException
+ {
+ byte[] buf = new byte[4];
+ is.readFully(buf);
+ return (buf[0] & 0xFF
+ | ((buf[1] & 0xFF) << 8)
+ | ((buf[2] & 0xFF) << 16)
+ | ((buf[3] & 0xFF) << 24));
+ }
+
+ private static short readUnsignedShortLE (DataInputStream is)
+ throws IOException
+ {
+ byte[] buf = new byte[2];
+ is.readFully(buf);
+ return (short) (buf[0] & 0xFF
+ | ((buf[1] & 0xFF) << 8));
+ }
+
+ /* Get an AudioFileFormat from the given File.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.io.File)
+ */
+ public AudioFileFormat getAudioFileFormat(File file)
+ throws UnsupportedAudioFileException, IOException
+ {
+ InputStream is = new FileInputStream(file);
+ try
+ {
+ return getAudioFileFormat(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
+ /* Get an AudioFileFormat from the given InputStream.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.io.InputStream)
+ */
+ public AudioFileFormat getAudioFileFormat(InputStream in)
+ throws UnsupportedAudioFileException, IOException
+ {
+ DataInputStream din;
+
+ if (in instanceof DataInputStream)
+ din = (DataInputStream) in;
+ else
+ din = new DataInputStream(in);
+
+ if (din.readInt() != 0x52494646) // "RIFF"
+ throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
+
+ // Read the length of this RIFF thing.
+ readUnsignedIntLE(din);
+
+ if (din.readInt() != 0x57415645) // "WAVE"
+ throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
+
+ boolean foundFmt = false;
+ boolean foundData = false;
+
+ short compressionCode = 0, numberChannels = 0, blockAlign = 0, bitsPerSample = 0;
+ long sampleRate = 0, bytesPerSecond = 0;
+ long chunkLength = 0;
+
+ while (! foundData)
+ {
+ int chunkId = din.readInt();
+ chunkLength = readUnsignedIntLE(din);
+ switch (chunkId)
+ {
+ case 0x666D7420: // "fmt "
+ foundFmt = true;
+ compressionCode = readUnsignedShortLE(din);
+ numberChannels = readUnsignedShortLE(din);
+ sampleRate = readUnsignedIntLE(din);
+ bytesPerSecond = readUnsignedIntLE(din);
+ blockAlign = readUnsignedShortLE(din);
+ bitsPerSample = readUnsignedShortLE(din);
+ din.skip(chunkLength - 16);
+ break;
+ case 0x66616374: // "fact"
+ // FIXME: hold compression format dependent data.
+ din.skip(chunkLength);
+ break;
+ case 0x64617461: // "data"
+ if (! foundFmt)
+ throw new UnsupportedAudioFileException("This implementation requires WAV fmt chunks precede data chunks.");
+ foundData = true;
+ break;
+ default:
+ // Unrecognized chunk. Skip it.
+ din.skip(chunkLength);
+ }
+ }
+
+ AudioFormat.Encoding encoding;
+
+ switch (compressionCode)
+ {
+ case 1: // PCM/uncompressed
+ if (bitsPerSample <= 8)
+ encoding = AudioFormat.Encoding.PCM_UNSIGNED;
+ else
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ break;
+
+ default:
+ throw new UnsupportedAudioFileException("Unrecognized WAV compression code: 0x"
+ + Integer.toHexString(compressionCode));
+ }
+
+ return new AudioFileFormat (AudioFileFormat.Type.WAVE,
+ new AudioFormat(encoding,
+ (float) sampleRate,
+ bitsPerSample,
+ numberChannels,
+ ((bitsPerSample + 7) / 8) * numberChannels,
+ (float) bytesPerSecond, false),
+ (int) chunkLength);
+ }
+
+ /* Get an AudioFileFormat from the given URL.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.net.URL)
+ */
+ public AudioFileFormat getAudioFileFormat(URL url)
+ throws UnsupportedAudioFileException, IOException
+ {
+ InputStream is = url.openStream();
+ try
+ {
+ return getAudioFileFormat(is);
+ }
+ finally
+ {
+ is.close();
+ }
+ }
+
+ /* Get an AudioInputStream from the given File.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.io.File)
+ */
+ public AudioInputStream getAudioInputStream(File file)
+ throws UnsupportedAudioFileException, IOException
+ {
+ return getAudioInputStream(new FileInputStream(file));
+ }
+
+ /* Get an AudioInputStream from the given InputStream.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.io.InputStream)
+ */
+ public AudioInputStream getAudioInputStream(InputStream stream)
+ throws UnsupportedAudioFileException, IOException
+ {
+ AudioFileFormat aff = getAudioFileFormat(stream);
+ return new AudioInputStream(stream, aff.getFormat(), (long) aff.getFrameLength());
+ }
+
+ /* Get an AudioInputStream from the given URL.
+ * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.net.URL)
+ */
+ public AudioInputStream getAudioInputStream(URL url)
+ throws UnsupportedAudioFileException, IOException
+ {
+ return getAudioInputStream(url.openStream());
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixer.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixer.java
new file mode 100644
index 000000000..1910ea655
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixer.java
@@ -0,0 +1,248 @@
+/* GStreamerMixer.java -- Mixer implementation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer;
+
+import gnu.javax.sound.sampled.gstreamer.lines.GstSourceDataLine;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.Control.Type;
+
+/**
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class GStreamerMixer
+ implements Mixer
+{
+ public static class GstInfo extends Info
+ {
+ /* Mixer Properties */
+
+ /** Name */
+ private static final String name = "Classpath GStreamer Sound Audio Engine";
+
+ /** Vendor */
+ private static final String vendor = "GNU Classpath";
+
+ /** Description */
+ private static final String desc = "GStreamer-based software mixer";
+
+ /** Version */
+ private static final String vers = "0.0.1";
+
+ protected GstInfo()
+ {
+ super(name, vendor, desc, vers);
+ }
+ }
+
+ public static final String GST_BACKEND = GstInfo.name;
+ public static final String GST_DECODER = "decoder";
+ public static final String GST_TYPE_NAME = "type";
+ public static final String GST_FILE_EXTENSION = "ext";
+
+ /** Mixer Info */
+ private static final Mixer.Info INFO = new GStreamerMixer.GstInfo();
+
+ public Line getLine(Line.Info info)
+ throws LineUnavailableException
+ {
+ // get all the lines formats supported by this mixer and
+ // and see if there is one matching the given line
+ // if the format comes from the gstreamer backend
+ // gstreamer will be able to deal with it
+ Class clazz = info.getLineClass();
+ DataLine.Info _info = (DataLine.Info) info;
+
+ if (clazz == SourceDataLine.class)
+ {
+ for (AudioFormat format : _info.getFormats())
+ {
+ // see if we are a gstreamer child :)
+ if (format.properties().containsKey(GST_BACKEND));
+ {
+ // we got it
+ return new GstSourceDataLine(format);
+ }
+ }
+ }
+
+ // TODO: we also support basic PCM
+
+ throw new LineUnavailableException("Cannot open a line");
+ }
+
+ public int getMaxLines(Line.Info info)
+ {
+ // TODO
+ return 1;
+ }
+
+ public Info getMixerInfo()
+ {
+ return INFO;
+ }
+
+ public javax.sound.sampled.Line.Info[] getSourceLineInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Line.Info[] getSourceLineInfo(Line.Info info)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Line[] getSourceLines()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public javax.sound.sampled.Line.Info[] getTargetLineInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Line.Info[] getTargetLineInfo(Line.Info info)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Line[] getTargetLines()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isLineSupported(Line.Info info)
+ {
+ // We support any kind of mixer that comes
+ // from our gstreamer backend.
+ // In addition, we support PCM based audio streams for
+ // direct playback.
+ if (info instanceof DataLine.Info)
+ {
+ DataLine.Info _dinfo = (DataLine.Info) info;
+ _dinfo.getFormats();
+ }
+
+ return true;
+ }
+
+ public boolean isSynchronizationSupported(Line[] lines, boolean sync)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void synchronize(Line[] lines, boolean sync)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void unsynchronize(Line[] lines)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void addLineListener(LineListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Control getControl(Type what)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Control[] getControls()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public javax.sound.sampled.Line.Info getLineInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isControlSupported(Type what)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void open() throws LineUnavailableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void removeLineListener(LineListener listener)
+ {
+ // TODO Auto-generated method stub
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixerProvider.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixerProvider.java
new file mode 100644
index 000000000..6a0d7faa7
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/GStreamerMixerProvider.java
@@ -0,0 +1,71 @@
+/*GStreamerMixerProvider -- GNU Classpath GStreamer Mixer provider.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer;
+
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.Mixer.Info;
+import javax.sound.sampled.spi.MixerProvider;
+
+/**
+ * Concrete provider class for GStreamerMixer.
+ *
+ * @author Mario Torre
+ */
+public class GStreamerMixerProvider
+ extends MixerProvider
+{
+ private static final GStreamerMixer mixer = new GStreamerMixer();
+
+ @Override
+ public Mixer getMixer(Info info)
+ {
+ if (info.equals(mixer.getMixerInfo()))
+ return mixer;
+
+ throw new
+ IllegalArgumentException("This provider cannot handle a mixer or type: "
+ + info.getName());
+ }
+
+ @Override
+ public Info[] getMixerInfo()
+ {
+ Info[] info = { mixer.getMixerInfo() };
+ return info;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReader.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReader.java
new file mode 100644
index 000000000..26fb12b09
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReader.java
@@ -0,0 +1,185 @@
+/*GstAudioFileReader -- GNU Classpath GStreamer AudioFileReader.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.io;
+
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.javax.sound.sampled.gstreamer.GStreamerMixer;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * An implementation of a general AudioFileReader. Uses GStreamer to
+ * parse and retrieve informations about the file passed as input.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class GstAudioFileReader
+ extends AudioFileReader
+{
+ @Override
+ public AudioFileFormat getAudioFileFormat(File file)
+ throws UnsupportedAudioFileException, IOException
+ {
+ CPStringBuilder name = new CPStringBuilder(file.getName());
+ String _name = name.substring(name.lastIndexOf(".") + 1);
+
+ return getAudioFileFormat(
+ new BufferedInputStream(new FileInputStream(file)), _name);
+ }
+
+ @Override
+ public AudioFileFormat getAudioFileFormat(InputStream is)
+ throws UnsupportedAudioFileException, IOException
+ {
+ return getAudioFileFormat(is, null);
+ }
+
+ private AudioFileFormat getAudioFileFormat(InputStream is, String extension)
+ throws UnsupportedAudioFileException
+ {
+ AudioFormat format = null;
+ try
+ {
+ format = GstAudioFileReaderNativePeer.getAudioFormat(is);
+ }
+ catch (Exception e)
+ {
+ UnsupportedAudioFileException ex =
+ new UnsupportedAudioFileException("Unsupported encoding.");
+
+ ex.initCause(ex.getCause());
+ throw ex;
+ }
+
+ if (format == null)
+ throw new UnsupportedAudioFileException("Unsupported encoding.");
+
+ String name = format.getProperty(GStreamerMixer.GST_DECODER).toString();
+
+ if (extension == null)
+ {
+ extension =
+ format.getProperty(GStreamerMixer.GST_FILE_EXTENSION).toString();
+ }
+
+ AudioFileFormat.Type type =
+ new AudioFileFormat.Type(name, extension);
+
+ // TODO: we should calculate this in some way. We don't need it, but
+ // application may want to use this data.
+ return new AudioFileFormat(type, format, AudioSystem.NOT_SPECIFIED);
+ }
+
+ @Override
+ public AudioFileFormat getAudioFileFormat(URL url)
+ throws UnsupportedAudioFileException, IOException
+ {
+ return getAudioFileFormat(new BufferedInputStream(url.openStream()));
+ }
+
+ @Override
+ public AudioInputStream getAudioInputStream(File file)
+ throws UnsupportedAudioFileException, IOException
+ {
+ InputStream stream = new FileInputStream(file);
+ long length = file.length();
+
+ AudioFormat format = null;
+
+ try
+ {
+ format = GstAudioFileReaderNativePeer.getAudioFormat(file);
+ }
+ catch (Exception e)
+ {
+ UnsupportedAudioFileException ex =
+ new UnsupportedAudioFileException("Unsupported encoding.");
+
+ ex.initCause(ex.getCause());
+ throw ex;
+ }
+
+ // get the header size
+ if (format == null)
+ throw new UnsupportedAudioFileException("Unsupported encoding.");
+
+ return new AudioInputStream(stream, format, length);
+ }
+
+ @Override
+ public AudioInputStream getAudioInputStream(InputStream is)
+ throws UnsupportedAudioFileException, IOException
+ {
+ AudioFormat format = null;
+
+ try
+ {
+ format = GstAudioFileReaderNativePeer.getAudioFormat(is);
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // get the header size
+ if (format == null)
+ throw new UnsupportedAudioFileException("Unsupported encoding.");
+
+ return new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED);
+ }
+
+ @Override
+ public AudioInputStream getAudioInputStream(URL url)
+ throws UnsupportedAudioFileException, IOException
+ {
+ return getAudioInputStream(new BufferedInputStream(url.openStream()));
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer.java
new file mode 100644
index 000000000..6345d7654
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileReaderNativePeer.java
@@ -0,0 +1,284 @@
+/*GstAudioFileReaderNativePeer -- GNU Classpath GStreamer AudioFileReader
+ native peer class.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.io;
+
+import gnu.classpath.Pointer;
+import gnu.javax.sound.sampled.gstreamer.GStreamerMixer;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * GStreamer native peer for GstAudioFileReader.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+final class GstAudioFileReaderNativePeer
+{
+ private static final String GST_ENCODING = "GStreamer Generic Audio Reader";
+
+ private static class GstHeader
+ {
+ /*
+ * NOTE: these properties are accessed by the native code, be careful
+ * if you change them.
+ * Not all the fields are necessarily set.
+ *
+ */
+ public String file = null;
+
+ public String suffix = null;
+
+ public String name = null;
+
+ public String mimetype = null;
+
+ public String endianness = null;
+
+ public String channels = null;
+
+ public String rate = null;
+
+ public String width = null;
+
+ public String depth = null;
+
+ public String isSigned = null;
+
+ public String layer = null;
+
+ public String bitrate = null;
+
+ public String framed = null;
+
+ public String type = null;
+ }
+
+ public static AudioFormat getAudioFormat(File file) throws Exception
+ {
+ GstHeader header = new GstHeader();
+ header.file = file.getAbsolutePath();
+
+ if (!gstreamer_get_audio_format_file(header))
+ return null;
+
+ return getAudioFormat(header);
+ }
+
+ public static AudioFormat getAudioFormat(InputStream is) throws Exception
+ {
+ return getAudioFormat(is, new GstHeader());
+ }
+
+ public static AudioFormat getAudioFormat(URL url) throws Exception
+ {
+ GstHeader header = new GstHeader();
+ header.file = url.toExternalForm();
+
+ return getAudioFormat(url.openStream(), header);
+ }
+
+ private static AudioFormat getAudioFormat(InputStream is, GstHeader header)
+ throws Exception
+ {
+ BufferedInputStream stream = new BufferedInputStream(is);
+ if(!stream.markSupported())
+ throw new IOException("Stream must support marking.");
+
+ stream.mark(0);
+
+ if (!gstreamer_get_audio_format_stream(header, new GstInputStream(stream).
+ getNativeClass()))
+ return null;
+
+ return getAudioFormat(header);
+ }
+
+ private static Encoding getEncoding(GstHeader header)
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ if (header.name == null)
+ {
+ buffer.append(GST_ENCODING);
+ if (header.mimetype != null)
+ {
+ buffer.append(" ");
+ buffer.append(header.mimetype);
+ }
+
+ header.name = buffer.toString();
+ }
+ else
+ {
+ // strip the "decoder" word from the name, if any
+ // this is a bit ugly, the alternative would be to still output the
+ // full name of the decoder/demuxer
+ String lowerCase = header.name.toLowerCase();
+ int index = lowerCase.indexOf("decoder");
+ if (index == -1)
+ {
+ index = lowerCase.indexOf("demuxer");
+ }
+
+ if (index == -1)
+ index = lowerCase.length();
+
+ buffer.append(header.name.substring(0, index));
+
+ }
+
+ return new Encoding(buffer.toString().trim());
+ }
+
+ private static AudioFormat getAudioFormat(GstHeader header)
+ throws Exception
+ {
+ int na = AudioSystem.NOT_SPECIFIED;
+
+ /* we use mimetype as an header, but this could have some side effects */
+ Encoding encoding = getEncoding(header);
+
+ float sampleRate = ((header.rate != null) ?
+ new Float(header.rate).floatValue() : na);
+
+ int sampleSizeInBits = ((header.depth != null) ?
+ new Integer(header.depth).intValue() : na);
+
+ int channels = ((header.channels != null) ?
+ new Integer(header.channels).intValue() : na);
+
+ boolean bigEndian = false;
+ if (header.endianness != null)
+ {
+ if (header.endianness.compareTo("4321") == 0)
+ bigEndian = true;
+ }
+
+ String ext = null;
+
+ int frameSize = na;
+ float frameRate = na;
+ String lowerCase = header.name.toLowerCase();
+
+ // FIXME: frameRate = sampleRate in these cases under all the tests so far
+ // but I'm not sure if this is always correct...
+ if (lowerCase.contains("law") || lowerCase.contains("au"))
+ {
+ frameSize = (sampleSizeInBits >> 3) * channels;
+ frameRate = sampleRate;
+ ext = "au";
+ }
+ else if (lowerCase.contains("wav"))
+ {
+ frameSize = ((sampleSizeInBits + 7) / 8) * channels;
+ frameRate = sampleRate;
+ ext = "wav";
+ }
+ else if (lowerCase.contains("iff"))
+ {
+ frameSize = (sampleSizeInBits * channels) / 8;
+ frameRate = sampleRate;
+ ext = "aiff";
+ }
+
+ // write all the additional properties we got to identify
+ // the gstreamer plugin actually used to deal with this stream
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put(GStreamerMixer.GST_BACKEND, true);
+ properties.put(GStreamerMixer.GST_DECODER, header.name);
+ properties.put(GStreamerMixer.GST_TYPE_NAME, encoding.toString());
+ if (ext != null)
+ properties.put(GStreamerMixer.GST_FILE_EXTENSION, ext);
+
+ /* now we put in some of the additional properties if we have them */
+ if (header.type != null) properties.put("type", header.type);
+ if (header.framed != null) properties.put("framed", header.framed);
+ if (header.bitrate != null) properties.put("bitrate", header.bitrate);
+ if (header.isSigned != null) properties.put("isSigned", header.isSigned);
+ if (header.depth != null) properties.put("depth", header.depth);
+ if (header.mimetype != null) properties.put("mimetype", header.mimetype);
+
+ AudioFormat format = new AudioFormat(encoding,
+ sampleRate,
+ sampleSizeInBits,
+ channels,
+ frameSize,
+ frameRate,
+ bigEndian,
+ properties);
+ return format;
+ }
+
+ /* ***** native methods ***** */
+
+ /**
+ * Retrieve header information about the stream being played.
+ */
+ native static final
+ protected boolean gstreamer_get_audio_format_stream(GstHeader info,
+ Pointer pointer);
+
+ /**
+ * Retrieve header information about the file being played.
+ */
+ native static final
+ protected boolean gstreamer_get_audio_format_file(GstHeader info);
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the static initializer.
+ */
+ native private static final void init_id_cache();
+
+ static
+ {
+ System.loadLibrary("gstreamerpeer"); //$NON-NLS-1$
+ init_id_cache();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileWriter.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileWriter.java
new file mode 100644
index 000000000..9b395dca2
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstAudioFileWriter.java
@@ -0,0 +1,80 @@
+/*GstAudioFileWriter -- GNU Classpath GStreamer AudioFileReader.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.javax.sound.sampled.gstreamer.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioFileFormat.Type;
+import javax.sound.sampled.spi.AudioFileWriter;
+
+public class GstAudioFileWriter
+ extends AudioFileWriter
+{
+ @Override
+ public Type[] getAudioFileTypes()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Type[] getAudioFileTypes(AudioInputStream ais)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int write(AudioInputStream ais, Type type, File out)
+ throws IOException
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int write(AudioInputStream ais, Type type, OutputStream os)
+ throws IOException
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstInputStream.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstInputStream.java
new file mode 100644
index 000000000..56bddcaad
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/io/GstInputStream.java
@@ -0,0 +1,119 @@
+/* GstInputStream.java -- Trampoline class for an InputStream, mean to be used
+ by native code.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.io;
+
+import gnu.classpath.Pointer;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Encapsulates the functionality of an InputStream Object.
+ *
+ * This class is only meant to be used by the native code, to allow reading
+ * of the given InputStream as part of a the GStreamer InputStream Source
+ * Plugin.
+ *
+ * <strong>Note:</strong> this class will be not garbage collected as the
+ * native code contains strong references to internal fields.
+ * The native layer provides a method that can be called by the C code to
+ * free the resources and to let the garbage collected to handle this class
+ * when not needed anymore.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class GstInputStream
+{
+ /** The real InputStream on which to perform reading operations. */
+ private InputStream istream;
+
+ /**
+ * Initialized in the native code, don't change without changes
+ * in the native layer.
+ */
+ private Pointer gstInputStream = null;
+
+ public GstInputStream(InputStream istream)
+ {
+ this.istream = istream;
+ init_instance();
+ }
+
+ public int read(byte[] buf, int off, int len) throws IOException
+ {
+ return this.istream.read(buf, off, len);
+ }
+
+ public int available() throws IOException
+ {
+ return this.istream.available();
+ }
+
+ /**
+ * Return a reference to the GstInputStream native class as a Pointer object.
+ * This method is intended as an helper accessor and the returned pointer
+ * needs to be casted and used in the native code only.
+ *
+ * @return Pointer to the native GstInputStream class.
+ */
+ public Pointer getNativeClass()
+ {
+ return this.gstInputStream;
+ }
+
+ /* native methods */
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the class constructor.
+ */
+ native private final void init_instance();
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the static initializer.
+ */
+ native private static final void init_id_cache();
+
+ static
+ {
+ System.loadLibrary("gstreamerpeer"); //$NON-NLS-1$
+ init_id_cache();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstDataLine.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstDataLine.java
new file mode 100644
index 000000000..4e8cb1bb2
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstDataLine.java
@@ -0,0 +1,151 @@
+/* GstDataLine.java -- Abstract DataLine.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.lines;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.Control.Type;
+
+public abstract class GstDataLine
+ implements DataLine
+{
+ public static final int DEFAULT_BUFFER_SIZE = 1024;
+
+ /** Represents if this Line is opened or not. */
+ protected Boolean open = false;
+
+ private AudioFormat format = null;
+ private int bufferSize = 0;
+
+ public GstDataLine(AudioFormat format)
+ {
+ this.format = format;
+ this.bufferSize = DEFAULT_BUFFER_SIZE;
+ }
+
+ public GstDataLine(AudioFormat format, int bufferSize)
+ {
+ this.format = format;
+ this.bufferSize = bufferSize;
+ }
+
+ public int getBufferSize()
+ {
+ return this.bufferSize;
+ }
+
+ public AudioFormat getFormat()
+ {
+ return this.format;
+ }
+
+ public float getLevel()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public void addLineListener(LineListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Control getControl(Type what)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Control[] getControls()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public javax.sound.sampled.Line.Info getLineInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isControlSupported(Type what)
+ {
+ return false;
+ }
+
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void removeLineListener(LineListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* protected methods for subclasses */
+
+ /**
+ * @param open the open to set
+ */
+ protected void setOpen(Boolean open)
+ {
+ this.open = open;
+ }
+
+ /**
+ * @param bufferSize the bufferSize to set
+ */
+ protected void setBufferSize(int bufferSize)
+ {
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * @param format the format to set
+ */
+ protected void setFormat(AudioFormat format)
+ {
+ this.format = format;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstNativeDataLine.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstNativeDataLine.java
new file mode 100644
index 000000000..896f0cb85
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstNativeDataLine.java
@@ -0,0 +1,77 @@
+/* GstNativeDataLine.java -- SourceDataLine implementation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.lines;
+
+import gnu.classpath.Pointer;
+
+import javax.sound.sampled.LineUnavailableException;
+
+public class GstNativeDataLine
+{
+ public static final GstPipeline createSourcePipeline(int bufferSize)
+ throws LineUnavailableException
+ {
+ GstPipeline pipeline = new GstPipeline(bufferSize);
+
+ pipeline.createForWrite();
+
+ if (!setup_sink_pipeline(pipeline.getNativeClass()))
+ throw new LineUnavailableException("Line unavailable");
+
+ return pipeline;
+ }
+
+ /* native methods */
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the static initializer.
+ */
+ native static final private void init_id_cache();
+
+ /**
+ * Setup a new GStreamer Pipeline
+ */
+ native static final private boolean setup_sink_pipeline(Pointer pipeline);
+
+ static
+ {
+ System.loadLibrary("gstreamerpeer"); //$NON-NLS-1$
+ init_id_cache();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstPipeline.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstPipeline.java
new file mode 100644
index 000000000..9280e9f15
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstPipeline.java
@@ -0,0 +1,415 @@
+/* GstPipeline.java -- Represents a Gstreamer Pipeline.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.lines;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.prefs.Preferences;
+
+import javax.sound.sampled.LineUnavailableException;
+
+import gnu.classpath.Pointer;
+
+/**
+ * This class represent a GStreamer pipeline and is resposible to handle the
+ * flow of data to and from the GStreamer native backend.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class GstPipeline
+{
+ /*
+ * Implementation note:
+ * This class is at first a bit confusing as it serves as a gateway
+ * to a real filesystem named pipe.
+ * The pipelines is shared by the gstreamer backend and by the java code.
+ * If the operation we are performing is to play a given stream of bytes,
+ * we need to open the java side of the pipeline for writing, which is done
+ * in the prepareWrite method. At the same time, the native side of the code
+ * need to open the pipeline in read mode, to get access to the data,
+ * and hence, act as a source element. This is why you will see terms
+ * like "read" or "source" in methods that are used to write in the pipeline,
+ * in other words, each the native operation is the opposite of the java
+ * side operation.
+ * Opening the pipe to record audio data from the sound card works the same
+ * except that all the operation are inverted.
+ */
+
+ // These enums are used in the native code also, changes here must reflect
+ // changes in the native code.
+ public static enum State
+ {
+ PLAY, PAUSE, STOP, CLOSE
+ }
+
+ private static final int READ = 0;
+ private static final int WRITE = 1;
+ private static final int QUEUED = 1;
+
+ private static final String CAPACITY_KEY = "Capacity";
+
+ private static final Object [] lock = new Object[0];
+
+ /*
+ * Preference subsystem. We use this to store some system specific settings.
+ */
+ protected Preferences prefs =
+ Preferences.userNodeForPackage(GstPipeline.class).node("GStreamer");
+
+ // used by the native code, stores the size of the named pipeline
+ // created by the operating system.
+ private long capacity = -1;
+
+ /** Represents the playing state of this Line. */
+ private State state = State.STOP;
+
+ /** The name of the named pipe. */
+ // Will be setup and filled in the native code. See the native library
+ // for details.
+ private String name = null;
+
+ /** This is the named pipe that will be read by the gstreamer backend. */
+ private FileOutputStream output = null;
+
+ /**
+ * Defines if we are getting data from a sink pipe
+ * or writing to a source pipe.
+ */
+ private boolean source = true;
+
+ /** Indicate that we are ready to process audio data to/from the pipe. */
+ private boolean ready = false;
+
+ /**
+ * This is the native GStreamer Pipeline.
+ */
+ // This field is used by the native code, so any change to it must be
+ // followed by similar changes in the native peer.
+ private Pointer pipeline = null;
+
+ /**
+ * Creates a new GstPipeline with a capacity of
+ * {@link GstDataLine#DEFAULT_BUFFER_SIZE}.
+ *
+ * @see GstDataLine#DEFAULT_BUFFER_SIZE
+ */
+ public GstPipeline()
+ {
+ this(GstDataLine.DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Creates a new GstPipeline with a capacity of bufferSize.
+ * @see GstDataLine#DEFAULT_BUFFER_SIZE
+ */
+ public GstPipeline(int bufferSize)
+ {
+ // see if we need to detect the size of the named pipe or we can use
+ // an already computet default for this system.
+ // Note that this is very different from the bufferSize parameter,
+ // see below.
+ capacity = prefs.getLong(CAPACITY_KEY, -1);
+ if (capacity == -1)
+ {
+ synchronized (lock)
+ {
+ capacity = detect_pipe_size();
+ }
+
+ prefs.putLong(CAPACITY_KEY, capacity);
+ }
+
+ // FIXME: bufferSize actually not used nor needed by the backend.
+ // Applications that expects a buffer of different size will be a
+ // bit disappointed by that..
+ init_instance();
+
+ // need to remove the named pipe in case of abnormal termination
+ Runtime.getRuntime().addShutdownHook(new CleanPipeline());
+ }
+
+ /**
+ * Creates a source pipeline. A source pipeline is a pipe you send data for
+ * processing using the write method.
+ */
+ public void createForWrite() throws LineUnavailableException
+ {
+ // create the named pipe
+ if (!create_named_pipe(this.pipeline))
+ throw new LineUnavailableException("Unable to create filesystem pipe");
+
+ open_native_pipe(this.pipeline, READ);
+ prepareWrite();
+
+ this.source = true;
+ }
+
+ /**
+ * @return the state
+ */
+ public State getState()
+ {
+ return this.state;
+ }
+
+ /**
+ * Closes this pipeline.
+ * Short hand for #setState(State.STOP).
+ */
+ public void close()
+ {
+ setState(State.STOP);
+ }
+
+ /**
+ * @param state the state to set
+ */
+ public void setState(final State state)
+ {
+ int _state = -1;
+ switch (state)
+ {
+ case PLAY:
+ _state = 0;
+ break;
+
+ case PAUSE:
+ _state = 1;
+ break;
+
+ case STOP: case CLOSE:
+ _state = 2;
+ closePipe();
+ break;
+ }
+
+ if (set_state(pipeline, _state))
+ GstPipeline.this.state = state;
+ }
+
+ /**
+ * Return a reference to the GstPipeline native class as a Pointer object.
+ * This method is intended as an helper accessor and the returned pointer
+ * needs to be casted and used in the native code only.
+ *
+ * @return Pointer to the native GstPipeline class.
+ */
+ public Pointer getNativeClass()
+ {
+ return this.pipeline;
+ }
+
+ /**
+ * Write length bytes from the given buffer into this pipeline,
+ * starting at offset.
+ * This method block if the pipeline can't accept more data.
+ *
+ * @param buffer
+ * @param offset
+ * @param length
+ * @return
+ */
+ public int write(byte[] buffer, int offset, int length)
+ {
+ if (this.state == State.STOP)
+ return -1;
+ else if (this.state == State.PAUSE)
+ return 0;
+ else if (!ready)
+ return -1;
+
+ try
+ {
+ if (output != null)
+ {
+ output.write(buffer, offset, length);
+ return length;
+ }
+ return 0;
+ }
+ catch (Exception e)
+ {
+ /* nothing to do */
+ }
+
+ return -1;
+ }
+
+ public int read(byte[] buffer, int offset, int length)
+ {
+ return 0;
+ }
+
+ public int available()
+ {
+ if (this.source)
+ return available(this.pipeline, READ);
+ else
+ return available(this.pipeline, WRITE);
+ }
+
+ /**
+ * Wait for remaining data to be enqueued in the pipeline.
+ */
+ public void drain()
+ {
+ if (this.state == State.STOP)
+ return;
+
+ try
+ {
+ // wait untill there is anymore data in the pipe
+ while (available(this.pipeline, QUEUED) > 0)
+ Thread.sleep(3000);
+
+ // plus a bit to allow data to be processed
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ {
+ /* nothing to do*/
+ }
+ }
+
+ /**
+ * Flush all the data currently waiting to be processed.
+ */
+ public void flush()
+ {
+ try
+ {
+ if (source)
+ this.output.flush();
+ }
+ catch (IOException e)
+ {
+ /* nothing */
+ }
+ }
+
+ private void closePipe()
+ {
+ try
+ {
+ GstPipeline.this.flush();
+ if (source)
+ GstPipeline.this.output.close();
+ }
+ catch (IOException e)
+ {
+ /* nothing to do */
+ }
+ }
+
+ private void prepareWrite()
+ {
+ try
+ {
+ // if this is not completed for some reason, we will catch
+ // in the write method. As this call can block, we assume we will
+ // succeed and that the dataline can get data.
+ GstPipeline.this.ready = true;
+ GstPipeline.this.output = new FileOutputStream(name);
+ }
+ catch (Exception e)
+ {
+ GstPipeline.this.ready = false;
+ }
+ }
+
+ /* ***** native ***** */
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the static initializer.
+ */
+ native private static final void init_id_cache();
+
+ /**
+ * Set the playing state of this pipeline.
+ */
+ native private static final boolean set_state(Pointer pipeline, int state);
+
+ /**
+ * Get the number of bytes currently available for reading or writing
+ * from the pipeline.
+ */
+ native private static final int available(Pointer pipeline, int mode);
+
+ /**
+ * Open the native pipeline with the given mode.
+ */
+ native private static final void open_native_pipe(Pointer jpipeline,
+ int mode);
+
+ /**
+ * Close the native pipeline.
+ */
+ native private static final void close_native_pipe(Pointer jpipeline);
+
+ /**
+ * Initialize the native peer and enables the object cache.
+ * It is meant to be used by the class constructor.
+ */
+ native private final void init_instance();
+
+ /**
+ * Crates the named pipe used to pass data between the application code
+ * and gstreamer.
+ */
+ native private final boolean create_named_pipe(Pointer jpipeline);
+
+ /**
+ * Detect and return the size of the filesystem named pipe.
+ */
+ native private final long detect_pipe_size();
+
+ private class CleanPipeline extends Thread
+ {
+ public void run()
+ {
+ GstPipeline.close_native_pipe(GstPipeline.this.pipeline);
+ }
+ }
+
+ static
+ {
+ System.loadLibrary("gstreamerpeer"); //$NON-NLS-1$
+ init_id_cache();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstSourceDataLine.java b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstSourceDataLine.java
new file mode 100644
index 000000000..2bc2de454
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/sampled/gstreamer/lines/GstSourceDataLine.java
@@ -0,0 +1,153 @@
+/* GstSourceDataLine.java -- SourceDataLine implementation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.sound.sampled.gstreamer.lines;
+
+import gnu.javax.sound.AudioSecurityManager;
+import gnu.javax.sound.sampled.gstreamer.lines.GstPipeline.State;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+import static gnu.javax.sound.AudioSecurityManager.Permission;
+
+public class GstSourceDataLine
+ extends GstDataLine implements SourceDataLine
+{
+ private GstPipeline pipeline = null;
+ private boolean open = false;
+
+ public GstSourceDataLine(AudioFormat format)
+ {
+ super(format);
+ }
+
+ public void open() throws LineUnavailableException
+ {
+ AudioSecurityManager.checkPermissions(Permission.PLAY);
+
+ if (open)
+ throw new IllegalStateException("Line already opened");
+
+ // create the pipeline
+ pipeline = GstNativeDataLine.createSourcePipeline(getBufferSize());
+
+ this.open = true;
+ }
+
+ public void open(AudioFormat fmt) throws LineUnavailableException
+ {
+ AudioSecurityManager.checkPermissions(Permission.PLAY);
+
+ setFormat(fmt);
+ this.open();
+ }
+
+ public void open(AudioFormat fmt, int size) throws LineUnavailableException
+ {
+ AudioSecurityManager.checkPermissions(Permission.PLAY);
+
+ setBufferSize(size);
+ this.open(fmt);
+ }
+
+ public int write(byte[] buf, int offset, int length)
+ {
+ return this.pipeline.write(buf, offset, length);
+ }
+
+ public int available()
+ {
+ return this.pipeline.available();
+ }
+
+ public void drain()
+ {
+ this.pipeline.drain();
+ }
+
+ public void flush()
+ {
+ this.pipeline.flush();
+ }
+
+ public int getFramePosition()
+ {
+ System.out.println("getFramePosition -: IMPLEMENT ME!!");
+ return 0;
+ }
+
+ public long getLongFramePosition()
+ {
+ System.out.println("getLongFramePosition -: IMPLEMENT ME!!");
+ return 0;
+ }
+
+ public long getMicrosecondPosition()
+ {
+ System.out.println("getMicrosecondPosition -: IMPLEMENT ME!!");
+ return 0;
+ }
+
+ public boolean isActive()
+ {
+ State state = pipeline.getState();
+ return (state == State.PLAY || state == State.PAUSE);
+ }
+
+ public void start()
+ {
+ pipeline.setState(State.PLAY);
+ }
+
+ public void stop()
+ {
+ pipeline.setState(State.PAUSE);
+ }
+
+ public void close()
+ {
+ pipeline.close();
+ this.open = false;
+ }
+
+ public boolean isRunning()
+ {
+ return (pipeline.getState() == State.PLAY);
+ }
+}