Looping an ogg vorbis file.

Hi!

I am currently working on a game which I would like to create a sound player for. This sound player should be able to load ogg vorbis files, loop them and fade them in and out. I’ve read the tutorial on https://joal-demos.dev.java.net/devmaster/lesson8.html which help tremendously with loading and playing but looping… Is there an easy way of looping ogg vorbis files? Wav files are easily looped in openAL but wav files are too large for easy distribution.

Thanks in advance!

/ Kalle

I would’ve thought that applying the looping property - alSourcei(sourceID, AL_LOOPING, AL_TRUE) - would be enough, but it might not apply to a streaming. However, reading the OpenAL programmer’s guide states that “As long as there is always a new buffer to play in the queue, the source will continue to play.” With that knowledge, maybe it’s just enough to find-out when you’ve queued the buffer from the end of the file, so that you start queuing buffers from the start of the file immediately after it.

Thanks for the answer!

No, the alSourcei(sourceID, AL_LOOPING, AL_TRUE) does not work, it throws an exception when I tried to do that.

Ok, that is roughly what I had in mind but I would have liked an easier way, like the statement above… We are always looking for the easiest way, huh? :wink:
I’ve looked at this solution to some extension, but the input streams (VorbisInputstream) returns false when calling isMarkSupported(). Can I reset (rewind) an VorbisStream or do I have to create new streams?

Here is how the streams are created. This is from the file OggDecoder.java on https://joal-demos.dev.java.net/source/browse/joal-demos/src/java/demos/devmaster/lesson8/OggDecoder.java?view=markup

    
public boolean initialize() {
	try {
	    CachedUrlStream os = new CachedUrlStream(url);

	    loStream = (LogicalOggStream) os.getLogicalStreams().iterator().next();
	    
	    vStream = new VorbisStream(loStream);
	    vStreamHdr = vStream.getIdentificationHeader();

	    audioFormat = new AudioFormat(
		    (float) vStreamHdr.getSampleRate(),
		    16,
		    vStreamHdr.getChannels(),
		    true, true);

	    ais = new AudioInputStream(
		    new VorbisInputStream(vStream), audioFormat, -1);
	    
	} catch (Exception e) {
	    e.printStackTrace();
	    return false;
	}

	return true;
    }

I don’t know the j-ogg API that well, but from what you say and the little I’ve read, it would seem that yes, you’ll have to get a new stream since resetting isn’t supported by the VorbisInputStream.

[EDIT]: I was just thinking that maybe you could wrap the VorbisInputStream with an InputStream that does allow resetting, but the only ones that come to mind store the entire stream to memory. Kinda defeats the purpose of streaming then.

What I did, was to decode the entire ogg file and then not use tha “alqueuebuffer” thing. Just make a normal buffer as you normally would with a wav file. When this is done, you will have fast access to your sample(music I presume) and you can use AL.AL_LOOP to loop it. This takes a while for big files(4-5mb ogg files), but its worth it so ou can squeeze out some extra FPS during gameplay.

I’m not gonna send you my code, cuz its dead ugly right now. But the thing I did was just to adjust the buffersize to match the filesize and then load it into a normal buffer. It’s not hard to do, it requires some getting-to-know example 8, but you have that pegged apparently :slight_smile:

If you end up with a beautiful solution please pm me or something. I’m tired of restructuring code :frowning: [/lazy]

edit
PS: Does anyone else find the code extremely strange in example 8? All that returning booleans, its frustrating when you query for “if(initialized())…” then you are in fact doing it as you ask for it…I hate that very much!