Best Way to Implement Music and Effects in Java 2D Game

like almost all of you know, im making a little library for my games in pure java without
frameworks, but i want to implement sounds, i know that the sound api java has, can play only wav files and others formats i dont remember right now.

the question is, what the better way or library to implement in my library for play WAV and MP3 files in java, to use those sounds like Background music and Effect sound?

thanks in advance…

this code is what i found to play sound effects, the new question is, how can optimize this?


public class Sound {
    public static synchronized void play(final String fileName) 
    {
        // Note: use .wav files             
        new Thread(new Runnable() { 
            @Override
            public void run() {
                try {
                    Clip clip = AudioSystem.getClip();
                    AudioInputStream inputStream = AudioSystem.getAudioInputStream
        (
                java.lang.String.class.getClass().getResourceAsStream(fileName)
        );
                    clip.open(inputStream);
                    clip.start(); 
                } catch (LineUnavailableException | UnsupportedAudioFileException | IOException e) {
                    System.out.println("play sound error: " + e.getMessage() + " for " + fileName);
                }
            }
        }).start();
    }

  
}

i dont like to use a thread every time i play the sound

Using a thread for a sound is quite mandatory.

E.g. If you want to play a sound 2 seconds in length after you level up and you play it in the same thread as you use for picking it up and finishing the rest of your game logic you’ll end up with a 2 second delay, i.e. everything in your game will stop for 2 seconds untill you’ve finished playing your sound.

It doesn’t really impact a lot on your performance when you’re using threads with care, even if there are a substantial amount of them.

thanks, so im ok with that code?, i mena its safe?

That code is good for playing small amounts of sounds in applications but you might find that it is no good for games because once you need to repeat sounds successively it can become quite buggy where you begin to hear audible popping noises and there are pauses before the next loop begins (this is what happened for me at least).

Unfortunately the Java Sound API is very low level, there is a chapter in a textbook called Fundamental 2D Game Programming with Java that covers making your own sound library and it was mighty complicated; requiring an in-depth understanding of multi-threading (using thread pools and locks) and you have to be careful to dispose of all of the resources that you create. You also need determine if the sound you are looking to play should be loaded into RAM for quick access (small, commonly used sound effects) or streamed from storage (large, background music files) and each one of these methods is coded using different data lines.

The sound is the only aspect of a basic engine that I haven’t mastered myself so it would be good to hear if someone else has a good resource or method. I hate to suggest a library after you mentioned that you want to make your own, but Tiny Sound is a really good, lightweight library that gives you efficient use of sound effects without the need to spend months learning how to create data lines, convert audio files to byte arrays and all of the other low level stuff that you need to know to create a game-quality sound system.

Here’s a link if you are interested:

thanks , i’ve tried that library but i could’nt make it work,

the book you mentioned, i think i have it somewhere, im going to read the part of the sound framework.

by the way, when i play the WAV sounds, in console i have a message:

2015-10-11 07:15:18.302 java[41802:1457138] 07:15:18.302 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API’s in AudioComponent.h.

In what way? What happened / failed?

The code you posted above is about the worst possible way to handle this! :wink:

Bizarrely there’s a conversation going on on the PortAudio mailing list about the very same issue. Looks like both they and Java are using an API that is being phased out. Will follow up if there’s any useful info, but if it works right now you can probably ignore it (note being phased out) - not something you can work around anyway.

TinySound might indeed be the best option available right now, depending upon your target machines. One of the big benefits is that it funnels all the sounds you play into a single sound line output. Thus, there is no additional thread management needed beyond giving TinySound its own thread (something one has to do in any event when playing a sound).

I think TinySound only supports compressed sound files in ogg format, not mp3 which is proprietary. A tool such as Audacity can be used to compress wav files to ogg. I could be wrong about TinySound supporting mp3.

David Brackeen’s now ancient book “Developing Games in Java” has a very good section on sound and sound tools. It includes provisions for a SoundManager, for supporting 3D, and for working with compressed sound (he uses libraries from JavaZoom for MP3 and Ogg Vorbis). As far as I know, most people supporting MP3 or Ogg are still using JavaZoom, a decade later.

I advise you to use Paul Lamb Sound library, it’s more capable than TinySound but still simple to use and it doesn’t force you to use JavaSound (i.e you can work around its bugs and limitations).

Except the OP mentioned wanting to use pure Java and Paul Lamb’s JavaSound backend is terrible! :wink:

There are a few other libraries other than TinySound that might be worth a look. Two libraries often used with Processing but usable from plain Java are Beads and Minim. Beads is probably a bit advanced (and there’s a bug on Windows with the current download), but Minim is probably worth a look.

'ang on a minute… I know I probably suddenly sound even more like a broken record than usual but doesn’t JavaFX have a completely revamped API for sound? Which should satisfy the OP’s requirement for “pureness”.

Cas :slight_smile:

Hadn’t thought about that. Mind you, seem to recall you didn’t have much positive to say about GStreamer once upon a time! :stuck_out_tongue:

Not “pure” for me on Ubuntu until OpenJFX hits an LTS either! :wink:

As with much in JavaFX, the sound commands are both simpler to use and have more features than the corresponding Java version (javax.audio.sampled).

I have no idea how the underlying code is implemented, if it is different from javax.audio.sampled’s or not.

Now that Java is on the move again, with definite positive developments, one hopes that the Open versions find a way to keep up!

Both TinySound and Paul Lamb Sound Library are libraries. Therefore, his demand of pureness is a bit contradictory anyway. JavaSound is terrible :clue: Long life to OpenAL :smiley:

AFAIK, as implied in my previous comment, it’s implemented using the GStreamer based JavaFX media libraries, so yes different to JavaSound. Not necessarily better though! Found this bug report while checking this. Doesn’t bode well, not because the bug is necessarily still there, but because it implies that JavaFX clips are implemented in the same way as JavaSound - opening a sound pipeline for every play. Perfectly suitable for a desktop application with occasional sound needs - terrible for a game where you want to play lots of sounds quickly.

That shouldn’t be too hard given that development happens in the Open*** repositories! :wink: Remember that OpenJDK is the reference implementation of Java SE and Oracle’s build is based on it. The problem has been with Linux distributions not shipping up-to-date packages (to be fair, Java’s release schedule couldn’t be worse for Ubuntu’s LTS schedule)

Surely it’s more about not relying on native code outside of the JRE.

That’s like saying Java NIO terrible, long live nginx - it makes no sense!

:emo: I can’t be bothered explaining the difference again - every time I think you get it you prove me wrong! :stuck_out_tongue:

Both do their job well when you understand where to use them and how they work.

I have a lot less troubles with JOAL than with JavaSound and including the latter would prevent me from using any compact profile. I already talked about the things I had to do to work around known limitations or bugs of JavaSound (especially on very short sound samples). Sometimes, it’s not really JavaSound’s fault but I’m happy to have a painless experience with JOAL.

I agree with nsigma. Don’t forget that OpenJDK is the reference implementation of Java and almost all new developments in JavaSE happen in it. More than 97% of the source of OpenJDK and Oracle Java is identical. The Java plugin isn’t part of OpenJDK (see Icedtea Web) but who cares? The plugins will no longer be supported in Mozilla Firefox from the end of 2016.

Exactly, because the two libraries have different purposes! You realise it would be possible to write an OpenAL-like library on top of JavaSound?! OpenAL is great, but it’s also the wrong tool for the job sometimes - eg. look at what @philfrei is currently working on. OpenAL is a much higher level library.

Your problems with JavaSound all stem from a) using libraries that ignore the spec and b) using it in ways it wasn’t designed for. (OK, b is a bit dubious but the short sound bug is related to the way clips are specified - I wonder what JavaFX is like in this regard given their clips are implemented with a similar architecture ^^)

That’s not to say I wouldn’t be happy with a better low-level sound library - a decent binding* to PortAudio would be fantastic (incidentally AFAIK what the low-level bits of OpenAL-Soft use).

  • for decent read not the one that’s actually available! :wink:

It’s strange, it wasn’t designed for handling very short sound samples which is a no go for games or any softwares that use samples of less than 2 seconds. Just face it, using JOAL allows me to play those short sound samples without any problem. Therefore, I’ll go on advising it and Paul Lamb Sound Library is a nice solution to use JOAL without having to write lots of code to do more or less the same than with JavaSound.

Oh, FFS do you delight in willful misunderstanding?! There are countless JavaSound libraries that would also allow you to play short sounds in minimal lines of code. Stop comparing apples and oranges.

Well hold on… what Julien is saying is that maybe he’s not had so much success getting Javasound to do this correctly. I know that OpenAL works just perfectly (coz I’ve been using it exclusively for the last 15 years), and I remember in the dim dark past that Javasound was just hopeless which is why I didn’t use it, so does it now work ok?

Cas :slight_smile: