|
|
|
|
@@ -73,66 +73,67 @@ void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *out
|
|
|
|
|
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;}
|
|
|
|
|
do {
|
|
|
|
|
// Open a file with ExtAudioFileOpen()
|
|
|
|
|
err = ExtAudioFileOpenURL(inFileURL, &extRef);
|
|
|
|
|
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", err); break; }
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
// Get the audio data format
|
|
|
|
|
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat);
|
|
|
|
|
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", err); break; }
|
|
|
|
|
if (theFileFormat.mChannelsPerFrame > 2) { printf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); break;}
|
|
|
|
|
|
|
|
|
|
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 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); break; }
|
|
|
|
|
|
|
|
|
|
// 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); break; }
|
|
|
|
|
|
|
|
|
|
// 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); break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while(0);
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
|
// Dispose the ExtAudioFileRef, it is no longer needed
|
|
|
|
|
if (extRef) ExtAudioFileDispose(extRef);
|
|
|
|
|
return theData;
|
|
|
|
|
|