changeset 47:2785b9eba70d

Added support for querying the audio formats available to pulseaudio and obtaining a line based on those formats also added test cases
author Omair Majid <omajid@redhat.com>
date Fri, 08 Aug 2008 11:11:03 -0400
parents 2331da2e5f6a
children f27fbf96d5aa
files src/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java src/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java src/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java
diffstat 5 files changed, 307 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Wed Aug 06 16:30:43 2008 -0400
+++ b/src/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Fri Aug 08 11:11:03 2008 -0400
@@ -48,6 +48,7 @@
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
 import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
 import javax.sound.sampled.Line;
 import javax.sound.sampled.LineEvent;
 import javax.sound.sampled.LineListener;
@@ -71,8 +72,6 @@
 	private List<PulseAudioSourceDataLine> sourceLines = new ArrayList<PulseAudioSourceDataLine>();
 	// private List<PulseAudioTargetDataLine> targetLines = null;
 
-	private Line.Info sourceDataLineInfo = new Line.Info(
-			PulseAudioSourceDataLine.class);
 	// private Line.Info targetDataLineInfo = new
 	// Line.Info(PulseAudioTargetDataLine.class);
 
@@ -99,11 +98,14 @@
 			throw new LineUnavailableException();
 		}
 
-		if (info.matches(sourceDataLineInfo)) {
-			PulseAudioSourceDataLine sourceLine = null;
-			sourceLine = new PulseAudioSourceDataLine(eventLoop);
-			sourceLines.add(sourceLine);
-			return sourceLine;
+		PulseAudioSourceDataLine sourceLine = null;
+		sourceLine = new PulseAudioSourceDataLine(eventLoop);
+		Line.Info sourceDataLineInfo = sourceLine.getLineInfo();
+		if (info instanceof DataLine.Info) {
+			if (info.matches(sourceDataLineInfo)) {
+				sourceLines.add(sourceLine);
+				return sourceLine;
+			}
 		}
 
 		// if (info.matches(_targetDataLineInfo)) {
@@ -127,8 +129,14 @@
 
 	@Override
 	public javax.sound.sampled.Line.Info[] getSourceLineInfo() {
-		Line.Info[] info = { new Line.Info(PulseAudioSourceDataLine.class), };
-		return info;
+		if (isOpen) {
+			SourceDataLine sourceLine = new PulseAudioSourceDataLine(eventLoop);
+			Line.Info[] info = new Line.Info[] { sourceLine.getLineInfo() };
+			return info;
+		}
+
+		// if not open, then return empty array
+		return new Line.Info[] {};
 	}
 
 	@Override
@@ -347,7 +355,7 @@
 		eventLoopThread.start();
 
 		try {
-//			System.out.println("waiting...");
+			// System.out.println("waiting...");
 			ready.acquire();
 			if (eventLoop.getStatus() != 4) {
 				/*
@@ -362,12 +370,13 @@
 				throw new LineUnavailableException();
 			}
 			eventLoop.removeContextListener(initListener);
-//			System.out.println("got signal");
+			// System.out.println("got signal");
 		} catch (InterruptedException e) {
-			System.out.println("PulseAudioMixer: got interrupted while waiting for the EventLoop to initialize");
+			System.out
+					.println("PulseAudioMixer: got interrupted while waiting for the EventLoop to initialize");
 		}
 
-//		System.out.println(this.getClass().getName() + ": ready");
+		// System.out.println(this.getClass().getName() + ": ready");
 
 		this.isOpen = true;
 
--- a/src/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Wed Aug 06 16:30:43 2008 -0400
+++ b/src/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Fri Aug 08 11:11:03 2008 -0400
@@ -39,22 +39,29 @@
 
 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.AudioFormat;
+import javax.sound.sampled.AudioSystem;
 import javax.sound.sampled.BooleanControl;
 import javax.sound.sampled.Control;
-import javax.sound.sampled.Line;
+import javax.sound.sampled.DataLine;
 import javax.sound.sampled.LineEvent;
 import javax.sound.sampled.LineListener;
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.AudioFormat.Encoding;
 import javax.sound.sampled.Control.Type;
 
 public class PulseAudioSourceDataLine implements SourceDataLine {
 
 	private static final int DEFAULT_BUFFER_SIZE = 1000;
+	private static final String PULSEAUDIO_FORMAT_KEY = "PulseAudioFormatKey";
+
 	private String streamName = "Java Stream";
 	private List<StreamListener> streamListeners = new ArrayList<StreamListener>();
 
@@ -63,7 +70,8 @@
 	private boolean isOpen = false;
 	private boolean isPaused = false;
 
-	private AudioFormat format = null;
+	private List<AudioFormat> supportedFormats = null;
+	private AudioFormat currentFormat = null;
 
 	private Control[] controls;
 	private Mute muteControl;
@@ -79,9 +87,8 @@
 	@SuppressWarnings("unused")
 	private long streamPointer;
 
-	private native void native_open(long contextPointer, String name,
-			String encoding, float rate, int size, int channels,
-			boolean bigEndian, int bufferSize);
+	private native void native_open(long contextPointer, String streamName,
+			String encoding, int sampleRate, int channels, int bufferSize);
 
 	private native void native_write(byte[] data, int offset, int length);
 
@@ -113,6 +120,9 @@
 			assert ("Loading failed".endsWith("library"));
 		}
 	}
+	
+	
+	
 
 	public PulseAudioSourceDataLine(EventLoop eventLoop) {
 		this.eventLoop = eventLoop;
@@ -121,6 +131,189 @@
 		volumeControl = new StreamVolume(this);
 		muteControl = new Mute();
 		controls = new Control[] { volumeControl, muteControl };
+
+		/*
+		 * 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;
+
 	}
 
 	public void open(AudioFormat format, int bufferSize)
@@ -128,19 +321,23 @@
 		if (isOpen) {
 			throw new IllegalStateException("Line is already open");
 		}
-
-		isOpen = true;
+		
+		// ignore suggested buffer size
 
-		int channels = format.getChannels();
-		float rate = format.getSampleRate();
-		int sampleSize = format.getSampleSizeInBits();
-		String encoding = format.getEncoding().toString();
-		boolean bigEndian = format.isBigEndian();
+		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;
+				return;
+			}
+		}
 
-		synchronized (eventLoop.threadLock) {
-			native_open(eventLoop.getContextPointer(), streamName, encoding,
-					rate, sampleSize, channels, bigEndian, bufferSize);
-		}
+		throw new IllegalArgumentException("invalid format");
+
 	}
 
 	public void open(AudioFormat format) throws LineUnavailableException {
@@ -149,7 +346,9 @@
 	}
 
 	public void open() throws LineUnavailableException {
-		format = new AudioFormat(44100, 16, 2, true, false);
+		// pick a random format
+		AudioFormat format = new AudioFormat(Encoding.PCM_UNSIGNED, 22050, 8,
+				2, 2, AudioSystem.NOT_SPECIFIED, false);
 		open(format, DEFAULT_BUFFER_SIZE);
 	}
 
@@ -260,6 +459,8 @@
 	};
 
 	public void close() {
+		assert (isOpen);
+
 		synchronized (eventLoop.threadLock) {
 			native_close();
 		}
@@ -271,13 +472,12 @@
 	}
 
 	public int getBufferSize() {
-		// TODO Auto-generated method stub
-		return 0;
+		// FIXME!
+		return 10000;
 	}
 
 	public AudioFormat getFormat() {
-		// TODO Auto-generated method stub
-		return null;
+		return currentFormat;
 	}
 
 	public int getFramePosition() {
@@ -300,6 +500,7 @@
 		return 0;
 	}
 
+	
 	public boolean isActive() {
 		// TODO Auto-generated method stub
 		return false;
@@ -312,7 +513,7 @@
 
 	public Control getControl(Type control) {
 		for (int i = 0; i < controls.length; i++) {
-			if (controls[i].getType() == control){
+			if (controls[i].getType() == control) {
 				return controls[i];
 			}
 		}
@@ -324,7 +525,8 @@
 	}
 
 	public javax.sound.sampled.Line.Info getLineInfo() {
-		return new Line.Info(SourceDataLine.class);
+		return new DataLine.Info(SourceDataLine.class,
+				supportedFormats.toArray(new AudioFormat[0]), 0, 100000);
 	}
 
 	public boolean isControlSupported(Type control) {
--- a/src/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c	Wed Aug 06 16:30:43 2008 -0400
+++ b/src/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c	Fri Aug 08 11:11:03 2008 -0400
@@ -98,14 +98,13 @@
 	return;
 
 }
-
 /*
  * Class:     org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine
  * Method:    native_open
- * Signature: (JLjava/lang/String;Ljava/lang/String;FIIZI)V
+ * Signature: (JLjava/lang/String;Ljava/lang/String;III)V
  */
 JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine_native_1open
-(JNIEnv* env, jobject obj, jlong contextPointer, jstring name, jstring encodingString, jfloat rate, jint size, jint channels, jboolean bigEndian, jint bufferSize) {
+(JNIEnv* env, jobject obj, jlong contextPointer, jstring name, jstring encodingString, jint sampleRate, jint channels, jint bufferSize) {
 
 	//TODO: Need to deal with the buffer size. Currently ignored
 
@@ -121,33 +120,44 @@
 
 	const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL);
 
-	if( (strcmp(encoding, "PCM_UNSIGNED") == 0) && (size == 8)) {
+	if (strcmp(encoding, "PA_SAMPLE_U8") == 0) {
 		sample_spec.format = PA_SAMPLE_U8;
-	} else if( (strcmp(encoding, "ALAW") == 0) && (size == 8)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_ALAW") == 0) {
 		sample_spec.format = PA_SAMPLE_ALAW;
-	} else if( (strcmp(encoding, "ULAW") == 0) && (size == 8)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_ULAW;") == 0) {
 		sample_spec.format = PA_SAMPLE_ULAW;
-	} else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 16) && (bigEndian == 1)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_S16BE") == 0) {
 		sample_spec.format = PA_SAMPLE_S16BE;
-	} else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 16) && (bigEndian == 0)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_S16LE") == 0) {
 		sample_spec.format = PA_SAMPLE_S16LE;
-	} else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 32) && (bigEndian == 1)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_S32BE") == 0) {
 		sample_spec.format = PA_SAMPLE_S32BE;
