Re: <Sound Dev> Opening multiple output lines

View: New views
6 Messages — Rating Filter:   Alert me  

Re: <Sound Dev> Opening multiple output lines

by Juraj Svec :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
could you please send some more information? Output of the
TRACE1("Opening ALSA device %s\n", buffer); above the snd_pcm_open would
be great and also your sound card type and version will definitely help.

Thanks,

Juraj


 > Hi,
 >
 > I'm testing a sound-using applet on Fedora 8.  Sun JDK 1.6 runs the
applet
 > correctly but OpenJDK does not.  The applet attempts to open two
audio playback
 > lines in succession, without closing the first before attempting to
open the
 > second.  The first open attempt succeeds but the second attempt fails
with:
 >
 > javax.sound.sampled.LineUnavailableException: line with format
PCM_SIGNED
 > 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
 >          at
 >
com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:511)
 >          at
com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:124)
 >          at
com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:156)
 >          at PAPU.start(PAPU.java:198)
 >          at NES.enableSound(NES.java:390)
 >          at AppletGui.init(AppletGui.java:38)
 >          at sun.applet.AppletPanel.run(AppletPanel.java:435)
 >          at java.lang.Thread.run(Thread.java:674)
 >
 > The exception message is misleading since the line format is
supported.  The
 > actual cause of the failure is in:
 >
 > PLATFORM_API_LinuxOS_ALSA_PCMUtils.c:openPCMfromDeviceID
 >
 > This call:
 >
 >      ret = snd_pcm_open(handle, buffer,
 >
isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
 >                         SND_PCM_NONBLOCK);
 >
 > returns the error corresponding to "Device or resource busy".
 >
 > The attached test case demonstrates the failure.
 >
 > Tom
 >
 > -------------- next part --------------
 > A non-text attachment was scrubbed...
 > Name: AudioSystemGetLineTest.java
 > Type: text/x-java
 > Size: 747 bytes
 > Desc: not available
 > Url :
http://mail.openjdk.java.net/pipermail/sound-dev/attachments/20071123/3375bb6c/attachment.bin 



Re: <Sound Dev> Opening multiple output lines

by Thomas Fitzsimmons :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I've attached the output of running AudioSystemGetLineTest against
openjdk-6-src-b09-11_apr_2008 with USE_TRACE defined, and the description of my
sound card reported by lspci -vv.

Tom

Juraj Svec wrote:

> Hi,
> could you please send some more information? Output of the
> TRACE1("Opening ALSA device %s\n", buffer); above the snd_pcm_open would
> be great and also your sound card type and version will definitely help.
>
> Thanks,
>
> Juraj
>
>
>  > Hi,
>  >
>  > I'm testing a sound-using applet on Fedora 8.  Sun JDK 1.6 runs the
> applet
>  > correctly but OpenJDK does not.  The applet attempts to open two
> audio playback
>  > lines in succession, without closing the first before attempting to
> open the
>  > second.  The first open attempt succeeds but the second attempt fails
> with:
>  >
>  > javax.sound.sampled.LineUnavailableException: line with format
> PCM_SIGNED
>  > 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
>  >          at
>  >
> com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:511)
>
>  >          at
> com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:124)
>  >          at
> com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:156)
>  >          at PAPU.start(PAPU.java:198)
>  >          at NES.enableSound(NES.java:390)
>  >          at AppletGui.init(AppletGui.java:38)
>  >          at sun.applet.AppletPanel.run(AppletPanel.java:435)
>  >          at java.lang.Thread.run(Thread.java:674)
>  >
>  > The exception message is misleading since the line format is
> supported.  The
>  > actual cause of the failure is in:
>  >
>  > PLATFORM_API_LinuxOS_ALSA_PCMUtils.c:openPCMfromDeviceID
>  >
>  > This call:
>  >
>  >      ret = snd_pcm_open(handle, buffer,
>  > isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
>  >                         SND_PCM_NONBLOCK);
>  >
>  > returns the error corresponding to "Device or resource busy".
>  >
>  > The attached test case demonstrates the failure.
>  >
>  > Tom
>  >
>  > -------------- next part --------------
>  > A non-text attachment was scrubbed...
>  > Name: AudioSystemGetLineTest.java
>  > Type: text/x-java
>  > Size: 747 bytes
>  > Desc: not available
>  > Url :
> http://mail.openjdk.java.net/pipermail/sound-dev/attachments/20071123/3375bb6c/attachment.bin 
>
>

