Can a source play various wav files without to re-init all buffers?

Started by cleo, March 19, 2012, 16:47:19

Previous topic - Next topic

cleo

Hello,

I'm sure this must be possible.

I have thousands of small wav files to play. For obvious reasons, I can't initiate thousands of sources for this purpose. I have a few hundred fixed sources, while one "universal" source is supposed to play various wav files from time to time. Of course, whenever a new wav file is played, the buffer size shouldn't increase, nor should the whole program be re-initiated; the other fixed buffers and sources should remain intact.

But I don't get it to work with my sample code below. Once the buffers are set and the program runs, I can't assign a new wav file to my "universal" source. The source keeps its previous buffer. I can't overwrite the old buffer with a new buffer.

Does anybody know what's missing here? I'm completely lost.

Thank you in advance!

Regards

import java.io.*;
import java.nio.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.util.WaveData;

class OpenAL_Test {

	static IntBuffer buffer, source;
	static int sourceClap = 0, sourceKnock = 1, sourceUniversal = 2;

	static void addSource(int sourceId, String wavFileName) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(wavFileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return;
		}
		WaveData wd = WaveData.create(fis);
		try {
			fis.close();
		} catch (IOException e) {
		}
		if (buffer != null)
			AL10.alBufferData(buffer.get(sourceId), wd.format, wd.data, wd.samplerate);
		wd.dispose();
		int position = source.position();
		try {
			source.limit(position + 1);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		AL10.alGenSources(source);
		int i = source.get(position);
		AL10.alSourcei(i, AL10.AL_BUFFER, buffer.get(sourceId));
		source.position(position + 1);
	}

	static void playUniversal(String wavFileName) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(wavFileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return;
		}
		WaveData wd = WaveData.create(fis);
		try {
			fis.close();
		} catch (IOException e) {
		}
		AL10.alBufferData(buffer.get(sourceUniversal), wd.format, wd.data,
				wd.samplerate);
		wd.dispose();
		play(sourceUniversal);
	}

	static void play(int srce) {
		int i = source.get(srce);
		AL10.alSourcePlay(i);
		do {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
			}
		} while (AL10.alGetSourcei(i, AL10.AL_SOURCE_STATE) == AL10.AL_PLAYING);
	}

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

		try {
			AL.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			return;
		}

		buffer = BufferUtils.createIntBuffer(3);
		source = BufferUtils.createIntBuffer(3);
		AL10.alGetError();
		AL10.alGenBuffers(buffer);
		if (AL10.alGetError() != AL10.AL_NO_ERROR) {
			System.out.println("Error");
			return;
		}

		addSource(sourceClap, "clap.wav");
		addSource(sourceKnock, "knock.wav");
		addSource(sourceUniversal, "gong.wav");

		play(sourceClap);
		play(sourceKnock);
		play(sourceUniversal);

		/*
		 * The following three lines don't work. The last loaded sound (gong)
		 * plays again three times. It is not possible to assign a new wav to a 
		 * preset source. I'd like to have a few hundred sources with fixed sounds, 
		 * and one universal source that can be linked with new wav files that 
		 * aren't available at program start. I.e. while the preset sources remain 
		 * intact, one source should do an universal job without increasing the 
		 * buffers.
		 */
		playUniversal("flute1.wav");
		playUniversal("flute2.wav");
		playUniversal("flute3.wav");

		if (source != null) {
			int position = source.position();
			source.position(0).limit(position);
			AL10.alDeleteSources(source);
		}
		if (buffer != null) {
			AL10.alDeleteBuffers(buffer);
		}

		System.out.println("Exit");
	}

}