[solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.

Started by Cottonwood, December 16, 2010, 13:47:07

Previous topic - Next topic

Cottonwood

When I run the sample from http://lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_2_-_Loading_Sounds_for_LWJGL
my core temperature increases. You can see the processor load on the screenshot.

This happens though I have a sleep within the loop at end of the code. It is marked with "// inserted 2010-12-15".
So I think that there is a loop within a different thread that could need a sleep also. Here my actual source:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.openal.AL;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.AudioLoader;
import org.newdawn.slick.openal.SoundStore;
 
public class SoundExample {
    /** The ogg sound effect */
    private Audio oggEffect;
    /** The wav sound effect */
    private Audio wavEffect;
    /** The aif source effect */
    private Audio aifEffect;
    /** The ogg stream thats been loaded */
    private Audio oggStream;
    /** The mod stream thats been loaded */
    private Audio modStream;
     
    /**
     * Start the test
     */
    public void start() {
        initGL(800,600);
        init();
         
        while (true) {
            update();
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            render();
             
            Display.update();
            Display.sync(100);
 
            if (Display.isCloseRequested()) {
                AL.destroy();
                System.exit(0);
            }
        }
    }
     
    /**
     * Initialise the GL display
     *
     * @param width The width of the display
     * @param height The height of the display
     */
    private void initGL(int width, int height) {
        try {
            Display.setDisplayMode(new DisplayMode(width,height));
            Display.create();
            Display.setVSyncEnabled(true);
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(0);
        }
 
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glShadeModel(GL11.GL_SMOOTH);       
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glDisable(GL11.GL_LIGHTING);                   
         
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);               
        GL11.glClearDepth(1);                                      
         
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
         
        GL11.glViewport(0,0,width,height);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, width, height, 0, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }
     
    /**
    * Initialise resources
    */
    public void init() {
 
        try {
        // you can play oggs by loading the complete thing into
        // a sound
        oggEffect = AudioLoader.getAudio("OGG", new FileInputStream("testdata/restart.ogg"));
             
        // or setting up a stream to read from. Note that the argument becomes
        // a URL here so it can be reopened when the stream is complete. Probably
        // should have reset the stream by thats not how the original stuff worked
        oggStream = AudioLoader.getStreamingAudio
                               ("OGG", new File("testdata/bongos.ogg").toURI().toURL());
             
        // can load mods (XM, MOD) using ibxm which is then played through OpenAL. MODs
        // are always streamed based on the way IBXM works
        modStream = AudioLoader.getStreamingAudio
                               ("MOD", new File("testdata/SMB-X.XM").toURI().toURL());
 
        // playing as music uses that reserved source to play the sound. The first
        // two arguments are pitch and gain, the boolean is whether to loop the content
        modStream.playAsMusic(1.0f, 1.0f, true);
             
        // you can play aifs by loading the complete thing into
        // a sound
        aifEffect = AudioLoader.getAudio("AIF", new FileInputStream("testdata/burp.aif"));
 
        // you can play wavs by loading the complete thing into
        // a sound
        wavEffect = AudioLoader.getAudio("WAV", new FileInputStream("testdata/cbrown01.wav"));
        } catch (IOException e) {
        e.printStackTrace();
    }
    }
     
    /**
     * Game loop update
     */
    public void update() {
        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (Keyboard.getEventKey() == Keyboard.KEY_Q) {
                    // play as a one off sound effect
                    oggEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_W) {
                    // replace the music thats curretly playing with
                    // the ogg
                    oggStream.playAsMusic(1.0f, 1.0f, true);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_E) {
                    // replace the music thats curretly playing with
                    // the mod
                    modStream.playAsMusic(1.0f, 1.0f, true);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_R) {
                    // play as a one off sound effect
                    aifEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_T) {
                    // play as a one off sound effect
                    wavEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
            }
            try{                                           // inserted 2010-12-15
                Thread.sleep(100);                         // inserted 2010-12-15
                }catch(InterruptedException e){            // inserted 2010-12-15
                System.out.println("Sleep Interrupted");   // inserted 2010-12-15
            }                                              // inserted 2010-12-15
        }
         
        // polling is required to allow streaming to get a chance to
        // queue buffers.
        SoundStore.get().poll(0);
    }
 
    /**
     * Game loop render
     */
    public void render() {
         
    }
     
    /**
     * Main method
     */
    public static void main(String[] argv) {
        SoundExample soundExample = new SoundExample();
        soundExample.start();
    }
}
Regards. Cottonwood.

kappa

