[solved] Windows\lwjgl-2.6 sample lesson1 is not working

Started by Cottonwood, December 06, 2010, 22:26:47

Previous topic - Next topic

Cottonwood

Hi,

I'm new here, so a kind hello to you all.

I tried to run the Windows sample lesson1. The download of the sample had compile errors. It seems to be an older version. So I took the source by adding the code snippets from http://lwjgl.org/documentation_openal_01.php

Even that had an error. I hopefully corrected it. Here is the result:

import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.util.WaveData;

public class Lesson1 {
  /** Buffers hold sound data. */
  IntBuffer buffer = BufferUtils.createIntBuffer(1);

  /** Sources are points emitting sound. */
  IntBuffer source = BufferUtils.createIntBuffer(1);

  /** Position of the source sound. */
  FloatBuffer sourcePos = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Velocity of the source sound. */
  FloatBuffer sourceVel = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Position of the listener. */
  FloatBuffer listenerPos = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Velocity of the listener. */
  FloatBuffer listenerVel = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Orientation of the listener. (first 3 elements are "at", second 3 are "up") */
  FloatBuffer listenerOri =
      BufferUtils.createFloatBuffer(6).put(new float[] { 0.0f, 0.0f, -1.0f,  0.0f, 1.0f, 0.0f });


  /**
   * boolean LoadALData()
   *
   *  This function will load our sample data from the disk using the Alut
   *  utility and send the data into OpenAL as a buffer. A source is then
   *  also created to play that buffer.
   */
  int loadALData() {

    // Load wav data into a buffer.
    AL10.alGenBuffers(buffer);

    if(AL10.alGetError() != AL10.AL_NO_ERROR)
      return AL10.AL_FALSE;

    WaveData waveFile = WaveData.create("FancyPants.wav");
    AL10.alBufferData(buffer.get(0), waveFile.format, waveFile.data, waveFile.samplerate);
    waveFile.dispose();

    // Bind the buffer with the source.
    AL10.alGenSources(source);

    if (AL10.alGetError() != AL10.AL_NO_ERROR)
      return AL10.AL_FALSE;

    AL10.alSourcei(source.get(0), AL10.AL_BUFFER,   buffer.get(0) );
    AL10.alSourcef(source.get(0), AL10.AL_PITCH,    1.0f          );
    AL10.alSourcef(source.get(0), AL10.AL_GAIN,     1.0f          );
    AL10.alSource (source.get(0), AL10.AL_POSITION, sourcePos     );
    AL10.alSource (source.get(0), AL10.AL_VELOCITY, sourceVel     );

    // Do another error check and return.
    if (AL10.alGetError() == AL10.AL_NO_ERROR)
      return AL10.AL_TRUE;

    return AL10.AL_FALSE;
  }                            // <=== <=== <=== <=== <=== <=== <=== <=== <=== <=== this line was inserted by me.

  /**
   * void setListenerValues()
   *
   *  We already defined certain values for the Listener, but we need
   *  to tell OpenAL to use that data. This function does just that.
   */
  void setListenerValues() {
    AL10.alListener(AL10.AL_POSITION,    listenerPos);
    AL10.alListener(AL10.AL_VELOCITY,    listenerVel);
    AL10.alListener(AL10.AL_ORIENTATION, listenerOri);
  }

  /**
   * void killALData()
   *
   *  We have allocated memory for our buffers and sources which needs
   *  to be returned to the system. This function frees that memory.
   */
  void killALData() {
    AL10.alDeleteSources(source);
    AL10.alDeleteBuffers(buffer);
  }

  public static void main(String[] args) {
    new Lesson1().execute();
  }

  public void execute() {
    // Initialize OpenAL and clear the error bit.
    try{
    AL.create();
    } catch (LWJGLException le) {
    le.printStackTrace();
      return;
    }
    AL10.alGetError();

    // Load the wav data.
    if(loadALData() == AL10.AL_FALSE) {
      System.out.println("Error loading data.");
      return;
    }

    setListenerValues();

    // Loop.
    char c = ' ';
    while(c != 'q') {
      try {
      c = (char) System.in.read();
      } catch (IOException ioe) {
      c = 'q';
      }

      switch(c) {
        // Pressing 'p' will begin playing the sample.
        case 'p': AL10.alSourcePlay(source.get(0)); break;

        // Pressing 's' will stop the sample from playing.
        case's': AL10.alSourceStop(source.get(0)); break;

        // Pressing 'h' will pause the sample.
        case 'h': AL10.alSourcePause(source.get(0)); break;
      };
    }
    killALData();
  }
}


But when I run that program I get error messages:

Exception in thread "main" java.lang.IllegalArgumentException: Number of remaining buffer elements is 0, must be at least 1
	at org.lwjgl.BufferChecks.throwBufferSizeException(BufferChecks.java:162)
	at org.lwjgl.BufferChecks.checkBufferSize(BufferChecks.java:189)
	at org.lwjgl.BufferChecks.checkBuffer(BufferChecks.java:258)
	at org.lwjgl.openal.AL10.alSource(AL10.java:823)
	at Lesson1.loadALData(Lesson1.java:63)
	at Lesson1.execute(Lesson1.java:111)
	at Lesson1.main(Lesson1.java:97)


What please am I doing wrong?

//Edit:
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)
Regards. Cottonwood.

jediTofu

Wow!  :o

You've uncovered a major bug in LWJGL.  When alSource checks if value (FloatBuffer) is valid, it uses checkBuffer/checkBufferSize, which then checks Buffer.remaining -- which is "limit - position."

In the creation of Buffers in LWJGL (and normal nio's methods I believe also), position is not set to 0!  So Buffer.remaining returns "3 -3" or 0!

This is a major bug that either needs to be fixed in AL10 or in how LWJGL creates buffers!  Reset the position back to 0!

Here's the current workaround for your code:
public Lesson1() {
    sourcePos.position(0);
    sourceVel.position(0);
    listenerPos.position(0);
    listenerVel.position(0);
    listenerOri.position(0);
  }


After I added this code, worked like a charm for me!

For other people reading this, the "path" in WaveData might trip you up.  It's actually wanting a resource path.  To specifiy a file path, pass in "new FileInputStream(myFilePath)".  Also, type 'p' to play, 's' to stop, 'q' to quit.

I hope someone that works on LWJGL reads this.
cool story, bro

Matthias

FloatBuffer.put(float[]) will advance the position. And the correct way is to use flip() - not position(0).

jediTofu

Quote from: Matthias on December 07, 2010, 01:01:24
FloatBuffer.put(float[]) will advance the position. And the correct way is to use flip() - not position(0).

Then flip() it is  :)  but position(0) will also work and without adjusting limit.  rewind() would probably be best, doesn't really matter.

OpenAL tutorial code needs to be changed then or checkBuffer in OpenAL code.
cool story, bro

Cottonwood

Thanks a lot. After inserting those statements it seemed to work. But there was no sound. Doubleclicking the wav showed me that the speakers are working.

So i tried it with the complete path for the wav and got the next error.

Here the actual source:
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.util.WaveData;

public class Lesson1 {
  /** Buffers hold sound data. */
  IntBuffer buffer = BufferUtils.createIntBuffer(1);

  /** Sources are points emitting sound. */
  IntBuffer source = BufferUtils.createIntBuffer(1);

  /** Position of the source sound. */
  FloatBuffer sourcePos = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Velocity of the source sound. */
  FloatBuffer sourceVel = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Position of the listener. */
  FloatBuffer listenerPos = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Velocity of the listener. */
  FloatBuffer listenerVel = BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f });

  /** Orientation of the listener. (first 3 elements are "at", second 3 are "up") */
  FloatBuffer listenerOri =
      BufferUtils.createFloatBuffer(6).put(new float[] { 0.0f, 0.0f, -1.0f,  0.0f, 1.0f, 0.0f });


  /**
   * boolean LoadALData()
   *
   *  This function will load our sample data from the disk using the Alut
   *  utility and send the data into OpenAL as a buffer. A source is then
   *  also created to play that buffer.
   */
  int loadALData() {

	sourcePos.position(0);
	sourceVel.position(0);
	listenerPos.position(0);
	listenerVel.position(0);
	listenerOri.position(0);

// Load wav data into a buffer.
    AL10.alGenBuffers(buffer);

    if(AL10.alGetError() != AL10.AL_NO_ERROR)
      return AL10.AL_FALSE;

    WaveData waveFile = WaveData.create("d:\\java\\lwjgl\\project\\lession1\\FancyPants.wav");
    AL10.alBufferData(buffer.get(0), waveFile.format, waveFile.data, waveFile.samplerate);
    waveFile.dispose();

    // Bind the buffer with the source.
    AL10.alGenSources(source);

    if (AL10.alGetError() != AL10.AL_NO_ERROR)
      return AL10.AL_FALSE;

    AL10.alSourcei(source.get(0), AL10.AL_BUFFER,   buffer.get(0) );
    AL10.alSourcef(source.get(0), AL10.AL_PITCH,    1.0f          );
    AL10.alSourcef(source.get(0), AL10.AL_GAIN,     1.0f          );
    AL10.alSource (source.get(0), AL10.AL_POSITION, sourcePos     );
    AL10.alSource (source.get(0), AL10.AL_VELOCITY, sourceVel     );

    // Do another error check and return.
    if (AL10.alGetError() == AL10.AL_NO_ERROR)
      return AL10.AL_TRUE;

    return AL10.AL_FALSE;
  }                            // <=== this line was inserted by me.

  /**
   * void setListenerValues()
   *
   *  We already defined certain values for the Listener, but we need
   *  to tell OpenAL to use that data. This function does just that.
   */
  void setListenerValues() {
    AL10.alListener(AL10.AL_POSITION,    listenerPos);
    AL10.alListener(AL10.AL_VELOCITY,    listenerVel);
    AL10.alListener(AL10.AL_ORIENTATION, listenerOri);
  }

  /**
   * void killALData()
   *
   *  We have allocated memory for our buffers and sources which needs
   *  to be returned to the system. This function frees that memory.
   */
  void killALData() {
    AL10.alDeleteSources(source);
    AL10.alDeleteBuffers(buffer);
  }

  public static void main(String[] args) {
    new Lesson1().execute();
  }

  public void execute() {
    // Initialize OpenAL and clear the error bit.
    try{
    AL.create();
    } catch (LWJGLException le) {
    le.printStackTrace();
      return;
    }
    AL10.alGetError();

    // Load the wav data.
    if(loadALData() == AL10.AL_FALSE) {
      System.out.println("Error loading data.");
      return;
    }

    setListenerValues();

    // Loop.
    char c = ' ';
    while(c != 'q') {
      try {
      c = (char) System.in.read();
      } catch (IOException ioe) {
      c = 'q';
      }

      switch(c) {
        // Pressing 'p' will begin playing the sample.
        case 'p': AL10.alSourcePlay(source.get(0)); break;

        // Pressing 's' will stop the sample from playing.
        case's': AL10.alSourceStop(source.get(0)); break;

        // Pressing 'h' will pause the sample.
        case 'h': AL10.alSourcePause(source.get(0)); break;
      };
    }
    killALData();
  }
}


