changeset 59:03d5da3409ac

2008-08-11 Omair Majid <omajid@redhat.com> * src/java/org/classpath/icedtea/pulseaudio/EventLoop.java: fixed library path * src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java: added support for finding a DataLine with the last valid format in the list of valid formats asked for * src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java: added a default format for each line which will be used for doing a simple open(). spacing changes (used ctrl+shift+f in eclipse) * src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c: fixed the execption class that was being thrown incase of an incorrect sample specification (aka audio format) * unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java: added a note to explain that a test is currently failing * unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java: slightly modified the audio format tests to print out more info
author Omair Majid <omajid@redhat.com>
date Mon, 11 Aug 2008 16:49:26 -0400
parents 6d8250e41a44
children e77e418081f7
files src/java/org/classpath/icedtea/pulseaudio/EventLoop.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java
diffstat 6 files changed, 127 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java	Mon Aug 11 14:40:43 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java	Mon Aug 11 16:49:26 2008 -0400
@@ -103,17 +103,15 @@
 	 */
 
 	static {
-		//try {
-			/*String library = new java.io.File(".").getCanonicalPath()
-					+ java.io.File.separatorChar + "lib"
+		try {
+			String library = new java.io.File(".").getCanonicalPath()
 					+ java.io.File.separatorChar
-					+ System.mapLibraryName("pulse-java");*/
-			String library = "/home/yyz/iivan/workspace/pulseaudio/lib/libpulse-java.so";
+					+ System.mapLibraryName("pulse-java");
 			System.out.println(library);
 			System.load(library);
-		/*} catch (IOException e) {
+		} catch (IOException e) {
 			assert ("Loading failed".endsWith("library"));
-		}*/
+		}
 	}
 
 	private EventLoop() {
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Mon Aug 11 14:40:43 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Mon Aug 11 16:49:26 2008 -0400
@@ -103,14 +103,40 @@
 		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 (DataLine.class.isAssignableFrom(info.getLineClass())
+				&& info instanceof DataLine.Info) {
+			System.out
+					.println("DEBUG: trying to find data line with last matching format");
+
+			DataLine.Info dataLineInfo = (DataLine.Info) info;
+			// need to find the DataLine with the last valid format
+			AudioFormat[] wantedFormats = dataLineInfo.getFormats();
+			AudioFormat[] availableFormats = ((DataLine.Info) sourceDataLineInfo)
+					.getFormats();
+			for (int i = wantedFormats.length - 1; i > -1; i--) {
+				for (AudioFormat aFormat : availableFormats) {
+					if (wantedFormats[i].matches(aFormat)) {
+						System.out.println("DEBUG: found a matching format");
+						System.out.println("wanted: " + wantedFormats[i]);
+						System.out.println("available: " + aFormat);
+						sourceLine.setDefaultFormat(wantedFormats[i]);
+						sourceLines.add(sourceLine);
+						return sourceLine;
+					}
+				}
 			}
-		}*/
-		
-		return sourceLine;
+
+			System.out.println("DEBUG: no matches found");
+			// no format matches, so return any line
+			throw new IllegalArgumentException("No matching format found");
+
+		}
+
+		if (info.matches(sourceDataLineInfo)) {
+			sourceLines.add(sourceLine);
+			return sourceLine;
+		}
 
 		// if (info.matches(_targetDataLineInfo)) {
 		// PulseAudioTargetDataLine targetLine = new PulseAudioTargetDataLine();
@@ -118,7 +144,7 @@
 		// return targetLine;
 		// }
 
-		//throw new IllegalArgumentException();
+		throw new IllegalArgumentException();
 	}
 
 	@Override
@@ -430,21 +456,24 @@
 
 		System.out.println("got a line");
 
-		//File soundFile = new File(new java.io.File(".").getCanonicalPath() + "/testsounds/logout.wav");
-		File soundFile = new File( "/home/iivan/workspace/pulseaudio/testsounds/logout.wav");
+		// File soundFile = new File(new java.io.File(".").getCanonicalPath() +
+		// "/testsounds/logout.wav");
+		File soundFile = new File(
+				"/home/iivan/workspace/pulseaudio/testsounds/logout.wav");
 		AudioInputStream audioInputStream = AudioSystem
 				.getAudioInputStream(soundFile);
 		AudioFormat audioFormat = audioInputStream.getFormat();
 		line.open(audioFormat);
 		line.start();
-		PulseAudioStreamVolumeControl control = (PulseAudioStreamVolumeControl) line.getControl(FloatControl.Type.VOLUME);
-		PulseAudioStreamMuteControl mute = (PulseAudioStreamMuteControl) line.getControl(BooleanControl.Type.MUTE);
+		PulseAudioStreamVolumeControl control = (PulseAudioStreamVolumeControl) line
+				.getControl(FloatControl.Type.VOLUME);
+		PulseAudioStreamMuteControl mute = (PulseAudioStreamMuteControl) line
+				.getControl(BooleanControl.Type.MUTE);
 		mute.setValue(true);
 		control.setValue(40000);
 		mute.setValue(false);
 		System.out.println("Volume set to " + control.getValue());
