[OpenAL] Status of OpenAL 1.1 on OS X
George Warner
geowar at apple.com
Mon Aug 21 14:52:04 PDT 2006
On Mon, 21 Aug 2006 10:47:22 +0200, "Sven Panne" <Sven.Panne at BenQ.com>
wrote:
>> Several Mac OS X OpenAL developers have requested a
>> replacement for alutLoadWAVFile (and I needed it for a few of
>> my projects ;-) so... [...]
>
> http://www.openal.org/openal_webstf/specs/alut.html#Loading :-)The
> corresponding LGPL'd code is available e.g. via Subversion at
> http://opensource.creative.com/repos/openal/trunk/alut/src/alutLoader.c.
The problem with that routine is that it only loads WAV files. The alut 1.1
replacement API ( alutCreateBufferFromFile ) is source file agnostic (which
is why I chose to implement it instead of the depreciated API).
BTW: In my testing I determined that I wasn't handling all file formats
correctly. Our Core Audio guru set me strait; This (newer) version of the
code worked for all sound file formats I could find to test it with. ;-)
//*************************************************************************
//
// alutCreateBufferFromFile ( inFilename )
//
// Purpose: Create OpenAL buffer from contents of a file
//
// Inputs: inFilename - address of complete file name ( path )
//
// Returns: On success, a handle to an OpenAL buffer containing the
loaded sound.
// It returns AL_NONE on failure.
//
ALuint alutCreateBufferFromFile ( const char * inFilename )
{
ALuint result = AL_NONE; // assume failure
ExtAudioFileRef tExtAudioFileRef = NULL;
AudioBufferList tABL;
tABL.mNumberBuffers = 1;
tABL.mBuffers[0].mNumberChannels = 0;
tABL.mBuffers[0].mDataByteSize = 0;
tABL.mBuffers[0].mData = nil;
do {
FSRef tFSRef; // convert the path into an FSRef
OSStatus status = FSPathMakeRef( ( const UInt8 * )inFilename,
&tFSRef, FALSE );
if ( noErr != status ) break;
FSCatalogInfo tFSCatalogInfo; // determine the size of the file
status = FSGetCatalogInfo( &tFSRef, kFSCatInfoDataSizes,
&tFSCatalogInfo, NULL, NULL, NULL );
if ( noErr != status ) break;
// Open the input file
status = ExtAudioFileOpen( &tFSRef, &tExtAudioFileRef );
if ( noErr != status ) break;
AudioStreamBasicDescription tASBD; // get the description ( ASDB
) of the audio file on disk
UInt32 asbd_size = sizeof( AudioStreamBasicDescription );
status = ExtAudioFileGetProperty( tExtAudioFileRef,
kExtAudioFileProperty_FileDataFormat, &asbd_size, &tASBD );
if ( noErr != status ) break;
// OpenAL doesn't need 16-bit or stereo sounds so...
ALenum format = AL_FORMAT_MONO8;
if ( !format ) break;
// configure the output ASBD
//tASBD.mSampleRate = tASBD.mSampleRate; // don't change the
sample rate
tASBD.mFormatID = kAudioFormatLinearPCM;
tASBD.mFormatFlags = kAudioFormatFlagIsPacked;
tASBD.mBytesPerPacket = 1;
tASBD.mFramesPerPacket = 1;
tASBD.mBytesPerFrame = 1;
tASBD.mChannelsPerFrame = 1;
tASBD.mBitsPerChannel = 8;
tASBD.mReserved = 0;
// now set the output ASDB
status = ExtAudioFileSetProperty( tExtAudioFileRef,
kExtAudioFileProperty_ClientDataFormat, asbd_size, &tASBD );
if ( noErr != status ) break;
tABL.mBuffers[0].mNumberChannels = tASBD.mChannelsPerFrame;
tABL.mBuffers[0].mDataByteSize = tFSCatalogInfo.dataLogicalSize;
SInt64 totalAudioFrames; // determine the number of frames in the
file
UInt32 ioPropertyDataSize = sizeof( totalAudioFrames );
status = ExtAudioFileGetProperty( tExtAudioFileRef,
kExtAudioFileProperty_FileLengthFrames, &ioPropertyDataSize,
&totalAudioFrames );
if ( noErr != status ) break;
UInt32 numberOfFrames = totalAudioFrames;
// allocate a buffer to read it into
tABL.mBuffers[0].mData = calloc( totalAudioFrames, sizeof( char ) );
if ( !tABL.mBuffers[0].mData ) {
status = memFullErr;
break;
}
// read all the frames into the buffer
status = ExtAudioFileRead( tExtAudioFileRef, &numberOfFrames, &tABL
);
if ( noErr != status ) break;
// generate a new OpenAL buffer
alGenBuffers( 1, &result );
status = alGetError( );
if ( AL_NO_ERROR != status ) break;
// load the file's data into our OpenAL buffer
ALsizei size = tFSCatalogInfo.dataLogicalSize;
ALsizei freq = tASBD.mSampleRate;
alBufferData( result, format, tABL.mBuffers[0].mData, size, freq );
status = alGetError( );
if ( AL_NO_ERROR != status ) break;
} while ( FALSE );
if ( tExtAudioFileRef ) { // close the audio file
ExtAudioFileDispose( tExtAudioFileRef );
}
if ( tABL.mBuffers[0].mData ) { // dispose of the data buffer
free( tABL.mBuffers[0].mData );
}
return result;
}
--
Enjoy,
George Warner,
Schizophrenic Optimization Scientist
Apple Developer Technical Support (DTS)
More information about the Openal
mailing list