And here the new error message:
Exception in thread "main" java.lang.NullPointerException
	at Lesson1.loadALData(Lesson1.java:57)
	at Lesson1.execute(Lesson1.java:117)
	at Lesson1.main(Lesson1.java:103)


What is the problem now?
Regards. Cottonwood.

jediTofu

When it runs, type in 'p' to play the sound and then push enter.
Type in 'q' to quit and 's' to stop playing.


To access a file and not a resource path, use this (BUT this is unnecessary in your case, since it ran without exceptions the first time):

FileInputStream fis = null;
try {
 fis = new FileInputStream("d:\\java\\lwjgl\\project\\lession1\\FancyPants.wav");
}
catch(FileIOException ex) {
 System.err("file io error");
 System.exit(0);
}
WaveData waveFile = WaveData.create(fstream);


You probably want to use Slick-Util instead of all of this stuff though.
https://bob.newdawnsoftware.com/repos/slick/trunk/Slick/src/org/newdawn/slick/tests/TestUtils.java
http://slick.cokeandcode.com/javadoc-util/
http://slick.cokeandcode.com/javadoc/org/newdawn/slick/util/package-summary.html
http://slick.cokeandcode.com/wiki/doku.php?id=loading_and_binding_opengl_textures_with_slick-util
cool story, bro

Cottonwood

Thank you very much.

After removing the path from the filename, playing of the sound works fine. But whe I quit with 'q' I get an error message, that means

jawaw.exe - Error in application.
The statement in "0x03888f8c" points to storage in "0x0397ecd0". Couldn't "read" this storage.
Click "OK" to terminate the program.


There is no difference whether I use 's' = stop before quitting or not. And there is no message in the console window of Eclipse.

Does that also happen when you quit? Or may that be a problem in my XP environment only?
Regards. Cottonwood.

jediTofu

That didn't happen for me; the memory address might have been corrupted from the previously failed attempts.  Restart your computer and see if you have the problem again.  You're using the latest version of LWJGL, right?  Can you please copy and paste the line of code it says the error occurs at?
cool story, bro

jediTofu

I updated the wiki with my modified source in an Appendix A section which includes:  the rewind fix, a message about 'p'/etc., and a commented section for how to load a file instead of a resource file.  All I did was add Appendix A; I didn't touch anything else.  I only did this so that if someone asks about this question again I can just redirect them to the working source code.  Feel free to delete/undo it of course; I don't care.  http://lwjgl.org/wiki/index.php?title=OpenAL_Tutorial_1_-_Single_Static_Source
cool story, bro

Cottonwood

Quote from: jediTofu on December 07, 2010, 23:30:39That didn't happen for me; the memory address might have been corrupted from the previously failed attempts.  Restart your computer and see if you have the problem again.
The error happens even after restarting the computer.

