Sound From Java Exclusive needs exclusive use of PulseAudio?

Asked by adam jvok on 2011-10-27

I'm making a java program beep using some code borrowed from a web page (can't find that helpful page's URL), but the code snipet is below.

And it beeps very nicely.

I'm running Ubuntu 11.10 ( AMD64) with pulseaudio.

While my java beeps just fine if no other application is using sound, if I have any other app making a sound, the beep is never heard.

Many other application all seem to work at the same time with pulseaudio, but it seems that java requires exclusive use of the sound system if it is to work at all.

Is there any way around this? I want java to beep while I play a some music (for example).

I have tried this using sun/oracle java & openjdk. I have also tried running 'padsp java ...' - all with the same negative result.

Searching the web throws up quite a few examples of people having similar problems, but none with a workable solution (that I've seen so far).

Thanks for any help.

======================================

byte[] buf = new byte[msecs*8];
for (int i=0; i<buf.length; i++) {
double angle = i / (8000.0 / hz) * 2.0 * Math.PI;
buf[i] = (byte)(Math.sin(angle) * 80.0);
}
AudioFormat af = new AudioFormat(8000f,8,1,true,false);
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af);
sdl.start();
sdl.write(buf,0,buf.length);
sdl.drain();

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu pulseaudio Edit question
Assignee:
No assignee Edit question
Solved by:
adam jvok
Solved:
2011-10-30
Last query:
2011-10-30
Last reply:
2011-10-28
Jacobsallan (jacobsallan) said : #1

It depends on what you mean by beep. If you want beeps inside a music synthesizer then your solution may be the best. If you want an alert signal then the following should work.

public class beep {
    public static void main(String[] args) {
        // java.awt.Toolkit.getDefaultToolkit().beep();
        // javax.swing.UIManager.getLookAndFeel().provideErrorFeedback(null);
        System.out.println("\007\007\007");
    }
}

The commented out lines are supposed to work. The AWT and Swing functions seem to assume an onboard sound card, which I don't have -- so they were silent when executed on my computer. The "System.out.println" method works fine.

adam jvok (ajvok1) said : #2

Thanks for the suggestion. I have tried those ideas and:
1. java.awt.Toolkit.getDefaultToolkit().beep(); => Silent.
2. javax.swing.UIManager.getLookAndFeel().provideErrorFeedback(null); => Silent
3.System.out.println("\007\007\007"); => Worked on one PC but not another.

The problem is a bit more general than just a simple beep.
It seems that java is not using pulse even though it appears to be configured for it.

According to 'sound.properties'

# OpenJDK on Ubuntu is configured to use PulseAudio by default
javax.sound.sampled.Clip=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider
javax.sound.sampled.Port=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider
javax.sound.sampled.SourceDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider
javax.sound.sampled.TargetDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider

But I can change these values to any garbage and java sound still works the same way. (i.e. java sound works ok if no other sound app is running but is silent otherwise).

So, as far as I can tell sound.properties is not being used as expected.

Further, when I do get sound (while no other sound apps are running), the PulseAusio 'Sound Settings' Applications tab does not show my java app. It is empty. This makes me think that Java is not using Pulse at all.

I have been doing some blind hacking and tried to use the icedTea PulseAudioMixerProvider directly (I don't think this is intended to be done, but I'm hunting for clues). I have managed to make a sound (there are problems though) and while this is running 'Java' does appear in the PulseAudio 'Sound Settings' Applications list.

So, I suspect that something is wrong with the configuration of java/sound.propties and whatever makes the java load the PulseAudioMixerProvider.

Thanks for any help.

adam jvok (ajvok1) said : #3

Some progress:

1. Messing about by directly using PulseAudioMixerProvider seemed to suggest an issue with the AudioFormat I was using perhaps not being supported by Pulse, so I tried a different approach.

2. Using code from the helpful person at http://www.java2s.com/Code/Java/Development-Class/AnexampleofloadingandplayingasoundusingaClip.htm
I have been able to make sound work with Pulse, but only when I explicitly run the java program with extra arguments:

-Djava.library.path=/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/ (so it picks up the libpulse-java.so)
-cp /usr/lib/jvm/java-6-openjdk/jre/lib/ext/pulse-java.jar

While this works, and it is a solution for me, I think it points to a problem with how java is configured on Ubuntu (OK, maybe not just Ubuntu - I've not tried another distro yet). I don't think these extra arguments should be required - shouldn't this be taken care of by the "sounds.properties" config file?

adam jvok (ajvok1) said : #4

Coming back to this today, I find I can run it without the extra args and it works fine.
Must have been having a bad week last week.
Sorry for the noise.