changeset 1087:a28576af0d10

2008-10-14 Omair Majid <omajid@redhat.com> * .hgignore: Added generated files to ignore list. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java (EventLoop): Initialize eventLoop object on construction. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java (PulseAudioClip): Removed the parameter eventLoop. (getMicrosecondLength): Return time in microseconds. (getMicrosecondPosition): Likewise. (open): Dont throw an exception if Mixer is not open. Let super handle it. (setFramePosition): Check frame position for being positive. (setLoopPoints): Check that the starting frame is valid. (setMicrosecondPosition): Deal with negative value and values over the maximum. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java (open): Open the mixer if it isnt open. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java (getLine): Dont pass eventLoop as a paramter. (close): Close all open lines on exit. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java (PulseAudioPort): Modified to not take an EventLoop paramter. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java (PulseAudioSourceDataLine): Likewise. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java (PulseAudioSourcePort): Likewise. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java (PulseAudioTargetDataLine): Likewise. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java (PulseAudioTargetPort): Likewise. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java (testMixerKnowsAboutOpenLines): Work even if mixer has some lines initially open.
author Omair Majid <omajid@redhat.com>
date Tue, 14 Oct 2008 13:26:35 -0400
parents 9032c6fda5c2
children 81e9c55169c4
files .hgignore ChangeLog pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java
diffstat 12 files changed, 131 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Oct 12 16:31:50 2008 +0200
+++ b/.hgignore	Tue Oct 14 13:26:35 2008 -0400
@@ -441,3 +441,7 @@
 rt/java/io/
 rt/sun/awt
 generated/sun/awt/X11/generator/sizer.32.orig
+pulseaudio/bin
+pulseaudio/.*\.o
+pulseaudio/src/native/org_.*.h
+pulseaudio/.*jar
--- a/ChangeLog	Sun Oct 12 16:31:50 2008 +0200
+++ b/ChangeLog	Tue Oct 14 13:26:35 2008 -0400
@@ -1,3 +1,39 @@
+2008-10-14 Omair Majid <omajid@redhat.com>
+
+	* .hgignore: Added generated files to ignore list.
+
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java
+	(EventLoop): Initialize eventLoop object on construction.
+
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java
+	(PulseAudioClip): Removed the parameter eventLoop.
+	(getMicrosecondLength): Return time in microseconds.
+	(getMicrosecondPosition): Likewise.
+	(open): Dont throw an exception if Mixer is not open. Let super handle it.
+	(setFramePosition): Check frame position for being positive.
+	(setLoopPoints): Check that the starting frame is valid.
+	(setMicrosecondPosition): Deal with negative value and values over the 
+	maximum.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java
+	(open): Open the mixer if it isnt open.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java
+	(getLine): Dont pass eventLoop as a paramter.
+	(close): Close all open lines on exit.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java
+	(PulseAudioPort): Modified to not take an EventLoop paramter.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java
+	(PulseAudioSourceDataLine): Likewise.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java
+	(PulseAudioSourcePort): Likewise.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java
+	(PulseAudioTargetDataLine): Likewise.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java
+	(PulseAudioTargetPort): Likewise.
+
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java
+	(testMixerKnowsAboutOpenLines): Work even if mixer has some lines
+	initially open.
+
 2008-10-12  Matthias Klose  <doko@ubuntu.com>
 
 	* Makefile.am (stamps/pulse-java.stamp): Add -I$(ICEDTEA_BOOT_DIR)/include
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java	Tue Oct 14 13:26:35 2008 -0400
@@ -110,7 +110,7 @@
 
 	private EventLoop() {
 		contextListeners = new ArrayList<ContextListener>();
-
+		threadLock = new Object();
 	}
 
 	synchronized public static EventLoop getEventLoop() {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Tue Oct 14 13:26:35 2008 -0400
@@ -194,10 +194,8 @@
 		stream.removeWriteListener(writeListener);
 	}
 