Quote from: jediTofu on December 07, 2010, 23:30:39You're using the latest version of LWJGL, right?
All the jar files have date/time like this: 2010-10-18 20:44. That may differ from what you have due to different time zones. (see(3))

Quote from: jediTofu on December 07, 2010, 23:30:39Can you please copy and paste the line of code it says the error occurs at?
There is no more message than what I showed. I inserted two printouts. Maybe it helps. (see (1))

Quote from: jediTofu on December 08, 2010, 02:15:37I updated the wiki with my modified source in an Appendix A section which includes:  the rewind fix, a message about 'p'/etc., and a commented section for how to load a file instead of a resource file.  All I did was add Appendix A; I didn't touch anything else.  I only did this so that if someone asks about this question again I can just redirect them to the working source code.  Feel free to delete/undo it of course; I don't care.  http://lwjgl.org/wiki/index.php?title=OpenAL_Tutorial_1_-_Single_Static_Source
After it happend with my version it also happens with your source code. (see(2))
After rebooting your code works fine. But mine brings the error again.

//Edit: It was just 1 time that your code worked fine after reboot. I tried to find out the statement that caused the error. So i copied statement for statement from your source to mine and tested the result after reboot. As there was no longer any essential difference I took your code again. And since that I get the error with your source as well.
Regards. Cottonwood.

kappa

Quote from: jediTofu on December 08, 2010, 02:15:37
I updated the wiki with my modified source in an Appendix A section which includes:  the rewind fix, a message about 'p'/etc., and a commented section for how to load a file instead of a resource file.  All I did was add Appendix A; I didn't touch anything else.  I only did this so that if someone asks about this question again I can just redirect them to the working source code.  Feel free to delete/undo it of course; I don't care.  http://lwjgl.org/wiki/index.php?title=OpenAL_Tutorial_1_-_Single_Static_Source

hey great work, that's a pretty old tutorial and any fixes and updates are appreciated. Feel free to update anything on the wiki, good documentation is probably the things that's most lacking atm and any updates are welcome, thx.

jediTofu

Cottonwood, sorry, there is nothing more I can do.  Because it worked once and then crashed again and because it works fine on my computer, I can only assume that either you're using native libraries with a memory leak (but then I would get it also, but perhaps, I'd need to run it 100 times on my system) or your main memory is faulty (more likely).  Try running some RAM tests on your computer.  Also, if you can, try running the code on multiple computers (just use a jar with the native libraries in the same directory as the jar), and you can more than likely get people here to also try the code.  If everyone else's works fine but yours, your main memory could be faulty and needs to be replaced.

It's just really odd that this occurs when freeing up the resources.  You could try this:

AL10.alSourceStop(source.get(0));
killALData();

ALSO, your JDK/JRE could be to blame, perhaps damaged or out of date (where a bug hasn't been fixed).  What version of Java are you using?  Make sure that both the JDK and JRE are up-to-date, and reinstall them if it's not too much trouble.
cool story, bro

Cottonwood

I'm rather sure that it is really not a problem with the source code.

My java:
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)

I tried it on a different Windows-XP-computer and with an older java version. Same error. (see =1=)

And I tried it on the original PC with "AL10.alSourceStop(source.get(0));". Same error even without playing before quitting. (see =2=)

Did you try it with Windows XP?

Regards. Cottonwood.

jediTofu

I tried it on Windows XP Home (32-bit), Windows Vista Home (32-bit), and Windows 7 Home (64-bit, already tested on).  Unfortunately, I still did not get the error that you got.

However, on Windows XP Home, it took a lot longer to load and made my hard drive spin/scratch for some reason.  I haven't used it in a while though, so it probably just needs a good defrag and update.  On Windows Vista Home, it also took longer to load, but once loaded, it ran quickly and worked perfectly.

What version of Windows XP Home are you using?  Make sure you have the latest updates installed.  Also, you should really try reinstalling Java and LWJGL.  It looks like your Java is corrupt.  When you re-download it, make sure to check the md5sum.

Sorry.  Will someone else here also try it please?  I could also try it on Linux and Solaris if you want me to.
cool story, bro

Cottonwood

With new software I always do it this way: First I install and test it. When I decide to use it for longer/ever I reload my last image, process my 2bd1 list with all the informations what I did since last image creation such as setting CLASSPATH, install the new software, do all updates, do reorganization of the boot drive and finally I create a new image. So I did it also with my freshly reloaded image that I made directly after installing java. This keeps my computer clean. And if I'm in doubt I check my pc after image creation with Kaspersky.

An so I tried it on a different computer too I dont't believe that my installation is corrupted.

Checking the md5sum with fciv.exe didn't report any checksum error on my boot drive and on my download directory.

My xp versions have both sp3 and all the updates. They come automatically.
Regards. Cottonwood.