No sound under Linux + JRE 1.6 update 16

Hi

I don’t know why I have no sound with any applet or Java Web Start application. I get this when I launch TUER :

[quote][java] Starting up SoundSystem…
[java] Initializing Java Sound
[java] (The Java Sound API. For more information, see http://java.sun.com/products/java-media/sound/)
[java] JavaSound initialized.
[java] Error in class ‘ChannelJava Sound’
[java] Unable to attach buffer to clip in method ‘attachBuffer’
[java] ERROR MESSAGE:
[java] Audio Device Unavailable
[java] STACK TRACE:
[java] com.sun.media.sound.HeadspaceMixer.nResume(Native Method)
[java] com.sun.media.sound.HeadspaceMixer.implOpen(HeadspaceMixer.java:346)
[java] com.sun.media.sound.AbstractMixer.open(AbstractMixer.java:286)
[java] com.sun.media.sound.AbstractMixer.open(AbstractMixer.java:323)
[java] com.sun.media.sound.MixerClip.open(MixerClip.java:162)
[java] paulscode.sound.libraries.ChannelJavaSound.attachBuffer(ChannelJavaSound.java:276)
[java] paulscode.sound.libraries.SourceJavaSound.play(SourceJavaSound.java:298)
[java] paulscode.sound.Library.play(Library.java:587)
[java] paulscode.sound.Library.play(Library.java:556)
[java] paulscode.sound.SoundSystem.CommandPlay(SoundSystem.java:1892)
[java] paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2388)
[java] paulscode.sound.CommandThread.run(CommandThread.java:121)
[/quote]
The audio device is unavailable even though I use directly the Java Sound library. Do you have an idea?

The only Java game that works fine with sound on my machine is “Breaking the tower”. TUER and Tesseract don’t work anymore :frowning:

Edit.: this bug is reproducible only when my webcam is connected

I would guess that JavaSound is trying to pick the webcam as the default audio device, rather than the soundcard. I am able to produce a similar bug with MIDI, where if I connect my MIDI keyboard, JavaSound will try to play out of it rather than through the soundcard. When I get a chance, I’ll write a test applet that prints out some diagnostic messages to see if this is the same bug you are experiencing here. If it is, a possible workaround is to choose the Mixer associated with your soundcard manually rather than going with the default Mixer (since JavaSound seems to be making a dumb choice by default).

BTW, I looked at the source code for “Breaking the tower”, and the reason why it works while the others don’t is because the author didn’t use a Mixer to play sound effects. He not only generates the sound effects programatically, but he also does the mixing programatically. Everything is placed into a single data stream played through a single SourceDataLine instance acquired with the following line of code:

AudioSystem.getSourceDataLine(audioFormat);

It seems that JavaSound picks the correct device by default when using the getSourceDataLine(…) method, but not when using the getMixer(…) method on the default device named “Java Sound Mixer”??? weird…

I actually considered using the single SourceDataLine method in my SoundSystem, but eventually gave up on the idea as it requires a single audio format for the output, which would require me to convert all data loaded or streamed into that format and then passed to a mixing algorithm. This seemed way to complicated at the time, but I may have to revisit it as a possibility. I’d probably write a separate Library plug-in rather than changing the one I wrote already. It would fix another issue where there is no “Java Sound Mixer” available on some Java versions, such as the OpenJDK…

Do you consider it is a bug of Java? Choosing manually the mixer can cause some regressions on some machines, can’t it?

you can use the other method he described.

I can’t because I don’t use several audio files with the same format.

On my view, maybe it is possible to detect the “bad” mixer that matches with my webcam by looking into Mixer.Info instances returned by getMixerInfo or in the Mixer instance itself in order to get a good mixer when calling getMixer(Mixer.info info).

I had this problem a couple of years back and ended up blacklisting the audio device for the camera in ALSA. Only seemed to be a problem if the camera was plugged in at boot for me.

The other logical solution (though I haven’t tried it) would be to iterate through the available mixers using getMaxLines() or getSourceLineInfo() to find one that’s actually capable of output. I would have thought the webcam only reports inputs?

Having done a variety of audio programming in Java, I’d recommend this approach for lowest latency. It also gets around the issue that the direct mixers aren’t guaranteed to support mixing! This is why on Linux Pulpcore can only play one sound at a time, for instance.