-	} else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 32) && (bigEndian == 0)) {
+	} else if (strcmp(encoding, "PA_SAMPLE_S32LE") == 0) {
 		sample_spec.format = PA_SAMPLE_S32LE;
 	} else {
-		printf("error in open\n");
+		printf("error in open: encoding is : %s\n", encoding);
 		throwByName(env, "IllegalArgumentException", "Invalid format");
 		/* clean up */
 		free(java_context);
+		(*env)->DeleteGlobalRef(env, obj);
+		(*env)->ReleaseStringUTFChars(env, encodingString, encoding);
+		return;
+	}
+
+	sample_spec.rate = sampleRate;
+	sample_spec.channels = channels;
+
+	if ( !pa_sample_spec_valid(&sample_spec)) {
+		throwByName(env, "IllegalArgumentException", "Invalid format");
+		/* clean up */
+		free(java_context);
+		(*env)->DeleteGlobalRef(env, obj);
+		(*env)->ReleaseStringUTFChars(env, encodingString, encoding);
 		return;
 	}
 
 	(*env)->ReleaseStringUTFChars(env, encodingString, encoding);
 
-	sample_spec.rate = rate;
-	sample_spec.channels = channels;
-
 	/* obtain the server from the caller */
 	const char* stream_name = NULL;
 	stream_name = (*env)->GetStringUTFChars(env, name, NULL);
