changeset 126:fe9c2599d07d

2009-09-18 Omair Majid <omajid@redhat.com> * src/java/org/classpath/icedtea/pulseaudio/Stream.java (native_pa_stream_is_corked): New function. (isCorked): Likewise. * src/native/org_classpath_icedtea_pulseaudio_Stream.c (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1corked): Likewise. Checks if the stream has been corked. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java (testStartNotificationOnCork): Major fixes. Renamed to testStartAndStopEventsOnCork. (testStartAndStopEventsOnCork): New function. Test START and STOP events on corking/uncorking a stream (ThreadWriter): New class. Writes data to a stream while running in a separate thread.
author Omair Majid <omajid@redhat.com>
date Thu, 18 Sep 2008 11:37:51 -0400
parents 3c5c586cf5f3
children da120992e52b
files src/java/org/classpath/icedtea/pulseaudio/Stream.java src/native/org_classpath_icedtea_pulseaudio_Stream.c unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java
diffstat 3 files changed, 117 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Tue Sep 16 14:05:45 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Thu Sep 18 11:37:51 2008 -0400
@@ -176,6 +176,8 @@
 	 * structure update for a stream.
 	 */
 
+	private native int native_pa_stream_is_corked();
+	
 	private native byte[] native_pa_stream_cork(int b);
 
 	private native byte[] native_pa_stream_flush();
@@ -629,6 +631,15 @@
 		}
 	}
 
+	
+	public boolean isCorked() {
+		int corked = native_pa_stream_is_corked();
+		if (corked < 0) {
+			throw new IllegalStateException("Unable to determine state");
+		}
+		return corked == 0 ? false : true;
+	}
+	
 	/**
 	 * Pause (or resume) playback of this stream temporarily.
 	 * 
--- a/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Tue Sep 16 14:05:45 2008 -0400
+++ b/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Thu Sep 18 11:37:51 2008 -0400
@@ -603,12 +603,23 @@
 	return convertNativePointerToJava(env, operation);
 }
 
+/*
+ * Class:     org_classpath_icedtea_pulseaudio_Stream
+ * Method:    native_pa_stream_is_corked
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1corked
+(JNIEnv* env, jobject obj) {
+	pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, "streamPointer");
+	assert(stream);
+	return pa_stream_is_corked(stream);
+}
+
 static void cork_callback(pa_stream* stream, int success, void* userdata) {
 	assert(success);
 	JNIEnv* env = pulse_thread_env;
 	assert(env);
 	notifyWaitingOperations(env);
-
 }
 
 /*
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java	Tue Sep 16 14:05:45 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java	Thu Sep 18 11:37:51 2008 -0400
@@ -69,6 +69,56 @@
 	AudioFormat aSupportedFormat = new AudioFormat(
 			AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 44100f, true);
 
+	class ThreadWriter extends Thread {
+		PulseAudioSourceDataLine line;
+		AudioInputStream stream;
+
+		public ThreadWriter(AudioInputStream stream,
+				PulseAudioSourceDataLine line) throws LineUnavailableException {
+
+			this.line = line;
+			this.stream = stream;
+
+			if (line.isOpen()) {
+				line.close();
+			}
+
+		}
+
+		@Override
+		public void run() {
+			try {
+				AudioFormat audioFormat = stream.getFormat();
+
+				line.open(audioFormat);
+
+				byte[] abData = new byte[1000];
+				int bytesRead = 0;
+
+				line.start();
+
+				while (bytesRead >= 0) {
+					bytesRead = stream.read(abData, 0, abData.length);
+					// System.out.println("read data");
+					if (bytesRead > 0) {
+						System.out.println("about to write data");
+						line.write(abData, 0, bytesRead);
+						// System.out.println("wrote data");
+					}
+				}
+
+				line.drain();
+				line.close();
+
+			} catch (LineUnavailableException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+
 	@Before
 	public void setUp() throws LineUnavailableException {
 
@@ -84,11 +134,13 @@
 
 	}
 
-	// FIXME this test is BROKEN!
 	@Test
-	public void testStartNotificationOnCork()
+	public void testStartAndStopEventsOnCork()
 			throws UnsupportedAudioFileException, IOException,
-			LineUnavailableException {
+			LineUnavailableException, InterruptedException {
+
+		System.out
+				.println("This test checks if START and STOP notifications appear on corking");
 
 		File soundFile = new File("testsounds/startup.wav");
 		AudioInputStream audioInputStream = AudioSystem
@@ -100,17 +152,17 @@
 				SourceDataLine.class, audioFormat));
 		Assert.assertNotNull(line);
 
-		line.open(audioFormat);
-
 		LineListener startStopListener = new LineListener() {
 
 			@Override
 			public void update(LineEvent event) {
 				if (event.getType() == LineEvent.Type.START) {
+					System.out.println("START");
 					started++;
 				}
 
 				if (event.getType() == LineEvent.Type.STOP) {
+					System.out.println("STOP");
 					stopped++;
 				}
 			}
@@ -118,53 +170,49 @@
 		};
 
 		line.addLineListener(startStopListener);
+		System.out.println("Launching threadWriter");
+		ThreadWriter writer = new ThreadWriter(audioInputStream, line);
+		writer.start();
+		// System.out.println("started");
 
-		byte[] abData = new byte[1000];
-		int bytesRead = 0;
-
-		line.start();
-		int count = 0;
+		Thread.sleep(1000);
 
-		while (bytesRead >= 0) {
-			bytesRead = audioInputStream.read(abData, 0, abData.length);
-			if (bytesRead > 0) {
-				line.write(abData, 0, bytesRead);
-				count++;
-				/*
-				 * keep count high. if it is too low, the line wont even start
-				 * playing so stopping is out of the question
-				 */
-				if (count == 100) {
-					Operation o;
-					synchronized (EventLoop.getEventLoop().threadLock) {
-						o = line.getStream().cork();
-					}
+		// CORK
+		Operation o;
+		synchronized (EventLoop.getEventLoop().threadLock) {
+			o = line.getStream().cork();
+		}
 
-					o.waitForCompletion();
-					o.releaseReference();
-
-					try {
-						Thread.sleep(1000);
-					} catch (InterruptedException e) {
-						// TODO Auto-generated catch block
-						e.printStackTrace();
-					}
-
-					synchronized (EventLoop.getEventLoop().threadLock) {
-						o = line.getStream().unCork();
-					}
-
-					o.waitForCompletion();
-					o.releaseReference();
-
-				}
-			}
+		o.waitForCompletion();
+		o.releaseReference();
+		synchronized (EventLoop.getEventLoop().threadLock) {
+			System.out.println("corked? " + line.getStream().isCorked());
+			assert (line.getStream().isCorked() == true);
 		}
 
-		line.drain();
+		System.out.println("corked");
+
+		Thread.sleep(1000);
+
+		// UNCORK
+		synchronized (EventLoop.getEventLoop().threadLock) {
+			o = line.getStream().unCork();
+		}
+
+		o.waitForCompletion();
+		o.releaseReference();
 
-		line.stop();
-		line.close();
+		System.out.println("uncorked");
+
+		synchronized (EventLoop.getEventLoop().threadLock) {
+			System.out.println("corked? " + line.getStream().isCorked());
+			assert (line.getStream().isCorked() == false);
+		}
+
+		Thread.sleep(1000);
+
+		// System.out.println("waiting for thread to finish");
+		writer.join();
 
 		Assert.assertEquals(2, started);
 		Assert.assertEquals(2, stopped);