-	
-		
+
 		byte[] abData = new byte[1000];
 		int bytesRead = 0;
 
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Mon Aug 11 14:40:43 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Mon Aug 11 16:49:26 2008 -0400
@@ -72,9 +72,10 @@
 
 	private List<AudioFormat> supportedFormats = null;
 	private AudioFormat currentFormat = null;
+	private AudioFormat defaultFormat = null;
 
 	private List<LineListener> listeners;
-	
+
 	private Control[] controls = new Control[2];
 	private PulseAudioStreamMuteControl muteControl;
 	private PulseAudioStreamVolumeControl volumeControl;
@@ -121,19 +122,11 @@
 
 	}
 
-	
-	
-	
-	
-
-
 	public PulseAudioSourceDataLine(EventLoop eventLoop) {
 		this.eventLoop = eventLoop;
 		this.listeners = new ArrayList<LineListener>();
 		this.volume = 65536;
 
-
-
 		/*
 		 * FIXME puselaudio supports any sample rate (it can covert between
 		 * sample rates without a problem). it calculates the frame size and the
@@ -150,9 +143,9 @@
 		 * 
 		 * 
 		 */
-		
+
 		supportedFormats = new LinkedList<AudioFormat>();
-		
+
 		Map<String, Object> properties;
 
 		int[] channelSizes = new int[] { 1, 2, 5 };
@@ -165,8 +158,7 @@
 			// as soon as they change something
 			// FIXME ^
 			int sampleSize = 8; // in bits
-			AudioFormat PA_SAMPLE_U8 = new AudioFormat(
-					Encoding.PCM_UNSIGNED, // encoding
+			AudioFormat PA_SAMPLE_U8 = new AudioFormat(Encoding.PCM_UNSIGNED, // encoding
 					AudioSystem.NOT_SPECIFIED, // sample rate
 					sampleSize, // sample size
 					channelSize, // channels
@@ -316,32 +308,31 @@
 
 		currentFormat = null;
 
-
 	}
 
 	protected boolean isMuted() {
 		return muted;
 	}
-	
+
 	protected void setMuted(boolean value) {
 		muted = value;
 	}
-	
+
 	protected float getVolume() {
 		return this.volume;
 	}
-	
+
 	protected void setVolume(float value) {
 		this.volume = value;
-		
+
 	}
-	
+
 	public void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
 		if (isOpen) {
 			throw new IllegalStateException("Line is already open");
 		}
-		
+
 		// ignore suggested buffer size
 
 		for (AudioFormat myFormat : supportedFormats) {
@@ -354,8 +345,10 @@
 				isOpen = true;
 			}
 		}
-
-		//throw new IllegalArgumentException("invalid format");
+		// no matches found
+		if (!isOpen) {
+			throw new IllegalArgumentException("Invalid format");
+		}
 
 		final Semaphore semaphore = new Semaphore(0);
 
@@ -383,7 +376,7 @@
 			// stream");
 		}
 		System.out.println(this.getClass().getName() + "stream is ready");
-		
+
 		volumeControl = new PulseAudioStreamVolumeControl(this);
 		controls[0] = volumeControl;
 		muteControl = new PulseAudioStreamMuteControl(this);
@@ -398,9 +391,12 @@
 
 	public void open() throws LineUnavailableException {
 		// pick a random format
-		AudioFormat format = new AudioFormat(Encoding.PCM_UNSIGNED, 22050, 8,
-				2, 2, AudioSystem.NOT_SPECIFIED, false);
-		open(format, DEFAULT_BUFFER_SIZE);
+		if (defaultFormat == null) {
+			defaultFormat = new AudioFormat(Encoding.PCM_UNSIGNED, 22050, 8, 2,
+					2, AudioSystem.NOT_SPECIFIED, false);
+		}
+		
+		open(defaultFormat, DEFAULT_BUFFER_SIZE);
 	}
 
 	@Override
@@ -443,16 +439,16 @@
 	}
 
 	public void start() {
-			if (isPaused) {
-				native_resume();
-				isPaused = false;
-			}
+		if (isPaused) {
+			native_resume();
+			isPaused = false;
+		}
 
 		/*
 		 * for(LineListener l :listeners) { l.update(new LineEvent(this,
 		 * LineEvent.Type.START, 0)); }
 		 */
-	
+
 	}
 
 	public void stop() {
@@ -507,6 +503,14 @@
 		return currentFormat;
 	}
 
+	public void setDefaultFormat(AudioFormat format) {
+		for (AudioFormat aFormat : supportedFormats) {
+			if (format.matches(aFormat)) {
+				defaultFormat = format;
+			}
+		}
+	}
+
 	public int getFramePosition() {
 		// TODO Auto-generated method stub
 		return 0;
@@ -527,7 +531,6 @@
 		return 0;
 	}
 
-	
 	public boolean isActive() {
 		// TODO Auto-generated method stub
 		return false;
@@ -540,7 +543,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];
 			}
