Need a really simple library for playing sounds and music? Try TinySound.

When I first start the program it’s at the usual 10mb and then within seconds it grows to 40mb and by the end of the mid file, which is a few seconds long, it stops around 50mb then after a while longer it drops from 60+mb to 20mb and starts growing up to around 70mb and repeats the cycle. I’ve noticed that if I leave the file on loop it does the same thing.
I’m starting to think that there is something in the rest of my program that is causing the memory to grow or something.

Cubus, I’m wondering if the info you are giving is correct. Usually it is a “Clip” type structure that has the position reset feature, not a streaming structure (e.g. SourceDataLine in java audio terms).

I would like to suggest changing .loadMusic() in your updated example to .streamMusic().

I think that loadMusic() functions like a Clip, loading the entire file to memory, and allowing looping and position setting. And streamMusic() functions like a SourceDataLine, allowing streaming without loading any more than a single buffer’s worth of sound data from the file at a time.

I could be wrong but it is worth a test, I think.

i think so. i tried it with a 500 KB wav file and after the music is loaded it does not grow more than ~1 KB per 20 seconds, and these are from my debug strings…

According to NetBeans “.streamMusic()” doesn’t exist. I was originally trying to set up streaming but I couldn’t get it to work due to a lack of examples of how to use TinySound.
I just tried removing the two lines that use the AudioHandler class and used memory, when profiling, never grows beyond 20MB. The two lines that I use are:


public ScreenMainMenu(GameCanvas canvas)
    {
        this.canvas = canvas;
        temp = new AudioHandler();
        temp.play();
    }

This method is only called once and that’s at the start of the program, when they’re removed the program never uses more than 20mb of memory.

My apologies, esp to Cubus! I was extrapolating from what I know about Java’s two playback mechanisms, not from direct usage of TinySound.

EDIT: I was just taking a refresher look at the api and code, and it seems to me that if you want to stream instead of loading data into memory, use this form:

loadMusic(file-or-url, true);
loadSound(file-or-url, true);

where true is for the boolean he calls “streamFromFile”.

And…it appears you are already doing so. :slight_smile:

OK, I will go away now. Sorry for adding to any confusion.

np philfrei :slight_smile:

FYI https://github.com/finnkuusisto/TinySound

I just did a quick build of my program to check if the audio is actually streaming. From what I read on the link that cubus just linked:

[quote]Memory Usage

The basic loading functions for Music and Sound objects produce implementations
that store all audio data in memory. This is good for maintaining low latency,
but can also require a lot of heap space if you load many, or particularly long,
audio resources. There are loading functions available that allow you to
request that the audio data be streamed from a file. If this is requested, the
audio data will first be converted as usual and then written to a temporary file
from which it will be streamed. This will dramatically reduce the overall
memory usage (after loading), but can potentially introduce occasional latency
when reading from disk.
[/quote]
I should, assuming that the file being created is created in the same folder as my .jar is, see the file that the data is being streamed from. After doing the test and letting it run for a while I never noticed nor saw any file being created on the startup of my .jar so I’ll assume that both “.loadMusic(url, true)” and “.loadSound(url, true)” aren’t telling it to stream the music.
Is there another way to tell TinySound to stream the music other than this way and the other way that I first tried which didn’t work?

the methods with the streamFromFile flag DO stream, you can see in in the source code :wink:
the temp file (which is used for streaming) should be in your temp folder, it gets created with

temp = File.createTempFile("tiny", "sound")

Found it, looks like the streaming is working properly then. I wonder what could be causing 40mb of ram to be used then since my program runs on a max of 20mb without TinySound being used at all. Is 40mb just for TinySound normal or…?

Edit: Also, are the temp TinySound files supposed to be deleted? I have around 15 5mb files in my temp folder just for it.

I have 1.82 GB of undeleted TinySound garbage. I feel like maybe deleting the files wasn’t originally accounted for in the source? If so, you (kuusisto) should implement a basic scanner to scan for old undeleted files and delete them, like in this code bit:


