changeset 175:66bcf656c0fb

2008-10-08 Omair Majid <omajid@redhat.com> Merged changes
author Omair Majid <omajid@redhat.com>
date Wed, 08 Oct 2008 15:27:58 -0400
parents 4260a476a101 (current diff) 4e6c0e204d29 (diff)
children 5108fc37a890
files src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java
diffstat 4 files changed, 72 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Wed Oct 08 14:27:39 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Wed Oct 08 15:27:58 2008 -0400
@@ -95,11 +95,31 @@
 
 		for (AudioFormat myFormat : supportedFormats) {
 			if (format.matches(myFormat)) {
+				/*
+				 * A few issues with format:
+				 * 
+				 * To match: SAME encoding: safe because its a java enum. SAME
+				 * number of channels: safe because myFormat has specific
+				 * values. SAME bits per sample (aka sampleSize) and bytes per
+				 * frame (aka frameSize): safe because myFormat has specific
+				 * values. SAME sample rate: _not_ safe because myFormat uses
+				 * AudioSystem.NOT_SPECIFIED. SAME frame rate: safe because we
+				 * _ignore_ it completely ;)
+				 * 
+				 * 
+				 */
+
+				float sampleRate = format.getSampleRate();
+				if (sampleRate == (float) AudioSystem.NOT_SPECIFIED) {
+					/* pick a random sample rate */
+					sampleRate = 44100.0f;
+				}
+
 				synchronized (eventLoop.threadLock) {
 					stream = new Stream(eventLoop.getContextPointer(),
 							streamName, Stream.Format.valueOf((String) myFormat
 									.getProperty(PULSEAUDIO_FORMAT_KEY)),
-							(int) format.getSampleRate(), format.getChannels());
+							(int) sampleRate, myFormat.getChannels());
 
 				}
 				currentFormat = format;
@@ -372,7 +392,9 @@
 	 * underrun/overflow.
 	 * 
 	 * 
-	 * HOWEVER, the javadocs say the opposite thing!
+	 * HOWEVER, the javadocs say the opposite thing! (need help from the jck =
+	 * official spec)
+	 * 
 	 * 
 	 */
 
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Wed Oct 08 14:27:39 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Wed Oct 08 15:27:58 2008 -0400
@@ -103,6 +103,8 @@
 				formats, StreamBufferAttributes.MIN_VALUE,
 				StreamBufferAttributes.MAX_VALUE));
 
