OpenAL crashing sound looping

I play sounds for my game with openAL, and I have some problems that sometimes arise with a weak breakdown. Also without a loop, I get a little pop ... sometimes, but not all.

I think this is because the buffer is too long, so at the end there is some undefined data. I just can't figure out how to change this. I upload the file to the cafe using this function:

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

Output: // Dispose ExtAudioFileRef, it is no longer needed if (extRef) ExtAudioFileDispose (extRef); return data; }

This is part of this sound: SoundEngine

I tried transferring my caf file directly to the sample code, and this is the same small glitch. (This cafe file did a great job with the old Apple SoundEngine.cpp, but I had other problems, so I decided to change)

+6
source share
1 answer

Answering my own question;)

With pure luck, I have to admit that I tried to remove the kAudioFormatFlagIsPacked flag from this line:

 theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

and it fixed him.

If anyone can tell me why it would be good to know ... or if there are some problems with removing this flag, I would also like to hear about it.

+4
source

Source: https://habr.com/ru/post/914500/


All Articles