private void scanAndDeleteOldFiles(String name, String suffix){
	// if the download is aborted, a temporary file will be left behind. this method deletes all temporary files left behind in the past
	DirectoryStream<Path> ds = null;
	try {
		ds = Files.newDirectoryStream(Paths.get(System.getProperty("java.io.tmpdir")), name + '*' + suffix);
		for(Path file : ds){
			if(file.toFile().delete())
				System.out.println("Old file " + file.toFile().getAbsolutePath() + " deleted successfully.");
			else
				System.out.println("Old file " + file.toFile().getAbsolutePath() + " denied being deleted. That evil file!");
		}
	} catch (IOException e) {
		ErrorLogger.logError(e);
		return;
	} finally {
		try {
			ds.close();
		} catch (IOException e) {
			ErrorLogger.logError(e);
			return;
		}
	}
}

I was about to suggest deleteOnExit(), but it appears the code already use this. However, it looks like there may be bugs with this, particularly on Windows, if the file is still open on exit.

Not saying this is the cause, but from a quick look at the code in the mixer - https://github.com/finnkuusisto/TinySound/blob/master/src/kuusisto/tinysound/internal/Mixer.java - it seems that MusicReferences (unlike SoundReferences) are not disposed when removed?

For responsible use of diskspace for the temporary files, I normally create a directory in the temp-dir, in which I store all my transient data, like /tmp/the-derp-game/*.wav. Upon launching the process (not upon exit), I cleanup old/big files in this directory, which I know only contains my files.

Having said that, TinySound really needs to stream audio right from compressed audio files, instead of unpacking it fully to disk and using that as a source for streaming. It causes extreme RAM usage and extreme disk usage. There is no reason for this (except limited dev-time), for an API that is meant to be used by other developers.

+1 to that approach, probably combined with the not-exactly-foolproof deleteOnExit().

There are lots of benefits to working with uncompressed audio data too though - single CPU hit for decoding, better seeking, etc. Depends a lot on how the audio is being used. Problem in TinySound is the RAM hit from reading the sound file in one go before writing it to disk. Could do that better by chaining the input and output streams with a much smaller working buffer. It’s hardly extreme disk usage! :wink:

You can decode mp3/ogg on a separate thread, so it won’t affect your main loop. Very few games (here) use all cores of a CPU.

Regarding diskspace: on a HDD I’d agree with your that 1.82GB is barely significant, but on an SSD… it’s a different matter, IMHO. Suddenly, diskspace is limited and/or expensive again.

I wasn’t talking about the 1.82GB! That’s caused by the bug with deleteOnExit() and not doing the cleanup you suggested. That’s not in itself a reason for switching to streaming directly from the compressed file, as per your original argument. It’s a good argument for fixing / working around the issue of temp files not being deleted. There’s no way that you’d get anywhere near that level of disk usage if that was fixed, unless you’re really using over 3hrs of audio data at the same time.

Not to mention that this is in a temp folder, and any decent OS should manage that for you! :wink:

So much for me jumping in a thread, clueless about its context :persecutioncomplex:

Does any OS actually manage the temp-dir in more more sophisticated ways than [quote]shall I wipe it now, or shall I wipe it later
[/quote]
?

So, does anyone know a simple sound library that doesn’t use a ton of RAM and can play midi files?

Yes, the JRE. Since Oracle Java 7 or OpenJDK anyway. These have Gervill built in (though you can ship it separately), which is an excellent MIDI / live DSP system. Just make sure you give it a decent soundbank to work with (which you may need to customize if you want to keep RAM usage down).

The bigger question is, why you want to do this? Note this message and Cas’ opinion (which I agree with). MIDI makes sense as a dynamic system, but not for playing static files.

Incidentally, if you go with Gervill, you’ll also be in a position where you’ll need to play your sound effects through it too - there was a discussion about this recently.

In general, I’d suggest that unless you have very particular needs outlined in those links, stick with TinySound.

Well, just clearing it on reboot is a good start on a desktop system (general Linux desktop with TMPFS or otherwise), then some do clearing up of files that haven’t been accessed in a set amount of time.

I dont wanna be a party pooper… but guys
TinySound only wraps JavaSound
JavaSound is really really bad… There are SO many nice alternatives

come on now :confused:

haven’t done much in ligbgdx yet but pauls 3d sound one (if that is the name) crashed on just about every single file I opened. It was fast and much leaner but hard crashed all the time. So I stayed the hell away from it.