alGenEffects() Not Available?

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

alGenEffects() Not Available?

John
This post was updated on .
I'm writing a simple program to apply a JOAL effect to a sound. Everything compiles and it recognizes the calls to JOAL functions, but I get this error message. Here is the error message and the program I have written:

Exception in thread "main" java.lang.UnsupportedOperationException: Method "alGenAuxiliaryEffectSlots" not available
        at jogamp.openal.ALImpl.alGenAuxiliaryEffectSlots(ALImpl.java:613)
        at joalplaywavwitheffects.JOALPlayWavWithEffects.loadALEffects(JOALPlayWavWithEffects.java:91)
        at joalplaywavwitheffects.JOALPlayWavWithEffects.main(JOALPlayWavWithEffects.java:161)
Java Result: 1

----------------------------

package joalplaywavwitheffects;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import com.jogamp.openal.*;
import com.jogamp.openal.util.*;

public class JOALPlayWavWithEffects {

    static AL al;

    // Buffers hold sound data.
    static int[] buffer = new int[1];

    // Sources are points emitting sound.
    static int[] source = new int[1];

    // Position of the source sound.
    static float[] sourcePos = { 0.0f, 0.0f, 0.0f };

    // Velocity of the source sound.
    static float[] sourceVel = { 0.0f, 0.0f, 0.0f };

    // Position of the listener.
    static float[] listenerPos = { 0.0f, 0.0f, 0.0f };

    // Velocity of the listener.
    static float[] listenerVel = { 0.0f, 0.0f, 0.0f };

    // Orientation of the listener. (first 3 elems are "at", second 3 are "up")
    static float[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };

    //New Effects Objects
   
    //holds id's of effect slots
    static int[] uiEffectsSlot = new int[4];
   
    //holds id's of effects
    static int[] uiEffect = new int[2];

    static int loadALData() {

        // variables to load into

        int[] format = new int[1];
        int[] size = new int[1];
        ByteBuffer[] data = new ByteBuffer[1];
        int[] freq = new int[1];
        int[] loop = new int[1];

        // Load wav data into a buffer.
        al.alGenBuffers(1, buffer, 0);
        if (al.alGetError() != AL.AL_NO_ERROR)
            return AL.AL_FALSE;

        ALut.alutLoadWAVFile(
            "Sound.wav",
            format,
            data,
            size,
            freq,
            loop);
        al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]);
