2012-04-30 1 views
6

私はopenALで自分のゲームのサウンドを再生しています。ループ中に小さなグリッチが再生されるといういくつかの問題があります。またループすることなく、私は小さなポップを得る...時にはすべてではない。音をループするときにOpenALを作る

私は、バッファがあまりにも長すぎるので、最終的にいくつかの未定義のデータがあることと関係があると思います。私はちょうどこれを変更する方法を把握することはできません。私は、この関数でCAFファイルをロードしています:

void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate, ALdouble *duration) { 
OSStatus      err = noErr;  
SInt64       theFileLengthInFrames = 0; 
AudioStreamBasicDescription  theFileFormat; 
UInt32       thePropertySize = sizeof(theFileFormat); 
ExtAudioFileRef     extRef = NULL; 
void*       theData = NULL; 
AudioStreamBasicDescription  theOutputFormat; 

// Open a file with ExtAudioFileOpen() 
err = ExtAudioFileOpenURL(inFileURL, &extRef); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", err); goto Exit; } 

// Get the audio data format 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", err); goto Exit; } 
if (theFileFormat.mChannelsPerFrame > 2) { printf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit;} 

// Set the client format to 16 bit signed integer (native-endian) data 
// Maintain the channel count and sample rate of the original source format 
theOutputFormat.mSampleRate = theFileFormat.mSampleRate; 
theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; 

theOutputFormat.mFormatID = kAudioFormatLinearPCM; 
theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame; 
theOutputFormat.mFramesPerPacket = 1; 
theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame; 
theOutputFormat.mBitsPerChannel = 16; 
theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

// Set the desired client (output) data format 
err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", err); goto Exit; } 

// Get the total frame count 
thePropertySize = sizeof(theFileLengthInFrames); 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", err); goto Exit; } 

// Read all the data into memory 
UInt32  dataSize = theFileLengthInFrames * theOutputFormat.mBytesPerFrame;; 
theData = malloc(dataSize); 
if (theData) 
{ 
    AudioBufferList  theDataBuffer; 
    theDataBuffer.mNumberBuffers = 1; 
    theDataBuffer.mBuffers[0].mDataByteSize = dataSize; 
    theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame; 
    theDataBuffer.mBuffers[0].mData = theData; 

    // Read the data into an AudioBufferList 
    err = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer); 
    if(err == noErr) 
    { 
     // success 
     *outDataSize = (ALsizei)dataSize; 
     *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; 
     *outSampleRate = (ALsizei)theOutputFormat.mSampleRate; 
    } 
    else 
    { 
     // failure 
     free (theData); 
     theData = NULL; // make sure to return NULL 
     printf("MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit; 
    } 
} 

// Alex(Colombiamug): get the file duration... 
// first, get the audioID for the file... 
AudioFileID audioID; 
UInt32 audioIDSize = sizeof(audioID); 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_AudioFile, &audioIDSize, &audioID); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_AudioFile) FAILED, Error = %ld\n", err); goto Exit; } 

//now the duration... 
double soundDuration; 
UInt32 durationSize = sizeof(soundDuration); 
err = AudioFileGetProperty(audioID, kAudioFilePropertyEstimatedDuration, &durationSize, &soundDuration); 
if(err) { printf("MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyEstimatedDuration) FAILED, Error = %ld\n", err); goto Exit; } 

*duration = soundDuration; 
//printf("Audio duration:%f secs.\n", soundDuration); 

終了: は//(EXTREF)ExtAudioFileDispose(EXTREF)場合、それはもはや を必要とされ、ExtAudioFileRefを廃棄しません。 theDataを返します。 }

それはこのsoundengineの一部です:SoundEngine

私はサンプルコードに直接私のCAFファイルを置くことを試みたが、それは同じ小さなグリッチです。 (このCAFファイルは古いアップルSoundEngine.cppと罰金やっていたが、私はそれで他の問題を持っていたので、私は変更することを決めた)自分の質問に答える

+0

ループ内の不連続の結果、ポップが発生する可能性があります。ループをクロスフェードさせていますか? – learnvst

+0

はい私はサウンドファイルを編集したときにクロスフェードしました。それは私のサウンドエディタで完全にループしているので、私はそれが私のcafファイルではないことを知っています – broch

答えて

4

を、純粋な運では)

を私がしようとした認めなければなりません次の行からkAudioFormatFlagIsPackedフラグを削除してください。

theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

それを修正しました。

なぜ誰かが知っているといいかもしれません。もし、そのフラグを削除する際に問題がある場合は、それについても聞きたいと思います。

+0

同じ問題。これは私を助けませんでした。他の解決策? –

+0

私は別のサウンドエンジン、つまりこれを使ってしまった:https://github.com/alexrestrepo/SoundEngine これはもっとうまくいくようだ – broch

関連する問題