@@ -161,6 +171,7 @@
 
 	pa_stream_set_state_callback(stream, stream_state_change_callback, java_context);
 
+	//	printf("seeting stream pointer: %d\n", (int)stream);
 	setJavaPointer(env, obj, "streamPointer", stream);
 	//	printf("returning from native_open\n");
 
@@ -191,6 +202,7 @@
 (JNIEnv* env, jobject obj) {
 
 	pa_stream *stream = (pa_stream*) getJavaPointer(env, obj, "streamPointer");
+	assert(stream);
 	int available = pa_stream_writable_size(stream);
 	return available;
 }
@@ -229,6 +241,7 @@
 JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine_native_1start
 (JNIEnv *env, jobject obj) {
 	pa_stream *stream = (pa_stream*)getJavaPointer(env, obj, "streamPointer");
+	assert(stream);
 	pa_stream_connect_playback(stream, NULL, NULL, 0, NULL, NULL);
 
 }
@@ -261,6 +274,7 @@
 JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine_native_1drain
 (JNIEnv* env, jobject obj) {
 	pa_stream *stream = (pa_stream*) getJavaPointer(env, obj, "streamPointer");
+	assert(stream);
 	pa_operation *o = pa_stream_drain(stream, NULL, NULL);
 	return (int) o;
 }