//        ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]);                

        // Bind buffer with a source.
        al.alGenSources(1, source, 0);                                          

        if (al.alGetError() != AL.AL_NO_ERROR)
            return AL.AL_FALSE;

        al.alSourcei(source[0], AL.AL_BUFFER, buffer[0]);
        al.alSourcef(source[0], AL.AL_PITCH, .8f);
        al.alSourcef(source[0], AL.AL_GAIN, 0.1f);
        al.alSourcefv(source[0], AL.AL_POSITION, sourcePos, 1);                    
        al.alSourcefv(source[0], AL.AL_VELOCITY, sourceVel, 1);              
        al.alSourcei(source[0], AL.AL_LOOPING, loop[0]);

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

        return AL.AL_FALSE;
    }
   
    static int loadALEffects() {
        al.alGetError();
        al.alGenAuxiliaryEffectSlots(1, uiEffectsSlot, 0);
        if (al.alGetError() != AL.AL_NO_ERROR)
            return AL.AL_FALSE;
       
        System.out.println("generated 1 effects slot");
       
        al.alGenEffects(1, uiEffect, 0);
        if(al.alGetError() != AL.AL_NO_ERROR)
            return AL.AL_FALSE;
       
        System.out.println("generated 1 effect");
       
        if (al.alIsEffect(uiEffect[0]))
        {
            al.alEffecti(uiEffect[0], AL.AL_EFFECT_TYPE, AL.AL_EFFECT_REVERB);
            if (al.alGetError() != AL.AL_NO_ERROR)
                System.out.println("ReverbEffectnotSupported");
            else
                al.alEffectf(uiEffect[0], AL.AL_REVERB_DECAY_TIME, 5.0f);
        }
       
        al.alAuxiliaryEffectSloti(uiEffectsSlot[0], AL.AL_EFFECTSLOT_EFFECT, uiEffect[0]);
       
        if(al.alGetError() == AL.AL_NO_ERROR)
            System.out.println("Successfully loaded effect into effect slot");

        return AL.AL_TRUE;
    }
   
    static int attachSourcesToEffects() {
        al.alSource3i(source[0], AL.AL_AUXILIARY_SEND_FILTER, uiEffectsSlot[0], 0, 0);
       
        if (al.alGetError() != AL.AL_NO_ERROR) {
            System.out.println("failed to configure source send 0");
            return AL.AL_FALSE;
        }
       
        return AL.AL_TRUE;  
    }

    static void setListenerValues() {
        al.alListenerfv(AL.AL_POSITION, listenerPos, 1);      
        al.alListenerfv(AL.AL_VELOCITY, listenerVel, 1);      
        al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 1);    
    }

    static void killAllData() {
        al.alDeleteBuffers(1, buffer, 0);
        al.alDeleteSources(1, source, 0);
        ALut.alutExit();
    }

    public static void main(String[] args) {
       
       
        // Initialize OpenAL and clear the error bit.
        try {
            al = ALFactory.getAL();
            ALut.alutInit();
            al.alGetError();
//        } catch (OpenALException e) {
        } catch (Exception e) {                          

            e.printStackTrace();
            return;
        }
        // Load the wav data.
        if (loadALData() == AL.AL_FALSE)
            System.exit(1);

        if(loadALEffects() == AL.AL_FALSE)
            System.exit(1);
       
        if(attachSourcesToEffects() == AL.AL_FALSE)
            System.exit(1);
       
        setListenerValues();

        char[] c = new char[1];
        while (c[0] != 'q') {
            try {
                BufferedReader buf =
                    new BufferedReader(new InputStreamReader(System.in));
                System.out.println(
                    "Press a key and hit ENTER: \n"
                        + "'p' to play, 's' to stop, " +
                          "'h' to pause and 'q' to quit");
                buf.read(c);
                switch (c[0]) {
                    case 'p' :
                        // Pressing 'p' will begin playing the sample.
                        al.alSourcePlay(source[0]);
                        break;
                    case 's' :
                        // Pressing 's' will stop the sample from playing.
                        al.alSourceStop(source[0]);
                        break;
                    case 'h' :
                        // Pressing 'n' will pause (hold) the sample.
                        al.alSourcePause(source[0]);
                        break;
                    case 'q' :
                        killAllData();
                        break;
                }
            } catch (IOException e) {
                System.exit(1);
            }
        }
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

Xerxes Rånby
This post was updated on .
I tested your code on a Linux Ubuntu machine running OpenAL soft and here it was working flawlessly, the sample was played back at a slower playback (pitch 0.8) speed with a soft-echo effect like if played in a cave.

The only oddity i saw was a pulseaudio warning that came from the OpenAL soft library. I will have to look at that.

Did you run this code on a Windows or a MacOS X machine? If so there might be limited functionality in the OpenAL library’s we currently bundle for one of these two platforms.

xranby@xranby-ESPRIMO-P7935:~/jogamp-all-platforms$ java -cp jar/joal.jar:jar/gluegen-rt.jar:. joalplaywavwitheffects/JOALPlayWavWithEffects
AL lib: pulseaudio.c:331: PulseAudio returned minreq > tlength/2; expect break up
generated 1 effects slot
generated 1 effect
Successfully loaded effect into effect slot
Press a key and hit ENTER:
'p' to play, 's' to stop, 'h' to pause and 'q' to quit
p
Press a key and hit ENTER:
'p' to play, 's' to stop, 'h' to pause and 'q' to quit
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

John
I'm running on a MacOS X.
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

gouessej
Administrator
jogamp.openal.ALProcAddressTable.isFunctionAvailable() would probably return false because you try to use a method that is not supported by your driver. Maybe you can work around this problem by forcing the use of OpenALSoft. Xerxes is much more comfortable than me with JOAL, maybe he has an idea.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

Xerxes Rånby
gouessej wrote
jogamp.openal.ALProcAddressTable.isFunctionAvailable() would probably return false because you try to use a method that is not supported by your driver. Maybe you can work around this problem by forcing the use of OpenALSoft. Xerxes is much more comfortable than me with JOAL, maybe he has an idea.
Yes OpenAL Soft 1.14 now include a CoreAudio backend for Mac OSX, supporting both playback and capture. http://kcat.strangesoft.net/openal.html
I believe that we can add support for OpenAL effects on MacOSX by simply adding a compile of OpenAL-soft project when we build the JOAL natives for MacOSX and then bundle a copy of OpenAL soft 1.14 inside the joal-natives-macosx-universal.jar . This will require that we update the build scripts for the MacOSX jenkins builds.

Please test compile OpenAL soft by compiling it manually using the sources found in this git:
git clone git://repo.or.cz/openal-soft.git openal-soft
OpenAL soft uses cmake to generate the build Makefile for make or xcode project files on mac os x.
cmake -G Xcode
After that you should be able to compile it like any other xcode project.

JogAmp JOAL can use the manually built OpenAL soft library instead of the OpenAL you currently have installed on your MacOSX system, simply place the built library next to your java classes.
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

gouessej
Administrator
Hi

I have no Mac but someone else has the same problem:
http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/jogl-support-jogl2-that-is/?topic_page=15&num=15#post-199510

How can I force the use of OpenALSoft?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

Xerxes Rånby
gouessej wrote
Hi

I have no Mac but someone else has the same problem:
http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/jogl-support-jogl2-that-is/?topic_page=15&num=15#post-199510

How can I force the use of OpenALSoft?
To "force" use of OpenALSoft first compile OpenAL Soft for Mac.
Then include the built openal library into the Mac OS X JOAL natives jar http://jogamp.org/deployment/jogamp-current/jar/joal-natives-macosx-universal.jar .
gluegen-rt will then load OpenAL Soft since it is the first OpenAL library detected on the Mac system.
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

gouessej
Administrator
It would be fine to have a flag allowing to favour software implementations when both are available. The problem seems to occur under Windows too.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

Xerxes Rånby
The root cause is really a missing merge of the JOAL OpenAL EFX patch in bug 567.
This even if OpenAL-soft supports EFX we are still unable to use them from JOAL unless this patch gets merged. I will focus on this bug and get it fixed.
https://jogamp.org/bugzilla/show_bug.cgi?id=567
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

gouessej
Administrator
Ok, it will allow to use it both in the hardware implementation and in the software one.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

Xerxes Rånby
This post was updated on .
Please test the following JOAL pullrequest:
http://forum.jogamp.org/JOAL-pullrequest-tp4027825p4028070.html

JOALPlayWavWithEffects.java
I have rewritten the JOALPlayWavWithEffects.java to use the new ALExt namespace.

javac -cp .:gluegen/build/gluegen-rt.jar:joal/build-i586/joal.jar JOALPlayWavWithEffects.java
cp joal/src/test/com/jogamp/openal/test/resources/lewiscarroll.wav Sound.wav
java -cp .:gluegen/build/gluegen-rt.jar:joal/build-i586/joal.jar JOALPlayWavWithEffects
generated 1 effects slot
generated 1 effect
Successfully loaded effect into effect slot
Press a key and hit ENTER:
'p' to play, 's' to stop, 'h' to pause and 'q' to quit
p

it work.
Reply | Threaded
Open this post in threaded view
|

Re: alGenEffects() Not Available?

sunnystormy
In reply to this post by John
If you read the comments your IDE is giving you (if you are using one), or check the JavaDoc, you'll see that you have to specify buffers to hold all of your data.

The two types of buffers that you will use for that program are:

FloatBuffer

and

IntBuffer

Here is a sample of the surgery I had to perform to get the code working correctly:

        // Buffers hold sound data.
        static int[] buffer = new int[1];
        static IntBuffer soundBuffer = IntBuffer.wrap(buffer,0,1);
       
        // Sources are points emitting sound.
        static int[] source = new int[1];
        static IntBuffer sourceBuffer = IntBuffer.wrap(source,0,1);
       
        // Position of the source sound.
        static float[] positionValue = { 0.0f, 0.0f, 0.0f };
        static FloatBuffer sourcePos = FloatBuffer.wrap(positionValue,0,3);
       
        // Velocity of the source sound.
        static float[] velocityValue = { 0.0f, 0.0f, 0.0f };
        static FloatBuffer sourceVel = FloatBuffer.wrap(velocityValue,0,3);
       
        // Position of the listener.
        static float[] listenerPos = { 0.0f, 0.0f, 0.0f };
        static FloatBuffer listenerPosBuffer = FloatBuffer.wrap(listenerPos,0,3);
       
        // Velocity of the listener.
        static float[] listenerVel = { 0.0f, 0.0f, 0.0f };
        static FloatBuffer listenerVelBuffer = FloatBuffer.wrap(listenerVel,0,3);
       
        // Orientation of the listener. (First 3 elements are "at", second 3 are "up")
        static float[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
        static FloatBuffer listenerOriBuffer = FloatBuffer.wrap(listenerOri,0,6);

Once you change the rest of the code so that the Float/Int Buffers are used where they're needed, the code should work fine. Let me know if you need any more help. (Code tested and works on Windows 7 using latest JDK update and Eclipse Juno)