is GAGESound right for me?

I currently load Clips for my .ogg audio files. However there’s no real easy way to pause all the sound when things aren’t active… like if I’m half-way through a sound and I pop up a menu pausing the game, I want the sound to stop. Right now I run through searching for all active sounds anywhere in the game and call .stop() on them, but that gets a little tricky. I would much rather use the GAGESound idea and just call .render() when necessary. That would perfectly solve my problem. However as far as I can tell GAGE won’t load .ogg’s.

I also want to introduce music. Right now I don’t know how to stream music from a file, but the docs say GAGE only supports midi.

I love how well GAGESound is set up and it would be perfect for me… but only if I can get my ogg files in there :slight_smile: Will I have any luck with this or do I need something else?

[quote]However as far as I can tell GAGE won’t load .ogg’s.
[/quote]
I have a patch that some helpful folks gave me that I’ve just been lazy about getting out. I can probably get it to you a bit later.

[quote] I also want to introduce music. Right now I don’t know how to stream music from a file, but the docs say GAGE only supports midi.
[/quote]
GAGE loads everything up into memory. If you want to stream an OGG, you’re better off getting an AudioInputStream and setting it to play through a SourceDataStream.

Gotta go. I’ll get back to this one later.

Ok Malokhan,

I’ve uploaded the new version of GAGESound that allows you to work with OGG files. I haven’t completely tested it though, so you’re going to have to be my guinea piggy. Don’t you feel special. :wink:

You can download the new version from:

http://java.dnsalias.com/downloads/gagesound-1.2.zip

Note that this is different from the file available on the main page. Let me know if it works for you.

Now keep in mind that while the WaveEngine should now be able to load OGG files, it can only do so when the JOrbis SPI plugin is present. Also keep in mind that it will load the complete decoded clip into memory! i.e. You can save on the size of your download, but don’t expect to save on your memory footprint!

Streaming OGG music is a bit easier. I don’t recommend the music engine for this, but rather that you simply load the file and play the bytes like this:


import java.io.*;
import javax.sound.sampled.*;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        File file = new File(args[0]);
        AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
        AudioInputStream in = AudioSystem.getAudioInputStream(file);
        AudioInputStream din = null;

        AudioFormat baseFormat = in.getFormat();
        AudioFormat  decodedFormat = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,
            baseFormat.getSampleRate(),
            16,
            baseFormat.getChannels(),
            baseFormat.getChannels() * 2,
            baseFormat.getSampleRate(),
            false);

        din = AudioSystem.getAudioInputStream(decodedFormat, in);
        rawplay(decodedFormat, din);
        in.close();
    }

    private static SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException
    {
        SourceDataLine res = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
        
        res = (SourceDataLine) AudioSystem.getLine(info);
        res.open(audioFormat);

        return res;
    }

    private static void rawplay(AudioFormat targetFormat, AudioInputStream din) throws IOException, LineUnavailableException
    {
        byte[] data = new byte[4096];
        SourceDataLine line = getLine(targetFormat);      

        line.start();
        int nBytesRead = 0, nBytesWritten = 0;

        while (nBytesRead != -1)
        {
            nBytesRead = din.read(data, 0, data.length);
            if (nBytesRead != -1) nBytesWritten = line.write(data, 0, nBytesRead);
        }

        line.drain();
        line.stop();
        line.close();
        din.close();
    }
}

You should be able to rework that to make it stream a little better. If you’re using applications instead of Applets, I’d actually suggest decoding the data to disk, then memory mapping the data to a ByteBuffer. Just pump the data from a ByteBuffer into a SourceDataLine, and everything should work great. If you don’t have that luxury, then I suggest keeping in mind that Vorbis files will reduce your usable CPU cycles, and that it may only be workable on faster machines.

Any questions? :slight_smile:

I think I’ll stick to my Clip implementation. While you say there’s a risk of blocking, I’ve never experienced that effect. In terms of quality, Clip’s are MUCH better on that note and I think even a risk of blockage is worth the quality gain. In using your library for the sound I got horrid static and screeches in some of my audio. I can’t deal with that especially when I want people to buy this :slight_smile: I still need some advice on how to stream music (and have good quality). Does any such thing exist in the world of JavaSound? :slight_smile:

