How do you stream audio in LWJGL 3?

422 Views Asked by At

I would like to be able to stream audio from a file so that if I wanted to play a longer file it won't hog up a huge amount of memory. I have tried to adapt quite a few from examples using LWJGL 2 but have had no luck. I can't find any good docs/examples for LWJGL 3, could someone give me a working example of audio streaming, and or some docs if there are any? Also no, the Javadoc isn't of much use to me since I don't know how to use it all together, let alone what to use.

I would like a snippet of working code so that I can see how it works. The code that I adapted is here: https://bedroomcoders.co.uk/lwjgl-streaming-sound-with-openal/

Here is my addapted code:

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;

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

import org.lwjgl.openal.ALCCapabilities;

public final class Synth {

    public static void main(String[] args) throws Exception {

        // ALContext alContext = ALContext.create();
        long device = alcOpenDevice((ByteBuffer) null);
        ALCCapabilities deviceCaps = ALC.createCapabilities(device);

        long alContext = alcCreateContext(device, (IntBuffer) null);
        alcMakeContextCurrent(alContext);
        AL.createCapabilities(deviceCaps);

        // a sound maker
        int source = alGenSources();

        // hold new data for transfer to AL
        ByteBuffer pcm = BufferUtils.createByteBuffer(11025); // about 1/4 second at 44.1khz

        float ang = 0;

        // throw 3 chunks of sound into a queue
        for (int i = 0; i < 3; i++) {
            ang = fillBuffer(ang, pcm);
            int b = alGenBuffers();
            alBufferData(b, AL_FORMAT_MONO8, pcm, 44100);
            alSourceQueueBuffers(source, b);
        }

        System.out.println("Playing sound ...");
        alSourcePlay(source);

        boolean done = false;
        int elapsed = 0;
        while (!done) {

            // buffers processed since last asked
            int p = alGetSourcei(source, AL_BUFFERS_PROCESSED);
            while (p != 0) {
                elapsed++;
                if (elapsed > 15)
                    break; // stop adding to queue

                // at least 1 buffer had played so remove it from the queue
                int b = alSourceUnqueueBuffers(source);

                // refill the byte buffer with the next chunk of sound
                ang = fillBuffer(ang, pcm);

                // send the buffer to AL
                alBufferData(b, AL_FORMAT_MONO8, pcm, 44100);

                // requeue the buffer
                alSourceQueueBuffers(source, b);

                // check if any more buffers have played
                p = alGetSourcei(source, AL_BUFFERS_PROCESSED);
            }

            Thread.sleep(20); // lets not hog the cpu... (we're not some crappy AAA game!)

            // just to show if we stop filling buffers it stops!
            if (alGetSourcei(source, AL_SOURCE_STATE) == AL_STOPPED) {
                done = true;
                System.out.println("source stopped ");
            }
        }
        alcDestroyContext(alContext);

    }

    // make a new chunk of sound picking off from where we where
    // when we made the last chunk of sound
    static int trig = 0;

    public static float fillBuffer(float ang, ByteBuffer buff) {
        int size = buff.capacity();
        trig++;
        for (int i = 0; i < size; i++) {

            int source1 = (int) (Math.sin(ang) * 127 + 128);
            int source2 = 0;

            if (trig > 3)
                source2 = (int) (Math.sin(ang * 3) * 127 + 128);
            if (trig > 4)
                trig = 0;

            // yes this really is how you do it.... *sigh*
            buff.put(i, (byte) ((source1 + source2) / 2));

            ang += 0.1f;
        }
        return ang;
    }

}

0

There are 0 best solutions below