Search code examples
iphoneiosopenal

Clearing OpenAL for loading new sounds


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?


Solution

  • 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

    AudioFileClose(fileID);