[quote]In using your library for the sound I got horrid static and screeches in some of my audio.
[/quote]
Static and screeching? Umm… that definitely shouldn’t be happening. When I say that quality may suffer, I mean that it won’t sound quite as crystal clear as some methods. It shouldn’t in any way be producing the types of artifacts you’re seeing. If you’d like, you can email me your current source, and I’ll see if I can figure out what’s going on.

[quote]I still need some advice on how to stream music (and have good quality). Does any such thing exist in the world of JavaSound? :slight_smile:
[/quote]

  1. Open an AudioInputSteam.
  2. Open a SourceOutputStream.
  3. Write data from AudioInputStream to SourceOutputStream.

That’s all their is to it. :slight_smile:

I emailed you with the sound that was sounding ugly. As for the code you gave there, I can’t find the SourceOutputStream class. Is that a typo?

[quote]I emailed you with the sound that was sounding ugly. As for the code you gave there, I can’t find the SourceOutputStream class. Is that a typo?
[/quote]
Sorry, SourceDataLine, not SourceOutputStream. I’ll look over the sound you sent me and see if there’s anything odd going on. Thanks!

Hi Malokhan,

Just wanted to let you know that I’m still looking at this. I haven’t had too much time over the weekend, so I haven’t gotten very far yet. I do hope to track this down today though. What I have noticed is that the sound plays crystal clear the first time, then turns into garbage noise the second time. If I open a new line each time, the sound plays fine.

Honestly, I’ve never seen anything like this problem. It’s almost like the PCM data is out of phase. (i.e. The line starts playing somewhere in the middle of the frame instead of at the start of the frame.) I’ll let you know what I find.

On the bright side, I did warn you that you were the guinea pig. :wink:

well don’t bang your head over it. Clips still work beautifully for me :slight_smile:

I finally got around to playing with the music code! Now I have some difficulties to share :wink:

For one, once that code starts, rawPlay() doesn’t return until the whole music file has played. I figured I’d just put it all in a separate thread to run, but is that the best way to handle it?

Also, I’d like to be able to pause and replay and stop whenever I want. I don’t know how to manage that’n… any ideas?

By the way, my code works great with Clips now. I have all the functionality I was hoping for. If anyone is in a similar situation to where I was and would like to see code let me know! Perhaps, jbanes, you might want the code to add to GAGE? I have it so that it should never garbage collect and it pools all the Clips so that you can play multiple sounds of the same source at the same time and not have the GC run you straight to heck ;D

Hey I’m intersted.

My current game uses straight jorbis decoding (streaming from a jar) and I’m pretty sure it consumes too much CPU for low end computers…

Lilian

jbanes,

do you plan to make GAGESound 1.2 public via GAGE website? The downloaf link still points to the 1.1 version. Also, do you plan to offer ogg streaming in the API?

Thanks!

[quote=“TheAnalogKid,post:13,topic:21666”]
Sorry, I didn’t notice this until just now.

I haven’t released 1.2 because of the problems that Malohkan found. While they seem to be JVM version related, they finally turned me off to the entire idea of using JavaSound for mixing. I’ve was working on a much more powerful replacement (with streaming support and everything), but other projects got in the way.

As it stands right now, GAGE2D and GAGESound are horribly out of date. They need to be updated to reflect the better understanding of Java Game programming that we as a community have developed over the past several years. I’ve left the page up for now, but I’m not sure when I’ll get back around to updating the APIs.

ok

Thanks for the answer. I was just asking and not necessarly expecting something new from GAGE.

Hi, I’ve updated GageSound 1.2 to add support for :

  • looping (for music themes)
  • setting gain to individual clips
  • enhanced render loop in case too much time has passed between two calls (like when reading a new long ogg file : render becomes blocking)

On top of that, I’ve developped a MusicThemeManager component that handles a nice fadeout to finish the current music theme and introduce the new one (or stop)

I’ll post the code in the coming weeks if someone is interested (after clean up)

Lilian

I’d be interested in it. The GAGE stuff shouldn’t fall off the map, so an update like this would be good.

Dr. A>