Mercurial > hg > pulseaudio
changeset 134:381f212496eb
2008-09-23 Omair Majid <omajid@redhat.com>
* src/java/org/classpath/icedtea/pulseaudio/Operation.java
(waitForComplete): Handles interrupts now. Maybe not the best way of
handling them, but it works.
* src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java
(ClipThread.run): Drain the stream by using the stream functions, not by a
call to drain.
(drain): Fixed to work the way reported in the bug report.
* unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java
(testLoopStartStopClip): Renamed to testLoop4Times. Now uses drain to
wait for the loop to complete playing.
(testDrainWithoutStart): Added a timeout.
(testDrainBlocksWhilePlaying): New function. Tests that drain() blocks
while playing.
(testLoop0Clip): Renamed to testLoop0InterruptsPlayback.
(testFramePosition): New function. Checks the value of getLongFrames()
from clip.
(testFramePositionAfterLooping): Checks that Looping the clip still
returns the correct number of frames played (not just the current frame
position in the audio stream).
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Tue, 23 Sep 2008 11:38:18 -0400 |
parents | 4a1c8f3d1f62 |
children | c46f6e0e7959 |
files | src/java/org/classpath/icedtea/pulseaudio/Operation.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java |
diffstat | 3 files changed, 130 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/Operation.java Tue Sep 23 10:29:27 2008 -0400 +++ b/src/java/org/classpath/icedtea/pulseaudio/Operation.java Tue Sep 23 11:38:18 2008 -0400 @@ -133,6 +133,8 @@ public void waitForCompletion() { assert (operationPointer != null); + + boolean interrupted = false; do { synchronized (eventLoop.threadLock) { if (getState() == Operation.State.Done) { @@ -141,10 +143,15 @@ try { eventLoop.threadLock.wait(); } catch (InterruptedException e) { - e.printStackTrace(); + // ingore the interrupt for now + interrupted = true; } } } while (getState() != State.Done); + // let the caller know about the interrupt + if (interrupted) { + Thread.currentThread().interrupt(); + } } }
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Tue Sep 23 10:29:27 2008 -0400 +++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Tue Sep 23 11:38:18 2008 -0400 @@ -104,7 +104,15 @@ } - PulseAudioClip.this.drain(); + Operation operation; + + synchronized (eventLoop.threadLock) { + operation = stream.drain(); + } + + operation.waitForCompletion(); + operation.releaseReference(); + } } @@ -209,19 +217,29 @@ } + /* + * + * drain() on a Clip should block until the entire clip has finished playing + * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4732218 + * + * + * @see org.classpath.icedtea.pulseaudio.PulseAudioDataLine#drain() + */ @Override public void drain() { if (!isOpen) { throw new IllegalStateException("line not open"); } - if (clipThread != null) { - clipThread.interrupt(); + while (clipThread != null && clipThread.isAlive()) { try { clipThread.join(); } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } + Operation operation; synchronized (eventLoop.threadLock) {
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java Tue Sep 23 10:29:27 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java Tue Sep 23 11:38:18 2008 -0400 @@ -116,8 +116,12 @@ } @Test - public void testLoopStopStartClip() throws LineUnavailableException, - IOException, UnsupportedAudioFileException { + public void testLoop4Times() throws LineUnavailableException, IOException, + UnsupportedAudioFileException { + System.out + .println("This tests loop(4) on the Clip. " + + "You should hear a certain part of the clip play back 5 time"); + Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); File soundFile = new File("testsounds/startup.wav"); AudioInputStream audioInputStream = AudioSystem @@ -127,18 +131,11 @@ clip.setLoopPoints((int) (clip.getFrameLength() / 4), (int) (clip .getFrameLength() / 2)); clip.loop(4); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + + clip.drain(); + clip.stop(); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - clip.start(); + clip.close(); } @@ -280,7 +277,7 @@ } - @Test + @Test(timeout = 1000) public void testDrainWithoutStart() throws UnsupportedAudioFileException, IOException, LineUnavailableException { @@ -300,7 +297,37 @@ } @Test - public void testLoop0Clip() throws LineUnavailableException, IOException, + public void testDrainBlocksWhilePlaying() + throws UnsupportedAudioFileException, IOException, + LineUnavailableException { + + String fileName = "testsounds/startup.wav"; + File soundFile = new File(fileName); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + Clip clip; + clip = (Clip) mixer.getLine(new DataLine.Info(Clip.class, audioFormat)); + Assert.assertNotNull(clip); + + long startTime = System.currentTimeMillis(); + + clip.open(audioInputStream); + clip.start(); + clip.drain(); + clip.stop(); + clip.close(); + + long endTime = System.currentTimeMillis(); + + Assert.assertTrue(endTime - startTime > 3000); + System.out.println("Playback of " + fileName + " completed in " + + (endTime - startTime) + " milliseconds"); + } + + @Test + public void testLoop0InterruptsPlayback() throws LineUnavailableException, IOException, UnsupportedAudioFileException { Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); File soundFile = new File("testsounds/startup.wav"); @@ -383,6 +410,65 @@ } @Test + public void testFramePosition() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + System.out + .println("This tests if the Clip provides the correct frame position"); + Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); + String fileName = "testsounds/logout.wav"; + File soundFile1 = new File(fileName); + AudioInputStream audioInputStream1 = AudioSystem + .getAudioInputStream(soundFile1); + clip.open(audioInputStream1); + + clip.start(); + + clip.drain(); + + long pos = clip.getFramePosition(); + + clip.close(); + + long expected = 136703; + long granularity = 100; + System.out.println("Frames in " + fileName + ": " + expected); + System.out.println("Frame position in clip :" + pos); + Assert.assertTrue("Expected: " + expected + " got " + pos, Math + .abs(expected - pos) < granularity); + + } + + @Test + public void testFramePositionAfterLooping() + throws LineUnavailableException, UnsupportedAudioFileException, + IOException { + System.out + .println("This tests if the Clip provides the correct frame position"); + Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); + String fileName = "testsounds/logout.wav"; + File soundFile1 = new File(fileName); + AudioInputStream audioInputStream1 = AudioSystem + .getAudioInputStream(soundFile1); + clip.open(audioInputStream1); + + clip.loop(1); + + clip.drain(); + + long pos = clip.getFramePosition(); + + clip.close(); + + long expected = 136703 * 2; + long granularity = 100; + System.out.println("Frames in " + fileName + ": " + expected); + System.out.println("Frame position in clip :" + pos); + Assert.assertTrue("Expected: " + expected + " got " + pos, Math + .abs(expected - pos) < granularity); + + } + + @Test public void testMixerKnowsAboutOpenClips() throws LineUnavailableException, UnsupportedAudioFileException, IOException { Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class));