@@ -273,7 +287,8 @@
 JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine_native_1close
 (JNIEnv* env, jobject obj) {
 
-	pa_stream *stream = (pa_stream*) getJavaPointer(env, obj, "streamPointer");
+	pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, "streamPointer");
+	assert(stream);
 	pa_operation *o = pa_stream_drain(stream, stream_drain_complete_callback, NULL);
 	if (o == NULL) {
 		pa_stream_disconnect(stream);
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Wed Aug 06 16:30:43 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Fri Aug 08 11:11:03 2008 -0400
@@ -170,12 +170,15 @@
 
 	@Test
 	public void testSourceLinesOpenAndClose() throws LineUnavailableException {
+		System.out.println("This test checks if source lines open and close");
 		selectedMixer.open();
 		Line.Info allLineInfo[] = selectedMixer.getSourceLineInfo();
 		for (Line.Info lineInfo : allLineInfo) {
 			SourceDataLine sourceDataLine = (SourceDataLine) selectedMixer
 					.getLine(lineInfo);
+			System.out.println("opening line");
 			sourceDataLine.open();
+			System.out.println("closing line");
 			sourceDataLine.close();
 		}
 	}
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Wed Aug 06 16:30:43 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Fri Aug 08 11:11:03 2008 -0400
@@ -33,18 +33,17 @@
 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 org.classpath.icedtea.pulseaudio;
 
-
 import java.io.File;
 import java.io.IOException;
 
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.Line;
+import javax.sound.sampled.DataLine;
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.Mixer;
 import javax.sound.sampled.SourceDataLine;
@@ -57,30 +56,34 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import org.classpath.icedtea.pulseaudio.PulseAudioMixer;
-
 public class PulseSourceDataLineTest {
 	Mixer mixer;
-	SourceDataLine line;
-	
-	public static junit.framework.Test suite() { 
-	    return new JUnit4TestAdapter(PulseSourceDataLineTest.class); 
+
+	public static junit.framework.Test suite() {
+		return new JUnit4TestAdapter(PulseSourceDataLineTest.class);
 	}
-	
+
 	@Before
 	public void setUp() throws Exception {
 		mixer = PulseAudioMixer.getInstance();
 		mixer.open();
-		line = (PulseAudioSourceDataLine) mixer.getLine(new Line.Info(PulseAudioSourceDataLine.class));
-		Assert.assertNotNull(line);
-		
+
 	}
-	
+
 	@Test
-	public void testPlay() throws LineUnavailableException, UnsupportedAudioFileException, IOException {
+	public void testPlay() throws LineUnavailableException,
+			UnsupportedAudioFileException, IOException {
 		File soundFile = new File("testsounds/startup.wav");
-		AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
+		AudioInputStream audioInputStream = AudioSystem
+				.getAudioInputStream(soundFile);
 		AudioFormat audioFormat = audioInputStream.getFormat();
+		
+		SourceDataLine line;
+		line = (PulseAudioSourceDataLine) mixer.getLine(new DataLine.Info(
+				SourceDataLine.class, audioFormat));
+		Assert.assertNotNull(line);
+
+
 		line.open(audioFormat);
 		line.start();
 
@@ -100,33 +103,18 @@
 	}
 
 	@Test
-	public void testPlayLoud() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
-		File soundFile = new File("testsounds/startup.wav");
-		AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
-		AudioFormat audioFormat = audioInputStream.getFormat();
-		line.open(audioFormat);
-		
-	
-		line.start();
-
-		byte[] abData = new byte[1000];
-		int bytesRead = 0;
+	public void testFindLineWithFormat() throws LineUnavailableException {
+		SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info(
+				SourceDataLine.class, new AudioFormat(
+						AudioFormat.Encoding.PCM_UNSIGNED, 44100, 8, 1, 1, 10,
+						true)));
+		line.open();
 
-		while (bytesRead >= 0) {
-			bytesRead = audioInputStream.read(abData, 0, abData.length);
-			if (bytesRead > 0) {
-				line.write(abData, 0, bytesRead);
-			}
-		}
+	}
 
-		line.flush();
-		line.close();
-		
-	}
-	
 	@After
 	public void tearDown() throws Exception {
-		
+
 		mixer.close();
 	}