-	public PulseAudioClip(EventLoop eventLoop, AudioFormat[] formats,
-			AudioFormat defaultFormat) {
+	public PulseAudioClip(AudioFormat[] formats, AudioFormat defaultFormat) {
 		supportedFormats = formats;
-		this.eventLoop = eventLoop;
 		this.defaultFormat = defaultFormat;
 		this.currentFormat = defaultFormat;
 		this.volume = PulseAudioVolumeControl.MAX_VOLUME;
@@ -342,7 +340,7 @@
 			return AudioSystem.NOT_SPECIFIED;
 		}
 		synchronized (clipLock) {
-			return frameCount / currentFormat.getFrameSize();
+			return (long) (frameCount / currentFormat.getFrameRate() * 1000);
 		}
 	}
 
@@ -353,7 +351,7 @@
 		}
 
 		synchronized (clipLock) {
-			return framesSinceOpen / currentFormat.getFrameSize();
+			return (long) (framesSinceOpen / currentFormat.getFrameRate() * 1000);
 		}
 	}
 
@@ -398,11 +396,6 @@
 	public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
 			throws LineUnavailableException {
 
-		if(!PulseAudioMixer.getInstance().isOpen()) {
-			throw new LineUnavailableException("The mixer needs to be opened before opening a line");
-		}
-
-
 		/* check for permission to play audio */
 		AudioPermission perm = new AudioPermission("play", null);
 		perm.checkGuard(null);
@@ -472,7 +465,7 @@
 			throw new IllegalStateException("Line not open");
 		}
 
-		if (frames > frameCount) {
+		if (frames < 0 || frames > frameCount) {
 			throw new IllegalArgumentException("incorreft frame value");
 		}
 
@@ -497,6 +490,11 @@
 					"ending point must be greater than or equal to the starting point");
 		}
 
+		if (start < 0) {
+			throw new IllegalArgumentException(
+					"starting point must be greater than or equal to 0");
+		}
+
 		synchronized (clipLock) {
 			startFrame = start;
 			endFrame = end;
@@ -510,7 +508,16 @@
 			throw new IllegalStateException("Line not open");
 		}
 
-		float frameIndex = microseconds * currentFormat.getFrameRate();
+		float frameIndex = microseconds * currentFormat.getFrameRate() / 1000;
+
+		/* make frameIndex positive */
+		while (frameIndex < 0) {
+			frameIndex += frameCount;
+		}
+
+		/* frameIndex is in the range [0, frameCount-1], inclusive */
+		frameIndex = frameIndex % frameCount;
+
 		synchronized (clipLock) {
 			currentFrame = (int) frameIndex;
 		}
@@ -563,7 +570,7 @@
 		super.stop();
 
 	}
