changeset in /hg/pulseaudio: * src/java/org/classpath/icedtea/pu...
iivan at town.yyz.redhat.com
iivan at town.yyz.redhat.com
Thu Aug 14 13:09:02 PDT 2008
changeset 20b37b004b8e in /hg/pulseaudio
details: http://icedtea.classpath.org/hg/pulseaudio?cmd=changeset;node=20b37b004b8e
description:
* src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java:
modified getLine() to allow us to obtain a TargetDataLine
* src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java:
added open(), read() and close()
* src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java
marged the streamListeners into a single listener
diffstat:
8 files changed, 652 insertions(+), 445 deletions(-)
ChangeLog | 13
build.xml | 2
src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java | 6
src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java | 40
src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java | 456 ++++------
src/java/org/classpath/icedtea/pulseaudio/SimpleAudioRecorder.java | 248 +++++
src/native/Makefile.am | 2
src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetDataLine.c | 330 +++----
diffs (truncated from 1336 to 500 lines):
diff -r 3003bf4192f2 -r 20b37b004b8e ChangeLog
--- a/ChangeLog Wed Aug 13 14:22:35 2008 -0400
+++ b/ChangeLog Thu Aug 14 16:09:15 2008 -0400
@@ -1,10 +1,21 @@ 2008-08-13 Ioana Ivan <iivan at redhat.com
+2008-08-13 Ioana Ivan <iivan at redhat.com>
+
+ * src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java:
+ modified getLine() to allow us to obtain a TargetDataLine
+ * src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java:
+ added open(), read() and close()
+ * src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java
+ marged the streamListeners into a single listener
+
+
+
2008-08-13 Ioana Ivan <iivan at redhat.com>
* src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java: the
list of formats recognized by PulseAudio is being set here, so it can
be used by all DataLines. Also made some changes to get*LineInfo() and
isLineSupported()
- *src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java:
+ * src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java:
changed the constructor
diff -r 3003bf4192f2 -r 20b37b004b8e build.xml
--- a/build.xml Wed Aug 13 14:22:35 2008 -0400
+++ b/build.xml Thu Aug 14 16:09:15 2008 -0400
@@ -38,9 +38,11 @@
<class name="org.classpath.icedtea.pulseaudio.EventLoop"/>
<class name="org.classpath.icedtea.pulseaudio.Operation"/>
<class name="org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine"/>
+ <class name="org.classpath.icedtea.pulseaudio.PulseAudioTargetDataLine"/>
<class name="org.classpath.icedtea.pulseaudio.PulseAudioClip"/>
<class name="org.classpath.icedtea.pulseaudio.PulseAudioStreamVolumeControl"/>
<class name="org.classpath.icedtea.pulseaudio.Operation"/>
+ <class name="org.classpath.icedtea.pulseaudio.SimpleAudioRecorder"/>
</javah>
</target>
diff -r 3003bf4192f2 -r 20b37b004b8e src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Wed Aug 13 14:22:35 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Thu Aug 14 16:09:15 2008 -0400
@@ -317,9 +317,9 @@ private AudioFormat[] getSupportedFormat
return new PulseAudioSourceDataLine(eventLoop, formats, defaultFormat);
}
- /*if ((info.getLineClass() == TargetDataLine.class)) {
- return new PulseAudioTargetDataLine(this, (DataLine.Info) info);
- }*/
+ if ((info.getLineClass() == TargetDataLine.class)) {
+ return new PulseAudioTargetDataLine(eventLoop, formats, defaultFormat);
+ }
PulseAudioClip clip = new PulseAudioClip();
diff -r 3003bf4192f2 -r 20b37b004b8e src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Wed Aug 13 14:22:35 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Thu Aug 14 16:09:15 2008 -0400
@@ -81,6 +81,8 @@ public class PulseAudioSourceDataLine im
private boolean muted;
private float volume;
+ private Semaphore semaphore = new Semaphore(0);
+
private long currentFramePosition = 0;
/*
@@ -122,10 +124,7 @@ public class PulseAudioSourceDataLine im
}
public PulseAudioSourceDataLine(EventLoop eventLoop, AudioFormat[] formats, AudioFormat defaultFormat) {
- if (formats == null) {
-
- }
-
+
supportedFormats = formats;
this.eventLoop = eventLoop;
this.lineListeners = new ArrayList<LineListener>();
@@ -182,10 +181,12 @@ public class PulseAudioSourceDataLine im
if (e.getType() == StreamEvent.Type.READY) {
fireLineEvent(new LineEvent(PulseAudioSourceDataLine.this,
LineEvent.Type.OPEN, AudioSystem.NOT_SPECIFIED));
+ semaphore.release();
} else if (e.getType() == StreamEvent.Type.TERMINATED
|| e.getType() == StreamEvent.Type.FAILED) {
fireLineEvent((new LineEvent(PulseAudioSourceDataLine.this,
LineEvent.Type.CLOSE, AudioSystem.NOT_SPECIFIED)));
+ semaphore.release();
}
}
@@ -193,18 +194,9 @@ public class PulseAudioSourceDataLine im
addStreamListener(openCloseListener);
- final Semaphore semaphore = new Semaphore(0);
-
- synchronized (eventLoop.threadLock) {
-
- this.addStreamListener(new StreamListener() {
- @Override
- public void update(StreamEvent e) {
- if (e.getType() == StreamEvent.Type.READY) {
- semaphore.release();
- }
- }
- });
+
+
+ synchronized (eventLoop.threadLock) {
native_start();
}
@@ -264,7 +256,7 @@ public class PulseAudioSourceDataLine im
while (remainingLength != 0) {
synchronized (eventLoop.threadLock) {
- availableSize = native_get_writable_size();
+ availableSize = available();
if (availableSize < 0) {
return sizeWritten;
}
@@ -346,19 +338,6 @@ public class PulseAudioSourceDataLine im
public void close() {
assert (isOpen);
- final Semaphore semaphore = new Semaphore(0);
-
- StreamListener closeListener = new StreamListener() {
- @Override
- public void update(StreamEvent e) {
- if (e.getType() == StreamEvent.Type.TERMINATED
- || e.getType() == StreamEvent.Type.FAILED) {
- semaphore.release();
- }
- }
- };
-
- addStreamListener(closeListener);
synchronized (eventLoop.threadLock) {
native_close();
@@ -367,7 +346,6 @@ public class PulseAudioSourceDataLine im
try {
semaphore.acquire();
System.out.println("stream closed");
- removeStreamListener(closeListener);
} catch (InterruptedException e) {
// throw new LineUnavailableException("unable to prepare
// stream");
diff -r 3003bf4192f2 -r 20b37b004b8e src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Wed Aug 13 14:22:35 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Thu Aug 14 16:09:15 2008 -0400
@@ -37,41 +37,51 @@ exception statement from your version.
package org.classpath.icedtea.pulseaudio;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Semaphore;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.Control.Type;
+import javax.sound.sampled.Port.Info;
public class PulseAudioTargetDataLine implements TargetDataLine {
- protected long contextPointer;
- protected long mainLoopPointer;
- protected long streamPointer;
+
protected boolean isOpen = false;
protected boolean isPaused = false;
- protected int defaultBufferSize;
-
-
+
+ private AudioFormat[] supportedFormats = null;
+ private AudioFormat currentFormat = null;
+ private AudioFormat defaultFormat = null;
+
+ private List<LineListener> lineListeners;
+
+ private List<StreamListener> streamListeners = new ArrayList<StreamListener>();
+
+ private String streamName = "Java Stream";
private static final int DEFAULT_BUFFER_SIZE = 1000;
private static final String PULSEAUDIO_FORMAT_KEY = "PulseAudioFormatKey";
- private List<AudioFormat> supportedFormats = null;
- private AudioFormat currentFormat = null;
+
private EventLoop eventLoop = null;
protected ArrayList<LineListener> listeners;
+
+ private Semaphore semaphore = new Semaphore(0);
+
+ @SuppressWarnings("unused")
+ private long streamPointer;
static {
try {
- String library = new java.io.File(".").getCanonicalPath()
- + java.io.File.separatorChar + "lib"
- + java.io.File.separatorChar
+ String library = new java.io.File(".").getCanonicalPath() + java.io.File.separatorChar
+ System.mapLibraryName("pulse-java");
System.out.println(library);
System.load(library);
@@ -80,226 +90,148 @@ public class PulseAudioTargetDataLine im
}
}
- public PulseAudioTargetDataLine(EventLoop eventLoop) {
+ private native void native_open(long contextPointer, String streamName,
+ String encoding, int sampleRate, int channels, int bufferSize);
+
+ private native void native_start();
+
+ private native int native_get_readable_size();
+
+ private native void native_close();
+
+ private native int native_read(byte[] array, int remaininglength, int position);
+
+ public PulseAudioTargetDataLine(EventLoop eventLoop, AudioFormat[] formats, AudioFormat defaultFormat) {
+ supportedFormats = formats;
this.eventLoop = eventLoop;
- this.listeners = new ArrayList<LineListener>();
-
-
-
-
- /*
- * FIXME puselaudio supports any sample rate (it can covert between
- * sample rates without a problem). it calculates the frame size and the
- * frame rate based on that.
- *
- * Java's AudioSystem interface accepts NOT_SPECIFIED only for sample
- * rate and frame rate. eg: cant say that it supports any number of
- * audio channels
- *
- * sample size in bytes [PA_SAMPLE_U8] = 1, [PA_SAMPLE_ULAW] = 1,
- * [PA_SAMPLE_ALAW] = 1, [PA_SAMPLE_S16LE] = 2, [PA_SAMPLE_S16BE] = 2,
- * [PA_SAMPLE_FLOAT32LE] = 4, [PA_SAMPLE_FLOAT32BE] = 4,
- * [PA_SAMPLE_S32LE] = 4, [PA_SAMPLE_S32BE] = 4,
- *
- *
- */
-
- supportedFormats = new LinkedList<AudioFormat>();
-
- Map<String, Object> properties;
-
- int[] channelSizes = new int[] { 1, 2, 5 };
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_U8");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
- int sampleSize = 8; // in bits
- AudioFormat PA_SAMPLE_U8 = new AudioFormat(
- Encoding.PCM_UNSIGNED, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size in bytes
- AudioSystem.NOT_SPECIFIED, // frame rate
- false, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_U8);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ALAW");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 8;
- final AudioFormat PA_SAMPLE_ALAW = new AudioFormat(Encoding.ALAW, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- false, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_ALAW);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ULAW");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 8;
- final AudioFormat PA_SAMPLE_ULAW = new AudioFormat(Encoding.ULAW, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- false, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_ULAW);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16BE");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 16;
- final AudioFormat PA_SAMPLE_S16BE = new AudioFormat(
- Encoding.PCM_SIGNED, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- true, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_S16BE);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16LE");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 16;
- final AudioFormat A_SAMPLE_S16LE = new AudioFormat(
- Encoding.PCM_SIGNED, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- false, // big endian?
- properties);
-
- supportedFormats.add(A_SAMPLE_S16LE);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32BE");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 32;
- final AudioFormat PA_SAMPLE_S32BE = new AudioFormat(
- Encoding.PCM_SIGNED, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- true, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_S32BE);
- }
-
- for (int channelSize : channelSizes) {
- properties = new HashMap<String, Object>();
- properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32LE");
-
- // frameSize = sample size (in bytes, not bits) x # of channels
- // ^ that's from PulseAudio sources, so it will pretty much break
- // as soon as they change something
- // FIXME ^
-
- int sampleSize = 32;
- final AudioFormat PA_SAMPLE_S32LE = new AudioFormat(
- Encoding.PCM_SIGNED, // encoding
- AudioSystem.NOT_SPECIFIED, // sample rate
- sampleSize, // sample size
- channelSize, // channels
- sampleSize / 8 * channelSize, // frame size
- AudioSystem.NOT_SPECIFIED, // frame rate
- false, // big endian?
- properties);
-
- supportedFormats.add(PA_SAMPLE_S32LE);
- }
-
- currentFormat = null;
-
+ this.lineListeners = new ArrayList<LineListener>();
+ this.defaultFormat = defaultFormat;
+ this.currentFormat = defaultFormat;
}
public void open(AudioFormat format, int bufferSize)
throws LineUnavailableException {
- isOpen = true;
-
- int channels = format.getChannels();
- float rate = format.getSampleRate();
- int sampleSize = format.getSampleSizeInBits();
- String encoding = format.getEncoding().toString();
- boolean bigEndian = format.isBigEndian();
- openStream(encoding, rate, sampleSize, channels, bigEndian, bufferSize);
+ System.out.println("OPEn CALLED");
+ if (isOpen) {
+ throw new IllegalStateException("Line is already open");
+ }
+
+ // ignore suggested buffer size
+
+ for (AudioFormat myFormat : supportedFormats) {
+ if (format.matches(myFormat)) {
+ native_open(eventLoop.getContextPointer(), streamName,
+ (String) myFormat.getProperty(PULSEAUDIO_FORMAT_KEY),
+ (int) format.getSampleRate(), format.getChannels(),
+ bufferSize);
+ currentFormat = format;
+ isOpen = true;
+ }
+ }
+ // no matches found
+ if (!isOpen) {
+ throw new IllegalArgumentException("Invalid format");
+ }
+
+ StreamListener openCloseListener = new StreamListener() {
+
+ @Override
+ public void update(StreamEvent e) {
+ if (e.getType() == StreamEvent.Type.READY) {
+ fireLineEvent(new LineEvent(PulseAudioTargetDataLine.this,
+ LineEvent.Type.OPEN, AudioSystem.NOT_SPECIFIED));
+ System.out.println("IN HERE");
+ semaphore.release();
+ } else if (e.getType() == StreamEvent.Type.TERMINATED
+ || e.getType() == StreamEvent.Type.FAILED) {
+ fireLineEvent((new LineEvent(PulseAudioTargetDataLine.this,
+ LineEvent.Type.CLOSE, AudioSystem.NOT_SPECIFIED)));
+ semaphore.release();
+ }
+ }
+
+ };
+
+ addStreamListener(openCloseListener);
+
+
+
+ synchronized (eventLoop.threadLock) {
+
+ native_start();
+ }
+
+ try {
+ semaphore.acquire();
+ } catch (InterruptedException e) {
+ // throw new LineUnavailableException("unable to prepare
+ // stream");
+ }
}
public void open(AudioFormat format) throws LineUnavailableException {
More information about the distro-pkg-dev
mailing list