[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