ALC_INVALID_CONTEXT

Hi all.
As I’m trying to port the lesson 8 from the openAL tutorial, and I’m getting the error code ALC_INVALID_CONTEXT from alGetError() just after calling alSource3f(…). If I Call alGetError() before alSource3f() I get ALC_INVALID_DEVICE.
I don’t know how to solve that problem.
Another clue : when I call AudioSystem3D.openDevice(“DirectSound3D”), I get a NullPointerException.

All of this is quite surprising given the lesson 1 works pretty good…

Thanks for your answers.

Could you please post / attach complete source code?

Why are you using the Sound3D wrapper library rather than e.g. ALut? Have you tried just calling ALut.alutInit() to get your context?

I just used the sound 3D wrapper for testing, else I use alutInit().

I will post the source code as soon as I get my dev-machine back.

Here’s the source code :


ALut.alutInit();
al = ALFactory.getAL();
if (alc.alcGetError(device) != ALC.ALC_NO_ERROR)
     return AL.AL_FALSE;

ois = new OggInputStream(new File(path).toURL().openStream()); // deprecated

al.alGenBuffers(2, IntBuffer.wrap(buffers));
check();
al.alGenSources(1, IntBuffer.allocate(source));
check();
al.alSource3f(source, AL.AL_POSITION, 0.0f, 0.0f, 0.0f);
check();

The check method :


private void check() {
    int error = al.alGetError();
    if (error != AL.AL_NO_ERROR)
	throw new ALException("OpenAL error was raised.");
}

The latest call to check() causes an ALException with 40961 in error which is related to the ALC_INVALID_DEVICE or AL_INVALIDE_NAME constant…
Any idea?

Thanks guys

A lot of stuff looks wrong with this code. I’m not sure where you’re getting the device from; and the call to IntBuffer.allocate(source) looks wrong; for example. Could you please look at the source code for the JOAL versions of the devmaster tutorials (in the joal-demos source tree; check it out via CVS) and build from those examples, which are known to work?

Ok, I’ll give it a try.

I’m just getting started with openAL, I need to get used to it :-[

I just tried lesson 3 & lesson 5 source code, I have arguments problems, some AL methods seems OK while others don’t. Does this indicate any version conflict? This would be quite surprinsing given I’m pretty sure I downloaded the latest version…

That works now, thanks to your help Ken, as you said, I was missusing IntBuffer.
I’m facing another problem now… Playing an ogg file takes 100% of my CPU.
I just ported the code from Game Dev (lesson 8), is there any way to improve the use of the CPU?

Thanks again.

I think there are several people on these forums who use Ogg Vorbis files in their games but I don’t have any experience with them myself. I’d suggest you post maybe on the performance forum asking the general question about whether people do the decompression up front (at say the beginning of a level) or on the fly.

With my understanding of what lesson 8 is about (I haven’t read all the source, nor completely comprehend it), it doesn’t look like it should be using all of the CPU cycles. It simply just decodes a little bit, puts it onto a 2-sized buffer queue, and then waits until there is more space in the buffer to add the next decoded piece.

Maybe your implementation doesn’t wait when the buffer is full? I can imagine 100% CPU usage if you’ve decided to use a sort of polling loop/thread which keeps trying to add decoded data to the buffer when there isn’t enough space. Getting this thread to wait (or the loop to yield and/or back-off for a set period of time) could reduce CPU usage.

On a different machine, it “just” take 50% of the CPU…

How would do that in the given code?

Thanks

I’m guessing the 50% thing is because it’s a dual-core processor. Because your program isn’t multi-threaded, it’ll just shunt all instructions to 1 core of the processor.

Anyway, regarding wait/notify/backing-off:

Backing-Off/Polling:
By no means the most efficient way of checking if the buffer has space to add more data to it, but the easiest to understand. This is effectively a polling mechanism that checks if there’s space in the buffer to add more data. If there isn’t any space, it goes to sleep for a while, before checking again.


// Method to add more data to the buffer
public void addData() {

    while (thereIsMoreToDecode) {
        if (buffer.isFull()) {
            Thread.sleep(500); // Sleep for 500ms
        }
        else {
            // Add more data to the buffer
        }
    }
}

public static void main(String[] args) {

    // Start a new add-data-to-buffer thread
    new Thread(new Runnable() {
        public void run() {
            addData();
        }
    }).start();

    // Do other stuff, like reading from the buffer
}

Thread wait/notify:
This is a tougher concept to understand: synchronization, locks, etc… but just as easy to implement. If you don’t already know about them (which I’ll assume) I’d probably recommend a primer in Java threads before trying this out.
In this case, the method that puts data on to the buffer is going to wait until there is more room before adding more data. What wait() means, is that the method goes to sleep until another thread tells it to wake-up (which happens when the notify() method is called) on the event that there is more room.


private int bufferSize = 2;
private int bufferUsed = 0;

// Putting data onto the buffer method
public synchronized void addData() {

    while (thereIsMoreToDecode) {

        // Decode OGG data ...

        //  Then put it onto the buffer if there's room
        if (bufferUsed < bufferSize) {
            // Queue the new data onto the buffer
            bufferUsed++;
            notify();
        }
        // Otherwise wait until there's room
        else {
            wait();
        }
    }
}

// Taking data off the buffer method
public synchronized void takeData() {

    while (thereIsMoreToRead) {

        // Only read if there is data in the buffer
        if (bufferUsed > 0) {
            // Read the data from the buffer
            bufferUsed--;
            notify();
        }
        // Otherwise, sleep until there is more 
        else {
            wait();'
        }
    }
}

// Method to start the decoding and reading threads
public static void main(String[] args) {

    // Create and start a new add-data-to-buffer thread
    new Thread(new Runnable() {
        public void run() {
            addData();
        }
    }).start();

    // Create and start a take-data-from-buffer thread
    new Thread(new Runnable() {
        public void run() {
           takeData();
        }
    }).start();
}

This is all just examples and pseudo-code, but if you can wrap your head around what the wait() and nofity() methods do, as well as fill-in the gaps for actually putting data onto the buffers where I’ve just left comments, then you should be fine. The example that I’ve written above for wait/notify is similar to the one given to this chapter on multi-threading in Java (w/ a producers-consumers example) here:
http://java.sun.com/docs/books/tutorial/essential/threads/multithreaded.html