【发布时间】:2015-05-09 03:14:55
【问题描述】:
我从本教程复制/粘贴了 OpenAL 声音加载器的代码:http://wiki.lwjgl.org/wiki/OpenAL_Tutorial_6_-_Advanced_Loading_and_Error_Handles
但是,每当我尝试加载多个声音时,getALBuffer 方法中的 for 循环就会陷入无限循环。我认为我没有更改任何我复制/粘贴的代码。 i 类型为 Iterator 的调用 i.next() 似乎总是返回 true,但我不知道为什么。我会发布我所有的复制/粘贴代码,以防我在没有意识到的情况下意外更改了某些内容。代码从调用 loadALData() 开始。
public static String getALErrorString(int err) {
switch (err) {
case AL_NO_ERROR:
return "AL_NO_ERROR";
case AL_INVALID_NAME:
return "AL_INVALID_NAME";
case AL_INVALID_ENUM:
return "AL_INVALID_ENUM";
case AL_INVALID_VALUE:
return "AL_INVALID_VALUE";
case AL_INVALID_OPERATION:
return "AL_INVALID_OPERATION";
case AL_OUT_OF_MEMORY:
return "AL_OUT_OF_MEMORY";
default:
return "No such error code";
}
}
public static String getALCErrorString(int err) {
switch (err) {
case ALC_NO_ERROR:
return "AL_NO_ERROR";
case ALC_INVALID_DEVICE:
return "ALC_INVALID_DEVICE";
case ALC_INVALID_CONTEXT:
return "ALC_INVALID_CONTEXT";
case ALC_INVALID_ENUM:
return "ALC_INVALID_ENUM";
case ALC_INVALID_VALUE:
return "ALC_INVALID_VALUE";
case ALC_OUT_OF_MEMORY:
return "ALC_OUT_OF_MEMORY";
default:
return "no such error code";
}
}
public static int loadALBuffer(String path){
int result;
IntBuffer buffer = BufferUtils.createIntBuffer(1);
// Load wav data into a buffers.
alGenBuffers(buffer);
if ((result = alGetError()) != AL_NO_ERROR){
throw new OpenALException(getALErrorString(result));
}
WaveData waveFile = LoadSound(path);
if (waveFile != null){
alBufferData(buffer.get(0), waveFile.format, waveFile.data, waveFile.samplerate);
waveFile.dispose();
}else{
throw new RuntimeException("No such file: " + path);
}
// Do another error check and return.
if ((result = alGetError()) != AL_NO_ERROR) {
throw new OpenALException(getALErrorString(result));
}
return buffer.get(0);
}
/**
* 1) Checks if file has already been loaded.
* 2) If it has been loaded already, return the buffer id.
* 3) If it has not been loaded, load it and return buffer id.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static int getLoadedALBuffer(String path) {
int count = 0;
for (Iterator i = loadedFiles.iterator(); i.hasNext(); count++) {
if (i.equals(path)) {
return ((Integer) buffers.get(count)).intValue();
}
//I added this if statement to catch the infinite loop
if (count>=100000){
System.out.println("getLoadedALBuffer was caught in an infinite loop!");
return -1;
}
}
int buffer = loadALBuffer(path);
buffers.add(new Integer(buffer));
loadedFiles.add(path);
return buffer;
}
/**
* 1) Creates a source.
* 2) Calls 'GetLoadedALBuffer' with 'path' and uses the returned buffer id as it's sources buffer.
* 3) Returns the source id.
*/
@SuppressWarnings("unchecked")
public static int loadALSample(String path, boolean loop) {
IntBuffer source = BufferUtils.createIntBuffer(1);
int buffer;
int result;
// Get the files buffer id (load it if necessary).
buffer = getLoadedALBuffer(path);
//I added this to handle infinite loop error
if (buffer == -1){
return -1;
}
// Generate a source.
alGenSources(source);
if ((result = alGetError()) != AL_NO_ERROR)
throw new OpenALException(getALErrorString(result));
// Setup the source properties.
alSourcei(source.get(0), AL_BUFFER, buffer);
alSourcef(source.get(0), AL_PITCH, 1.0f);
alSourcef(source.get(0), AL_GAIN, 1.0f);
//alSource(source.get(0), AL_POSITION, sourcePos);
//alSource(source.get(0), AL_VELOCITY, sourceVel);
alSourcei(source.get(0), AL_LOOPING, (loop ? AL_TRUE : AL_FALSE));
// Save the source id.
sources.add(new Integer(source.get(0)));
// Return the source id.
return source.get(0);
}
//I created this method
public static int LoadWaveFile(String name, int location, boolean loop){
return loadALSample(getWaveFilePath(name,location), loop);
}
/**
* 1) Releases temporary loading phase data.
*/
public static void killALLoadedData() {
loadedFiles.clear();
}
// Source id's.
public static int busterShot;
public static int lifeGain;
public static void loadALData() {
// Anything for your application here. No worrying about buffers.
busterShot = LoadWaveFile("MM_Shoot", SFX_FOLDER, false);
lifeGain = LoadWaveFile("MM_1up", SFX_FOLDER, false);
killALLoadedData();
}
//I created these integers
public static final int MUSIC_FOLDER = 0;
public static final int SFX_FOLDER = 1;
//I created this method
public static WaveData LoadSound(String path){
System.out.println("\nLoadSound() called!");
WaveData sound = null;
try {
sound = WaveData.create(new BufferedInputStream(new FileInputStream(path)));
System.out.println(path+((sound!=null) ? " exists!" : " does not exist!"));
} catch (Exception e) {
e.printStackTrace();
}
return sound;
}
//I created this method
public static WaveData QuickLoad(String name, int location){
WaveData sound = LoadSound(getWaveFilePath(name, location));
return sound;
}
//I created this Method
public static String getWaveFilePath(String name, int location){
if (location == MUSIC_FOLDER){
return "res/sounds/music/"+name+".wav";
}else if(location == SFX_FOLDER){
return "res/sounds/soundEffects/"+name+".wav";
}
return null;
}
编辑:这是我运行此代码时的控制台输出:
LoadSound() 已调用!
res/sounds/soundEffects/MM_Shoot.wav 存在!
getLoadedALBuffer 陷入无限循环!
【问题讨论】:
-
您是否尝试过在 for 循环中增加迭代器而不是 count 变量?
-
@fingaz 哦,呵呵!哇,这是 OpenAL 官方网站自己的教程上的错误!感谢您指出这一点!
-
刚刚发布作为答案。可以的话点个赞吧!
标签: java infinite-loop openal