Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  How to play a OGG-file ?  (Read 12139 times)
0 Members and 2 Guests are viewing this topic.
Offline Jack_E

Senior Newbie





« Posted 2011-08-31 06:34:22 »

Can someone please provide me some sample
code on how to load and play a short OGG-file ?

I know there are lots of OGG-decoders available,
but I find it all kind of overwhelming,
especially because I cannot find any
(simple) examples on the subject.

Thanks.
Offline paulscode

Senior Duke


Medals: 12


Staff Sergeant


« Reply #1 - Posted 2011-08-31 07:45:38 »

If simplicity outweighs some extra bloat, then you could use my 3D Sound System library (a bit like fishing with dynamite, though Grin).  Basically, you would want to download the core SoundSystem, the CodecJOrbis plug-in, and a library plug-in (simplest is LibraryJavaSound, because it is pure Java and doesn't require any additional libraries to be linked with).

In your code, you'd import the necessary classes:
1  
2  
3  
4  
5  
import pauscode.sound.SoundSystem;
import paulscode.sound.SoundSystemConfig;
import paulscode.sound.SoundSystemException;
import paulscode.sound.libraries.LibraryJavaSound;
import paulscode.sound.codecs.CodecJOrbis;


Then initialize by linking with the plug-ins and instantiating the SoundSystem:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
try
{
    SoundSystemConfig.addLibrary( LibraryJavaSound.class );
    SoundSystemConfig.setCodec( "ogg", CodecJOrbis.class );
}
catch( SoundSystemException e )
{
    System.err.println("error linking with the plug-ins" );
}
SoundSystem mySoundSystem = new SoundSystem();


Then to play your ogg:
1  
2  
mySoundSystem.quickPlay( false, "filename.ogg", false,
    0, 0, 0, SoundSystemConfig.ATTENUATION_NONE, 0 );


If you go this route, to be more compatible, I'd recommend using the LibraryLWJGLOpenAL or LibraryJOAL  plug-ins by default (require you to link with 3rd-party libraries), with LibraryJavaSound as a fallback option.

To eliminate bloat, if you are handling the audio system yourself and just want to decode .ogg files easily, you can use the CodecJOrbis plug-in by itself with some minor tweaking of the code (remove calls to SoundSystemConfig for getting default values.  I can help with this if you have problems).  Then you can use the CodecJOrbis class stand-alone to decode ogg files much more easily than with the uber-low-level JOrbis library.  Basically, use intialize(URL) to connect to a file, getAudioFormat() to get the format of returned data, read() or readAll() to get decoded audio data, endOfStream() to check for end of file, and cleanup() to shut down.

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Offline Cero
« Reply #2 - Posted 2011-08-31 08:27:16 »

Kevin Glass writes code which is just beautiful - works well, is nice, clean and easy to use.
So I highly recommend EasyOgg, which uses Jogg and Jorbis. Both of which I have used myself before, but EasyOgg is absolutely what you would want.

You can find it here http://www.cokeandcode.com/index.html?page=libs

1  
2  
3  
4  
5  
6  
7  
OggClip ogg = new OggClip("startup2.ogg");
ogg.loop();
ogg.setBalance(-1.0f);
ogg.pause();
ogg.resume();
ogg.stop();
ogg.setGain(1.0f);


I dont know if there is a javadoc, but it just THAT simple, and it works.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jack_E

Senior Newbie





« Reply #3 - Posted 2011-08-31 10:40:41 »

EasyOgg looks very promising indeed, but I'm a kinda discouraged by thread
'Improving EasyOgg' (http://www.java-gaming.org/index.php?topic=18766).

People seem to have all kind of issues with it and I see several
attempts, (that is, code), to get around those issues.

Looks like after all these years, there's still no general,
simple and robust way for using OGG-files in games...
Offline kevglass

JGO Kernel


Medals: 186
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #4 - Posted 2011-08-31 10:47:50 »

The issues that haven't been address are with Java Sound, not the OGG code.

I use EasyOGG quite a bit - specifically in legends of yore and in my recent LD48 entry. No complaints other than Java Sound doesn't always work on Linux.

Kev

Offline gouessej
« Reply #5 - Posted 2011-08-31 10:52:14 »

Looks like after all these years, there's still no general,
simple and robust way for using OGG-files in games...
I have used ogg files since October 2006 for my own first person shooter. Paul Lamb Sound Library works better than my own code (which was enough in the past). His library is quite simple and you can use it with OpenAL or JavaSound, what is wrong with it?

Offline Cero
« Reply #6 - Posted 2011-08-31 12:04:46 »

simple and robust way for using OGG-files in games...

You can also decode Ogg using Jorbis/Jogg and then play it with OpenAL, which is what Slick does (also by Kevin)
OpenAL is surely more robust.
If you wanna do that, you can use Slick or LWJGL directly for OpenAL and then Jorbis/Jogg for decoding.


Also FMOD supports many formats, one of which is OGG. FMod is of course an industry standard for playing audio, and a java lib called NativeFmod (& Ex).
FMod is just brilliant. However its only free for non-commercial games.

Offline gouessej
« Reply #7 - Posted 2011-08-31 12:12:38 »

You can use OpenAL through JOAL directly too.

Offline Mr. Gol

Senior Duke


Medals: 1



« Reply #8 - Posted 2011-08-31 12:22:35 »

I think EasyOGG does a fantastic job of giving you a high-level API over Java Sound. I've used it in a couple of projects between 2007 and now, and never had any problems with it. The fact that there is a thread about its bugs does not mean that you shouldn't use it - look how many threads we've had complaining about Thread.sleep!
Offline Jack_E

Senior Newbie





« Reply #9 - Posted 2011-08-31 12:24:09 »

Quote
The issues that haven't been address are with Java Sound, not the OGG code.

I use EasyOGG quite a bit - specifically in legends of yore and in my recent LD48 entry. No complaints other than Java Sound doesn't always work on Linux.

Oh, ok. I was under the impression that you actually did not use it
yourself, because somewhere in the aforementioned thread, you said  ;
'Doh, shows how much I don't use EasyOGG for my stuff doesn't it ?'

But this eased my mind and I'll give it a try now.   Smiley

Quote
Paul Lamb Sound Library works better than my own code (which was enough in the past). His library is quite simple and you can use it with OpenAL or JavaSound, what is wrong with it?

There's nothing wrong with it, but it just overwhelms me a bit,
with its 3 soundsystems and 8 plugins to choose from.  :-)
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline paulscode

Senior Duke


Medals: 12


Staff Sergeant


« Reply #10 - Posted 2011-08-31 13:03:16 »

There's nothing wrong with it, but it just overwhelms me a bit,
with its 3 soundsystems and 8 plugins to choose from.  :-)
Haha, I suppose I have added quite a few options over the years, which can be a bit like walking into a giant candy store to someone new just looking at it.  The API itself is very simple once you've downloaded the options you want (in a case like yours, probably the core SoundSystem, plus LibraryJavaSound and CodecJOrbis plug-ins).  But it's probably overkill for you particular needs anyway - depends on how compatible on various systems you need your application to be (read: problems with JavaSound on Linux and typically better to use OpenAL with JavaSound as a fall-back option).  Since the need seems to come up fairly often, I'm planning to make a simpler non-3D sound system once I finish my Simple Line Mixer project.  Hopefully it won't be quite as overwhelming for folks to look at - one base library plus the codec plug-ins.

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Offline teletubo
« League of Dukes »

