Sound tool recommendations and/or javax.sound problems

I am presently using javax.sound for my sound needs. Is this used much? Is there any kind of community preference/standard or can you recommend anything I should use? I really just need very basic sound functions I think.

My problem with javax.sound: I have 1 serious and 1 minor problem I’m aware of with java sound.

  1. It will hang my program when trying to close a large number of Clip streams. I don’t know how else to play clips (like sound FX) and have them close on their own and avoid system lag.

  2. It has lag on the volume change and it pops sometimes. It just seems cheap. I don’t see how I’m doing it wrong code-wise, but I suppose I could be. All I do is send a float at it to change the gain:

		if (BGMclip != null)
		{
	    	FloatControl gainControl = 
	        	    (FloatControl) BGMclip.getControl(FloatControl.Type.MASTER_GAIN);
	        	gainControl.setValue(volNum); // Set volume at <volNum> decibels. -10.0f
		}

It doesn’t do this immediately and it sometimes pops. I can live with that, but surely I can find a sound system that can handle my very basic needs without issue (or use this one better :wink: ).

I believe this thread and nsigma answered my question. I shouldn’t be using Clip as I am. I should perhaps use TinySound or OpenAL.

“usually” it goes like … javax.sound < tinysound < openal < fmod

Problems with closing a large number of Clips?
I’m surprised this is an issue. Could we see more?

Volume clicks:

Yes, a very real problem. I decided to write a clip-equivalent, and output the data from memory to a SourceDataLine. Volume changes are spread out over 1028 samples on a per sample basis. With a Clip, the changes can only occur with each buffer playback, and a large jump creates an audible discontinuity. You can get a bit more granularity by reducing the buffer size and spreading the changes out over time. But making the buffer too small leads to dropouts.

Design around the problem? Have your Clips only play back at fixed volumes, but maybe allow files (SourceDataLine) to be opened up and given the per-sample spread of volume changes. The code for getting at the individual sound frames can be found on the Java Tutorials in the first code example, at the point where there is a comment “//Here do something useful”.

I do not know how TinySound handles this. It seems to me he has some provision for fading in and out smoothly, but I am not up on specifics of using this library.

OpenAL probably requires using a wrapper like Libgdx. if you are going to LIBGDX anyway, it makes sense to use it. There are lots of good features and some annoying liabilities and limitations. FMod is expensive if you are going commercial. There might be a free version though. I was told there is another library that is competing but I’ve lost my notes on this. Sorry.

Doesn’t look like TinySound does gain interpolation either. :frowning:

Other libraries to look at would be Minim and Beads, both of which are well known in the Processing community, but will work with just Java.

One day I’ll get around to exporting the pure Java audio library from Praxis LIVE … :persecutioncomplex:

+1 for http://www.beadsproject.net/.

fmod is free to use for non-comercial projects. there is no “limited” version.

Beads is great, but has the potential issue of being GPL, unlike Minim - http://code.compartmental.net/tools/minim/ Beads has a better architecture in my opinion, but I’m also biased because I contributed the audio IO from Praxis LIVE to it! :wink:

Also, probably better to compile Beads from source as there’s been a variety of changes since the last release. https://github.com/orsjb/beads

Wish to encourage this. (Not the sense of persecution/paranoia, but the release of a better Java audio library.)

Maybe it would be good to start a wish list/feature list of a minimal but genuinely useful library?

I’m going to be working full-time for a while on Praxis LIVE and related media libraries, so this just might happen!

A none-obvious, but key one for me, is that it’s lock-free. This is one of the reasons I don’t use Beads. And also why I haven’t yet extracted some of the code out of Praxis LIVE, because outside of the environment it’s not so easy to work with - however, good use of lambdas / method references in an API might make this not too painful.

This is my method for playing a sound effect:

	//start clip play
	public synchronized void play(final String fileName)
	{
	    if(!muted && !FXmuted)
	    {
	    	try {
	            AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(fileName));
		        Clip FXclip = AudioSystem.getClip();
		        FXclip.open(inputStream);
		        
	            FloatControl gainControl = 
	            	    (FloatControl) FXclip.getControl(FloatControl.Type.MASTER_GAIN);
	            	gainControl.setValue(FXvc); // Set volume at <vc> decibels. -10.0f
		        
                       //listener for closing clip when done
	            	FXclip.addLineListener(new LineListener() {
	            	    public void update(LineEvent myLineEvent) {
	            	      if (myLineEvent.getType() == LineEvent.Type.STOP)
	            	        FXclip.close();
	            	    }	
	            	  });
	            	
		        FXclip.start();
		    } catch (Exception e) {
		    	System.out.println("play FX error: " + e.getMessage() + " for " + fileName);
		        System.err.println(e.getMessage());
		    }
	    }	
	}

I can’t always get it to lag. I can’t always replicate the problem, but it seems related to the sound. In a prior attempt at using sound, it had clearly been the case (that closing was the problem). This newest version works a lot of the time, but under heavy load it hangs until it can catch up.

It could be an issue with making too many sounds now rather than closing?

For a test I just set a sound effect to run 6 times per click. After clicking very rapidly, this eventually made it hang. It shows no signs of stress until seizing up.

The good news is that you can improve your performance a couple orders of magnitude over what you have coded.

Clips were designed to be loaded separately from the act of playing them. If you combine loading and playing, the playing won’t even commence until after the slower process of loading the sound file into memory completes.

There’s other code that looks kind of superfluous as well (surely there is a way to avoid having to do any synchronization), but I’m not able to straighten it all out by eyeballing. My brain is too full of other stuff at the moment.

When you want to play a clip, do only two things:

  1. set the cursor back to 0, as in clip.setFramePosition(0);
  2. then call clip.play.

Things like hooking up the volume line and loading the data (you only have to do this once) can be part of the construction/instantiation process of whatever class you are using to wrap the clip.


I am going to tinker with maybe making an open source SoundCue class that combines elements of Clip and SourceDataLine. I’m thinking it should be able to do the following:

play on demand, play from a given position within the cue, loop (n times or continuously), loop with overlap-smoothing at the edges, play concurrently (up to n copies), play at different velocities (faster or slower, using linear interpolation), continuous/smooth volume, velocity, and pan controls, and a customized Listener that can send notifications when the cue starts or stops (and no blocks or synchronization)

If it works, it might serve as a intermediate/stopgap step to making use of nsigma’s forthcoming library. If it shows up before 4/15 it means I am procrastinating dangerously on finishing taxes and other deadlines that seem to be besieging me at the moment.

[quote]Clips were designed to be loaded separately from the act of playing them.
When you want to play a clip, do only two things:

  1. set the cursor back to 0, as in clip.setFramePosition(0);
  2. then call clip.play.
    [/quote]
    Sounds like the same mentality I’ve had to learn to use for my images in OpenGL. Load them at startup and just reuse those textures.

I reckon if I wanted the same sound effect to play before one play of that track had finished, I’d need another Clip for that? But just keep a Clip pool (LinkedList or some data structure of Clips) and add on to that as I need. Reuse where I can, add on where needed.

Thanks for the help! Better make sure The Man gets his money. 8)

@Optimo – I started work on a Clip that allows concurrent playback. You can download it from the SharedCode area.

I think the next step will be providing a way to do normal Clip things like position the cursor and loop. Then I’ll get a real-time volume control working based on one I’ve used before. It spreads the volume change out over 1024 frames which is quick enough for most perceptions where fading is occurring and small enough increments to prevent zippering. Will try to find time to do this before end of May.