Playing compressed sound in Java, how?

Is there any piece of code that I can just paste into my project to make my game read any type of compressed sound? I have code for wave that I got from the Internet which worked fine but wave files are too large.

You have to include a Sound Provider Interface (SPI) in your classpath. Also, your music playing code must be set up in the “right” way or it won’t work.

I wrote a tutorial on my website. A link to the appropriate page is http://www.cowgodgames.com/articles/jgptutorial/ch01.5.php . All the code for my tutorial is linked to from http://www.cowgodgames.com/downloads.php .

My tutorial is old, and I kind of shudder when I look at the code. Even so, the music/sound code works. I’ve improved upon it slightly since (for instance, I made looped sound effects possible by making the SoundPlayer class more like the MusicStream class), but it’s essentially the same.

EasyOGG - works wonders for me :slight_smile:

I never got that link to EasyOgg to work ???

odd, don’t know why he took it down.

anyway, I have it here on my server.

link works fine for me

he means the download link inside the blog. which actually wasn’t removed, just mistyped. http://www.cokeandcode.com/downloads/EasyOgg-0.1.zip

I always get an exception when trying to OggClip oc= new OggClip(String);
Earlier, I used a method for playing .wav files and I am in code using the same path now and have just replaced the blahblah.wav with blahblah.ogg and create and try to create an OggClip from it.
I have the OggClip file in the same folder as the wave and they both have the same name.

This method throws IOException for me.

public OggClip(String ref) throws IOException {
try {
init(Thread.currentThread().getContextClassLoader().getResourceAsStream(ref));
} catch (IOException e) {
throw new IOException("Couldn’t find: "+ref);
}
}

i doubt thats OggClip’s fault, as its only acting upon your parameters. I’m using that same class. this is how i load the music in BeetleMania:


try {
	music = new OggClip(getClass().getResourceAsStream("music.ogg"));
}
catch (IOException e) {
	e.printStackTrace();
}

and it never throws an IOException at me, unless I use a bad parameter, of course. what IOException message are you getting?

notice I’m using the OggClip that takes the InputStream parameter, not the one that takes a String parameter. not that it should make a difference, as the String-parameter constructor grabs a stream anyway

i tried using new OggClip(“myfile.ogg”)
or new OggClip("C:/myclip.ogg)
or the one where i use a path defined inside my game like

path=ceaw.getSoundPath();

String s=path+“myfile.ogg”;
and then new MyClip(s);

Nothing works, but the paths work for the myclip.wav that i used in a method that was playing wave sound.
I also pu the myclip.ogg in the same folder as the OggClip.class in case the OggClip does not take a path (does it?)

again…

what is the IOException? (the full stack trace, including the message please)

java.io.IOException: Couldn’t find input source

at ceaw.game.OggClip._$1280(OggClip.java:87)

at ceaw.game.OggClip.<init>(OggClip.java:63)

at ceaw.game.OggPlayer.run(OggPlayer.java:170)

I also did a System.out.println on the ref i sent as String to the constructor and got ->
could not find: C:\ingame_music1.ogg

i know it sounds stupid, but that really looks like you’re not providing an existing file for OggClip to load :-\

can you open the same file in an FileInputStream? does File(path).exists() == true?

Ehm… lol. Did you notice that you print something different than you try to load?

If ref equals “C:\ingame_music1.ogg” then Thread.currentThread().getContextClassLoader().getResourceAsStream(ref) gives you null. Try printing that instead and you’ll see.

That getResource* stuff loads stuff from the classpath (I assume that “C:” isnt in the classpath).

try
{
FileInputStream f_in = new FileInputStream(“C:/ingame_music1.ogg”);
} catch(FileNotFoundException e) {System.exit(55);}

worked without any exception.

read oNyx’s post. more or less, getResource*() loads relative paths, not absolutes. pass that FileInputStream to OggClip and it will work:


try {
	clip = new OggClip(new FileInputStream("C:/ingame_music1.ogg"));
}
catch (IOException e) {
	e.printStackTrace();
}

Yes, seems the simplest way was to use the InputStream instead.it is now working :slight_smile:
The only thing missing in that OggPlayer is that I would want to know how long a sound file is, so if i put several different long OGG’s in queue, i can start the second one when the first one is finished.

The source is provided. Rather than knowing the length of the OGG and attempting to sync something in your main loop it’s probably easy to just poll whether clip has stopped playing.


	public boolean stopped() {
		return player == null;
	}

Might work.

Kev

I tried it but it did not work. I think threads do not become null when they die. However, this code worked for me and I use it withing my SoundPlayer loop.

code:

public boolean playing() {
if((player != null) && (player.isAlive())) return true;
else return false;
}

Sort…of. With a leading slash its kinda absolute… from all root dirs (virtual or not) in the classpath. So if your jar contains gfx/foo.tga you can access it from foo.bar.Game (or anywhere else) via getResourceAsStream("/gfx/foo.tga").

I prefer using a leading slash, because its imo clearer.