JGO Ninja


Medals: 48
Projects: 4
Exp: 8 years



« Reply #11 - Posted 2011-08-31 13:08:58 »

The API itself is very simple once you've downloaded the options you want

Yep . I've been using your sound system for a long time. I spent like 1-2 hours understanding how to use it , then encapsulated it in my own Sound classes, and I never looked at it again Smiley

I think the effort is valid though. I've never had problems with it.

Offline gouessej
« Reply #12 - Posted 2011-08-31 15:15:06 »

The API itself is very simple once you've downloaded the options you want

Yep . I've been using your sound system for a long time. I spent like 1-2 hours understanding how to use it , then encapsulated it in my own Sound classes, and I never looked at it again Smiley

I think the effort is valid though. I've never had problems with it.
That is my case too. That is why I advise this library. EasyOGG is fine, I gave it a try some years ago but it relies on JavaSound and you may know its limitations...

Offline Jack_E

Senior Newbie





« Reply #13 - Posted 2011-08-31 19:59:27 »

  Below is my attempt to load and play an OGG-file using the 'OggInputStream'-class.
  This code obviously won't work as it is now, because I don't know how to create
  an AudioFormat-object based on the data available.
  And my second problem is that I don't understand how to use the 'read'-method,
  it needs an byte-array as argument, but since I don't know the length of the
  decoded OGG-file yet, I don't know how large this array should be (?).
 
  What should be done to get this code-sample working ?
 
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
  private void loadAndPlayOgg()
  {
    InputStream input = getClass().getResourceAsStream("explosion.ogg");    
    OggInputStream ogg = new OggInputStream(input);
   
    int format = ogg.getFormat();
    int rate   = ogg.getRate();    
    AudioFormat audioFormat = // How to create an AudioFormat with only these two parameters ??
   
   
    // I think that the size of 'inputBuffer' should be equal to the size of the decoded OGG-file,
    // but I don't know this size, so what now ?
   
    byte[] inputBuffer = new byte[1024];
    try
    {      
      int readSize = 0;      
      while((readSize = input.read(inputBuffer, 0, 1024)) > -1)
      {
        ogg.read(inputBuffer, 0, readSize);
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
   
    Clip clip = loadClip(inputBuffer, audioFormat);    
    if (clip != null)
    {
      clip.start();
    }  
   
  }
 
  private Clip loadClip(byte[] data, AudioFormat format)
  {
    DataLine.Info info = new DataLine.Info(Clip.class, format);
    if (!AudioSystem.isLineSupported(info))
    {
      System.out.println("Unsupported Clip File");
      return null;
    }

    Clip clip = null;
    try
    {
      clip = (Clip) AudioSystem.getLine(info);
      clip.open(format, data, 0, data.length);
    }
    catch (LineUnavailableException e)
    {
      e.printStackTrace();
    }    
    return clip;
  }
Offline paulscode

Senior Duke


Medals: 12


Staff Sergeant


« Reply #14 - Posted 2011-08-31 21:13:59 »

For the audio format, you will need to determine the number of channels and sample size in bits.  I expect you can get that from whatever is returned in "format".  If it indicates things like mono8, mono16, stereo8, and stereo16, then:
mono8: sampleSize 8, channels 1
mono16: sampleSize 16, channels 1
stereo8: sampleSize 8, channels 2
stereo16: sampleSize 16, channels 2


In which case you could create your AudioFormat instance like so:
1  
AudioFormat audioFormat = new AudioFormat( (float) rate, sampleSize, channels, true, false );


I haven't used OggInputStream before, so I'll leave that question for someone else with the experience.

If you can get the length of the file from that OggInputStream there may be an easier way, but if not, you could just read the file in by chunks and append them together.  The following is thrown together quickly from some source code I had sitting around, so check for typos.  It should at least give you the basic idea:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public static final int BUFSIZE = 1024;
byte[] inputBuffer = new byte[BUFSIZE];
byte[] fullBuffer = null;

int readSize = readBuffer( input, inputBuffer );

if( readSize > 0 )
{
    if( readSize < BUFSIZE )
        fullBuffer = trimArray( inputBuffer, readSize );
    else
    {
        while( readSize > 0 )
        {
            readSize = readBuffer( input, inputBuffer );
            if( readSize > 0 )
                fullBuffer = appendByteArrays( fullBuffer, inputBuffer, readSize );
        }
    }
}
else
  ; //TODO: Handle no data situation

Clip clip = loadClip( fullBuffer, audioFormat );


I almost forgot; here are the methods I referenced in the above code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
/**
 * Attempts to read one buffer full of data, and returns
 * the number of bytes read in.
 * @param in Stream to read from.
 * @param buf Buffer to put the data into.
 * @return Bytes read, or 0 if error or end of stream.
 */

private int readBuffer( InputStream in, byte[] buf )
{
    try
    {    
        int readSize = 0;    
        while( ( readSize = in.read( buf, 0, BUFSIZE ) ) > -1 )
        {
            ogg.read( in, 0, readSize );
        }
    }
    catch( IOException e )
    {
        e.printStackTrace();
    }
    return readSize;
}



/**
 * Trims down the size of the array if it is larger than the specified
 * maximum length.
 * @param array Array containing audio data.
 * @param maxLength Maximum size this array may be.
 * @return New array.
 */

    private static byte[] trimArray( byte[] array, int maxLength )
    {
        byte[] trimmedArray = null;
        if( array != null && array.length > maxLength )
        {
            trimmedArray = new byte[maxLength];
            System.arraycopy( array, 0, trimmedArray, 0, maxLength );
        }
        return trimmedArray;
    }

/**
 * Creates a new array with the second array appended to the end of the first
 * array.
 * @param arrayOne The first array.
 * @param arrayTwo The second array.
 * @param arrayTwoBytes The number of bytes to append from the second array.
 * @return Byte array containing information from both arrays.
 */

    private static byte[] appendByteArrays( byte[] arrayOne, byte[] arrayTwo,
                                            int arrayTwoBytes )
    {
        byte[] newArray;
        int bytes = arrayTwoBytes;

        // Make sure we aren't trying to append more than is there:
        if( arrayTwo == null || arrayTwo.length == 0 )
            bytes = 0;
        else if( arrayTwo.length < arrayTwoBytes )
            bytes = arrayTwo.length;

        if( arrayOne == null && (arrayTwo == null || bytes <= 0) )
        {
            // no data, just return
            return null;
        }
        else if( arrayOne == null )
        {
            // create the new array, same length as arrayTwo:
            newArray = new byte[ bytes ];
            // fill the new array with the contents of arrayTwo:
            System.arraycopy( arrayTwo, 0, newArray, 0, bytes );
            arrayTwo = null;
        }
        else if( arrayTwo == null || bytes <= 0 )
        {
            // create the new array, same length as arrayOne:
            newArray = new byte[ arrayOne.length ];
            // fill the new array with the contents of arrayOne:
            System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length );
            arrayOne = null;
        }
        else
        {
            // create the new array large enough to hold both arrays:
            newArray = new byte[ arrayOne.length + bytes ];
            System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length );
            // fill the new array with the contents of both arrays:
            System.arraycopy( arrayTwo, 0, newArray, arrayOne.length,
                              bytes );
            arrayOne = null;
            arrayTwo = null;
        }

        return newArray;
    }

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Online Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #15 - Posted 2011-09-01 06:50:52 »

