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