オーディオのメモリが解放されない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
bonbo

オーディオのメモリが解放されない

#1

投稿記事 by bonbo » 13年前

早速ですが質問させていただきます
OpenALを使い再生した音楽のメモリを解放したいと思い(今回は再生直後に解放しているので音がぶつ切りになっている)
以下のようにコードをかきました。

コード:

void PlaySoundAL_inst(const char*FileName,float pitch=0,float gain=0,BOOL looping=FALSE){
    ALuint sou;
    ALuint buf;
    // 読み込み
    NSString* str = [NSString stringWithCString: FileName encoding:NSUTF8StringEncoding];
    NSString*fileName2=[str stringByDeletingPathExtension];
    NSString*   path = [[NSBundle mainBundle] pathForResource:fileName2 ofType:@"caf"];
    alGenBuffers(1, &buf);
    alGenSources(1, &sou);
    
    // オーディオデータを取得する
    void*   audioData;
    ALsizei dataSize;
    ALenum  dataFormat;
    ALsizei sampleRate;
    audioData = GetOpenALAudioData(
                                   (CFURLRef)[NSURL fileURLWithPath:path], &dataSize, &dataFormat, &sampleRate);// 内容は後半に記述
    // データをバッファに設定する
    alBufferData(buf, dataFormat, audioData, dataSize, sampleRate);
    
    // バッファをソースに設定する
    alSourcei(sou, AL_BUFFER, buf);
    
    // ならす
    ALuint soundSource=0;
    alGenSources(1, &soundSource);
    alSourcei(soundSource, AL_BUFFER, buf);
    alSourcei(soundSource, AL_LOOPING, looping);
    alSourcei(soundSource, AL_PITCH,10.5f);
    alSourcei(soundSource, AL_GAIN,1.15f);
    alSourcePlay(soundSource);
    if(sou){// souは解放しておく
        
        alSourceStop(sou);
        alDeleteSources(1, &sou);
        sou=0;
    }
    if(soundSource){
        alSourceStop(soundSource);
        alDeleteSources(1, &soundSource);
        soundSource=0;
    }
    if(buf){
        alDeleteBuffers(1, &buf);
        buf=0;
    }
}
↓上記関数に挿入されているGetOpenALAudioData関数

コード:

void* GetOpenALAudioData(
                         CFURLRef fileURL, ALsizei* dataSize, ALenum* dataFormat, ALsizei *sampleRate)
{
    OSStatus    err;
    UInt32      size;
    // バッファを用意する
    UInt32          bufferSize;
    void*           data;
    AudioBufferList dataBuffer;
    AudioStreamBasicDescription fileFormat;
    // オーディオファイルを開く
    ExtAudioFileRef audioFile;
    SInt64  fileLengthFrames = 0;
    err = ExtAudioFileOpenURL(fileURL, &audioFile);
    if (err) {
        goto Exit;
    }
    
    // オーディオデータフォーマットを取得する
    
    size = sizeof(fileFormat);
    err = ExtAudioFileGetProperty(
                                  audioFile, kExtAudioFileProperty_FileDataFormat, &size, &fileFormat);
    if (err) {
        goto Exit;
    }
    
    // アウトプットフォーマットを設定する
    AudioStreamBasicDescription outputFormat;
    outputFormat.mSampleRate = fileFormat.mSampleRate;
    outputFormat.mChannelsPerFrame = fileFormat.mChannelsPerFrame;
    outputFormat.mFormatID = kAudioFormatLinearPCM;
    outputFormat.mBytesPerPacket = 2 * outputFormat.mChannelsPerFrame;
    outputFormat.mFramesPerPacket = 1;
    outputFormat.mBytesPerFrame = 2 * outputFormat.mChannelsPerFrame;
    outputFormat.mBitsPerChannel = 16;
    outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
    err = ExtAudioFileSetProperty(
                                  audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat);
    if (err) {
        goto Exit;
    }
    
    // フレーム数を取得する
    
    size = sizeof(fileLengthFrames);
    err = ExtAudioFileGetProperty(
                                  audioFile, kExtAudioFileProperty_FileLengthFrames, &size, &fileLengthFrames);
    if (err) {
        goto Exit;
    }
    
    
    bufferSize = fileLengthFrames * outputFormat.mBytesPerFrame;;
    data = malloc(bufferSize);
    dataBuffer.mNumberBuffers = 1;
    dataBuffer.mBuffers[0].mDataByteSize = bufferSize;
    dataBuffer.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame;
    dataBuffer.mBuffers[0].mData = data;
    
    // バッファにデータを読み込む
    err = ExtAudioFileRead(audioFile, (UInt32*)&fileLengthFrames, &dataBuffer);
    if (err) {
        free(data);
        goto Exit;
    }
    
    // 出力値を設定する
    *dataSize = (ALsizei)bufferSize;
    *dataFormat = (outputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
    *sampleRate = (ALsizei)outputFormat.mSampleRate;
Exit:;
    
    // オーディオファイルを破棄する
    if (audioFile) {
        ExtAudioFileDispose(audioFile);
    }
    
    return data;
}
しかし、実際には解放できておらずメモリーがオーバーし、クラッシュしてしまいます。
どこがおかしいのでしょうか。
環境は
Xcode4.4
iphone4S
です。
ソースコードは長いので別途アップロードさせていただきました。
http://www1.axfc.net/uploader/so/2932996
上記ソースコードはAUDIO.h内に記述されています。
実行して、NSLogに5700と表示されたくらいの時点でクラッシュします。環境により異なるかもしれませんが。

初歩的な質問でもうしわけないのですが、よろしくお願いします。

bonbo

Re: オーディオのメモリが解放されない

#2

投稿記事 by bonbo » 13年前

メモリリークを調べていくとインスタンスの開放を行っていない場所がいくつか見つかり、それを直すことで改善しました。
ついでに言うとbufferおよびsourceの開放はできていました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る