If it’s of interest, I’ve got some code up at http://code.google.com/p/java-audio-utils/ under the Audio Servers section which uses this approach and a couple of other tricks to give stable low latency audio with JavaSound. On my Linux box I’m getting sub-20ms easily. The code’s GPL at the moment, but once I’ve finished the next release of Praxis (which I’m using it for), the intention is for this to be GPL w/CPE.

Best wishes,

Neil

How do you blacklist the audio device?

It is exactly the same for me.

It works. I do such things in the alpha version of TUER, not in the pre-beta version. I used some criteria to find the best mixer for my purposes. Maybe Paul could plan to add a mechanism (some methods in the API or a constructor in paulscode.sound.SoundSystem that would have a parameter) to choose a mixer related on some criteria :


enum SoundUsage {IN,OUT,BOTH,NONE};

public SoundSystem(java.lang.Class libraryClass,SoundUsage usage){
...
switch(usage){
...
//find the mixer that fits the purposes
}
}

Do you think it would be difficult to mix it with what Paul has done in his library?

I think it’s a bit distribution dependent. On Mint (and therefore Ubuntu I presume) it’s under /etc/modprobe.d There’s a blacklist file where you can just add the sound module for the webcam. Or, there’s also the possibility of controlling the index that ALSA gives it in the main alsa-base.conf file. This stops it getting index=0, so it won’t be the first one picked up by JS.

No idea. Not looked at Paul’s code. I’ve tried to design my code to be as simple as possible to work with - you just implement an AudioClient interface that takes FloatBuffers. Or, just hack the code in JavasoundAudioServer to give you the byte buffers directly. My code gives you floats because they’re much easier to work with for software mixing and effects, and also because other sound implementations (there’s a Jack server too) give you floats to start with.

[quote=“gouessej,post:6,topic:35502”]
The one that it uses now is whatever Mixer is labeled “Java Sound Mixer”. In my opinion, this should always be the sound card by default, but apparently Sun/Oracle disagrees. I would personally consider this a bug…

I’m not sure about this particular setup, but testing to see if I have both input and output on the default Mixer (whatever is labeled “Java Sound Mixer” by the Java Sound API) is a good idea. If not, then I can iterate through all other available Mixer’s to find one that does (which would most likely be the sound card, right? Or can you think of a situation where it wouldn’t be?) I’ll give this a shot to see if it works as a quick-fix. I still want to do a diagnostic applet first to make sure what we’re talking about is the actual problem, although I’m pretty sure it is. I’ll add in some more messages to show the input and output capabilities of each mixer as well (the more information the better). I may have time this evening to do a little programming (my schedule has really been crazy and doesn’t seem to be settling down any time soon).

[quote=“gouessej,post:8,topic:35502”]
I do not intend to use this particular code (I seriously despise the GPL and avoid it whenever possible), but it might be worthwhile to look at it and others just to see how other programmers have solved the problem. I’ll write my own code for format conversion and mixing, though, if I eventually go this route.

[quote=“gouessej,post:6,topic:35502”]
That’s the main thing holding me back at the moment. I’d need to take whatever format (sample rate, sample size, etc) the user hands to the SoundSystem and write a method for converting it into a single output format for mixing. I’m sure others have done this, so I just need to do some more research.

This isn’t the mixer to pick if you want low latency, btw, and I’m not sure it’s the default on Windows. It is the only one that’s meant to guarantee software mixing outputs, though. If it’s got no outputs then that definitely sounds like a bug. Are you sure your code is definitely not picking mixer[0] by mistake? In my case with a webcam it would show up as the first mixer, but not as the JavaSound Mixer.

Well, the GPL suits my needs well, so Praxis as a whole is staying GPL, but my intention is to open up any useful libraries that come out of it a bit more liberally. The AudioServers stuff should be GPL with Classpath Exception - I’m using some format conversion stuff from OpenJDK, and as the licence fitted I didn’t see the point in rewriting.

If CPE is still not open enough, then it should be easy enough to reuse the principles - pretty simple stuff. The actual low-latency stuff in the Javasound AudioServer is a mix and match inspired by various approaches from various blog posts and mailing lists. Don’t have the links to hand atm, but Google should be your friend! :wink: Particularly try looking around projects such as Frinika, Toot and RasmusDSP.

Hope that’s a help.