I believe Slick-Util runs the sound stuff in its own loop, if you are having issues, you should drop a post (or bug report) on the slick forums  they'll probably be able to throw some light on this or even fix it.

Cottonwood

Okay, thank you. I'll do that and report here later.

//Edit: At the moment I get an error at registration for slick.javaunlimited.net:
Ran into problems sending Mail. Response: 535 5.7.1 http://mail.google.com/support/bin/answer.py?answer=14257

I will try it again tomorrow.
Regards. Cottonwood.

Cottonwood

Sorry, I was wrong. It wasn't a loop within a second thread. I just placed my sleep at the wrong position.
Now I have a source without this problem.

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.openal.AL;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.AudioLoader;
import org.newdawn.slick.openal.SoundStore;
 
public class SoundExample {
    /** The ogg sound effect */
    private Audio oggEffect;
    /** The wav sound effect */
    private Audio wavEffect;
    /** The aif source effect */
    private Audio aifEffect;
    /** The ogg stream thats been loaded */
    private Audio oggStream;
    /** The mod stream thats been loaded */
    private Audio modStream;
     
    /**
     * Start the test
     */
    public void start() {
        initGL(800,600);
        init();
         
        while (true) {
            update();
            try{                                           // inserted 2010-12-16
                Thread.sleep(100);                         // inserted 2010-12-16
                }catch(InterruptedException e){            // inserted 2010-12-16
                System.out.println("Sleep Interrupted");   // inserted 2010-12-16
            }                                              // inserted 2010-12-16
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            render();
             
            Display.update();
            Display.sync(100);
 
            if (Display.isCloseRequested()) {
                AL.destroy();
                System.exit(0);
            }
        }
    }
     
    /**
     * Initialise the GL display
     *
     * @param width The width of the display
     * @param height The height of the display
     */
    private void initGL(int width, int height) {
        try {
            Display.setDisplayMode(new DisplayMode(width,height));
            Display.create();
            Display.setVSyncEnabled(true);
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(0);
        }
 
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glShadeModel(GL11.GL_SMOOTH);       
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glDisable(GL11.GL_LIGHTING);                   
         
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);               
        GL11.glClearDepth(1);                                      
         
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
         
        GL11.glViewport(0,0,width,height);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, width, height, 0, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }
     
    /**
    * Initialise resources
    */
    public void init() {
 
        try {
        // you can play oggs by loading the complete thing into
        // a sound
        oggEffect = AudioLoader.getAudio("OGG", new FileInputStream("testdata/The Pretenders - Angel Of The Morning.ogg"));
             
        // or setting up a stream to read from. Note that the argument becomes
        // a URL here so it can be reopened when the stream is complete. Probably
        // should have reset the stream by thats not how the original stuff worked
        oggStream = AudioLoader.getStreamingAudio("OGG", new File("testdata/bongos.ogg").toURI().toURL());
             
        // can load mods (XM, MOD) using ibxm which is then played through OpenAL. MODs
        // are always streamed based on the way IBXM works
        modStream = AudioLoader.getStreamingAudio("MOD", new File("testdata/SMB-X.XM").toURI().toURL());
 
        // playing as music uses that reserved source to play the sound. The first
        // two arguments are pitch and gain, the boolean is whether to loop the content
        modStream.playAsMusic(1.0f, 1.0f, true);
             
        // you can play aifs by loading the complete thing into
        // a sound
        aifEffect = AudioLoader.getAudio("AIF", new FileInputStream("testdata/burp.aif"));
 
        // you can play wavs by loading the complete thing into
        // a sound
        wavEffect = AudioLoader.getAudio("WAV", new FileInputStream("testdata/cbrown01.wav"));
        } catch (IOException e) {
        e.printStackTrace();
    }
    }
     
    /**
     * Game loop update
     */
    public void update() {
        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (Keyboard.getEventKey() == Keyboard.KEY_Q) {
                    // play as a one off sound effect
                    oggEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_W) {
                    // replace the music thats curretly playing with
                    // the ogg
                    oggStream.playAsMusic(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_E) {
                    // replace the music thats curretly playing with
                    // the mod
                    modStream.playAsMusic(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_R) {
                    // play as a one off sound effect
                    aifEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_T) {
                    // play as a one off sound effect
                    wavEffect.playAsSoundEffect(1.0f, 1.0f, false);
                }
            }
        }
         
        // polling is required to allow streaming to get a chance to
        // queue buffers.
        SoundStore.get().poll(0);
    }
 
    /**
     * Game loop render
     */
    public void render() {
         
    }
     
    /**
     * Main method
     */
    public static void main(String[] argv) {
        SoundExample soundExample = new SoundExample();
        soundExample.start();
    }
}
Regards. Cottonwood.

