changeset 146:313b9ddd2f04

2009-08-26 Omair Majid <omajid@redhat.com> * src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Removec commented out methods. Not needed anymore since the parent class doesnt expose them either. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java Removed unused variables and imports. (reconnectForSyncrhonization): Throws an exception if an error occurred instead of dumping the stack trace. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java (synchronize): Anticipate an exception being thrown from the call to reconnectForSynchronization and pass it up to the caller. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Removed unused varaibles and imports. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java (testSynchronization): New function. Tests if synchronization works. A copy of the current test in main() to prevent it from being lost if main is changed.
author Omair Majid <omajid@redhat.com>
date Fri, 26 Sep 2008 11:51:32 -0400
parents bfc67049ee9f
children e0d34e48bc29
files src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java
diffstat 5 files changed, 123 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Fri Sep 26 11:21:24 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Fri Sep 26 11:51:32 2008 -0400
@@ -399,20 +399,6 @@
 
 	}
 
-	// FIXME This is not exposed by the Clip interface, but becomes available if
-	// using PulseAudioClip
-	// @Override
-	// public void open(AudioFormat format, int bufferSize)
-	// throws LineUnavailableException {
-	// throw new IllegalArgumentException("open(AudioFormat, int) on a Clip is
-	// not allowed");
-	// }
-
-	@Override
-	// public void open(AudioFormat format) throws LineUnavailableException {
-	// throw new IllegalArgumentException("open(AudioFormat) on a Clip is not
-	// allowed");
-	// }
 	public byte[] native_setVolume(float value) {
 		return stream.native_setVolume(value);
 	}
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Fri Sep 26 11:21:24 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Fri Sep 26 11:51:32 2008 -0400
@@ -37,7 +37,6 @@
 
 package org.classpath.icedtea.pulseaudio;
 
-import java.util.ArrayList;
 import java.util.concurrent.Semaphore;
 
 import javax.sound.sampled.AudioFormat;
@@ -75,7 +74,6 @@
 	protected EventLoop eventLoop = null;
 	protected Semaphore semaphore = new Semaphore(0);
 	protected Stream stream;
-	private ArrayList<PulseAudioDataLine> synchronizedLines;
 
 	protected void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
@@ -283,7 +281,8 @@
 
 	}
 
-	public void reconnectforSynchronization(Stream masterStream) {
+	public void reconnectforSynchronization(Stream masterStream)
+			throws LineUnavailableException {
 		sendEvents = false;
 		drain();
 
@@ -295,19 +294,11 @@
 		} catch (InterruptedException e) {
 			throw new RuntimeException("unable to prepare stream");
 		}
-		try {
-			createStream(getFormat());
-		} catch (LineUnavailableException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+
+		createStream(getFormat());
 		addStreamListeners();
-		try {
-			connect(masterStream, getBufferSize());
-		} catch (LineUnavailableException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+		connect(masterStream, getBufferSize());
+
 		sendEvents = true;
 	}
 
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Fri Sep 26 11:21:24 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Fri Sep 26 11:51:32 2008 -0400
@@ -53,7 +53,6 @@
 import javax.sound.sampled.Clip;
 import javax.sound.sampled.Control;
 import javax.sound.sampled.DataLine;
-import javax.sound.sampled.FloatControl;
 import javax.sound.sampled.Line;
 import javax.sound.sampled.LineEvent;
 import javax.sound.sampled.LineListener;
@@ -407,20 +406,30 @@
 				break;
 			}
 		}
