LWJGL Forum

Programming => OpenAL => Topic started by: Cottonwood on December 16, 2010, 13:47:07

Title: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 13:47:07
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:
Code: [Select]
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();
    }
}
Title: Re: lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: kappa on December 16, 2010, 13:51:36
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 (http://slick.javaunlimited.net)  they'll probably be able to throw some light on this or even fix it.
Title: Re: lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 13:54:45
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.
Title: Re: lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 15:34:15
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.

Code: [Select]
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();
    }
}
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: 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);.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 15:57:28
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.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: kappa on December 16, 2010, 15:59:30
Thread.sleep(100) is equivalent to about 10fps in this example, so if you want to compare you should use Display.sync(10);
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 16:23:49
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?
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: kappa on December 16, 2010, 16:31:08
10fps is usually too slow for most games, you'd want at least 60fps for most action games.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 16, 2010, 16:36:44
Now I think we two are running into a loop  ::)

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.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: jediTofu on December 16, 2010, 21:05:50
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.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 17, 2010, 00:40:45
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%.
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.

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.
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.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: jediTofu on December 17, 2010, 01:58:48
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/
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 17, 2010, 10:11:07
Yes, 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. ;)

Also, 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. :-[
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: jediTofu on December 17, 2010, 20:31:20
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.
Title: Re: [solved] lwjgl Slick Sound; A hidden thread seems to run in a loop.
Post by: Cottonwood on December 17, 2010, 23:59:28
Okay, thank you. But is the GUI really needed here? It's just a sound sample.

Because the subject changed meanwhile I continued the theme in a new thread: http://lwjgl.org/forum/index.php/topic,3632.0.html