# HG changeset patch # User Omair Majid # Date 1221251302 14400 # Node ID cd7041f7a6550ab242bea48f4b96a3539f6057c4 # Parent d4bb2fa0df238a94c171b56a54baf021fb2857b5 2008-09-12 Omair Majid * build.xml: Rearranged the tests to run in order of importance. If the first ones fail there's probably a big problem somewhere. * unittests/org/classpath/icedtea/pulseaudio/OtherSoundProvidersAvailableTest.java Fixed name of file in the license. Renamed selectedMixer to mixer. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java Fixed the frameRate paramter for aSupportedFormat. (testObtainingAClip): Added output describing the test. (testClipOpenWrongUse): Likewise. (testPlayTwoClips): Assert that both clips are now closed. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioEventLoopOverhead.java Added license text. Renamed selectedMixer to mixer. (setUp): Removed usage of PulseAudioMixer. (tearDown): Close the mixer. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerRawTest.java This file tests those capabilites of PulseAudioMixer which are not exposed by the sampled.Mixer interface. (testOpen): Removed function. (testLocalOpen): New function. (testLocalOpenAppName): New function. (testRemoveOpenWithInvalidPort): Likewise. (testRemoveOpenWithValidPort): Likewise. (testRemoteOpen): Likewise. (testInvalidRemoteOpen): Likewise. (tearDown): Close the mixer. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java This file tests capabilites of PulseAudioMixer which are exposed by the sampled.Mixer interface. Changed type of selectedMixer to Mixer. (setUp): Removed cast to PulseAudioMixer. (testOpenClose): New function. Tests that open and close methods work. (testLocalOpen): Moved method to PulseAudioMixerRawTest.java. (testLocalOpenAppName): Likewise. (testRemoteOpenWithInvalidPort): Likewise. (testRemoteOpenWithValidPort): Likewise. (testRemoteOpen): Likewise. (testInvalidRemoteOpen): Likewise. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java New file. Tests those capabilites of PulseAudioSourceDataLine which are not exposed through the SourceDataLine interface. (setUp): New function. (testStartNotificationOnCork): Likewise. (testVolumeAndMute): Likewise. (testSettingStreamName): Likewise. (messWithStreams): Likewise. (tearDown): Likewise. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java Renamed PulseSourceDataLineTest.java * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java Added license. (setUp): Removed dependency on knowing the internals of PulseAudioMixer. It uses the AudioSystem to get the mixer. (tearDown): Close the mixer if it isnt closed already. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java Added license. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java Added license. (setUp): Removed dependency on knowing the interals of PulseAudioMixer. Uses AudioSystem to get the mixer now. (tearDown): Close the mixer if it isnt closed. * unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java Renamed file to PulseAudioSourceDataLineTest.java diff -r d4bb2fa0df23 -r cd7041f7a655 build.xml --- a/build.xml Fri Sep 12 12:44:34 2008 -0400 +++ b/build.xml Fri Sep 12 16:28:22 2008 -0400 @@ -70,16 +70,22 @@ - + + + + + - - - + + + + + - + diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/OtherSoundProvidersAvailableTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/OtherSoundProvidersAvailableTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/OtherSoundProvidersAvailableTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,4 +1,4 @@ -/* PulseAudioStreamVolumeControl.java +/* OtherSoundProvidersAvailableTest.java Copyright (C) 2008 Red Hat, Inc. This file is part of IcedTea. @@ -59,7 +59,7 @@ Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo(); Mixer.Info selectedMixerInfo = null; - Mixer selectedMixer; + Mixer mixer; boolean selected = false; int i = 0; @@ -81,14 +81,14 @@ System.out.print("Selected mixer is of class: "); - selectedMixer = AudioSystem.getMixer(selectedMixerInfo); - System.out.println(selectedMixer.getClass().toString()); + mixer = AudioSystem.getMixer(selectedMixerInfo); + System.out.println(mixer.getClass().toString()); try { Line.Info sourceDataLineInfo = null; - selectedMixer.open(); // initialize the mixer + mixer.open(); // initialize the mixer - Line.Info allLineInfo[] = selectedMixer.getSourceLineInfo(); + Line.Info allLineInfo[] = mixer.getSourceLineInfo(); System.out.println("Source lines supported by mixer: "); int j = 0; for (Line.Info lineInfo : allLineInfo) { @@ -103,7 +103,7 @@ if (sourceDataLineInfo == null) { System.out.println("Mixer supports no SourceDataLines"); } else { - SourceDataLine sourceDataLine = (SourceDataLine) selectedMixer + SourceDataLine sourceDataLine = (SourceDataLine) mixer .getLine(sourceDataLineInfo); sourceDataLine.open(); @@ -112,6 +112,8 @@ } } catch (LineUnavailableException e) { System.out.println("Line unavailable"); + } finally { + mixer.close(); } } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -64,7 +64,7 @@ Mixer mixer; AudioFormat aSupportedFormat = new AudioFormat( - AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 10, true); + AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 44100f, true); public static junit.framework.Test suite() { return new JUnit4TestAdapter(PulseAudioClipTest.class); @@ -87,12 +87,15 @@ @Test public void testObtainingAClip() throws LineUnavailableException { + System.out + .println("This tests if a clip can be obtained from the mixer"); Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); Assert.assertNotNull(clip); } @Test(expected = IllegalArgumentException.class) public void testClipOpenWrongUse() throws LineUnavailableException { + System.out.println("This test checks "); Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class)); clip.open(); } @@ -228,7 +231,7 @@ Assert.assertEquals(1, closed); } - + int started = 0; int stopped = 0; @@ -242,8 +245,7 @@ AudioFormat audioFormat = audioInputStream.getFormat(); Clip clip; - clip = (Clip) mixer.getLine(new DataLine.Info( - Clip.class, audioFormat)); + clip = (Clip) mixer.getLine(new DataLine.Info(Clip.class, audioFormat)); Assert.assertNotNull(clip); started = 0; @@ -284,8 +286,7 @@ stopped = 0; } - - + @Test public void testLoop0Clip() throws LineUnavailableException, IOException, UnsupportedAudioFileException { @@ -345,6 +346,9 @@ clip1.close(); clip2.close(); + Assert.assertFalse(clip1.isOpen()); + Assert.assertFalse(clip2.isOpen()); + } @Test diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioEventLoopOverhead.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioEventLoopOverhead.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioEventLoopOverhead.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,3 +1,40 @@ +/* PulseAudioEventLoopOverhead.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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 static org.junit.Assert.assertNotNull; @@ -19,7 +56,7 @@ return new JUnit4TestAdapter(PulseAudioEventLoopOverhead.class); } - Mixer selectedMixer; + Mixer mixer; @Before public void setUp() { @@ -34,18 +71,18 @@ } } assertNotNull(selectedMixerInfo); - selectedMixer = (PulseAudioMixer) AudioSystem - .getMixer(selectedMixerInfo); - assertNotNull(selectedMixer); - if (selectedMixer.isOpen()) { - selectedMixer.close(); + mixer = AudioSystem.getMixer(selectedMixerInfo); + assertNotNull(mixer); + if (mixer.isOpen()) { + mixer.close(); } } - @Test @Ignore + @Test + @Ignore public void testLongWait() throws LineUnavailableException { - selectedMixer.open(); + mixer.open(); try { /* * While this test is running, the java procces shouldnt be hogging @@ -61,7 +98,9 @@ @After public void tearDown() { - + if (mixer.isOpen()) { + mixer.close(); + } } } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerRawTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerRawTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerRawTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -37,8 +37,9 @@ package org.classpath.icedtea.pulseaudio; +import java.net.UnknownHostException; + import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.Mixer; import org.junit.After; import org.junit.Before; @@ -46,7 +47,7 @@ public class PulseAudioMixerRawTest { - Mixer mixer = null; + PulseAudioMixer mixer = null; @Before public void setUp() { @@ -54,15 +55,63 @@ } @Test - public void testOpen() throws LineUnavailableException { - mixer.open(); + public void testLocalOpen() throws LineUnavailableException { + System.out.println("This test tries to open to the local system"); + mixer.openLocal(); + } + + @Test + public void testLocalOpenAppName() throws LineUnavailableException { + System.out + .println("This test tries to connect to the local system while using an application name"); + mixer.openLocal("JunitTest"); + + } + + @Test(expected = LineUnavailableException.class) + public void testRemoteOpenWithInvalidPort() throws UnknownHostException, + LineUnavailableException { + System.out + .println("this test tries to connect to an invalid remote system"); + mixer.openRemote("JUnitTest", "128.0.0.1", 10); + + } + + /* + * This test assumes a computer named 'town' is in the network with + * pulseaudio listening on port 4173 + */ + @Test + public void testRemoteOpenWithValidPort() throws UnknownHostException, + LineUnavailableException { + System.out.println("This test tries to connect a valid remote system"); + mixer.openRemote("JUnitTest", "town", 4713); mixer.close(); + } + /* + * This test assumes a computer named 'town' is in the network with + * pulseaudio listening + */ + @Test + public void testRemoteOpen() throws UnknownHostException, + LineUnavailableException { + mixer.openRemote("JUnitTest", "town"); + mixer.close(); + } + + @Test(expected = LineUnavailableException.class) + public void testInvalidRemoteOpen() throws UnknownHostException, + LineUnavailableException { + mixer.openRemote("JUnitTest", "127.0.0.1"); + mixer.close(); } @After public void tearDown() { - + if (mixer.isOpen()) { + mixer.close(); + } } } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioMixerTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,4 +1,4 @@ -/* PulseAudioStreamVolumeControl.java +/* PulseAudioMixerTest.java Copyright (C) 2008 Red Hat, Inc. This file is part of IcedTea. @@ -37,10 +37,6 @@ package org.classpath.icedtea.pulseaudio; -import static org.junit.Assert.assertNotNull; - -import java.net.UnknownHostException; - import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Line; @@ -50,7 +46,6 @@ import javax.sound.sampled.Mixer; import javax.sound.sampled.Port; import javax.sound.sampled.TargetDataLine; -import javax.sound.sampled.DataLine.Info; import junit.framework.JUnit4TestAdapter; @@ -62,7 +57,7 @@ public class PulseAudioMixerTest { - PulseAudioMixer selectedMixer; + Mixer selectedMixer; AudioFormat aSupportedFormat = new AudioFormat( AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 44100f, true); @@ -83,10 +78,9 @@ selectedMixerInfo = info; } } - assertNotNull(selectedMixerInfo); - selectedMixer = (PulseAudioMixer) AudioSystem - .getMixer(selectedMixerInfo); - assertNotNull(selectedMixer); + Assert.assertNotNull(selectedMixerInfo); + selectedMixer = AudioSystem.getMixer(selectedMixerInfo); + Assert.assertNotNull(selectedMixer); if (selectedMixer.isOpen()) { selectedMixer.close(); } @@ -94,56 +88,10 @@ } @Test - public void testLocalOpen() throws LineUnavailableException { - System.out.println("This test tries to open to the local system"); - selectedMixer.openLocal(); - } - - @Test - public void testLocalOpenAppName() throws LineUnavailableException { - System.out - .println("This test tries to connect to the local system while using an application name"); - selectedMixer.openLocal("JunitTest"); - - } - - @Test(expected = LineUnavailableException.class) - public void testRemoteOpenWithInvalidPort() throws UnknownHostException, - LineUnavailableException { - System.out - .println("this test tries to connect to an invalid remote system"); - selectedMixer.openRemote("JUnitTest", "128.0.0.1", 10); - - } + public void testOpenClose() throws LineUnavailableException { + selectedMixer.open(); + selectedMixer.close(); - /* - * This test assumes a computer named 'town' is in the network with - * pulseaudio listening on port 4173 - */ - @Test - public void testRemoteOpenWithValidPort() throws UnknownHostException, - LineUnavailableException { - System.out.println("This test tries to connect a valid remote system"); - selectedMixer.openRemote("JUnitTest", "town", 4713); - selectedMixer.close(); - } - - /* - * This test assumes a computer named 'town' is in the network with - * pulseaudio listening - */ - @Test - public void testRemoteOpen() throws UnknownHostException, - LineUnavailableException { - selectedMixer.openRemote("JUnitTest", "town"); - selectedMixer.close(); - } - - @Test(expected = LineUnavailableException.class) - public void testInvalidRemoteOpen() throws UnknownHostException, - LineUnavailableException { - selectedMixer.openRemote("JUnitTest", "127.0.0.1"); - selectedMixer.close(); } @Test @@ -172,7 +120,7 @@ Assert.assertFalse("Found a new type of Line", true); } Line sourceLine = (Line) selectedMixer.getLine(lineInfo); - assertNotNull(sourceLine); + Assert.assertNotNull(sourceLine); } @@ -205,7 +153,7 @@ Assert.assertTrue("Found invalid type of target line", true); } Line targetLine = (Line) selectedMixer.getLine(lineInfo); - assertNotNull(targetLine); + Assert.assertNotNull(targetLine); } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -0,0 +1,281 @@ +/* PulseAudioSourceDataLineRawTest.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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.BooleanControl; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class PulseAudioSourceDataLineRawTest { + + PulseAudioMixer mixer = null; + + int started = 0; + int stopped = 0; + + AudioFormat aSupportedFormat = new AudioFormat( + AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 44100f, true); + + @Before + public void setUp() throws LineUnavailableException { + + mixer = PulseAudioMixer.getInstance(); + if (mixer.isOpen()) { + mixer.close(); + } + + mixer.open(); + + started = 0; + stopped = 0; + + } + + @Test + public void testStartNotificationOnCork() + throws UnsupportedAudioFileException, IOException, + LineUnavailableException { + + File soundFile = new File("testsounds/startup.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + PulseAudioSourceDataLine line; + line = (PulseAudioSourceDataLine) mixer.getLine(new DataLine.Info( + 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) { + started++; + } + + if (event.getType() == LineEvent.Type.STOP) { + stopped++; + } + } + + }; + + line.addLineListener(startStopListener); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + line.start(); + int count = 0; + + 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(); + } + + 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(); + + } + } + } + + line.drain(); + + line.stop(); + line.close(); + + Assert.assertEquals(2, started); + Assert.assertEquals(2, stopped); + + } + + @Test + public void testVolumeAndMute() throws Exception { + + Mixer selectedMixer = mixer; + SourceDataLine line = (SourceDataLine) selectedMixer + .getLine(new Line.Info(SourceDataLine.class)); + + File soundFile = new File(new java.io.File(".").getCanonicalPath() + + "/testsounds/logout.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + line.open(audioFormat); + line.start(); + PulseAudioVolumeControl volume = (PulseAudioVolumeControl) line + .getControl(FloatControl.Type.VOLUME); + PulseAudioMuteControl mute = (PulseAudioMuteControl) line + .getControl(BooleanControl.Type.MUTE); + + mute.setValue(true); + volume.setValue(PulseAudioVolumeControl.MAX_VOLUME); + + mute.setValue(false); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + + line.drain(); + line.close(); + selectedMixer.close(); + + } + + @Test + public void testSettingStreamName() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + File soundFile = new File("testsounds/logout.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + PulseAudioSourceDataLine line; + line = (PulseAudioSourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, audioFormat)); + + String name = "Knights Who Say ... Oh my god, i am so sorry, i didnt mean it..."; + line.setName(name); + + line.open(audioFormat); + line.start(); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + + Assert.assertTrue(line.getName() == name); + /* + * FIXME test that PulseAudio also knows this correctly using + * introspection + */ + + line.drain(); + line.stop(); + line.close(); + + } + + @Test + public void messWithStreams() throws LineUnavailableException { + System.out + .println("This test tries to unCork a stream which hasnt been corked"); + + PulseAudioSourceDataLine line = (PulseAudioSourceDataLine) mixer + .getLine(new DataLine.Info(SourceDataLine.class, + aSupportedFormat, 1000)); + + line.open(); + line.start(); + Stream s = line.getStream(); + Operation o; + synchronized (EventLoop.getEventLoop().threadLock) { + o = s.unCork(); + } + o.waitForCompletion(); + o.releaseReference(); + line.stop(); + line.close(); + } + + @After + public void tearDown() { + + } + +} diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -0,0 +1,580 @@ +/* PulseSourceDataLineTest.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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 static org.junit.Assert.assertNotNull; + +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.BooleanControl; +import javax.sound.sampled.Control; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; + +import junit.framework.JUnit4TestAdapter; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class PulseAudioSourceDataLineTest { + Mixer mixer; + + private int listenerCalled = 0; + + int started = 0; + int stopped = 0; + + AudioFormat aSupportedFormat = new AudioFormat( + AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 10, true); + + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(PulseAudioSourceDataLineTest.class); + } + + @Before + public void setUp() throws Exception { + Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo(); + Mixer.Info selectedMixerInfo = null; + // int i = 0; + for (Mixer.Info info : mixerInfos) { + // System.out.println("Mixer Line " + i++ + ": " + info.getName() + + // " " + info.getDescription()); + if (info.getName().contains("PulseAudio")) { + selectedMixerInfo = info; + } + } + assertNotNull(selectedMixerInfo); + mixer = AudioSystem.getMixer(selectedMixerInfo); + assertNotNull(mixer); + if (mixer.isOpen()) { + mixer.close(); + } + + mixer.open(); + + started = 0; + stopped = 0; + + } + + @Test + public void testOpenAndClose() throws LineUnavailableException { + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + line.open(); + Assert.assertTrue(line.isOpen()); + + line.close(); + Assert.assertFalse(line.isOpen()); + + } + + @Test + public void testIsActiveAndIsOpen() throws LineUnavailableException { + + SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, aSupportedFormat, 1000)); + + Assert.assertFalse(line.isActive()); + Assert.assertFalse(line.isOpen()); + line.open(); + Assert.assertTrue(line.isOpen()); + Assert.assertFalse(line.isActive()); + line.start(); + Assert.assertTrue(line.isOpen()); + Assert.assertTrue(line.isActive()); + line.stop(); + Assert.assertTrue(line.isOpen()); + Assert.assertFalse(line.isActive()); + line.close(); + Assert.assertFalse(line.isOpen()); + Assert.assertFalse(line.isActive()); + + } + + @Test + public void testPlay() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + System.out.println("This test plays a file"); + + File soundFile = new File("testsounds/startup.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + SourceDataLine line; + line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, audioFormat)); + Assert.assertNotNull(line); + + line.open(audioFormat); + System.out.println("opened"); + line.start(); + System.out.println("started"); + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + System.out.println("done"); + + line.drain(); + System.out.println("drained"); + line.stop(); + line.close(); + System.out.println("closed"); + + } + + @Test + public void testStartedStopped() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + + File soundFile = new File("testsounds/startup.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + SourceDataLine line; + line = (SourceDataLine) mixer.getLine(new DataLine.Info( + 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) { + started++; + Assert.assertEquals(1, started); + } + + if (event.getType() == LineEvent.Type.STOP) { + System.out.println("Stopped event"); + stopped++; + Assert.assertEquals(1, stopped); + } + } + + }; + + line.addLineListener(startStopListener); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + line.start(); + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + line.drain(); + + line.stop(); + line.close(); + + Assert.assertEquals(1, started); + Assert.assertEquals(1, stopped); + + } + + @Test(expected = IllegalArgumentException.class) + public void testPlayLessThanFrameSize() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + File soundFile = new File("testsounds/startup.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + // the audio file must have an even number of channels + Assert.assertTrue(audioFormat.getChannels() % 2 == 0); + SourceDataLine line; + line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, audioFormat)); + + byte[] data = new byte[1]; + data[0] = (byte) 'a'; + + line.open(); + line.start(); + try { + line.write(data, 0, 1); + } finally { + line.drain(); + line.stop(); + line.close(); + } + } + + @Test + public void testOpenFormat() throws LineUnavailableException, + UnsupportedAudioFileException, IOException { + /* + * This test makes sure that the default format of a line using open() + * is the same format that was passed to the mixer's getLine() function + * to get the line in the first place + */ + + File soundFile = new File("testsounds/startup.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + SourceDataLine line; + line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, audioFormat)); + Assert.assertNotNull(line); + line.open(); + Assert.assertTrue(line.getFormat().matches(audioFormat)); + line.close(); + } + + @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()); + line.close(); + + } + + @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, 10000, 1, 13, + 10, true))); + line.open(); + line.close(); + } + + @Test + public void testFindControl() throws LineUnavailableException { + SourceDataLine sourceLine = (SourceDataLine) mixer + .getLine(new Line.Info(SourceDataLine.class)); + sourceLine.open(); + Control[] controls = sourceLine.getControls(); + Assert.assertNotNull(controls); + Assert.assertTrue(sourceLine.getControls().length > 0); + for (Control control : controls) { + Assert.assertNotNull(control); + } + sourceLine.close(); + } + + @Test + public void testSupportedControls() throws LineUnavailableException { + SourceDataLine sourceLine = (SourceDataLine) mixer + .getLine(new Line.Info(SourceDataLine.class)); + sourceLine.open(); + Assert.assertTrue(sourceLine + .isControlSupported(FloatControl.Type.VOLUME)); + Assert.assertTrue(sourceLine + .isControlSupported(BooleanControl.Type.MUTE)); + sourceLine.close(); + } + + @Test + public void testVolumeAndMute() throws Exception { + + Mixer selectedMixer = mixer; + SourceDataLine line = (SourceDataLine) selectedMixer + .getLine(new Line.Info(SourceDataLine.class)); + + File soundFile = new File(new java.io.File(".").getCanonicalPath() + + "/testsounds/logout.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + line.open(audioFormat); + line.start(); + FloatControl volume = (FloatControl) line + .getControl(FloatControl.Type.VOLUME); + BooleanControl mute = (BooleanControl) line + .getControl(BooleanControl.Type.MUTE); + + mute.setValue(true); + volume.setValue(volume.getMaximum()); + + mute.setValue(false); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + + line.drain(); + line.close(); + selectedMixer.close(); + + } + + @Test + public void testVolumeChanging() throws LineUnavailableException, + IOException, UnsupportedAudioFileException { + + Mixer selectedMixer = mixer; + + SourceDataLine line = (SourceDataLine) selectedMixer + .getLine(new Line.Info(SourceDataLine.class)); + + File soundFile = new File(new java.io.File(".").getCanonicalPath() + + "/testsounds/logout.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + line.open(audioFormat); + line.start(); + FloatControl volume = (FloatControl) line + .getControl(FloatControl.Type.VOLUME); + + volume.setValue(volume.getMinimum()); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + volume.setValue(volume.getValue() + 100); + } + } + + line.drain(); + line.close(); + selectedMixer.close(); + + } + + @Test + public void testOpenEvent() throws LineUnavailableException { + + listenerCalled = 0; + LineListener openListener = new LineListener() { + public void update(LineEvent event) { + Assert.assertTrue(event.getType() == LineEvent.Type.OPEN); + PulseAudioSourceDataLineTest.this.listenerCalled++; + } + }; + + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + line.addLineListener(openListener); + line.open(); + line.removeLineListener(openListener); + line.close(); + Assert.assertEquals(1, listenerCalled); + listenerCalled = 0; + } + + @Test + public void testCloseEvent() throws LineUnavailableException { + listenerCalled = 0; + LineListener closeListener = new LineListener() { + public void update(LineEvent event) { + Assert.assertTrue(event.getType() == LineEvent.Type.CLOSE); + PulseAudioSourceDataLineTest.this.listenerCalled++; + } + }; + + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + line.open(); + line.addLineListener(closeListener); + line.close(); + line.removeLineListener(closeListener); + Assert.assertEquals(1, listenerCalled); + listenerCalled = 0; + } + + @Test + public void testCloseEventWrongListener() throws LineUnavailableException { + listenerCalled = 0; + LineListener closeListener = new LineListener() { + public void update(LineEvent event) { + PulseAudioSourceDataLineTest.this.listenerCalled++; + } + }; + + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + line.open(); + line.addLineListener(closeListener); + line.removeLineListener(closeListener); + line.close(); + Assert.assertEquals(0, listenerCalled); + listenerCalled = 0; + + } + + @Test + public void testFramePosition() throws UnsupportedAudioFileException, + IOException, LineUnavailableException { + File soundFile = new File("testsounds/logout.wav"); + AudioInputStream audioInputStream = AudioSystem + .getAudioInputStream(soundFile); + AudioFormat audioFormat = audioInputStream.getFormat(); + + SourceDataLine line; + line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, audioFormat)); + Assert.assertNotNull(line); + + line.open(audioFormat); + line.start(); + + byte[] abData = new byte[1000]; + int bytesRead = 0; + + while (bytesRead >= 0) { + bytesRead = audioInputStream.read(abData, 0, abData.length); + if (bytesRead > 0) { + line.write(abData, 0, bytesRead); + } + } + + line.drain(); + line.stop(); + System.out.println("time position: " + line.getMicrosecondPosition()); + Assert.assertEquals(6199L, line.getMicrosecondPosition()); + line.close(); + } + + @Test + public void testBufferSizes() throws LineUnavailableException { + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + line.open(aSupportedFormat, 10000); + Assert.assertEquals(10000, line.getBufferSize()); + line.close(); + } + + @Test + public void testHasADefaultFormat() throws LineUnavailableException { + SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + Assert.assertNotNull(line.getFormat()); + System.out.println(line.getFormat()); + + } + + @Test + public void testDefaultFormatWithGetLine() throws LineUnavailableException { + SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, aSupportedFormat, 1000)); + Assert.assertEquals(aSupportedFormat, line.getFormat()); + + } + + @Test + public void testDefaultBufferSize() throws LineUnavailableException { + SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( + SourceDataLine.class, aSupportedFormat, 1000)); + Assert.assertEquals(StreamBufferAttributes.SANE_DEFAULT, line + .getBufferSize()); + } + + @Test + public void testMixerKnowsAboutOpenLines() throws LineUnavailableException { + SourceDataLine sourceDataLine = (SourceDataLine) mixer + .getLine(new Line.Info(SourceDataLine.class)); + + Assert.assertEquals(0, mixer.getSourceLines().length); + sourceDataLine.open(); + Assert.assertEquals(1, mixer.getSourceLines().length); + Assert.assertEquals(sourceDataLine, mixer.getSourceLines()[0]); + sourceDataLine.close(); + Assert.assertEquals(0, mixer.getSourceLines().length); + + } + + @Test + public void testAllSourceLinesClosed() { + Assert.assertEquals(0, mixer.getSourceLines().length); + + } + + @After + public void tearDown() throws Exception { + started = 0; + stopped = 0; + + if (mixer.isOpen()) { + mixer.close(); + } + } + +} diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,5 +1,45 @@ +/* PulseAudioSourcePortTest.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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 static org.junit.Assert.assertNotNull; + +import javax.sound.sampled.AudioSystem; import javax.sound.sampled.BooleanControl; import javax.sound.sampled.FloatControl; import javax.sound.sampled.Line; @@ -17,7 +57,23 @@ @Before public void setUp() throws Exception { - mixer = PulseAudioMixer.getInstance(); + Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo(); + Mixer.Info selectedMixerInfo = null; + // int i = 0; + for (Mixer.Info info : mixerInfos) { + // System.out.println("Mixer Line " + i++ + ": " + info.getName() + + // " " + info.getDescription()); + if (info.getName().contains("PulseAudio")) { + selectedMixerInfo = info; + } + } + assertNotNull(selectedMixerInfo); + mixer = AudioSystem.getMixer(selectedMixerInfo); + assertNotNull(mixer); + if (mixer.isOpen()) { + mixer.close(); + } + mixer.open(); } @@ -54,8 +110,9 @@ @After public void tearDown() { - mixer.close(); - + if (mixer.isOpen()) { + mixer.close(); + } } } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLineTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,3 +1,40 @@ +/* PulseAudioTargetDataLineTest.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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; diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java Fri Sep 12 12:44:34 2008 -0400 +++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java Fri Sep 12 16:28:22 2008 -0400 @@ -1,5 +1,45 @@ +/* PulseAudioTargetPortTest.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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 static org.junit.Assert.assertNotNull; + +import javax.sound.sampled.AudioSystem; import javax.sound.sampled.BooleanControl; import javax.sound.sampled.FloatControl; import javax.sound.sampled.Line; @@ -17,7 +57,23 @@ @Before public void setUp() throws Exception { - mixer = PulseAudioMixer.getInstance(); + Mixer.Info mixerInfos[] = AudioSystem.getMixerInfo(); + Mixer.Info selectedMixerInfo = null; + // int i = 0; + for (Mixer.Info info : mixerInfos) { + // System.out.println("Mixer Line " + i++ + ": " + info.getName() + + // " " + info.getDescription()); + if (info.getName().contains("PulseAudio")) { + selectedMixerInfo = info; + } + } + assertNotNull(selectedMixerInfo); + mixer = AudioSystem.getMixer(selectedMixerInfo); + assertNotNull(mixer); + if (mixer.isOpen()) { + mixer.close(); + } + mixer.open(); } @@ -54,7 +110,9 @@ @After public void tearDown() { - mixer.close(); + if (mixer.isOpen()) { + mixer.close(); + } } } diff -r d4bb2fa0df23 -r cd7041f7a655 unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java --- a/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java Fri Sep 12 12:44:34 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,710 +0,0 @@ -/* PulseSourceDataLineTest.java - Copyright (C) 2008 Red Hat, Inc. - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, version 2. - -IcedTea is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -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.BooleanControl; -import javax.sound.sampled.Control; -import javax.sound.sampled.DataLine; -import javax.sound.sampled.FloatControl; -import javax.sound.sampled.Line; -import javax.sound.sampled.LineEvent; -import javax.sound.sampled.LineListener; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.Mixer; -import javax.sound.sampled.SourceDataLine; -import javax.sound.sampled.UnsupportedAudioFileException; - -import junit.framework.JUnit4TestAdapter; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class PulseSourceDataLineTest { - Mixer mixer; - - private int listenerCalled = 0; - - int started = 0; - int stopped = 0; - - AudioFormat aSupportedFormat = new AudioFormat( - AudioFormat.Encoding.PCM_UNSIGNED, 44100f, 8, 1, 1, 10, true); - - public static junit.framework.Test suite() { - return new JUnit4TestAdapter(PulseSourceDataLineTest.class); - } - - @Before - public void setUp() throws Exception { - mixer = PulseAudioMixer.getInstance(); - mixer.open(); - - started = 0; - stopped = 0; - - } - - @Test - public void testOpenAndClose() throws LineUnavailableException { - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - - line.open(); - Assert.assertTrue(line.isOpen()); - - line.close(); - Assert.assertFalse(line.isOpen()); - - } - - @Test - public void testIsActiveAndIsOpen() throws LineUnavailableException { - - SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, aSupportedFormat, 1000)); - - Assert.assertFalse(line.isActive()); - Assert.assertFalse(line.isOpen()); - line.open(); - Assert.assertTrue(line.isOpen()); - Assert.assertFalse(line.isActive()); - line.start(); - Assert.assertTrue(line.isOpen()); - Assert.assertTrue(line.isActive()); - line.stop(); - Assert.assertTrue(line.isOpen()); - Assert.assertFalse(line.isActive()); - line.close(); - Assert.assertFalse(line.isOpen()); - Assert.assertFalse(line.isActive()); - - } - - @Test - public void testPlay() throws LineUnavailableException, - UnsupportedAudioFileException, IOException { - System.out.println("This test plays a file"); - - File soundFile = new File("testsounds/startup.wav"); - 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); - System.out.println("opened"); - line.start(); - System.out.println("started"); - byte[] abData = new byte[1000]; - int bytesRead = 0; - - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - } - } - System.out.println("done"); - - line.drain(); - System.out.println("drained"); - line.stop(); - line.close(); - System.out.println("closed"); - - } - - @Test - public void testStartedStopped() throws LineUnavailableException, - UnsupportedAudioFileException, IOException { - - File soundFile = new File("testsounds/startup.wav"); - 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); - - LineListener startStopListener = new LineListener() { - - @Override - public void update(LineEvent event) { - if (event.getType() == LineEvent.Type.START) { - started++; - Assert.assertEquals(1, started); - } - - if (event.getType() == LineEvent.Type.STOP) { - System.out.println("Stopped event"); - stopped++; - Assert.assertEquals(1, stopped); - } - } - - }; - - line.addLineListener(startStopListener); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - line.start(); - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - } - } - line.drain(); - - line.stop(); - line.close(); - - Assert.assertEquals(1, started); - Assert.assertEquals(1, stopped); - - } - - @Test - public void testStartNotificationOnCork() - throws UnsupportedAudioFileException, IOException, - LineUnavailableException { - - File soundFile = new File("testsounds/startup.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - - PulseAudioSourceDataLine line; - line = (PulseAudioSourceDataLine) mixer.getLine(new DataLine.Info( - 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) { - started++; - } - - if (event.getType() == LineEvent.Type.STOP) { - stopped++; - } - } - - }; - - line.addLineListener(startStopListener); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - line.start(); - int count = 0; - - 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(); - } - - 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(); - - } - } - } - - line.drain(); - - line.stop(); - line.close(); - - Assert.assertEquals(2, started); - Assert.assertEquals(2, stopped); - - } - - @Test(expected = IllegalArgumentException.class) - public void testPlayLessThanFrameSize() throws LineUnavailableException, - UnsupportedAudioFileException, IOException { - File soundFile = new File("testsounds/startup.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - // the audio file must have an even number of channels - Assert.assertTrue(audioFormat.getChannels() % 2 == 0); - SourceDataLine line; - line = (SourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, audioFormat)); - - byte[] data = new byte[1]; - data[0] = (byte) 'a'; - - line.open(); - line.start(); - try { - line.write(data, 0, 1); - } finally { - line.drain(); - line.stop(); - line.close(); - } - } - - @Test - public void testOpenFormat() throws LineUnavailableException, - UnsupportedAudioFileException, IOException { - /* - * This test makes sure that the default format of a line using open() - * is the same format that was passed to the mixer's getLine() function - * to get the line in the first place - */ - - File soundFile = new File("testsounds/startup.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - - SourceDataLine line; - line = (SourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, audioFormat)); - Assert.assertNotNull(line); - line.open(); - Assert.assertTrue(line.getFormat().matches(audioFormat)); - line.close(); - } - - @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()); - line.close(); - - } - - @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, 10000, 1, 13, - 10, true))); - line.open(); - line.close(); - } - - @Test - public void testVolumeAndMute() throws Exception { - - Mixer selectedMixer = mixer; - SourceDataLine line = (SourceDataLine) selectedMixer - .getLine(new Line.Info(SourceDataLine.class)); - - File soundFile = new File(new java.io.File(".").getCanonicalPath() - + "/testsounds/logout.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - - line.open(audioFormat); - line.start(); - PulseAudioVolumeControl volume = (PulseAudioVolumeControl) line - .getControl(FloatControl.Type.VOLUME); - PulseAudioMuteControl mute = (PulseAudioMuteControl) line - .getControl(BooleanControl.Type.MUTE); - - mute.setValue(true); - volume.setValue(PulseAudioVolumeControl.MAX_VOLUME); - - mute.setValue(false); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - } - } - - line.drain(); - line.close(); - selectedMixer.close(); - - } - - @Test - public void testVolumeChanging() throws LineUnavailableException, - IOException, UnsupportedAudioFileException { - - Mixer selectedMixer = mixer; - - SourceDataLine line = (SourceDataLine) selectedMixer - .getLine(new Line.Info(SourceDataLine.class)); - - File soundFile = new File(new java.io.File(".").getCanonicalPath() - + "/testsounds/logout.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - - line.open(audioFormat); - line.start(); - PulseAudioVolumeControl volume = (PulseAudioVolumeControl) line - .getControl(FloatControl.Type.VOLUME); - - volume.setValue(PulseAudioVolumeControl.MIN_VOLUME); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - volume.setValue(volume.getValue() + 100); - } - } - - line.drain(); - line.close(); - selectedMixer.close(); - - } - - @Test - public void testFindControl() throws LineUnavailableException { - SourceDataLine sourceLine = (SourceDataLine) mixer - .getLine(new Line.Info(SourceDataLine.class)); - sourceLine.open(); - Control[] controls = sourceLine.getControls(); - Assert.assertNotNull(controls); - Assert.assertTrue(sourceLine.getControls().length > 0); - for (Control control : controls) { - Assert.assertNotNull(control); - } - sourceLine.close(); - } - - @Test - public void testSupportedControls() throws LineUnavailableException { - SourceDataLine sourceLine = (SourceDataLine) mixer - .getLine(new Line.Info(SourceDataLine.class)); - sourceLine.open(); - Assert.assertTrue(sourceLine - .isControlSupported(FloatControl.Type.VOLUME)); - Assert.assertTrue(sourceLine - .isControlSupported(BooleanControl.Type.MUTE)); - sourceLine.close(); - } - - @Test - public void testOpenEvent() throws LineUnavailableException { - - listenerCalled = 0; - LineListener openListener = new LineListener() { - public void update(LineEvent event) { - Assert.assertTrue(event.getType() == LineEvent.Type.OPEN); - PulseSourceDataLineTest.this.listenerCalled++; - } - }; - - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - line.addLineListener(openListener); - line.open(); - line.removeLineListener(openListener); - line.close(); - Assert.assertEquals(1, listenerCalled); - listenerCalled = 0; - } - - @Test - public void testCloseEvent() throws LineUnavailableException { - listenerCalled = 0; - LineListener closeListener = new LineListener() { - public void update(LineEvent event) { - Assert.assertTrue(event.getType() == LineEvent.Type.CLOSE); - PulseSourceDataLineTest.this.listenerCalled++; - } - }; - - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - line.open(); - line.addLineListener(closeListener); - line.close(); - line.removeLineListener(closeListener); - Assert.assertEquals(1, listenerCalled); - listenerCalled = 0; - } - - @Test - public void testCloseEventWrongListener() throws LineUnavailableException { - listenerCalled = 0; - LineListener closeListener = new LineListener() { - public void update(LineEvent event) { - PulseSourceDataLineTest.this.listenerCalled++; - } - }; - - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - - line.open(); - line.addLineListener(closeListener); - line.removeLineListener(closeListener); - line.close(); - Assert.assertEquals(0, listenerCalled); - listenerCalled = 0; - - } - - @Test - public void testFramePosition() throws UnsupportedAudioFileException, - IOException, LineUnavailableException { - File soundFile = new File("testsounds/logout.wav"); - 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(); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - } - } - - line.drain(); - line.stop(); - System.out.println("time position: " + line.getMicrosecondPosition()); - Assert.assertEquals(6199L, line.getMicrosecondPosition()); - line.close(); - } - - @Test - public void testBufferSizes() throws LineUnavailableException { - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - line.open(aSupportedFormat, 10000); - Assert.assertEquals(10000, line.getBufferSize()); - line.close(); - } - - @Test - public void testHasADefaultFormat() throws LineUnavailableException { - SourceDataLine line = (SourceDataLine) mixer.getLine(new Line.Info( - SourceDataLine.class)); - Assert.assertNotNull(line.getFormat()); - System.out.println(line.getFormat()); - - } - - @Test - public void testDefaultFormatWithGetLine() throws LineUnavailableException { - SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, aSupportedFormat, 1000)); - Assert.assertEquals(aSupportedFormat, line.getFormat()); - - } - - @Test - public void testDefaultBufferSize() throws LineUnavailableException { - SourceDataLine line = (SourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, aSupportedFormat, 1000)); - Assert.assertEquals(StreamBufferAttributes.SANE_DEFAULT, line - .getBufferSize()); - } - - @Test - public void testMixerKnowsAboutOpenLines() throws LineUnavailableException { - SourceDataLine sourceDataLine = (SourceDataLine) mixer - .getLine(new Line.Info(SourceDataLine.class)); - - Assert.assertEquals(0, mixer.getSourceLines().length); - sourceDataLine.open(); - Assert.assertEquals(1, mixer.getSourceLines().length); - Assert.assertEquals(sourceDataLine, mixer.getSourceLines()[0]); - sourceDataLine.close(); - Assert.assertEquals(0, mixer.getSourceLines().length); - - } - - @Test - public void testAllSourceLinesClosed() { - Assert.assertEquals(0, mixer.getSourceLines().length); - - } - - @Test - public void testSettingStreamName() throws LineUnavailableException, - UnsupportedAudioFileException, IOException { - File soundFile = new File("testsounds/logout.wav"); - AudioInputStream audioInputStream = AudioSystem - .getAudioInputStream(soundFile); - AudioFormat audioFormat = audioInputStream.getFormat(); - - PulseAudioSourceDataLine line; - line = (PulseAudioSourceDataLine) mixer.getLine(new DataLine.Info( - SourceDataLine.class, audioFormat)); - - String name = "Knights Who Say ... Oh my god, i am so sorry, i didnt mean it..."; - line.setName(name); - - line.open(audioFormat); - line.start(); - - byte[] abData = new byte[1000]; - int bytesRead = 0; - - while (bytesRead >= 0) { - bytesRead = audioInputStream.read(abData, 0, abData.length); - if (bytesRead > 0) { - line.write(abData, 0, bytesRead); - } - } - - Assert.assertTrue(line.getName() == name); - /* - * FIXME test that PulseAudio also knows this correctly using - * introspection - */ - - line.drain(); - line.stop(); - line.close(); - - } - - @Test - public void messWithStreams() throws LineUnavailableException { - System.out - .println("This test tries to unCork a stream which hasnt been corked"); - - PulseAudioSourceDataLine line = (PulseAudioSourceDataLine) mixer - .getLine(new DataLine.Info(SourceDataLine.class, - aSupportedFormat, 1000)); - - line.open(); - line.start(); - Stream s = line.getStream(); - Operation o; - synchronized (EventLoop.getEventLoop().threadLock) { - o = s.unCork(); - } - o.waitForCompletion(); - o.releaseReference(); - line.stop(); - line.close(); - } - - @After - public void tearDown() throws Exception { - started = 0; - stopped = 0; - - if (mixer.isOpen()) { - mixer.close(); - } - } - -}