+		refreshSourceAndTargetLines();
+
 	}
 
 	synchronized public static PulseAudioMixer getInstance() {
@@ -119,12 +121,21 @@
 		Map<String, Object> properties;
 
 		/*
-		 * frameSize = sample size (in bytes, not bits) x # of channels ^ From
-		 * PulseAudio's sources
+		 * frameSize = sample size (in bytes, not bits) x # of channels
+		 * 
+		 * From PulseAudio's sources
 		 * http://git.0pointer.de/?p=pulseaudio.git;a=blob;f=src/pulse/sample.c;h=93da2465f4301e27af4976e82737c3a048124a68;hb=82ea8dde8abc51165a781c69bc3b38034d62d969#l63
 		 */
 
-		int[] channelSizes = new int[] { 1, 2, 5, 6, 8 };
+		/*
+		 * technically, PulseAudio supports up to 16 channels, but things get
+		 * interesting with channel maps
+		 * 
+		 * PA_CHANNEL_MAP_DEFAULT (=PA_CHANNEL_MAP_AIFF) supports 1,2,3,4,5 or 6
+		 * channels only
+		 * 
+		 */
+		int[] channelSizes = new int[] { 1, 2, 3, 4, 5, 6 };
 		for (int channelSize : channelSizes) {
 			properties = new HashMap<String, Object>();
 			properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_U8");
@@ -252,17 +263,16 @@
 	}
 
 	@Override
-	public Line getLine(javax.sound.sampled.Line.Info info)
-			throws LineUnavailableException {
+	public Line getLine(Line.Info info) throws LineUnavailableException {
+
+		if (!isLineSupported(info)) {
+			throw new IllegalArgumentException("Line unsupported: " + info);
+		}
 
 		if (!isOpen) {
 			throw new LineUnavailableException("The mixer isnt open");
 		}
 
-		if (!isLineSupported(info)) {
-			throw new IllegalArgumentException("Line unsupported: " + info);
-		}
-
 		AudioFormat[] formats = null;
 		AudioFormat defaultFormat = null;
 
@@ -324,7 +334,7 @@
 		if (isLineSupported(info)) {
 			return AudioSystem.NOT_SPECIFIED;
 		}
-		
+
 		return 0;
 	}
 
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Wed Oct 08 14:27:39 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java	Wed Oct 08 15:27:58 2008 -0400
@@ -39,6 +39,7 @@
 
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
 import javax.sound.sampled.Line;
 import javax.sound.sampled.LineEvent;
 import javax.sound.sampled.LineListener;
@@ -60,6 +61,8 @@
 
 	AudioFormat aSupportedFormat = new AudioFormat(
 			AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 44100f, true);
+	AudioFormat aNotSupportedFormat = new AudioFormat(
+			AudioFormat.Encoding.ULAW, 44100, 32, 10, 10, 44100f, true);
 
 	@Before
 	public void setUp() throws Exception {
@@ -289,7 +292,6 @@
 			try {
 				Line sourceLine = selectedMixer.getLine(lineInfo);
 				sourceLine.open();
-				System.out.println("closing line");
 				sourceLine.close();
 			} catch (IllegalArgumentException e) {
 				// ignore this
@@ -308,15 +310,12 @@
 				TargetDataLine targetLine = (TargetDataLine) selectedMixer
 						.getLine(lineInfo);
 				Assert.assertNotNull(targetLine);
-				System.out.println("opening line");
 				targetLine.open(aSupportedFormat);
-				System.out.println("closing line");
 				targetLine.close();
 			} catch (ClassCastException cce) {
 				Port targetLine = (Port) selectedMixer.getLine(lineInfo);
 				Assert.assertNotNull(targetLine);
 				targetLine.open();
-				System.out.println("closing line");
 				targetLine.close();
 			}
 
@@ -367,6 +366,19 @@
 	}
 
 	@Test
+	public void testLineSupportedWorksWithoutOpeningMixer() {
+
+		Assert.assertFalse(selectedMixer.isOpen());
+
+		Assert.assertFalse(selectedMixer.isLineSupported(new DataLine.Info(
+				SourceDataLine.class, aNotSupportedFormat)));
+
+		Assert.assertTrue(selectedMixer.isLineSupported(new DataLine.Info(
+				SourceDataLine.class, aSupportedFormat)));
+
+	}
+
+	@Test
 	public void testSynchronizationNotSupported()
 			throws LineUnavailableException {
 		selectedMixer.open();
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Wed Oct 08 14:27:39 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Wed Oct 08 15:27:58 2008 -0400
@@ -37,8 +37,6 @@
 
 package org.classpath.icedtea.pulseaudio;
 
-import static org.junit.Assert.assertNotNull;
-
 import java.io.File;
 import java.io.IOException;
 import java.net.UnknownHostException;
@@ -138,9 +136,9 @@
 				selectedMixerInfo = info;
 			}
 		}
-		assertNotNull(selectedMixerInfo);
+		Assert.assertNotNull(selectedMixerInfo);
 		mixer = AudioSystem.getMixer(selectedMixerInfo);
-		assertNotNull(mixer);
+		Assert.assertNotNull(mixer);
 		if (mixer.isOpen()) {
 			mixer.close();
 		}
@@ -1029,11 +1027,21 @@
 
 	@Test
 	public void testHasADefaultFormat() throws LineUnavailableException {
+		System.out.println("This test checks that a SourceDataLine has "
+				+ " a default format, and it can be opened with"
+				+ " that format");
+
 		sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info(
 				SourceDataLine.class));
+
+		/* check that there is a default format */
 		Assert.assertNotNull(sourceDataLine.getFormat());
 		System.out.println(sourceDataLine.getFormat());
 
+		/* check that the line can be opened with the default format */
+		sourceDataLine.open();
+		sourceDataLine.close();
+
 	}
 
 	@Test