-	
+
 	public javax.sound.sampled.Line.Info getLineInfo() {
 		return new DataLine.Info(Clip.class, supportedFormats,
 				StreamBufferAttributes.MIN_VALUE,
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Tue Oct 14 13:26:35 2008 -0400
@@ -84,10 +84,13 @@
 		if (isOpen) {
 			throw new IllegalStateException("Line is already open");
 		}
-		if(!PulseAudioMixer.getInstance().isOpen()) {
-			throw new LineUnavailableException("The mixer needs to be opened before opening a line");
+		
+		PulseAudioMixer mixer = PulseAudioMixer.getInstance();
+		if(!mixer.isOpen()) {
+			mixer.open();
 		}
 
+		eventLoop = EventLoop.getEventLoop();
 
 		createStream(format);
 		addStreamListeners();
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Tue Oct 14 13:26:35 2008 -0400
@@ -43,6 +43,7 @@
 import java.net.UnknownHostException;
 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;
@@ -301,8 +302,7 @@
 			AudioPermission perm = new AudioPermission("play", null);
 			perm.checkGuard(null);
 
-			return new PulseAudioSourceDataLine(eventLoop, formats,
-					defaultFormat);
+			return new PulseAudioSourceDataLine(formats, defaultFormat);
 		}
 
 		if ((info.getLineClass() == TargetDataLine.class)) {
@@ -310,8 +310,7 @@
 			AudioPermission perm = new AudioPermission("record", null);
 			perm.checkGuard(null);
 
-			return new PulseAudioTargetDataLine(eventLoop, formats,
-					defaultFormat);
+			return new PulseAudioTargetDataLine(formats, defaultFormat);
 		}
 
 		if ((info.getLineClass() == Clip.class)) {
@@ -319,15 +318,15 @@
 			AudioPermission perm = new AudioPermission("play", null);
 			perm.checkGuard(null);
 
-			return new PulseAudioClip(eventLoop, formats, defaultFormat);
+			return new PulseAudioClip(formats, defaultFormat);
 		}
 
 		if (Port.Info.class.isInstance(info)) {
 			Port.Info portInfo = (Port.Info) info;
 			if (portInfo.isSource()) {
-				return new PulseAudioSourcePort(portInfo.getName(), eventLoop);
+				return new PulseAudioSourcePort(portInfo.getName());
 			} else {
-				return new PulseAudioTargetPort(portInfo.getName(), eventLoop);
+				return new PulseAudioTargetPort(portInfo.getName());
 			}
 		}
 
@@ -507,6 +506,35 @@
 			throw new IllegalStateException("Mixer is not open; cant close");
 		}
 
+		List<Line> linesToClose = new LinkedList<Line>();
+		linesToClose.addAll(sourceLines);
+		if (sourceLines.size() > 0) {
+			linesToClose.addAll(sourceLines);
+			for (Line line : linesToClose) {
+				if (line.isOpen()) {
+					System.out
+							.println("PulseAudioMixer: DEBUG: some source lines have not been closed");
+					line.close();
+				}
+			}
+		}
+		linesToClose.clear();
+
+		if (targetLines.size() > 0) {
+			linesToClose.addAll(targetLines);
+			for (Line line : linesToClose) {
+				if (line.isOpen()) {
+					System.out
+							.println("PulseAudioMixer: DEBUG: some target lines have not been closed");
+					line.close();
+				}
+			}
+		}
+
+		synchronized (lineListeners) {
+			lineListeners.clear();
+		}
+
 		eventLoopThread.interrupt();
 
 		try {
@@ -520,19 +548,6 @@
 
 		isOpen = false;
 
-		if (sourceLines.size() > 0) {
-			System.out.println("DEBUG: some source lines have not been closed");
-			assert (sourceLines.size() < 0); // always fail
-		}
-		if (targetLines.size() > 0) {
-			System.out.println("DEBUG: some target lines have not been closed");
-			assert (targetLines.size() < 0); // always fail
-		}
-
-		synchronized (lineListeners) {
-			lineListeners.clear();
-		}
-
 		refreshSourceAndTargetLines();
 
 	}
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Tue Oct 14 13:26:35 2008 -0400
@@ -66,25 +66,25 @@
 		System.loadLibrary("pulse-java");
 	}
 