kappa

good that you solved it.

Btw just curious why are you using  your own sleep?

Display.sync(100); in the loop already sleeps allowing the loop to run at a constant 100fps. So if you'd like to run at 60fps you'd simply change this to Display.sync(60);.

Cottonwood

I'm not sure what "Display.sync();" is really doin'. But there is a difference between it and a sleep. You can see it on my shot.
Regards. Cottonwood.

kappa

Thread.sleep(100) is equivalent to about 10fps in this example, so if you want to compare you should use Display.sync(10);

Cottonwood

It looks like being quite the same. But all I found about is this:

http://www.lwjgl.org/javadoc/org/lwjgl/opengl/Display.html
static void    sync(int fps)
          Best sync method that works reliably.

That sounds like 10 frames per second display frequency. Is that really that what I need?
Regards. Cottonwood.

kappa

10fps is usually too slow for most games, you'd want at least 60fps for most action games.

Cottonwood

Now I think we two are running into a loop  ::)

Quote from: kappa on December 16, 2010, 15:36:45
good that you solved it.

Btw just curious why are you using  your own sleep?

Display.sync(100); in the loop already sleeps allowing the loop to run at a constant 100fps. So if you'd like to run at 60fps you'd simply change this to Display.sync(60);.

That works fine and I keep the 100fps. Or am I wrong? I can't believe that it is normal, that one window takes 50% of the cpu just for the 100fps. There is nothing else done in between.
Regards. Cottonwood.

jediTofu

Sleep is already called in the Display.sync code, so it shouldn't be taking that much CPU, and your sleep should be unnecessary.  Mine usually hovers around ~10%.

Make sure that you're checking the CPU when the files are already loaded, as that's going to take a lot of CPU power.
cool story, bro

Cottonwood

Quote from: jediTofu on December 16, 2010, 21:05:50Sleep is already called in the Display.sync code, so it shouldn't be taking that much CPU, and your sleep should be unnecessary.  Mine usually hovers around ~10%.
My question is whether the sleep(100) will bring the frame rate down or not. And why the sync(100) costs that much cpu power that 50% is used though there is no additional action. There is only the sound and that works fine even with the sleep(100) where it costs 1% of the cpu power.

Quote from: jediTofu on December 16, 2010, 21:05:50Make sure that you're checking the CPU when the files are already loaded, as that's going to take a lot of CPU power.
That's absolutely sure. I waitet with the shots until the sounds were already playing. And when I used the version with the sleep(100) I could see that it didnt't take much time until the use of the cpu went down. When the music began to play the cpu usage was already low.
Regards. Cottonwood.

jediTofu

Quote from: Cottonwood on December 17, 2010, 00:40:45
My question is whether the sleep(100) will bring the frame rate down or not. And why the sync(100) costs that much cpu power that 50% is used though there is no additional action. There is only the sound and that works fine even with the sleep(100) where it costs 1% of the cpu power.

Yes, sleep(100) will bring the frame rate down.  It seems like way too much sleeping though in the main loop, in my opinion, but if it works for you, that's fine.  "sync" would be safer though because sleep(100) is only guaranteed to work on your system.  "sync" is more guaranteed to work among more systems.  "sleep(100)" could slow the program tremendously on a slower system.   I don't know why sync is causing that much CPU usage on your system though, very odd.  Try sync(30).

Also, if you're just using sound and wanting to make a GUI, check out TWL for LWJGL:
http://twl.l33tlabs.org/
cool story, bro

Cottonwood

Quote from: jediTofu on December 17, 2010, 01:58:48Yes, sleep(100) will bring the frame rate down. ... "sync" would be safer though because sleep(100) is only guaranteed to work on your system.  "sync" is more guaranteed to work among more systems.  "sleep(100)" could slow the program tremendously on a slower system.   I don't know why sync is causing that much CPU usage on your system though, very odd.  Try sync(30).
Thanks a lot. Now I understand. The documentation is not that much abundant. ;)

Quote from: jediTofu on December 17, 2010, 01:58:48Also, if you're just using sound and wanting to make a GUI, check out TWL for LWJGL:
http://twl.l33tlabs.org/
I have a working gui just with native java. I only want to be able to play ogg/vorbis or mp3 with a program that works on windows as well as on debian linux. And I cannot find any sample or tutorial for that. :-[
Regards. Cottonwood.

jediTofu

Slick-Util can play ogg & mp3, so you're good there.

If you're just using Java for your GUI, you don't need a loop.
cool story, bro