(Does OpenAL work as expected?)

Cas :slight_smile:

Software OpenAL support works better but JOAL is almost no more maintained and I don’t want to use LWJGL, sorry. Using Paul’s library is quite simple, it is an excellent library and it allows me to concentrate on other aspects than audio… Paul seems to know better than me the bugs and limitations of Java Sound.

Paul, are you sure the first mixer called Java Sound Mixer has something to do with the webcam? I thought you pick the first mixer that matches with the first Mixer.Info returned by getMixerInfo(), I should have a look at your source code anew.

I suggested mixing nsigma source code with yours in order to avoid duplicating the efforts. A source code using GPL with Classpath exception can be legally mixed with your source code using your license, can’t it?

Personally, I use GPL v2 for political and legal reasons but I understand that people here have their own constraints and then use other licenses.

Hm, still pathologically resisting something that works?

Cas :slight_smile:

No. I only try to minimize the use of third party libraries that rely on native code.

I checked the code to make sure. It is possible to define your own Mixer, but by default I am definitely searching for it by name (actually the name is “Java Sound Audio Engine” not “Java Sound Mixer”… typo on my part). The relevant code can be found in the LibraryJavaSound.init() method:

        // Check if there is a mixer set yet:
        if( myMixer == null )
        {
            // No real "loading" for the JavaSound library, just grab the Mixer:
            for( Mixer.Info mixerInfo : AudioSystem.getMixerInfo() )
            {
                if( mixerInfo.getName().equals( "Java Sound Audio Engine" ) )
                {
                    // found it!
                    myMixer = AudioSystem.getMixer( mixerInfo );
                    break;
                }
            }
        }

OpenAL-Soft (especially the new version bundled with LWJGL 2.5) has probably the best sound support you can get on Linux.

It supports multiple backends ALSA, OSS, DirectSound, Solaris, PortAudio, PulseAudio, and a .wav writer.

Java Sounds is currently very poor compared to the above.

You can continue using JOGL and just use the OpenAL part of LWJGL if you like (it should work, not tried it).

Well if your already using JOGL an extra native for sound shouldn’t really be a problem.

What do I have to change in a JNLP file to load OpenAL-Soft?

I will try to address the issue with Java Sound as OpenAL-Soft is not available on Mac.

Is it possible that several instances of Mixer are called “Java Sound Audio Engine”? I will perform a test tonight.

Edit.: Paul was right, Java Sound Audio Engine tries to use the camera. This seems to work around the bug but may cause some regressions depending on the audio format:


try{soundSystem=new SoundSystem(LibraryJavaSound.class);
            //if a fucking camera is used as an audio device
            if(LibraryJavaSound.getMixer().getTargetLineInfo().length==0)
                {for(Mixer.Info info:infos)
                     if(!info.getName().contains("Camera"))
                         {Mixer mixer=AudioSystem.getMixer(info);
                	      if(mixer.getTargetLineInfo().length>0)
                	          {LibraryJavaSound.setMixer(mixer);
                		       break;
                	          }
                         }
                }
            SoundSystemConfig.setCodec("ogg",CodecJOrbis.class);
           }
        catch(SoundSystemException sse)
        {System.out.println("The initialization of the sound manager failed: "+sse);}

Sweet, thanks for solving this for me. I’ll put this fix in and have my beta testers try it out to make sure it doesn’t break any legacy code (although looking at it, it shouldn’t - it should only be different if the default Mixer doesn’t have output lines, in which case the previous method wouldn’t work anyway). It’ll be included in the upcoming release, which I’m hoping to post in a week or two after some beta testing (there are quite a few significant changes, such as playback events, a new position-check interface, and methods for Doppler effect).

On my view, my fix is a bad fix. A good fix would consist in modifying the mixer providers so that your own is called at first and the second part of the fix should force the Java Sound Audio Engine to work with the sound card rather than the webcam. We should write a bug report or a request for enhancement because this behavior is not acceptable. Keep in mind that many people use a webcam nowadays.

Moreover, a better fix should compute and associate a “score” to each mixer and pick the best one rather than taking one valid mixer almost randomly.

Maybe the best fix would consist in blacklisting the camera(s) temporarily and very early at runtime but I’m not sure it is possible and if it is, it will be a privileged action.

Would it be really problematic to use several mixers in LibraryJavaSound instead of a single one?