-	public PulseAudioPort(String name, EventLoop eventLoop) {
+	public PulseAudioPort(String name) {
 		this.name = name;
+		this.eventLoop = EventLoop.getEventLoop();
 		this.contextPointer = eventLoop.getContextPointer();
-		this.eventLoop = eventLoop;
+
 		updateVolumeInfo();
 
 		volumeControl = new PulseAudioVolumeControl(this, eventLoop);
 		controls.add(volumeControl);
 		muteControl = new PulseAudioMuteControl(this, volumeControl);
 		controls.add(muteControl);
-		//isOpen = true;
-		open();
+
 		/*
 		 * unlike other lines, Ports must either be open or close
 		 * 
 		 * close = no sound. open = sound
 		 * 
 		 */
-		// FIXME open();
+		open();
 
 		// System.out.println("Opened Target Port " + name);
 	}
@@ -141,7 +141,7 @@
 
 	@Override
 	public void open() {
-		if(isOpen) {
+		if (isOpen) {
 			return;
 		}
 		native_setVolume(volume);
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Tue Oct 14 13:26:35 2008 -0400
@@ -54,11 +54,10 @@
 	private boolean muted;
 	private float volume;
 
-	public PulseAudioSourceDataLine(EventLoop eventLoop, AudioFormat[] formats,
+	public PulseAudioSourceDataLine(AudioFormat[] formats,
 			AudioFormat defaultFormat) {
 
 		this.supportedFormats = formats;
-		this.eventLoop = eventLoop;
 		this.lineListeners = new ArrayList<LineListener>();
 		this.defaultFormat = defaultFormat;
 		this.currentFormat = defaultFormat;
@@ -69,7 +68,7 @@
 	synchronized public void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
 
-		/* check for permmission to play audio */
+		/* check for permission to play audio */
 		AudioPermission perm = new AudioPermission("play", null);
 		perm.checkGuard(null);
 
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Tue Oct 14 13:26:35 2008 -0400
@@ -43,43 +43,43 @@
 public class PulseAudioSourcePort extends PulseAudioPort {
 
 	/* aka mic */
-	
+
 	static {
 		System.loadLibrary("pulse-java");
 	}
 
-	public PulseAudioSourcePort(String name, EventLoop eventLoop) {
-		super(name, eventLoop);
+	public PulseAudioSourcePort(String name) {
+		super(name);
 	}
 
 	public void open() {
-		
+
 		/* check for permission to record audio */
 		AudioPermission perm = new AudioPermission("record", null);
 		perm.checkGuard(null);
-		
+
 		super.open();
-		
+
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.addSourceLine(this);
 	}
-	
+
 	public void close() {
-		
+
 		/* check for permission to record audio */
 		AudioPermission perm = new AudioPermission("record", null);
 		perm.checkGuard(null);
-		
+
 		if (!isOpen) {
 			throw new IllegalStateException("Port is not open; so cant close");
 		}
-		
+
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.removeSourceLine(this);
-		
-		super.close();		
+
+		super.close();
 	}
-	
+
 	public native byte[] native_setVolume(float newValue);
 
 	public synchronized native byte[] native_updateVolumeInfo();
@@ -88,7 +88,5 @@
 	public javax.sound.sampled.Line.Info getLineInfo() {
 		return new Port.Info(Port.class, getName(), false);
 	}
-	
-	
 
 }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Tue Oct 14 13:26:35 2008 -0400
@@ -61,10 +61,9 @@
 	boolean flushed = false;
 	boolean drained = false;
 
-	public PulseAudioTargetDataLine(EventLoop eventLoop, AudioFormat[] formats,
+	public PulseAudioTargetDataLine(AudioFormat[] formats,
 			AudioFormat defaultFormat) {
 		supportedFormats = formats;
-		this.eventLoop = eventLoop;
 		this.defaultFormat = defaultFormat;
 		this.currentFormat = defaultFormat;
 
@@ -363,7 +362,7 @@
 
 		fireLineEvent(new LineEvent(this, LineEvent.Type.STOP, framesSinceOpen));
 	}
-	
+
 	public javax.sound.sampled.Line.Info getLineInfo() {
 		return new DataLine.Info(TargetDataLine.class, supportedFormats,
 				StreamBufferAttributes.MIN_VALUE,
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Tue Oct 14 13:26:35 2008 -0400
@@ -48,9 +48,9 @@
 		System.loadLibrary("pulse-java");
 	}
 
-	public PulseAudioTargetPort(String name, EventLoop eventLoop) {
+	public PulseAudioTargetPort(String name) {
 
-		super(name, eventLoop);
+		super(name);
 	}
 
 	public void open() {
@@ -70,11 +70,11 @@
 		/* check for permission to play audio */
 		AudioPermission perm = new AudioPermission("play", null);
 		perm.checkGuard(null);
-		
+
 		if (!isOpen) {
 			throw new IllegalStateException("not open, so cant close Port");
 		}
-		
+
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.removeTargetLine(this);
 
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java	Sun Oct 12 16:31:50 2008 +0200
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java	Tue Oct 14 13:26:35 2008 -0400
@@ -536,11 +536,11 @@
 		targetDataLine = (TargetDataLine) mixer.getLine(new Line.Info(
 				TargetDataLine.class));
 
-		Assert.assertEquals(0, mixer.getTargetLines().length);
+		int initiallyOpen = mixer.getTargetLines().length;
 		targetDataLine.open();
-		Assert.assertEquals(1, mixer.getTargetLines().length);
+		Assert.assertEquals(initiallyOpen+1, mixer.getTargetLines().length);
 		targetDataLine.close();
-		Assert.assertEquals(0, mixer.getTargetLines().length);
+		Assert.assertEquals(initiallyOpen, mixer.getTargetLines().length);
 
 	}