-		if(masterStream == null) {
-			//for now, can't synchronize lines if none of them is open (no stream pointer to pass)
-			//will see what to do about this later
+		if (masterStream == null) {
+			// for now, can't synchronize lines if none of them is open (no
+			// stream pointer to pass)
+			// will see what to do about this later
 			throw new IllegalArgumentException();
 		}
-		
-		for(Line line : lines) {
-			if(line != masterStream) {
-			
-					((PulseAudioDataLine) line).reconnectforSynchronization(((PulseAudioDataLine) masterStream).getStream());
-				
+
+		try {
+
+			for (Line line : lines) {
+				if (line != masterStream) {
+
+					((PulseAudioDataLine) line)
+							.reconnectforSynchronization(((PulseAudioDataLine) masterStream)
+									.getStream());
+
+				}
 			}
+		} catch (LineUnavailableException e) {
+			// we couldn't reconnect, so tell the user we failed by throwing an
+			// exception
+			throw new IllegalArgumentException(e);
 		}
-	
+
 	}
 
 	@Override
@@ -466,7 +475,7 @@
 		synchronized (lineListeners) {
 			lineListeners.clear();
 		}
-		
+
 		refreshSourceAndTargetLines();
 
 	}
@@ -655,7 +664,7 @@
 	public static void debug(String string) {
 		System.out.println("DEBUG: " + string);
 	}
-	
+
 	public static void main(String[] args) throws Exception {
 		Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo();
 		Mixer.Info selectedMixerInfo = null;
@@ -685,18 +694,17 @@
 		line2 = (PulseAudioSourceDataLine) mixer.getLine(new Line.Info(
 				SourceDataLine.class));
 		line2.setName("Line 2");
-		
 
 		ThreadWriter writer1 = mixer.new ThreadWriter(line1, fileName1);
 		ThreadWriter writer2 = mixer.new ThreadWriter(line2, fileName2);
-		//line2.start();
-	//	line1.start();
-		
+		// line2.start();
+		// line1.start();
+
 		Line[] lines = { line1, line2 };
 		mixer.synchronize(lines, true);
-		
-	//	line2.stop();
-		
+
+		// line2.stop();
+
 		debug("PulseAudioMixer: " + line1.getName() + " and " + line2.getName()
 				+ " synchronized");
 		writer1.start();
@@ -704,8 +712,8 @@
 
 		debug("PulseAudioMixer: writers started");
 		line2.start();
-		//line1.stop();
-		//line1.start();
+		// line1.stop();
+		// line1.start();
 		debug("PulseAudioMixer: Started a line");
 
 		writer1.join();
@@ -743,8 +751,8 @@
 		public void run() {
 			debug("PulseAudioMixer: ThreadWriter: run(): entering");
 
-			//line.start();
-			//debug("PulseAudioMixer: " + line.getName() + " started");
+			// line.start();
+			// debug("PulseAudioMixer: " + line.getName() + " started");
 
 			byte[] abData = new byte[1000];
 			int bytesRead = 0;
@@ -753,8 +761,9 @@
 					bytesRead = audioInputStream.read(abData, 0, abData.length);
 					if (bytesRead > 0) {
 						line.write(abData, 0, bytesRead);
-						//debug("PulseAudioMixer: wrote " + bytesRead + "data on "
-						//		+ line.getName());
+						// debug("PulseAudioMixer: wrote " + bytesRead + "data
+						// on "
+						// + line.getName());
 					}
 				}
 			} catch (IOException e) {
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Fri Sep 26 11:21:24 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Fri Sep 26 11:51:32 2008 -0400
@@ -44,8 +44,6 @@
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.SourceDataLine;
 
-import org.classpath.icedtea.pulseaudio.Stream.WriteListener;
-
 public class PulseAudioSourceDataLine extends PulseAudioDataLine implements
 		SourceDataLine, PulseAudioPlaybackLine {
 
@@ -53,7 +51,6 @@
 	private PulseAudioVolumeControl volumeControl;
 	private boolean muted;
 	private float volume;
-	private int bytesAvailableToWrite;
 
 	private long currentFramePosition = 0;
 
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Fri Sep 26 11:21:24 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Fri Sep 26 11:51:32 2008 -0400
@@ -60,6 +60,7 @@
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class PulseAudioSourceDataLineTest {
@@ -334,7 +335,6 @@
 
 		sourceDataLine.start();
 
-
 		Thread.sleep(2000);
 
 		// System.out.println("waiting for thread to finish");
@@ -980,6 +980,87 @@
 
 	}
 
+	public static void debug(String string) {
+		System.out.println("DEBUG: " + string);
+	}
+
+	@Ignore
+	@Test
+	public void testSynchronization() throws Exception {
+		Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo();
+		Mixer.Info selectedMixerInfo = null;
+		// int i = 0;
+		for (Mixer.Info info : mixerInfos) {
+			// System.out.println("Mixer Line " + i++ + ": " + info.getName() +
+			// " " + info.getDescription());
+			if (info.getName().contains("PulseAudio")) {
+				selectedMixerInfo = info;
+				System.out.println(selectedMixerInfo);
+			}
+		}
+
+		PulseAudioMixer mixer = (PulseAudioMixer) AudioSystem
+				.getMixer(selectedMixerInfo);
+
+		mixer.open();
+
+		String fileName1 = "testsounds/startup.wav";
+		File soundFile1 = new File(fileName1);
+		AudioInputStream audioInputStream1 = AudioSystem
+				.getAudioInputStream(soundFile1);
+
+		PulseAudioSourceDataLine line1;
+		line1 = (PulseAudioSourceDataLine) mixer.getLine(new Line.Info(
+				SourceDataLine.class));
+		line1.setName("Line 1");
+
+		String fileName2 = "testsounds/logout.wav";
+		File soundFile = new File(fileName2);
+		AudioInputStream audioInputStream2 = AudioSystem
+				.getAudioInputStream(soundFile);
+
+		PulseAudioSourceDataLine line2;
+		line2 = (PulseAudioSourceDataLine) mixer.getLine(new Line.Info(
+				SourceDataLine.class));
+		line2.setName("Line 2");
+
+		ThreadWriter writer1 = new ThreadWriter(audioInputStream1, line1);
+		ThreadWriter writer2 = new ThreadWriter(audioInputStream2, line2);
+		// line2.start();
+		// line1.start();
+
+		Line[] lines = { line1, line2 };
+		mixer.synchronize(lines, true);
+
+		// line2.stop();
+
+		debug("PulseAudioMixer: " + line1.getName() + " and " + line2.getName()
+				+ " synchronized");
+		writer1.start();
+		writer2.start();
+
+		debug("PulseAudioMixer: writers started");
+		line2.start();
+		// line1.stop();
+		// line1.start();
+		debug("PulseAudioMixer: Started a line");
+
+		writer1.join();
+		writer2.join();
+
+		debug("PulseAudioMixer: both lines joined");
+
+		line2.close();
+		debug("PulseAudioMixer: " + line2.getName() + " closed");
+
+		line1.close();
+		debug("PulseAudioMixer: " + line1.getName() + " closed");
+
+		mixer.close();
+		debug("PulseAudioMixer: mixer closed");
+
+	}
+
 	@After
 	public void tearDown() throws Exception {
 		started = 0;