Strange NullPointerException with Loading Audio....

Started by DGK, June 13, 2018, 03:11:19

Previous topic - Next topic

DGK

I am getting a NullPointerException trying to load audio with OpenAL. I am using LWJGL 3, and I have no idea how to fix it. Searched everywhere.

Error below:

Exception in thread "main" java.lang.NullPointerException
	at org.lwjgl.system.MemoryUtil.memAddress(MemoryUtil.java:653)
	at org.lwjgl.openal.AL10.alBufferData(AL10.java:1436)
	at dgk.prototype.sound.Sound.<init>(Sound.java:46)
	at dgk.prototype.sound.SoundManager.start(SoundManager.java:41)
	at dgk.prototype.game.GameWindow.loop(GameWindow.java:169)
	at dgk.prototype.main.Main.main(Main.java:12)
AL lib: (EE) alc_cleanup: 1 device not closed


Classes used:

package dgk.prototype.sound;

import dgk.prototype.util.IManager;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.ALC;
import org.lwjgl.openal.ALCCapabilities;
import org.lwjgl.openal.ALCapabilities;

import java.util.HashMap;

import static org.lwjgl.openal.ALC10.*;

public class SoundManager implements IManager {

    private HashMap<String, Sound> soundMap;

    private long device;
    private long context;

    public SoundManager() {
        this.soundMap = new HashMap<String, Sound>();
    }

    @Override
    public void start() {
        String defaultDevice = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER);
        device = alcOpenDevice(defaultDevice);

        int[] attr = {0};

        context = alcCreateContext(device, attr);
        alcMakeContextCurrent(context);

        ALCCapabilities alcCapabilities = ALC.createCapabilities(device);
        ALCapabilities alCapabilities = AL.createCapabilities(alcCapabilities);

        if(alCapabilities.OpenAL10) {
            System.out.println("OpenAL 1.0 is supported.");
        }

        Sound sound = new Sound("buttonClick.wav");

        soundMap.put("buttonClick", sound);
    }

    public Sound getSound(String name) {
        if(soundMap.containsKey(name)) {
            return soundMap.get(name);
        }

        return null;
    }

    public boolean hasSound(String name) {
        return (soundMap.containsKey(name));
    }

    @Override
    public void stop() {
        alcDestroyContext(context);
        alcCloseDevice(device);
    }

    @Override
    public void onUpdate() {

    }
}


package dgk.prototype.sound;

import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import static org.lwjgl.openal.AL10.*;
import static org.lwjgl.stb.STBVorbis.stb_vorbis_decode_filename;
import static org.lwjgl.system.MemoryStack.stackMallocInt;
import static org.lwjgl.system.MemoryStack.stackPop;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.libc.LibCStdlib.free;

public class Sound {

    private int bufferPointer;
    private int sourcePointer;

    public Sound(String fileName) {
        //File file = new File("res/sounds/" + fileName + ".wav");

        stackPush();

        IntBuffer channelBuffer = stackMallocInt(1);
        stackPush();
        IntBuffer sampleRateBuffer = stackMallocInt(1);

        ShortBuffer audioBuffer = stb_vorbis_decode_filename(fileName, channelBuffer, sampleRateBuffer);


        int channels = channelBuffer.get();
        int sampleRate = sampleRateBuffer.get();

        stackPop();
        stackPop();

        int format = -1;

        if(channels == 1) {
            format = AL_FORMAT_MONO16;
        }else if(channels == 2) {
            format = AL_FORMAT_STEREO16;
        }

        bufferPointer = alGenBuffers();

        alBufferData(bufferPointer, format, audioBuffer, sampleRate);

        //free(audioBuffer);

        sourcePointer = alGenSources();
    }

    public int getSourcePointer() {
        return sourcePointer;
    }

    public void playSound() {
        alSourcei(sourcePointer, AL_BUFFER, bufferPointer);

        alSourcePlay(sourcePointer);
    }

    public void destroy() {
        alDeleteBuffers(bufferPointer);
        alDeleteSources(sourcePointer);
    }
}

spasi

The NPE happens because stb_vorbis_decode_filename has returned null. It means it couldn't find the file or decoding failed somehow (corrupt vorbis file?).

DGK

Quote from: spasi on June 13, 2018, 15:56:57
The NPE happens because stb_vorbis_decode_filename has returned null. It means it couldn't find the file or decoding failed somehow (corrupt vorbis file?).

I figured that but the fileName is right, but I have my .wav file in res/sounds/buttonClick.wav. I tried moving it into the first folder for the project and it still won't load it. It is kind of ambiguous where it loads the file from, do you know how to fix that?

spasi

You can either use an absolute path, or a path relative to the working directory of the process. In any other case, use Java (N)IO to load the file to a buffer and use stb_vorbis_decode_memory instead.

Anyway, in this case the problem seems to be that you're trying to decode a .wav file as an Ogg Vorbis file. That's not going to work.

DGK

Quote from: spasi on June 13, 2018, 19:15:15
You can either use an absolute path, or a path relative to the working directory of the process. In any other case, use Java (N)IO to load the file to a buffer and use stb_vorbis_decode_memory instead.

Anyway, in this case the problem seems to be that you're trying to decode a .wav file as an Ogg Vorbis file. That's not going to work.

I just converted the .wav to a .ogg. I forgot it only does .ogg files. Thanks!