From damjan.jov at gmail.com Mon May 30 02:30:53 2011 From: damjan.jov at gmail.com (Damjan Jovanovic) Date: Mon, 30 May 2011 11:30:53 +0200 Subject: JDK6 doesn't see the "default" ALSA device, preventing sound card sharing with other applications? Message-ID: Hi On Linux, JDK6 doesn't show/use the "default" ALSA device. By comparison, this device is shown and used by OpenJDK. The "default" device is the only device capable of properly sharing access to the sound card with other native applications, so it's pretty vital. My investigation is detailed below: Sound card: 00:1b.0 Audio device: Intel Corporation 82801I (ICH9 Family) HD Audio Controller (rev 03) JDK = JDK 1.6.0_22 on x86 Linux OpenJDK = OpenJDK7 19.0-b06 on same x86 Linux JDK's /META-INF/services/javax.sound.sampled.spi.MixerProvider: com.sun.media.sound.PortMixerProvider com.sun.media.sound.SimpleInputDeviceProvider com.sun.media.sound.HeadspaceMixerProvider com.sun.media.sound.DirectAudioDeviceProvider OpenJDK's /META-INF/services/javax.sound.sampled.spi.MixerProvider: com.sun.media.sound.PortMixerProvider com.sun.media.sound.DirectAudioDeviceProvider JDK's mixer list: "Intel [plughw:0,0], version 1.0.21" "Intel [plughw:0,3], version 1.0.21" "Java Sound Audio Engine, version 1.0" "Port Intel [hw:0], version 1.0.21" OpenJDK's mixer list: "default [default], version 1.0.21" "Intel [plughw:0,0], version 1.0.21" "Intel [plughw:0,3], version 1.0.21" "Port Intel [hw:0], version 1.0.21" Here we have 5 distinct mixers, 3 of which are common to both JDK and OpenJDK. Now testing them with the following conditions: * audio format is "AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 2, 8000, true);" * 3 cases are tested: pasuspender is used to bypass PulseAudio, PulseAudio is active with no other sound playing, and PulseAudio active with VLC playing sound through its PulseAudio output module during the test * AudioSystem.getSourceDataLine(audioFormat, mixerInfo) is tested, and if that succeeds, open(audioFormat, 2*8*60*3) on that sourceDataLine is tested The following results are obtained for each mixer: "default [default]" (description: Direct Audio Device: default, default, default) Only available in OpenJDK OpenJDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + no other sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + VLC playing sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds In other words, this mixer works perfectly. "Intel [plughw:0,0], version 1.0.21" (description: Direct Audio Device: HDA Intel, AD198x Analog, AD198x Analog) JDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds JDK + no other sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + no other sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." JDK + VLC playing sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." OpenJDK + VLC playing sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." "Intel [plughw:0,3], version 1.0.21" (description: Direct Audio Device: HDA Intel, INTEL HDMI, INTEL HDMI) JDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds JDK + no other sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + no other sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds JDK + VLC playing sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds OpenJDK + VLC playing sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds "Java Sound Audio Engine, version 1.0" (description: Software mixer and synthesizer) Only available in JDK JDK + pasuspender: AudioSystem.getSourceDataLine() succeeds, open() succeeds JDK + no other sound: AudioSystem.getSourceDataLine() succeeds, open() succeeds JDK + VLC playing sound: AudioSystem.getSourceDataLine() succeeds, open() throws "javax.sound.sampled.LineUnavailableException: Audio Device Unavailable" "Port Intel [hw:0], version 1.0.21" (description: HDA Intel, Intel G45 DEVCTG) JDK + pasuspender: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." OpenJDK + pasuspender: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." JDK + no other sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." OpenJDK + no other sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." JDK + VLC playing sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." OpenJDK + VLC playing sound: AudioSystem.getSourceDataLine() throws "java.lang.IllegalArgumentException: Line unsupported: ..." Also, while VLC is playing audio: * In JDK, AudioSystem.getSourceDataLine(audioFormat) succeeds, but open() throws an exception * In OpenJDK, AudioSystem.getSourceDataLine(audioFormat) succeeds, and open() succeeds The above carnage amounts to: * In JDK, sound is completely unusable with any other application playing sound * In OpenJDK, at least one SourceDataLine - the default one called "default [default]" - works well even with other applications playing sound The lack of the "default" device in JDK6 is strange, since jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c seems to have had it since the initial import in revision 0c738a3e5791. $ strings openjdk7/build/linux-i586/j2sdk-image/jre/lib/i386/libjsoundalsa.so | grep default default $ strings jdk6/jre/lib/i386/libjsoundalsa.so | grep default (nothing) So it looks like there's some vital patch that adds support for the "default" ALSA device that hasn't been applied to JDK6. My tests on jre-7-ea-bin-b144-linux-i586-26_may_2011.tar.gz from http://jdk7.java.net show that it does see the "default" device, but even the latest jdk1.6.0_25 doesn't see it, so this bug seems specific to JDK6/JRE6. So please can you add the "default" device to JDK6? Thank you Damjan Jovanovic P.S. Out of interest, why is the "default" device necessary? Java opens most ALSA devices with the "plughw:" prefix, which is "plug" (ALSA does sample conversions in user-space) and "hw" together (direct hardware access, locking out other applications unless the sound card supports hardware mixing). The "default" device is special-cased, and opened without a "plughw:" prefix. In addition, with PulseAudio installed, most Linux distributions make the "default" device go through PulseAudio, which does high quality resampling and mixing, and allows multiple applications to share access to sound hardware. From omajid at redhat.com Mon May 30 06:47:57 2011 From: omajid at redhat.com (Omair Majid) Date: Mon, 30 May 2011 09:47:57 -0400 Subject: JDK6 doesn't see the "default" ALSA device, preventing sound card sharing with other applications? In-Reply-To: References: Message-ID: <4DE3A00D.8030103@redhat.com> On 05/30/2011 05:30 AM, Damjan Jovanovic wrote: > Hi > > On Linux, JDK6 doesn't show/use the "default" ALSA device. By > comparison, this device is shown and used by OpenJDK. The "default" > device is the only device capable of properly sharing access to the > sound card with other native applications, so it's pretty vital. > You may find this OpenJDK bug report relevant: https://bugs.openjdk.java.net/show_bug.cgi?id=100043 Unfortunately, there is nothing I can do to fix the proprietary JDK6. If you don't mind me asking, is there any particular reason you are using the proprietary JDK and not OpenJDK6/IcedTea6? Thanks, Omair From damjan.jov at gmail.com Mon May 30 08:00:39 2011 From: damjan.jov at gmail.com (Damjan Jovanovic) Date: Mon, 30 May 2011 17:00:39 +0200 Subject: JDK6 doesn't see the "default" ALSA device, preventing sound card sharing with other applications? In-Reply-To: <4DE3A00D.8030103@redhat.com> References: <4DE3A00D.8030103@redhat.com> Message-ID: On Mon, May 30, 2011 at 3:47 PM, Omair Majid wrote: > On 05/30/2011 05:30 AM, Damjan Jovanovic wrote: >> >> Hi >> >> On Linux, JDK6 doesn't show/use the "default" ALSA device. By >> comparison, this device is shown and used by OpenJDK. The "default" >> device is the only device capable of properly sharing access to the >> sound card with other native applications, so it's pretty vital. >> > > You may find this OpenJDK bug report relevant: > https://bugs.openjdk.java.net/show_bug.cgi?id=100043 > > Unfortunately, there is nothing I can do to fix the proprietary JDK6. > > If you don't mind me asking, is there any particular reason you are using > the proprietary JDK and not OpenJDK6/IcedTea6? > > Thanks, > Omair > Well I want my application to work for other Linux users who might only have the proprietary JDK. Also a pulse-java.jar bug makes recording sound in IcedTea and at least Ubuntu's OpenJDK package completely unusable for me so I can't recommend that either: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=734 Thank you Damjan Jovanovic