2012-04-30 23 views
6

Tôi đang phát âm thanh cho trò chơi của mình bằng openAL và tôi có một số vấn đề đôi khi một lỗi nhỏ được phát trong khi lặp lại. Ngoài ra không có looping tôi nhận được một cửa sổ pop nhỏ ... đôi khi nhưng không phải tất cả.Trục trặc làm cho OpenAL khi âm thanh vòng lặp

Tôi nghĩ rằng nó có một cái gì đó để làm với bộ đệm được một chút quá lâu vì vậy có một số dữ liệu không xác định cuối cùng. Tôi chỉ không thể tìm ra cách thay đổi điều này. Tôi đang tải một file caf với chức năng này:

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

Exit: // Vứt bỏ các ExtAudioFileRef, nó không còn cần thiết if (extRef) ExtAudioFileDispose (extRef); trả vềData; }

Nó là một phần của soundengine này: SoundEngine

Tôi đã cố gắng để đưa tập tin caf tôi trực tiếp vào mã mẫu và nó là như nhau trục trặc nhỏ. (File caf này đang làm tốt với Apple SoundEngine.cpp cũ nhưng tôi có những vấn đề khác với điều đó vì vậy tôi quyết định thay đổi)

+0

Xuất hiện có thể xảy ra do gián đoạn trong vòng lặp. Bạn có vượt qua mờ dần vòng lặp? – learnvst

+0

Có, tôi đã làm một crossfading khi tôi chỉnh sửa các soundfile. Nó là vòng lặp hoàn hảo trong soundeditor của tôi, vì vậy tôi biết nó không phải là tập tin caf của tôi – broch

Trả lời

4

Trả lời câu hỏi của riêng tôi;)

Bằng tinh khiết may mắn Tôi phải thừa nhận tôi đã cố gắng để xóa cờ kAudioFormatFlagIsPacked khỏi dòng này:

theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

và sửa nó.

Nếu có ai có thể cho tôi biết lý do tại sao bạn nên biết ... nếu có một số vấn đề trong việc xóa cờ đó, tôi cũng muốn nghe về điều đó.

+0

Cùng một vấn đề. Điều này không giúp tôi. Bất kỳ giải pháp nào khác? –

+0

Tôi đã sử dụng soundengine khác, cụ thể là: https://github.com/alexrestrepo/SoundEngine Dường như hoạt động tốt hơn rất nhiều – broch

Các vấn đề liên quan