Quote
1  
 while( ( readSize = in.read( buf, 0, BUFSIZE ) ) > -1 )
IndexOutOfBoundsException !!

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline paulscode

Senior Duke


Medals: 12


Staff Sergeant


« Reply #16 - Posted 2011-09-01 11:30:46 »

Haha, I just appended stuff to the code that Jack_E posted.. no guarantees there aren't bugs.  This was more of a way to programmaticaly explain the basic idea of reading the file in pieces and appending them together. (for me at least, that's the easiest way to grasp unfamiliar concepts)

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Offline philfrei
« Reply #17 - Posted 2011-09-02 10:00:20 »

Yeah...some issues on this...

http://www.java-gaming.org/topics/using-jorbis-jar-from-jcraft/24367/msg/204698/view.html#msg204698

There is some interesting code in the above, generously supplied by princec, for playing Ogg files, as used in "Revenge of the Titans".

I'm working on the plan of decoding OggVorbis into wav and storing them on the client. OggVorbis playback is guaranteed to take more resources than straight up PCM data, since you have to unpack the audio data as part of the streaming process. I'm guessing if you just have a lot of short Clips playing concurrently with no more than one long-playing OggVorbis file, you will be okay. But if you want to have more than that going on at the same time, it could get dicy. (Do other people who like and use the JOrbis.jar resource have problems with memory leaks when looping sounds?)

I keep getting side-tracked from that project, though.

"It's after the end of the world! Don't you know that yet?"
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (38 views)
2014-10-17 03:59:02

Norakomi (29 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (28 views)
2014-10-15 16:18:58

TehJavaDev (57 views)
2014-10-14 00:39:48

TehJavaDev (56 views)
2014-10-14 00:35:47

TehJavaDev (47 views)
2014-10-14 00:32:37

BurntPizza (64 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (78 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!