清除 OpenAL 以加载新声音
我正在将一组初始的 100 多个声音加载到 OpenAL 缓冲区中。过了一会儿,我清除了 OpenAL 上下文并重新加载另一组声音。但新加载的文件没有播放。看来之前的OpenAL buffers并没有真正释放。
这是我用于初始化和销毁 OpenAL 的代码
- (void)initOpenAL
{
// Initialization
mDevice = alcOpenDevice(NULL); // select the “preferred device”
if (mDevice) {
// use the device to make a context
mContext=alcCreateContext(mDevice,NULL);
// set my context to the currently active one
alcMakeContextCurrent(mContext);
}
}
- (void)cleanUpOpenAL
{
// delete the sources
for (NSNumber * sourceNumber in [soundDictionary allValues])
{
NSUInteger sourceID = [sourceNumber unsignedIntegerValue];
alDeleteSources(1, &sourceID);
}
[soundDictionary removeAllObjects];
// delete the buffers
for (NSNumber * bufferNumber in bufferStorageArray)
{
NSUInteger bufferID = [bufferNumber unsignedIntegerValue];
alDeleteBuffers(1, &bufferID);
}
[bufferStorageArray removeAllObjects];
// destroy the context
alcDestroyContext(mContext);
// close the device
alcCloseDevice(mDevice);
}
这是我在循环内加载声音的方法:
NSString *filePath = [[NSBundle mainBundle] pathForResource:subString ofType:@"wav"];
AudioFileID fileID = [self openAudioFile:filePath];
// find out how big the actual audio data is
UInt32 fileSize = (UInt32)[self audioFileSize:fileID];
// this is where the audio data will live for the moment
unsigned char * outData = malloc(fileSize);
// this where we actually get the bytes from the file and put them
// into the data buffer
OSStatus result = noErr;
result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData);
if (result != 0) NSLog(@"cannot load effect: %@",fileName);
NSUInteger bufferID;
// grab a buffer ID from openAL
alGenBuffers(1, &bufferID);
if((alGetError()) != AL_NO_ERROR) {
printf("Error!");
}
// jam the audio data into the new buffer
alBufferData(bufferID,AL_FORMAT_STEREO16,outData,fileSize,44100);
if((alGetError()) != AL_NO_ERROR) {
printf("Error!");
}
// clean up the buffer
if (outData)
{
free(outData);
}
else
{
outData = NULL;
}
// save the buffer so I can release it later
[bufferStorageArray addObject:[NSNumber numberWithUnsignedInteger:bufferID]];
NSUInteger sourceID;
// grab a source ID from openAL
alGenSources(1, &sourceID);
// attach the buffer to the source
alSourcei(sourceID, AL_BUFFER, bufferID);
// store this for future use
[soundDictionary setObject:[NSNumber numberWithUnsignedInt:sourceID] forKey: [NSNumber numberWithUnsignedInt:i+(padNumber*10)]];
subString = NULL;
filePath = NULL;
这就是我在重新加载新的声音集之前所做的事情:
[self cleanUpOpenAL];
[self initOpenAL];
知道哪里出了问题吗?
I am loading a initial set of 100+ sounds into the OpenAL buffer. After a while I am clearing the OpenAL context and reloading another set of sounds. But the newly loaded files are not playing. It seems that the previous OpenAL buffers are not really released.
Here is my code for initializing and destroying OpenAL
- (void)initOpenAL
{
// Initialization
mDevice = alcOpenDevice(NULL); // select the “preferred device”
if (mDevice) {
// use the device to make a context
mContext=alcCreateContext(mDevice,NULL);
// set my context to the currently active one
alcMakeContextCurrent(mContext);
}
}
- (void)cleanUpOpenAL
{
// delete the sources
for (NSNumber * sourceNumber in [soundDictionary allValues])
{
NSUInteger sourceID = [sourceNumber unsignedIntegerValue];
alDeleteSources(1, &sourceID);
}
[soundDictionary removeAllObjects];
// delete the buffers
for (NSNumber * bufferNumber in bufferStorageArray)
{
NSUInteger bufferID = [bufferNumber unsignedIntegerValue];
alDeleteBuffers(1, &bufferID);
}
[bufferStorageArray removeAllObjects];
// destroy the context
alcDestroyContext(mContext);
// close the device
alcCloseDevice(mDevice);
}
This is how I load the sounds inside a loop:
NSString *filePath = [[NSBundle mainBundle] pathForResource:subString ofType:@"wav"];
AudioFileID fileID = [self openAudioFile:filePath];
// find out how big the actual audio data is
UInt32 fileSize = (UInt32)[self audioFileSize:fileID];
// this is where the audio data will live for the moment
unsigned char * outData = malloc(fileSize);
// this where we actually get the bytes from the file and put them
// into the data buffer
OSStatus result = noErr;
result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData);
if (result != 0) NSLog(@"cannot load effect: %@",fileName);
NSUInteger bufferID;
// grab a buffer ID from openAL
alGenBuffers(1, &bufferID);
if((alGetError()) != AL_NO_ERROR) {
printf("Error!");
}
// jam the audio data into the new buffer
alBufferData(bufferID,AL_FORMAT_STEREO16,outData,fileSize,44100);
if((alGetError()) != AL_NO_ERROR) {
printf("Error!");
}
// clean up the buffer
if (outData)
{
free(outData);
}
else
{
outData = NULL;
}
// save the buffer so I can release it later
[bufferStorageArray addObject:[NSNumber numberWithUnsignedInteger:bufferID]];
NSUInteger sourceID;
// grab a source ID from openAL
alGenSources(1, &sourceID);
// attach the buffer to the source
alSourcei(sourceID, AL_BUFFER, bufferID);
// store this for future use
[soundDictionary setObject:[NSNumber numberWithUnsignedInt:sourceID] forKey: [NSNumber numberWithUnsignedInt:i+(padNumber*10)]];
subString = NULL;
filePath = NULL;
And this is what I am doing before I am reloading the new set of sounds:
[self cleanUpOpenAL];
[self initOpenAL];
Any idea where things are going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过近一周的分析,我发现了这个错误。问题是我没有关闭音频文件。在我使用 fileID 之后添加这段代码后,一切正常
After almost a week of analysis, I found the bug. The problem was that I wasn't closing the AudioFile. Everything worked after I added this piece of code after I've used the fileID