LWJGL v3 / can anyone get sound to work?

Started by purpleturtle, January 19, 2015, 23:51:57

Previous topic - Next topic

purpleturtle

I can get v2.9.2 to play sounds, but just cannot get the same code with v3 to work (I hear nothing). 

What's more, every version (nightly/stable) of the v3 lib I try seems to vary as to whether the AL.create() method is there or not.

Can anyone confirm it works?  If so please can you post the code and the md5 of the lib you built against.

Here is my code.. It's basically just the tutorial code with the AL.create/destroy calls modified with a specific context handle.

Thanks!

import java.io.BufferedInputStream;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Scanner;
 
import org.lwjgl.BufferUtils;
//import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.openal.ALContext;
//import org.lwjgl.openal.ALContext;
import org.lwjgl.util.WaveData;

public class Sound {
  /** 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 = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind();
 
  /** Velocity of the source sound. */
  FloatBuffer sourceVel = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind();
 
  /** Position of the listener. */
  FloatBuffer listenerPos = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind();
 
  /** Velocity of the listener. */
  FloatBuffer listenerVel = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind();
 
  /** Orientation of the listener. (first 3 elements are "at", second 3 are "up") */
  FloatBuffer listenerOri = (FloatBuffer)BufferUtils.createFloatBuffer(6).put(new float[] { 0.0f, 0.0f, -1.0f,  0.0f, 1.0f, 0.0f }).rewind();
 
  /**
  * 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;
 
    //Loads the wave file from your file system
    java.io.FileInputStream fin = null;
    try {
      fin = new java.io.FileInputStream("/home/james/lib/lwjgl-2.9.2/res/Footsteps.wav");
    } catch (java.io.FileNotFoundException ex) {
      ex.printStackTrace();
      return AL10.AL_FALSE;
    }
    WaveData waveFile = WaveData.create(new BufferedInputStream(fin));
    try {
      fin.close();
    } catch (java.io.IOException ex) {
    }
 
    //Loads the wave file from this class's package in your classpath
//    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;
  }
 
  /**
   * 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 Sound().execute();
  }
 
  public void execute() {
    // Initialize OpenAL and clear the error bit.
	  ALContext con = null;
	  
//      try {
    	  con = AL.create();
//    	  con = AL.getCurrentContext();
//	} catch (LWJGLException e) {
//		e.printStackTrace();
//	}
 
    // Load the wav data.
    if(loadALData() == AL10.AL_FALSE) {
      System.out.println("Error loading data.");
      return;
    }
 
    setListenerValues();
 
    // Loop.
    System.out.println("OpenAL Tutorial 1 - Single Static Source");
    System.out.println("[Menu]");
    System.out.println("p - Play the sample.");
    System.out.println("s - Stop the sample.");
    System.out.println("h - Pause the sample.");
    System.out.println("q - Quit the program.");
    char c = ' ';
    Scanner stdin = new Scanner(System.in);
    while(c != 'q') {
      try {
        System.out.print("Input: ");
        c = (char)stdin.nextLine().charAt(0);
      } catch (Exception ex) {
        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();
    AL.destroy(con);
  }
}

SHC

I got it working in the latest nightly #37, and since #32, it is working for me (Dunno before, I have tried first only in #32). At first, you need to create a context, and obtain a device like this.

ALContext context = ALContext.create();
ALDevice device = context.getDevice();

// Make the context current
context.makeCurrent();

This creates a context using the default audio device. Then you have to check for the capabilities, whether it supports the OpenAL version you are using or not. Since the tutorial is using 1.0, here is how to check that.

ALCCapabilities capabilities = device.getCapabilities();

if (!capabilities.OpenALC10)
    throw new RuntimeException("OpenAL Context Creation failed");

And then, you can call your OpenAL functions, they are pretty much the same as in the previous versions of the LWJGL library. If you are in doubt, you can take a look at the audio package of my SilenceEngine here. The code is commented, so it should be easy to understand.

Hope this helps.

abcdef

Have a look a the demo package on github, lots of useful examples that should always work with the current version

https://github.com/LWJGL/lwjgl3/tree/master/src/tests/org/lwjgl/demo/openal

purpleturtle

Thank you so much for your suggestions: I now have sound  :D

I threw away that v2 code and started from scratch from the example on github.

BrickFarmer

Quote from: abcdef on January 20, 2015, 06:26:37
Have a look a the demo package on github, lots of useful examples that should always work with the current version

https://github.com/LWJGL/lwjgl3/tree/master/src/tests/org/lwjgl/demo/openal

Is there an updated link for OpenAL examples/demos with latest LWJGL 3 please?
Oculus Rift CV1, MBP 2016 - 2.9 i7 - Radeon Pro 460  OSX 10.12.4,  Win7 - i5 4670K - GTX1070.
Oculus Rift VR Experiments: https://github.com/WhiteHexagon

spasi


BrickFarmer

Thanks.  Is this version also supporting 3D sound processing, ie. these type of features?

"OpenAL provides capabilities for playing audio in a virtual 3D environment. Distance attenuation, doppler shift, and directional sound emitters"
Oculus Rift CV1, MBP 2016 - 2.9 i7 - Radeon Pro 460  OSX 10.12.4,  Win7 - i5 4670K - GTX1070.
Oculus Rift VR Experiments: https://github.com/WhiteHexagon

abcdef

What specific openal functions are you after?

Openal 1.0 supports doppler shifts

static void   alDopplerFactor(float dopplerFactor)
static void   alDopplerVelocity(float dopplerVelocity)

There is also AL_VELOCITY,AL_DIRECTION, AL_POSITION you can apply to the listener and source.

Just look at the java doc, it should cover all you need. LWJGL should cover what you need, but with out knowing the functions you are interested in its hard to say.

spasi

The OpenAL implementation that comes with LWJGL is OpenAL Soft. Our build server also builds OpenAL Soft, so the binaries are up-to-date with the latest changes. This may change for 3.0, we'll probably stick with a stable release.

The OpenAL bindings on the other hand have not been updated in quite a while. They're low priority for me right now, but let me know if something important is missing.