Java_com_sun_media_sound_PortMixerProvider_nGetNumDevices.
> PORT_GetPortMixerCount
PORT_GetPortMixerCount: Opening alsa device "hw:0"...
< PORT_GetPortMixerCount
Java_com_sun_media_sound_PortMixerProvider_nGetNumDevices returning 1.
Java_com_sun_media_sound_PortMixerProvider_nNewPortMixerInfo(0).
> PORT_GetPortMixerDescription
Opening alsa device "hw:0"...
< PORT_GetPortMixerDescription
Java_com_sun_media_sound_PortMixerProvider_nNewPortMixerInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nGetNumDevices.
Opening alsa device "hw:0"...
Java_com_sun_media_sound_DirectAudioDeviceProvider_nGetNumDevices returning 6.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(0).
Get description for device 0
 getAudioDeviceDescriptionByIndex(mixerIndex = 0
Returning dmix:0 [default], ALSA (http://www.alsa-project.org), dmix:0, dmix:0, dmix:0, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(1).
Get description for device 1
 getAudioDeviceDescriptionByIndex(mixerIndex = 1
Opening alsa device "hw:0"...
Returning ICH5 [plughw:0,0], ALSA (http://www.alsa-project.org), Intel ICH5, Intel ICH, Intel ICH5, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(2).
Get description for device 2
 getAudioDeviceDescriptionByIndex(mixerIndex = 2
Opening alsa device "hw:0"...
Returning ICH5 [plughw:0,1], ALSA (http://www.alsa-project.org), Intel ICH5, Intel ICH - MIC ADC, Intel ICH5 - MIC ADC, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(3).
Get description for device 3
 getAudioDeviceDescriptionByIndex(mixerIndex = 3
Opening alsa device "hw:0"...
Returning ICH5 [plughw:0,2], ALSA (http://www.alsa-project.org), Intel ICH5, Intel ICH - MIC2 ADC, Intel ICH5 - MIC2 ADC, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(4).
Get description for device 4
 getAudioDeviceDescriptionByIndex(mixerIndex = 4
Opening alsa device "hw:0"...
Returning ICH5 [plughw:0,3], ALSA (http://www.alsa-project.org), Intel ICH5, Intel ICH - ADC2, Intel ICH5 - ADC2, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo(5).
Get description for device 5
 getAudioDeviceDescriptionByIndex(mixerIndex = 5
Opening alsa device "hw:0"...
Returning ICH5 [plughw:0,4], ALSA (http://www.alsa-project.org), Intel ICH5, Intel ICH - IEC958, Intel ICH5 - IEC958, 1.0.16rc2
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo succeeded.
Opening ALSA device default
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=10000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=20000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=1
could not get format from alsa for format 14
could not get format from alsa for format 15
could not get format from alsa for format 16
could not get format from alsa for format 17
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=8 bytes, channels=1, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=80000 bytes, channels=10000, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=2, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=8 bytes, channels=1, sampleRate=-1 enc=2, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=80000 bytes, channels=10000, sampleRate=-1 enc=2, signed=0, bigEndian=0
could not get format from alsa for format 22
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=1
Opening ALSA device default
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=10000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=20000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=32 bits, frameSize=40000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=1
could not get format from alsa for format 14
could not get format from alsa for format 15
could not get format from alsa for format 16
could not get format from alsa for format 17
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=8 bytes, channels=1, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=80000 bytes, channels=10000, sampleRate=-1 enc=1, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=2, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=8 bytes, channels=1, sampleRate=-1 enc=2, signed=0, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=80000 bytes, channels=10000, sampleRate=-1 enc=2, signed=0, bigEndian=0
could not get format from alsa for format 22
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=1, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=0
AddAudioFormat with sigBits=18 bits, frameSize=-1 bytes, channels=-1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=0, bigEndian=1
AddAudioFormat with sigBits=18 bits, frameSize=30000 bytes, channels=10000, sampleRate=-1 enc=0, signed=0, bigEndian=1
Opening ALSA device hw:0,0
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=6 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=8 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=10 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=12 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=3 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=4 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=5 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=6 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=8 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=12 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=16 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=20 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=32 bits, frameSize=24 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=4 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=8 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=12 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=16 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=20 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=24 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=6 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=9 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=12 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=15 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=24 bits, frameSize=18 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=3 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=6 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=9 bytes, channels=3, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=12 bytes, channels=4, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=15 bytes, channels=5, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=20 bits, frameSize=18 bytes, channels=6, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,0
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,1
Opening ALSA device hw:0,1
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,2
Opening ALSA device hw:0,2
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,3
Opening ALSA device hw:0,3
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,4
AddAudioFormat with sigBits=16 bits, frameSize=2 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=16 bits, frameSize=4 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=1 bytes, channels=1, sampleRate=-1 enc=0, signed=1, bigEndian=0
AddAudioFormat with sigBits=8 bits, frameSize=2 bytes, channels=2, sampleRate=-1 enc=0, signed=1, bigEndian=0
Opening ALSA device hw:0,4
> PORT_Open
> PORT_GetPortCount
Simple mixer control 'Master',0
Simple mixer control 'Master Mono',0
Simple mixer control 'Master Surround',0
Simple mixer control 'Headphone Jack Sense',0
Simple mixer control 'PCM',0
Simple mixer control 'Surround',0
Simple mixer control 'Surround Jack Mode',0
Simple mixer control 'Center',0
Simple mixer control 'LFE',0
Simple mixer control 'Line',0
Simple mixer control 'Line Jack Sense',0
Simple mixer control 'CD',0
Simple mixer control 'Mic',0
Simple mixer control 'Mic Boost (+20dB)',0
Simple mixer control 'Mic Select',0
Simple mixer control 'Video',0
Simple mixer control 'Phone',0
Simple mixer control 'Aux',0
Simple mixer control 'Capture',0
Simple mixer control 'Mix',0
Simple mixer control 'Mix Mono',0
Simple mixer control 'Channel Mode',0
Simple mixer control 'Downmix',0
Simple mixer control 'Exchange Front/Surround',0
Simple mixer control 'External Amplifier',0
Simple mixer control 'High Pass Filter Enable',0
Simple mixer control 'Spread Front to Surround and Center/LFE',0
Simple mixer control 'Stereo Mic',0
Simple mixer control 'V_REFOUT Enable',0
< PORT_GetPortCount
< PORT_Open
> PORT_GetPortCount
< PORT_GetPortCount
Java_com_sun_media_sound_PortMixer_nGetPortType(0).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(0).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Master".
Java_com_sun_media_sound_PortMixer_nGetPortType(1).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(1).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Master Mono".
Java_com_sun_media_sound_PortMixer_nGetPortType(2).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(2).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Master Surround".
Java_com_sun_media_sound_PortMixer_nGetPortType(3).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(3).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "PCM".
Java_com_sun_media_sound_PortMixer_nGetPortType(4).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(4).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Surround".
Java_com_sun_media_sound_PortMixer_nGetPortType(5).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(5).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Center".
Java_com_sun_media_sound_PortMixer_nGetPortType(6).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(6).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "LFE".
Java_com_sun_media_sound_PortMixer_nGetPortType(7).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(7).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Line".
Java_com_sun_media_sound_PortMixer_nGetPortType(8).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(8).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "CD".
Java_com_sun_media_sound_PortMixer_nGetPortType(9).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(9).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Mic".
Java_com_sun_media_sound_PortMixer_nGetPortType(10).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(10).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Phone".
Java_com_sun_media_sound_PortMixer_nGetPortType(11).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 256.
Java_com_sun_media_sound_PortMixer_nGetPortName(11).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Aux".
Java_com_sun_media_sound_PortMixer_nGetPortType(12).
> PORT_GetPortType
< PORT_GetPortType
Java_com_sun_media_sound_PortMixerProvider_nGetPortType returning 1.
Java_com_sun_media_sound_PortMixer_nGetPortName(12).
> PORT_GetPortName
< PORT_GetPortName
Java_com_sun_media_sound_PortMixerProvider_nGetName returning "Capture".
> PORT_Close
< PORT_Close
> DAUDIO_Open
Opening ALSA device plughw:0,0
  DAUDIO_Open: period size = 1024 frames, periods = 16. Buffer size: 65536 bytes.
< DAUDIO_Open: Opened device successfully. Handle=0x8b73fe8
> DAUDIO_Open
Opening ALSA device plughw:0,0
DAUDIO_Close
Exception in thread "main" javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
        at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:511)
        at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:124)
        at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:156)
        at AudioSystemGetLineTest.main(AudioSystemGetLineTest.java:15)

00:1f.5 Multimedia audio controller: Intel Corporation 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (rev 02)
        Subsystem: Dell Unknown device 0155
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupt: pin B routed to IRQ 17
        Region 0: I/O ports at ee00 [size=256]
        Region 1: I/O ports at edc0 [size=64]
        Region 2: Memory at febffa00 (32-bit, non-prefetchable) [size=512]
        Region 3: Memory at febff900 (32-bit, non-prefetchable) [size=256]
        Capabilities: [50] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Kernel driver in use: Intel ICH
        Kernel modules: snd-intel8x0

Re: <Sound Dev> Opening multiple output lines

by Mark Wielaard :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tom,

On Wed, Apr 30, 2008 at 09:17:11PM -0400, Thomas Fitzsimmons wrote:

>>> I'm testing a sound-using applet on Fedora 8.  Sun JDK 1.6 runs the
>>> appletcorrectly but OpenJDK does not.  The applet attempts to open two
>>> audio playback lines in succession, without closing the first before
>>> attempting to open the second.
>>> The first open attempt succeeds but the second attempt fails with:
>>>
>>> javax.sound.sampled.LineUnavailableException: line with format
>>> PCM_SIGNED
>>> 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
>>> [...]
>>>
>>> The exception message is misleading since the line format is
>>> supported.  The actual cause of the failure is in:
>>>
>>> PLATFORM_API_LinuxOS_ALSA_PCMUtils.c:openPCMfromDeviceID
>>>
>>> This call:
>>>
>>>      ret = snd_pcm_open(handle, buffer,
>>> isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
>>>                         SND_PCM_NONBLOCK);
>>>
>>> returns the error corresponding to "Device or resource busy".
>
> Juraj Svec wrote:
>> could you please send some more information? Output of the
>> TRACE1("Opening ALSA device %s\n", buffer); above the snd_pcm_open would
>> be great and also your sound card type and version will definitely help.
>
> I've attached the output of running AudioSystemGetLineTest against
> openjdk-6-src-b09-11_apr_2008 with USE_TRACE defined,
> and the description of my sound card reported by lspci -vv.
I had the same problem with a similar setup and with applications that
forget to close a line they don't use anymore (unfortunately this seems
very common). With the current directaudio backend I don't see how multiple
lines for the same hardware device could work though. So I am using a
trick to look for "sloppy" applications. If the last line opened in the
directaudio device was for the same hardware format then we silence that
one first so we can hand out a new one. This seems to work surprisingly
well. And it doesn't seem to interfere with applications that handle the
hardware formats they need explicitly.

With gcjwebplugin and this patch we can happily play the vNES games :)

Of course a real solution would be to import or write a better mixer
that does share lines properly.

Cheers,

Mark

--- /home/mark/src/openjdk/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java 2008-04-13 01:05:30.000000000 +0200
+++ openjdk/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java 2008-05-04 18:42:39.000000000 +0200
@@ -394,7 +394,10 @@
         private float leftGain, rightGain;
         protected volatile boolean noService = false; // do not run the nService method
 
-        protected Object lockNative = new Object();
+        // Guards all native calls and the lastOpened static variable.
+        protected static Object lockNative = new Object();
+        // Keeps track of last opened line, see implOpen "trick".
+        protected static DirectDL lastOpened;
 
         // CONSTRUCTOR
         protected DirectDL(DataLine.Info info,
@@ -496,20 +499,47 @@
             // align buffer to full frames
             bufferSize = ((int) bufferSize / format.getFrameSize()) * format.getFrameSize();
 
-            id = nOpen(mixerIndex, deviceID, isSource,
-                       encoding,
-                       hardwareFormat.getSampleRate(),
-                       hardwareFormat.getSampleSizeInBits(),
-                       hardwareFormat.getFrameSize(),
-                       hardwareFormat.getChannels(),
-                       hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
-                       hardwareFormat.isBigEndian(),
-                       bufferSize);
+    synchronized(lockNative) {
+      id = nOpen(mixerIndex, deviceID, isSource,
+ encoding,
+ hardwareFormat.getSampleRate(),
+ hardwareFormat.getSampleSizeInBits(),
+ hardwareFormat.getFrameSize(),
+ hardwareFormat.getChannels(),
+ hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
+ hardwareFormat.isBigEndian(),
+ bufferSize);
+      
+      if (id == 0) {
+ // Bah... Dirty trick. The most likely cause is an application
+ // already having a line open for this particular hardware
+ // format and forgetting about it. If so, silently close that
+ // implementation and try again. Unfortuantely we can only
+ // open one line per hardware format currently.
+ if (lastOpened != null
+    && hardwareFormat.matches(lastOpened.hardwareFormat)) {
+  lastOpened.implClose();
+  lastOpened = null;
+  
+  id = nOpen(mixerIndex, deviceID, isSource,
+     encoding,
+     hardwareFormat.getSampleRate(),
+     hardwareFormat.getSampleSizeInBits(),
+     hardwareFormat.getFrameSize(),
+     hardwareFormat.getChannels(),
+     hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
+     hardwareFormat.isBigEndian(),
+     bufferSize);
+ }
+
+ if (id == 0) {
+    // TODO: nicer error messages...
+    throw new LineUnavailableException("line with format "+format+" not supported.");
+                }
+      }
+      lastOpened = this;
+    }
 
-            if (id == 0) {
-                // TODO: nicer error messages...
-                throw new LineUnavailableException("line with format "+format+" not supported.");
-            }
             this.bufferSize = nGetBufferSize(id, isSource);
             if (this.bufferSize < 1) {
                 // this is an error!
@@ -616,6 +646,8 @@
             id = 0;
             synchronized (lockNative) {
                 nClose(oldID, isSource);
+                if (lastOpened == this)
+                  lastOpened = null;
             }
             bytePosition = 0;
             softwareConversionSize = 0;

Re: <Sound Dev> Opening multiple output lines

by Mark Wielaard :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

On Sun, 2008-05-04 at 19:19 +0200, Mark Wielaard wrote:

> I had the same problem with a similar setup and with applications that
> forget to close a line they don't use anymore (unfortunately this seems
> very common). With the current directaudio backend I don't see how multiple
> lines for the same hardware device could work though. So I am using a
> trick to look for "sloppy" applications. If the last line opened in the
> directaudio device was for the same hardware format then we silence that
> one first so we can hand out a new one. This seems to work surprisingly
> well. And it doesn't seem to interfere with applications that handle the
> hardware formats they need explicitly.
>
> With gcjwebplugin and this patch we can happily play the vNES games :)
>
> Of course a real solution would be to import or write a better mixer
> that does share lines properly.
I updated the patch a little to make it all a bit more robust. It splits
the locks, so there is no longer one gaint static one (I shouldn't have
reused the lockNative one and made that static in the original patch).

And it makes sure that all methods that require the nativeLock check the
doIO inside their synchronized block and the lock around nStop() isn't
released before the flag is set. ALSA can actually hang when called on a
pcm you already stopped or closed. This race was already in the code,
since a DataSourceLine could be asynchronously stopped or closed at any
time. My patch just exposed it more easily, because DirectAudioDevice is
the mixer that is now always used by defailt.

2008-05-08  Mark Wielaard  <mark@...>

        * patches/icedtea-directaudio-close-trick.patch: Use new static
        lockLast for nOpen/nClose guarding.  Make lockNative non-static
        again.  Do all checks before native calls of doIO inside
        lockNative guard. Set doIO to false after nClose before dropping
        lockNative guard.

I do think we should write a new MixerProvider based on a modern
soundserver, like pulseaudio. The current DirectAudioDeviceProvider code
cannot easily be extended to provide true software sound mixing. And the
way it opens direct hardware alsa devices means it locks out other
applications.

Cheers,

Mark

Patch against original code (updated patch file in icedtea6).

--- /home/mark/src/openjdk/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java 2008-04-13 01:05:30.000000000 +0200
+++ openjdk/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java 2008-05-09 02:18:21.000000000 +0200
@@ -394,7 +394,12 @@
         private float leftGain, rightGain;
         protected volatile boolean noService = false; // do not run the nService method
 
+        // Guards all native calls.
         protected Object lockNative = new Object();
+        // Guards the lastOpened static variable in implOpen and implClose.
+        protected static Object lockLast = new Object();
+        // Keeps track of last opened line, see implOpen "trick".
+        protected static DirectDL lastOpened;
 
         // CONSTRUCTOR
         protected DirectDL(DataLine.Info info,
@@ -496,20 +501,47 @@
             // align buffer to full frames
             bufferSize = ((int) bufferSize / format.getFrameSize()) * format.getFrameSize();
 
-            id = nOpen(mixerIndex, deviceID, isSource,
-                       encoding,
-                       hardwareFormat.getSampleRate(),
-                       hardwareFormat.getSampleSizeInBits(),
-                       hardwareFormat.getFrameSize(),
-                       hardwareFormat.getChannels(),
-                       hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
-                       hardwareFormat.isBigEndian(),
-                       bufferSize);
+    synchronized(lockLast) {
+      id = nOpen(mixerIndex, deviceID, isSource,
+ encoding,
+ hardwareFormat.getSampleRate(),
+ hardwareFormat.getSampleSizeInBits(),
+ hardwareFormat.getFrameSize(),
+ hardwareFormat.getChannels(),
+ hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
+ hardwareFormat.isBigEndian(),
+ bufferSize);
+      
+      if (id == 0) {
+ // Bah... Dirty trick. The most likely cause is an application
+ // already having a line open for this particular hardware
+ // format and forgetting about it. If so, silently close that
+ // implementation and try again. Unfortuantely we can only
+ // open one line per hardware format currently.
+ if (lastOpened != null
+    && hardwareFormat.matches(lastOpened.hardwareFormat)) {
+  lastOpened.implClose();
+  lastOpened = null;
+  
+  id = nOpen(mixerIndex, deviceID, isSource,
+     encoding,
+     hardwareFormat.getSampleRate(),
+     hardwareFormat.getSampleSizeInBits(),
+     hardwareFormat.getFrameSize(),
+     hardwareFormat.getChannels(),
+     hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
+     hardwareFormat.isBigEndian(),
+     bufferSize);
+ }
+
+ if (id == 0) {
+    // TODO: nicer error messages...
+    throw new LineUnavailableException("line with format "+format+" not supported.");
+                }
+      }
+      lastOpened = this;
+    }
 
-            if (id == 0) {
-                // TODO: nicer error messages...
-                throw new LineUnavailableException("line with format "+format+" not supported.");
-            }
             this.bufferSize = nGetBufferSize(id, isSource);
             if (this.bufferSize < 1) {
                 // this is an error!
@@ -580,12 +612,12 @@
             }
             synchronized (lockNative) {
                 nStop(id, isSource);
-            }
 
-            // need to set doIO to false before notifying the
-            // read/write thread, that's why isStartedRunning()
-            // cannot be used
-            doIO = false;
+                // need to set doIO to false before notifying the
+                // read/write thread, that's why isStartedRunning()
+                // cannot be used
+                doIO = false;
+            }
             // wake up any waiting threads
             synchronized(lock) {
                 lock.notifyAll();
@@ -614,8 +646,12 @@
             doIO = false;
             long oldID = id;
             id = 0;
-            synchronized (lockNative) {
-                nClose(oldID, isSource);
+            synchronized (lockLast) {
+                synchronized (lockNative) {
+                    nClose(oldID, isSource);
+                    if (lastOpened == this)
+                      lastOpened = null;
+                }
             }
             bytePosition = 0;
             softwareConversionSize = 0;
@@ -630,7 +666,8 @@
             }
             int a = 0;
             synchronized (lockNative) {
-                a = nAvailable(id, isSource);
+                if (doIO)
+                    a = nAvailable(id, isSource);
             }
             return a;
         }
@@ -644,9 +681,9 @@
             int counter = 0;
             long startPos = getLongFramePosition();
             boolean posChanged = false;
-            while (!drained && doIO) {
+            while (!drained) {
                 synchronized (lockNative) {
-                    if ((id == 0) || !nIsStillDraining(id, isSource))
+                    if ((id == 0) || (!doIO) || !nIsStillDraining(id, isSource))
                         break;
                 }
                 // check every now and then for a new position
@@ -686,7 +723,7 @@
                     lock.notifyAll();
                 }
                 synchronized (lockNative) {
-                    if (id != 0) {
+                    if (id != 0 && doIO) {
                         // then flush native buffers
                         nFlush(id, isSource);
                     }
@@ -697,9 +734,10 @@
 
         // replacement for getFramePosition (see AbstractDataLine)
         public long getLongFramePosition() {
-            long pos;
+            long pos = 0;
             synchronized (lockNative) {
-                pos = nGetBytePosition(id, isSource, bytePosition);
+                if (doIO)
+                    pos = nGetBytePosition(id, isSource, bytePosition);
             }
             // hack because ALSA sometimes reports wrong framepos
             if (pos < 0) {
@@ -745,11 +783,12 @@
             }
             int written = 0;
             while (!flushing) {
-                int thisWritten;
+                int thisWritten = 0;
                 synchronized (lockNative) {
-                    thisWritten = nWrite(id, b, off, len,
-                            softwareConversionSize,
-                            leftGain, rightGain);
+                    if (doIO)
+                        thisWritten = nWrite(id, b, off, len,
+                                softwareConversionSize,
+                                leftGain, rightGain);
                     if (thisWritten < 0) {
                         // error in native layer
                         break;
@@ -972,9 +1011,10 @@
             }
             int read = 0;
             while (doIO && !flushing) {
-                int thisRead;
+                int thisRead = 0;
                 synchronized (lockNative) {
-                    thisRead = nRead(id, b, off, len, softwareConversionSize);
+                    if (doIO)
+                        thisRead = nRead(id, b, off, len, softwareConversionSize);
                     if (thisRead < 0) {
                         // error in native layer
                         break;
@@ -1209,7 +1249,8 @@
             // set new native position (if necessary)
             // this must come after the flush!
             synchronized (lockNative) {
-                nSetBytePosition(id, isSource, frames * frameSize);
+                if (doIO)
+                    nSetBytePosition(id, isSource, frames * frameSize);
             }
 
             if (Printer.debug) Printer.debug("  DirectClip.setFramePosition: "

Re: <Sound Dev> Opening multiple output lines

by Karl Helgason-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I added software sound mixing to the gervill Project which writes to default directaudio backend.
And thus allows true sharing of audio device (within the Java application).

cheers,
Karl Helgason
________________________________________
Frá: sound-dev-bounces@... [sound-dev-bounces@...] Fyrir hönd Mark Wielaard [mark@...]
Sent: 9. maí 2008 00:48
Viðtakandi: Thomas Fitzsimmons
Afrit: sound-dev@...; distro-pkg-dev@...
Efni: Re: <Sound Dev> Opening multiple output lines

Hi,

On Sun, 2008-05-04 at 19:19 +0200, Mark Wielaard wrote:

> I had the same problem with a similar setup and with applications that
> forget to close a line they don't use anymore (unfortunately this seems
> very common). With the current directaudio backend I don't see how multiple
> lines for the same hardware device could work though. So I am using a
> trick to look for "sloppy" applications. If the last line opened in the
> directaudio device was for the same hardware format then we silence that
> one first so we can hand out a new one. This seems to work surprisingly
> well. And it doesn't seem to interfere with applications that handle the
> hardware formats they need explicitly.
>
> With gcjwebplugin and this patch we can happily play the vNES games :)
>
> Of course a real solution would be to import or write a better mixer
> that does share lines properly.

I updated the patch a little to make it all a bit more robust. It splits
the locks, so there is no longer one gaint static one (I shouldn't have
reused the lockNative one and made that static in the original patch).

And it makes sure that all methods that require the nativeLock check the
doIO inside their synchronized block and the lock around nStop() isn't
released before the flag is set. ALSA can actually hang when called on a
pcm you already stopped or closed. This race was already in the code,
since a DataSourceLine could be asynchronously stopped or closed at any
time. My patch just exposed it more easily, because DirectAudioDevice is
the mixer that is now always used by defailt.

2008-05-08  Mark Wielaard  <mark@...>

        * patches/icedtea-directaudio-close-trick.patch: Use new static
        lockLast for nOpen/nClose guarding.  Make lockNative non-static
        again.  Do all checks before native calls of doIO inside
        lockNative guard. Set doIO to false after nClose before dropping
        lockNative guard.

I do think we should write a new MixerProvider based on a modern
soundserver, like pulseaudio. The current DirectAudioDeviceProvider code
cannot easily be extended to provide true software sound mixing. And the
way it opens direct hardware alsa devices means it locks out other
applications.

Cheers,

Mark

Patch against original code (updated patch file in icedtea6).

No virus found in this incoming message.
Checked by AVG.
Version: 7.5.524 / Virus Database: 269.23.10/1421 - Release Date: 7.5.2008 17:23



Re: <Sound Dev> Opening multiple output lines

by Mark Wielaard :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Karl,

On Fri, 2008-05-09 at 19:58 +0000, Karl Helgason wrote:
> I added software sound mixing to the gervill Project which writes to default directaudio backend.
> And thus allows true sharing of audio device (within the Java application).

This is great! Sorry for the late response. I integrated it into
icedtea. But I haven't set it as default yet because I didn't have time
to fully test it. I do want to have it integrated so others can play
with it though.

Also thanks for your AudioFloatFormatConverter.getTargetFormats() fix, I
removed my own attempt of fixing that. And for integrating the dls/sf2
soundbank opening issues.

Also since we now have jtreg integrated I imported all the tests so they
will now all be run by default on a make check (or make jtregcheck).
That found two issues.

One with a test. TestRender1 accesses its test files through
getResourceAsStream(), but the jtreg tag specification recommends
opening files through the system property test.src so that the test can
be run inside another work directory. See
http://www.openjdk.org/jtreg/tag-spec.txt
Patch to change this attached.

The other issue is with the change that made SoftAudioProcessor
(limiter, reverb, chorus, agc) more general. Since you cannot provide a
Synthesizer directly to one of these classes you need a way to pass it
the control rate. Unfortunately SoftSynthesizer.getControlRate() is
currently protected and there is as far as I can see no other way to get
the control rate. So I believe the method should be made public. A
change to do this and adapt the tests to use this is attached.

With these changes all tests pass.

Cheers,

Mark

[TestRender1-test.src.patch]

Index: test/com/sun/media/sound/SoftSynthesizer/TestRender1.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftSynthesizer/TestRender1.java,v
retrieving revision 1.1
diff -u -r1.1 TestRender1.java
--- test/com/sun/media/sound/SoftSynthesizer/TestRender1.java 2 Jan 2008 12:24:16 -0000 1.1
+++ test/com/sun/media/sound/SoftSynthesizer/TestRender1.java 25 May 2008 19:07:10 -0000
@@ -29,6 +29,8 @@
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.OutputStream;
 import java.util.HashMap;
 import java.util.Map;
@@ -134,13 +136,15 @@
 
  public static void main(String[] args) throws Exception {
 
- InputStream sb = new BufferedInputStream(TestRender1.class
- .getResourceAsStream("/ding.sf2"));
+ File fb = new File(System.getProperty("test.src", "."),
+   "ding.sf2");
+ InputStream sb = new FileInputStream(fb);
  soundbank = MidiSystem.getSoundbank(sb);
  sb.close();
 
- InputStream si = new BufferedInputStream(TestRender1.class
- .getResourceAsStream("/expresso.mid"));
+ File fi = new File(System.getProperty("test.src", "."),
+   "expresso.mid");
+ InputStream si = new FileInputStream(fi);
  sequence = MidiSystem.getSequence(si);
  si.close();
 


[controlrate.patch]

Index: src/com/sun/media/sound/SoftSynthesizer.java
===================================================================
RCS file: /cvs/gervill/src/com/sun/media/sound/SoftSynthesizer.java,v
retrieving revision 1.31
diff -u -r1.31 SoftSynthesizer.java
--- src/com/sun/media/sound/SoftSynthesizer.java 5 Mar 2008 03:35:22 -0000 1.31
+++ src/com/sun/media/sound/SoftSynthesizer.java 25 May 2008 19:12:24 -0000
@@ -331,7 +331,10 @@
  return deviceid;
  }
 
- protected float getControlRate() {
+ /**
+ * Returns the number of control changes per second.
+ */
+ public float getControlRate() {
  return controlrate;
  }
 
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_mix.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix.java 11 Dec 2007 02:49:18 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix.java 25 May 2008 19:12:24 -0000
@@ -71,7 +71,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(true);
  limiter.setInput(0, in1);
  limiter.setInput(1, in2);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_mix_mono.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono.java 11 Dec 2007 02:49:19 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono.java 25 May 2008 19:12:24 -0000
@@ -63,7 +63,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(true);
  limiter.setInput(0, in1);
  limiter.setOutput(0, out1);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_mix_mono_overdrive.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java 11 Dec 2007 02:49:17 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java 25 May 2008 19:12:24 -0000
@@ -64,7 +64,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(true);
  limiter.setInput(0, in1);
  limiter.setOutput(0, out1);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_overdrive.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_overdrive.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_mix_overdrive.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_overdrive.java 11 Dec 2007 02:50:21 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_mix_overdrive.java 25 May 2008 19:12:24 -0000
@@ -71,7 +71,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(true);
  limiter.setInput(0, in1);
  limiter.setInput(1, in2);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_normal.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal.java 11 Dec 2007 02:50:22 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal.java 25 May 2008 19:12:24 -0000
@@ -71,7 +71,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(false);
  limiter.setInput(0, in1);
  limiter.setInput(1, in2);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal_mono.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal_mono.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_normal_mono.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal_mono.java 11 Dec 2007 02:50:23 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_normal_mono.java 25 May 2008 19:12:24 -0000
@@ -63,7 +63,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(false);
  limiter.setInput(0, in1);
  limiter.setOutput(0, out1);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_overdrive.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive.java 11 Dec 2007 02:49:50 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive.java 25 May 2008 19:12:24 -0000
@@ -71,7 +71,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(false);
  limiter.setInput(0, in1);
  limiter.setInput(1, in2);
Index: test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive_mono.java
===================================================================
RCS file: /cvs/gervill/test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive_mono.java,v
retrieving revision 1.1
diff -u -r1.1 ProcessAudio_replace_overdrive_mono.java
--- test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive_mono.java 11 Dec 2007 02:50:23 -0000 1.1
+++ test/com/sun/media/sound/SoftLimiter/ProcessAudio_replace_overdrive_mono.java 25 May 2008 19:12:24 -0000
@@ -63,7 +63,8 @@
  }
 
  SoftLimiter limiter = new SoftLimiter();
- limiter.init(synth);
+ limiter.init(synth.getFormat().getSampleRate(),
+     synth.getControlRate());
  limiter.setMixMode(false);
  limiter.setInput(0, in1);
  limiter.setOutput(0, out1);