[Openal] Status of OpenAL 1.1 on OS X
George Warner
geowar at apple.com
Fri Aug 18 15:48:55 PDT 2006
Several Mac OS X OpenAL developers have requested a replacement for
alutLoadWAVFile (and I needed it for a few of my projects ;-) so...
[BEGIN]
//*****************************************************
#pragma mark - includes & imports
//-----------------------------------------------------
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <OpenAL/MacOSX_OALExtensions.h>
//*****************************************************
#pragma mark - local ( static ) function prototypes
//-----------------------------------------------------
static UInt32 GetOALFormatFromASBD( AudioStreamBasicDescription *inASBD
);
//*****************************************************
#pragma mark - exported function implementations
//-----------------------------------------------------
//*************************************************************************
//
// 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 {
// Open the input file
FSRef tFSRef;
OSStatus status = FSPathMakeRef( ( const UInt8 * )inFilename,
&tFSRef, FALSE );
if ( noErr != status ) break;
FSCatalogInfo tFSCatalogInfo;
status = FSGetCatalogInfo( &tFSRef, kFSCatInfoDataSizes,
&tFSCatalogInfo, NULL, NULL, NULL );
if ( noErr != status ) break;
tABL.mBuffers[0].mData = malloc( tFSCatalogInfo.dataLogicalSize );
if ( !tABL.mBuffers[0].mData ) {
status = memFullErr;
break;
}
status = ExtAudioFileOpen( &tFSRef, &tExtAudioFileRef );
if ( noErr != status ) break;
AudioStreamBasicDescription tASBD;
UInt32 asbd_size = sizeof( AudioStreamBasicDescription );
status = ExtAudioFileGetProperty( tExtAudioFileRef,
kExtAudioFileProperty_FileDataFormat, &asbd_size, &tASBD );
if ( noErr != status ) break;
// configure output ASBD
tASBD.mFormatID = kAudioFormatLinearPCM;
tASBD.mFormatFlags = kAudioFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
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;
UInt32 ioPropertyDataSize = sizeof( totalAudioFrames );
status = ExtAudioFileGetProperty( tExtAudioFileRef,
kExtAudioFileProperty_FileLengthFrames, &ioPropertyDataSize,
&totalAudioFrames );
if ( noErr != status ) break;
UInt32 numberOfFrames = totalAudioFrames;
status = ExtAudioFileRead( tExtAudioFileRef, &numberOfFrames, &tABL
);
if ( noErr != status ) break;
// load data in buffer
ALenum format = GetOALFormatFromASBD( &tASBD );
if ( !format ) break;
alGenBuffers( 1, &result );
status = alGetError( );
if ( AL_NO_ERROR != status ) break;
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 ) {
ExtAudioFileDispose( tExtAudioFileRef );
}
if ( tABL.mBuffers[0].mData ) {
free( tABL.mBuffers[0].mData );
}
return result;
}
//*****************************************************
#pragma mark - local ( static ) function implementations
//-----------------------------------------------------
static UInt32 GetOALFormatFromASBD( AudioStreamBasicDescription *inASBD )
{
UInt32 result = 0;
switch ( inASBD->mFormatID ) {
case kAudioFormatLinearPCM: {
// NOTE: if float: return 0;
if ( inASBD->mFormatFlags & kAudioFormatFlagIsFloat ) {
result = 0; // float currently unsupported
} else {
if ( 16 == inASBD->mBitsPerChannel ) {
if ( 1 == inASBD->mChannelsPerFrame ) {
result = AL_FORMAT_MONO16;
} if ( 2 == inASBD->mChannelsPerFrame ) {
result = AL_FORMAT_STEREO16;
}
} else if ( 8 == inASBD->mBitsPerChannel ) {
if ( 1 == inASBD->mChannelsPerFrame ) {
result = AL_FORMAT_MONO8;
} if ( 2 == inASBD->mChannelsPerFrame ) {
result = AL_FORMAT_STEREO8;
}
}
}
break;
}
default: {
break;
}
}
return result;
}
[END]
--
Enjoy,
George Warner,
Schizophrenic Optimization Scientist
Apple Developer Technical Support (DTS)
More information about the Openal
mailing list