Another thing I ran into while adding sound to the game was having more then one song. I wanted it so when a song ended the next one would start. But you had no methods that would tell me if a sound has ended its playing. The one method called I think playing() always return true if the sound had been played even if it hit the end.

You can make your own system for that, considering you can calculate minutes:seconds (that is mainly shown when looking at the length of a song) to milliseconds. Here is the code of the system that I made. There are 6 songs, and I just wrote down the millisecond length of all of the songs. Could it be simpler? Yes, if TinySound let us know when the song ended, but it's still pretty simple to make your own system to playing a new song every time the previous one ends. By the way, TestMusic[] has 6 elements and it is a Music variable.

Yup. I was going to code something like that next but decided not to. Sure you can do everything Tiny does yourself but that would defeat the purpose of a library. I am just saying it would be a nice feature to add.

Yup. I was going to code something like that next but decided not to. Sure you can do everything Tiny does yourself but that would defeat the purpose of a library. I am just saying it would be a nice feature to add.

I apologize for disappearing again for so long. You make a good point, so I've added a done() method to the Music interface which will tell you when the Music has finished. I've also fixed Music to stop "playing" when it's finished, as you mentioned the issue with playing() always returning true if you haven't called stop(). Note that you will have to call rewind() to set a Music back to the beginning. All of these changes are on the streams_and_redesign branch. Again, sorry for disappearing. I've had a lot on my plate.

The second you make a panning-system, this will become my main sound-library, and though shall get much praise in my credits Oh, and the ability to enable random pitching within a specific range. I'd love that!

The second you make a panning-system, this will become my main sound-library, and though shall get much praise in my credits Oh, and the ability to enable random pitching within a specific range. I'd love that!

Well, I didn't add random pitching, but I did add panning and it can be found on the streams_and_redesign branch (I'll eventually merge it to the trunk). Give it a go and see what you think. I'm not entirely sure how panning is normally implemented, but you can set a pan value in the range [-1.0,1.0]. 0.0 plays normally, whereas a negative or positive value shifts a proportional amount of one channel to the opposite. More specifically, a value of -0.25 will shift 25% of the right channel to the left channel. Note that panning to the left doesn't change the gain on the original left channel audio at all. It only affects how much of the right channel is shifted. The analogous situation goes for panning right.

On the game I used this library, I credited with your name. If you have a website with this library hosted, I would like to know so I can add a link on my citation.

