6

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);

終了:// ExtAudioFileRefを破棄します。(extRef)ExtAudioFileDispose(extRef);の場合は不要になります。theDataを返します。}

これはこのサウンドエンジンの一部です:SoundEngine

私は自分のcafファイルをサンプルコードに直接入れようとしましたが、それは同じ小さなグリッチです。(このcafファイルは古いApple SoundEngine.cppで正常に機能していましたが、他の問題があったため、変更することにしました)

4

1 に答える 1

4

私自身の質問に答える;)

運が良ければ、この行からkAudioFormatFlagIsPackedフラグを削除しようとしたことを認めなければなりません。

theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;

そしてそれはそれを修正しました。

誰かが知っておくといい理由を教えてくれるなら..またはそのフラグを削除するのに問題があるなら、私もそれについて聞きたいです。

于 2012-04-30T21:16:51.387 に答える