@@ -553,8 +556,8 @@
 	}
 
 	public javax.sound.sampled.Line.Info getLineInfo() {
-		return new DataLine.Info(SourceDataLine.class,
-				supportedFormats.toArray(new AudioFormat[0]), 0, 100000);
+		return new DataLine.Info(SourceDataLine.class, supportedFormats
+				.toArray(new AudioFormat[0]), 0, 100000);
 	}
 
 	public boolean isControlSupported(Type control) {
@@ -570,7 +573,7 @@
 			operation = new Operation(native_drain());
 			operationState = operation.getState();
 		}
-		
+
 		// FIXME need to find a way to do a wait than a busy loop
 		while (operationState != Operation.State.Done) {
 			synchronized (eventLoop.threadLock) {
@@ -595,7 +598,7 @@
 				operationState = operation.getState();
 			}
 		}
-		
+
 		operation.releaseReference();
 
 	}
@@ -629,12 +632,10 @@
 			streamListener.update(e);
 		}
 	}
-	
+
 	protected EventLoop getEventLoop() {
 		return this.eventLoop;
 	}
-	
-
 
 	public long getStreamPointer() {
 		return streamPointer;
--- a/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c	Mon Aug 11 14:40:43 2008 -0400
+++ b/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourceDataLine.c	Mon Aug 11 16:49:26 2008 -0400
@@ -136,7 +136,7 @@
 		sample_spec.format = PA_SAMPLE_S32LE;
 	} else {
 		printf("error in open: encoding is : %s\n", encoding);
-		throwByName(env, "IllegalArgumentException", "Invalid format");
+		throwByName(env, "java/lang/IllegalArgumentException", "Invalid format");
 		/* clean up */
 		free(java_context);
 		(*env)->DeleteGlobalRef(env, obj);
@@ -144,11 +144,18 @@
 		return;
 	}
 
+	
 	sample_spec.rate = sampleRate;
 	sample_spec.channels = channels;
 
+	printf("sample_spec.rate = %d\n", sample_spec.rate);
+	printf("sample_spec.channels = %d\n", sample_spec.channels);
+	
+	
+	
 	if ( !pa_sample_spec_valid(&sample_spec)) {
-		throwByName(env, "IllegalArgumentException", "Invalid format");
+		printf("error: invalid format\n");
+		throwByName(env, "java/lang/IllegalArgumentException", "Invalid format");
 		/* clean up */
 		free(java_context);
 		(*env)->DeleteGlobalRef(env, obj);
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Mon Aug 11 14:40:43 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Mon Aug 11 16:49:26 2008 -0400
@@ -172,6 +172,16 @@
 	public void testSourceLinesOpenAndClose() throws LineUnavailableException {
 		System.out.println("This test checks if source lines open and close");
 		selectedMixer.open();
+		
+		
+		/*
+		 * FIXME 
+		 * This test currently fails. The mixer returns information about the line
+		 * which leaves a lot of things as NOT_SPECIFIED
+		 * when using that to do a get line, things match, and the line returned
+		 * still has a few parameters as NOT_SPECIFIED and doing an open() on that fails
+		 * 
+		 */
 		Line.Info allLineInfo[] = selectedMixer.getSourceLineInfo();
 		for (Line.Info lineInfo : allLineInfo) {
 			SourceDataLine sourceDataLine = (SourceDataLine) selectedMixer
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Mon Aug 11 14:40:43 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Mon Aug 11 16:49:26 2008 -0400
@@ -106,24 +106,29 @@
 
 	@Test
 	public void testFindLineWithFormat() throws LineUnavailableException {
+		System.out.println("This test tries to find a line with a valid format");
+		AudioFormat wantedFormat = new AudioFormat(
+				AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 10, true);
+		System.out.println(wantedFormat);
+		SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info(
+				SourceDataLine.class, wantedFormat));
+		line.open();
+		System.out.println(line.getFormat());
+
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testFindLineWithWrongFormat() throws LineUnavailableException {
+		System.out
+				.println("This test tries to acquire a line with incorrect format spec");
 		SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info(
 				SourceDataLine.class, new AudioFormat(
-						AudioFormat.Encoding.PCM_UNSIGNED, 44100, 8, 1, 1, 10,
-						true)));
+						AudioFormat.Encoding.PCM_UNSIGNED, 44100, 10000, 1, 13,
+						10, true)));
 		line.open();
 
 	}
 
-	@Test (expected = IllegalArgumentException.class)
-	public void testFindLineWithWrongFormat() throws LineUnavailableException {
-		SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info(
-				SourceDataLine.class, new AudioFormat(
-						AudioFormat.Encoding.PCM_UNSIGNED, 44100, 100000, 1, 1, 10,
-						true)));
-		line.open();
-
-	}
-	
 	@Test
 	public void testVolumeAndMute() throws Exception {
 		Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo();
@@ -153,10 +158,10 @@
 				.getControl(FloatControl.Type.VOLUME);
 		PulseAudioStreamMuteControl mute = (PulseAudioStreamMuteControl) line
 				.getControl(BooleanControl.Type.MUTE);
-		
+
 		mute.setValue(true);
 		volume.setValue(40000);
-		
+
 		mute.setValue(false);
 
 		byte[] abData = new byte[1000];