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;
}
}
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と表示されたくらいの時点でクラッシュします。環境により異なるかもしれませんが。
初歩的な質問でもうしわけないのですが、よろしくお願いします。