Cool, thanks. The license I used doesn't require attribution like this, but I appreciate it. I don't actually have a web page for TinySound, but you could just link to the repository (https://github.com/finnkuusisto/TinySound) if you want to link it to something. I should probably think about making a web page.

Hi again! yes, that maybe would work too, but inside the kuusisto code, UpdateRunner method doesn't need an accurate loop, just a (more or less) regular loop for filling the buffer, so just increasing the buffer size is enough

Also, I've been working some more with this library. I found (in my opinion) an important limitation. As I can understand, by now, a sound cannot be played twice simultaneously. You need to load different sounds with the source file (waste of memory).

What I did is just add to the SteamMusic/MemMusic/SteamSound/MemSound a new method called getInstance() This method return a new music/sound that shares the source data. This is a quite small code addition:

Also, I've been working some more with this library. I found (in my opinion) an important limitation. As I can understand, by now, a sound cannot be played twice simultaneously. You need to load different sounds with the source file (waste of memory).

You should be able to play a Sound multiple times simultaneously. When you call play(), it creates a reference to the sound data and passes it off to the mixer. Can I ask how you came to this conclusion? If it really isn't working, it's possible there is a bug.

Increasing maxFramesPerUpdate for storing up to 100ms of data per iteration into audioBuffer worked great! No more crackling, the music became smooth and perfect.So, if there is not any extra problem, maybe is a good idea for futures updates to increase the default buffer size from 25ms to 100 ms or even more.

If I recall, the reason I had it at 25ms was to reduce latency. If it buffers up too much audio data there can be some audible lag between the time a sound is 'play()'ed and the time that it actually plays. It might be a good idea to up the default a little bit, but I'm reluctant to increase it to 100ms. That said, I'm glad it works so well for you though. I also think it's really cool that you're using TinySound and have taken enough of an interest to dig in the code!

Ok, my fault, I just tried it again and it works nice. I dunno why I assumed that. Maybe because I just started using music.

About the delay, 50 ms were also fine for removing the crackling. I didn't noticed any lag (core i5 laptop and core i7 desktop, both java 1.7). Maybe just happens with slower computers or other JVM. Why does it happens? because the computer takes a lot of time filling the whole buffer for the first time? Interesting. I will take a look again at the code.

BTW, as I saw in your page, you are doing your PhD, right? good luck!! I wish you to publish a lot of papers

About the delay, 50 ms were also fine for removing the crackling. I didn't noticed any lag (core i5 laptop and core i7 desktop, both java 1.7). Maybe just happens with slower computers or other JVM. Why does it happens? because the computer takes a lot of time filling the whole buffer for the first time? Interesting. I will take a look again at the code.

You're right, it could just happen in slower computers, but it would generally happen if there were ever a fairly large gap between buffering updates. It's all mixed and sent to one SourceDataLine, so if you buffer 100ms on the line, the next audio played won't actually hit the speakers until that buffer is complete. I can't recall now if I have designed it so that it recovers from long buffers, which would make a 100ms buffer less of an issue.

When Java code is executed, it is not immediately compiled.Instead, when a loop is encountered for the firsttime, a few iterations are executed in interpreted mode,and then only, the code is compiled. This is the HotSpotfeature of the Java Virtual Machine (JVM), which hasbeen introduced since the release 1.4.

While the speed of compiled Java code is fast enoughfor real-time computations [4], the first few iterations thatare executed in interpreted mode can be too slow. As aresult, the computation time can take much more than theduration of one audio buffer in the first iteration.

A work-around solution is to kick the mixer into gear with a silent tone at an interval of time sufficiently before real-time response is needed, then leave the mixer running for the rest of the game.

P.S. Thanks for making the code for TinySound available on GitHub. I see that what we are doing is pretty similar, in terms of obtaining a SourceDataLine, and that you are getting similar feedback re crackle. Now I can stop stressing about this issue and get on with coding.

I'm not new to Java but I have shied away from using audio in my games as I could never find a 'fully' reliably and undisputed way of playing and looping sound, efficiently. However, I have recently started writing my own engine (more as a personal project, but I will release it so that it can be used for Ludum Dare) and have finally reached the point of needing audio support. I have been searching around for a suitable method and managed to find 'java.applet.AudioClip' that works fairly well, but my question is: What does TinySound do that makes it superior to 'java.applet.AudioClip' or what are the shortcomings of 'java.applet.AudioClip'?

As an aside it would also be useful to hear anyone's suggestions for how I could approach sound in my engine or whether TinySound would be okay for me to use, from a licence perspective in my engine.

TinySound seems like it could be the best option (if I can use it) but the main thing I'm wondering is whether 'java.applet.AudioClip' will do?

The thing that drove me from AudioClip was the fact that you have no control over the volume. But if it loops, then it is pretty easy to use and costs very little. You might not have a lot of control over things like starting or stopping in the middle of the sound. I don't know. I stopped looking at it as soon as I saw there was no volume controls.

Of course there is javax.audio.sampled.Clip, for the same functionality, but with more control (volume, start & stop points).

But, if you are doing something like laser zaps that overlap, you will probably find TinySound a better choice, and well vetted.

Thanks for the help. I think if I was just working on a one off project I would definitely use TinySound, but for an engine it's probably best to just try and write my own system based on javax.audio.sampled.

What does TinySound do that makes it superior to 'java.applet.AudioClip'

What you've got with TinySound as opposed to java.applet.AudioClip or javax.audio.sampled.Clip is a system that opens a single line to the soundcard, keeps it open, and mixes sounds together in software. The way javax.audio.sampled.Clip is implemented means that it opens a separate line to the soundcard every time you want to play a sound. This is OK for occasional sounds in a desktop application, but for anything where you want multiple sounds or rapid triggering then the TinySound approach will work far better.

I think if I was just working on a one off project I would definitely use TinySound, but for an engine it's probably best to just try and write my own system based on javax.audio.sampled.

Why reinvent the wheel? Using the high-level stuff in javax.audio.sampled is not really suitable for games, and using the low-level stuff requires you to have a good grasp of audio coding or you can get into issues quite easily.

I meant to add a couple lines about the pluses of TinySound, but nsigma beat me to it by a few minutes!

I'll just add that there are some systems (certain flavors of Linux) that seem to have trouble with playing back multiple lines. With javax.sound.sampled, one is usually creating Clips and SourceDataLines that output at the same time (overlapping). A mixer, like the one Kuusisto has built will funnel all the outputs into a single line, allowing the sound to play back correctly on more operating systems.

Thanks for the clarification everyone. What I'm going to do, based on the most recent replies is to just try to implement TinySound straight into my engine (http://www.mythalore.com/ for more information). I will keep the source intact (within the jar file) and make sure not to imply that the code used is mine. I will probably be making the engine open source from when I release it, near April. Lastly, kuusisto if you have any objections to me packaging the TinySound jar file with my engine please email me at sam@Mythalore.com, as soon as possible. Thank you.

The thread has been inactive for a while but I hope that I can resolve this issue. I'm loading oggs for music in my game and the issue is that loading a single ogg ups the memory usage from 30 to 245 megs. Attempting to load more causes OutOfMemoryError

I'm using TinySound for playing wavs and oggs. The thread has been inactive for a while but I hope that I can resolve this issue. I'm loading oggs for music in my game and the issue is that loading a single ogg ups the memory usage from 30 to 245 megs. Attempting to load more causes OutOfMemoryError

If I recall, music is loaded into memory where sounds are streamed. Loading a whole song into memory is not bad as long as you only have 1 playing. I recommend playing the songs as sound files instead of music as they should be streamed. Most games stream music. I think SC2 supports up to 128 channels which mean 128 sounds playing at once. Or you can turn it down to 16.

That is not the issue, the issue is songs taking way too much space. 3 6-minute songs take up 400 megs (noticed when I increased heap space) and I find it ridiculous

If it's what's normal what can I do to stream music. I'm using LWJGL so I could use OpenAL but setting it up on my own will take very long time and I can't really find any frameworks to help me with ogg

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org