2008-06-02 17:41:35 -04:00
/* Copyright: <09> Copyright 2005 Apple Computer, Inc. All rights reserved.
Disclaimer : IMPORTANT : This Apple software is supplied to you by Apple Computer , Inc .
( " Apple " ) in consideration of your agreement to the following terms , and your
use , installation , modification or redistribution of this Apple software
constitutes acceptance of these terms . If you do not agree with these terms ,
please do not use , install , modify or redistribute this Apple software .
In consideration of your agreement to abide by the following terms , and subject
to these terms , Apple grants you a personal , non - exclusive license , under Apple <EFBFBD> s
copyrights in this original Apple software ( the " Apple Software " ) , to use ,
reproduce , modify and redistribute the Apple Software , with or without
modifications , in source and / or binary forms ; provided that if you redistribute
the Apple Software in its entirety and without modifications , you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software . Neither the name , trademarks , service marks or logos of
Apple Computer , Inc . may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple . Except as
expressly stated in this notice , no other rights or licenses , express or implied ,
are granted by Apple herein , including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated .
The Apple Software is provided by Apple on an " AS IS " basis . APPLE MAKES NO
WARRANTIES , EXPRESS OR IMPLIED , INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON - INFRINGEMENT , MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE , REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS .
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL , INDIRECT , INCIDENTAL OR
CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
ARISING IN ANY WAY OUT OF THE USE , REPRODUCTION , MODIFICATION AND / OR DISTRIBUTION
OF THE APPLE SOFTWARE , HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT , TORT
( INCLUDING NEGLIGENCE ) , STRICT LIABILITY OR OTHERWISE , EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
/*=============================================================================
CAAudioFile . h
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# ifndef __CAAudioFile_h__
# define __CAAudioFile_h__
2008-12-12 09:43:24 -05:00
# include <iostream>
2008-06-02 17:41:35 -04:00
# include <AvailabilityMacros.h>
# if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
# include <AudioToolbox/AudioToolbox.h>
# else
# include <AudioToolbox.h>
# endif
# include "CAStreamBasicDescription.h"
# include "CABufferList.h"
# include "CAAudioChannelLayout.h"
# include "CAXException.h"
# include "CAMath.h"
# ifndef CAAF_USE_EXTAUDIOFILE
// option: use AudioToolbox/ExtAudioFile.h? Only available on Tiger.
# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
// we are building software that must be deployable on Panther or earlier
# define CAAF_USE_EXTAUDIOFILE 0
# else
// else we require Tiger and can use the API
# define CAAF_USE_EXTAUDIOFILE 1
# endif
# endif
# ifndef MAC_OS_X_VERSION_10_4
// we have pre-Tiger headers; add our own declarations
typedef UInt32 AudioFileTypeID ;
enum {
kExtAudioFileError_InvalidProperty = - 66561 ,
kExtAudioFileError_InvalidPropertySize = - 66562 ,
kExtAudioFileError_NonPCMClientFormat = - 66563 ,
kExtAudioFileError_InvalidChannelMap = - 66564 , // number of channels doesn't match format
kExtAudioFileError_InvalidOperationOrder = - 66565 ,
kExtAudioFileError_InvalidDataFormat = - 66566 ,
kExtAudioFileError_MaxPacketSizeUnknown = - 66567 ,
kExtAudioFileError_InvalidSeek = - 66568 , // writing, or offset out of bounds
kExtAudioFileError_AsyncWriteTooLarge = - 66569 ,
kExtAudioFileError_AsyncWriteBufferOverflow = - 66570 // an async write could not be completed in time
} ;
# else
# if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
# include <AudioToolbox/ExtendedAudioFile.h>
# else
# include "ExtendedAudioFile.h"
# endif
# endif
// _______________________________________________________________________________________
// Wrapper class for an AudioFile, supporting encode/decode to/from a PCM client format
class CAAudioFile {
public :
// implementation-independent helpers
void Open ( const char * filePath ) {
FSRef fsref ;
2008-12-12 09:43:24 -05:00
std : : cerr < < " Opening " < < filePath < < std : : endl ;
2008-06-02 17:41:35 -04:00
XThrowIfError ( FSPathMakeRef ( ( UInt8 * ) filePath , & fsref , NULL ) , " locate audio file " ) ;
Open ( fsref ) ;
}
bool HasConverter ( ) const { return GetConverter ( ) ! = NULL ; }
double GetDurationSeconds ( ) {
double sr = GetFileDataFormat ( ) . mSampleRate ;
return fnonzero ( sr ) ? GetNumberFrames ( ) / sr : 0. ;
}
// will be 0 if the file's frames/packet is 0 (variable)
// or the file's sample rate is 0 (unknown)
# if CAAF_USE_EXTAUDIOFILE
public :
2008-12-12 09:43:24 -05:00
CAAudioFile ( ) : mExtAF ( NULL ) { std : : cerr < < " Constructing CAAudioFile \n " ; }
virtual ~ CAAudioFile ( ) { std : : cerr < < " Destroying CAAudiofile @ " < < this < < std : : endl ; if ( mExtAF ) Close ( ) ; }
2008-06-02 17:41:35 -04:00
void Open ( const FSRef & fsref ) {
// open an existing file
XThrowIfError ( ExtAudioFileOpen ( & fsref , & mExtAF ) , " ExtAudioFileOpen failed " ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void CreateNew ( const FSRef & inParentDir , CFStringRef inFileName , AudioFileTypeID inFileType , const AudioStreamBasicDescription & inStreamDesc , const AudioChannelLayout * inChannelLayout = NULL ) {
XThrowIfError ( ExtAudioFileCreateNew ( & inParentDir , inFileName , inFileType , & inStreamDesc , inChannelLayout , & mExtAF ) , " ExtAudioFileCreateNew failed " ) ;
}
void Wrap ( AudioFileID fileID , bool forWriting ) {
// use this to wrap an AudioFileID opened externally
XThrowIfError ( ExtAudioFileWrapAudioFileID ( fileID , forWriting , & mExtAF ) , " ExtAudioFileWrapAudioFileID failed " ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void Close ( ) {
2008-12-12 09:43:24 -05:00
std : : cerr < < " \t disposeo of ext audio file @ " < < mExtAF < < std : : endl ;
2008-06-02 17:41:35 -04:00
XThrowIfError ( ExtAudioFileDispose ( mExtAF ) , " ExtAudioFileClose failed " ) ;
mExtAF = NULL ;
}
const CAStreamBasicDescription & GetFileDataFormat ( ) {
UInt32 size = sizeof ( mFileDataFormat ) ;
XThrowIfError ( ExtAudioFileGetProperty ( mExtAF , kExtAudioFileProperty_FileDataFormat , & size , & mFileDataFormat ) , " Couldn't get file's data format " ) ;
return mFileDataFormat ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
const CAAudioChannelLayout & GetFileChannelLayout ( ) {
return FetchChannelLayout ( mFileChannelLayout , kExtAudioFileProperty_FileChannelLayout ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void SetFileChannelLayout ( const CAAudioChannelLayout & layout ) {
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_FileChannelLayout , layout . Size ( ) , & layout . Layout ( ) ) , " Couldn't set file's channel layout " ) ;
mFileChannelLayout = layout ;
}
const CAStreamBasicDescription & GetClientDataFormat ( ) {
UInt32 size = sizeof ( mClientDataFormat ) ;
XThrowIfError ( ExtAudioFileGetProperty ( mExtAF , kExtAudioFileProperty_ClientDataFormat , & size , & mClientDataFormat ) , " Couldn't get client data format " ) ;
return mClientDataFormat ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
const CAAudioChannelLayout & GetClientChannelLayout ( ) {
return FetchChannelLayout ( mClientChannelLayout , kExtAudioFileProperty_ClientChannelLayout ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void SetClientFormat ( const CAStreamBasicDescription & dataFormat , const CAAudioChannelLayout * layout = NULL ) {
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_ClientDataFormat , sizeof ( dataFormat ) , & dataFormat ) , " Couldn't set client format " ) ;
if ( layout )
SetClientChannelLayout ( * layout ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void SetClientChannelLayout ( const CAAudioChannelLayout & layout ) {
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_ClientChannelLayout , layout . Size ( ) , & layout . Layout ( ) ) , " Couldn't set client channel layout " ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
AudioConverterRef GetConverter ( ) const {
UInt32 size = sizeof ( AudioConverterRef ) ;
AudioConverterRef converter ;
XThrowIfError ( ExtAudioFileGetProperty ( mExtAF , kExtAudioFileProperty_AudioConverter , & size , & converter ) , " Couldn't get file's AudioConverter " ) ;
return converter ;
}
OSStatus SetConverterProperty ( AudioConverterPropertyID inPropertyID , UInt32 inPropertyDataSize , const void * inPropertyData , bool inCanFail = false )
{
OSStatus err = AudioConverterSetProperty ( GetConverter ( ) , inPropertyID , inPropertyDataSize , inPropertyData ) ;
if ( ! inCanFail )
XThrowIfError ( err , " Couldn't set audio converter property " ) ;
if ( ! err ) {
// must tell the file that we have changed the converter; a NULL converter config is sufficient
CFPropertyListRef config = NULL ;
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_ConverterConfig , sizeof ( CFPropertyListRef ) , & config ) , " couldn't signal the file that the converter has changed " ) ;
}
return err ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
SInt64 GetNumberFrames ( ) {
SInt64 length ;
UInt32 size = sizeof ( SInt64 ) ;
XThrowIfError ( ExtAudioFileGetProperty ( mExtAF , kExtAudioFileProperty_FileLengthFrames , & size , & length ) , " Couldn't get file's length " ) ;
return length ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void SetNumberFrames ( SInt64 length ) {
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_FileLengthFrames , sizeof ( SInt64 ) , & length ) , " Couldn't set file's length " ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void Seek ( SInt64 pos ) {
XThrowIfError ( ExtAudioFileSeek ( mExtAF , pos ) , " Couldn't seek in audio file " ) ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
SInt64 Tell ( ) {
SInt64 pos ;
XThrowIfError ( ExtAudioFileTell ( mExtAF , & pos ) , " Couldn't get file's mark " ) ;
return pos ;
}
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void Read ( UInt32 & ioFrames , AudioBufferList * ioData ) {
XThrowIfError ( ExtAudioFileRead ( mExtAF , & ioFrames , ioData ) , " Couldn't read audio file " ) ;
}
void Write ( UInt32 inFrames , const AudioBufferList * inData ) {
XThrowIfError ( ExtAudioFileWrite ( mExtAF , inFrames , inData ) , " Couldn't write audio file " ) ;
}
void SetIOBufferSizeBytes ( UInt32 bufferSizeBytes ) {
XThrowIfError ( ExtAudioFileSetProperty ( mExtAF , kExtAudioFileProperty_IOBufferSizeBytes , sizeof ( UInt32 ) , & bufferSizeBytes ) , " Couldn't set audio file's I/O buffer size " ) ;
}
private :
const CAAudioChannelLayout & FetchChannelLayout ( CAAudioChannelLayout & layoutObj , ExtAudioFilePropertyID propID ) {
UInt32 size ;
XThrowIfError ( ExtAudioFileGetPropertyInfo ( mExtAF , propID , & size , NULL ) , " Couldn't get info about channel layout " ) ;
AudioChannelLayout * layout = ( AudioChannelLayout * ) malloc ( size ) ;
OSStatus err = ExtAudioFileGetProperty ( mExtAF , propID , & size , layout ) ;
if ( err ) {
free ( layout ) ;
XThrowIfError ( err , " Couldn't get channel layout " ) ;
}
layoutObj = layout ;
free ( layout ) ;
return layoutObj ;
}
private :
ExtAudioFileRef mExtAF ;
CAStreamBasicDescription mFileDataFormat ;
CAAudioChannelLayout mFileChannelLayout ;
CAStreamBasicDescription mClientDataFormat ;
CAAudioChannelLayout mClientChannelLayout ;
# endif
# if !CAAF_USE_EXTAUDIOFILE
CAAudioFile ( ) ;
virtual ~ CAAudioFile ( ) ;
// --- second-stage initializers ---
// Use exactly one of the following:
// - Open
// - PrepareNew followed by Create
// - Wrap
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void Open ( const FSRef & fsref ) ;
// open an existing file
void CreateNew ( const FSRef & inParentDir , CFStringRef inFileName , AudioFileTypeID inFileType , const AudioStreamBasicDescription & inStreamDesc , const AudioChannelLayout * inChannelLayout = NULL ) ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void Wrap ( AudioFileID fileID , bool forWriting ) ;
// use this to wrap an AudioFileID opened externally
// ---
void Close ( ) ;
// In case you want to close the file before the destructor executes
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// --- Data formats ---
// Allow specifying the file's channel layout. Must be called before SetClientFormat.
// When writing, the specified channel layout is written to the file (if the file format supports
// the channel layout). When reading, the specified layout overrides the one read from the file,
// if any.
void SetFileChannelLayout ( const CAAudioChannelLayout & layout ) ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// This specifies the data format which the client will use for reading/writing the file,
// which may be different from the file's format. An AudioConverter is created if necessary.
// The client format must be linear PCM.
void SetClientFormat ( const CAStreamBasicDescription & dataFormat , const CAAudioChannelLayout * layout = NULL ) ;
void SetClientDataFormat ( const CAStreamBasicDescription & dataFormat ) { SetClientFormat ( dataFormat , NULL ) ; }
void SetClientChannelLayout ( const CAAudioChannelLayout & layout ) { SetClientFormat ( mClientDataFormat , & layout ) ; }
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// Wrapping the underlying converter, if there is one
OSStatus SetConverterProperty ( AudioConverterPropertyID inPropertyID ,
UInt32 inPropertyDataSize ,
const void * inPropertyData ,
bool inCanFail = false ) ;
void SetConverterConfig ( CFArrayRef config ) {
SetConverterProperty ( kAudioConverterPropertySettings , sizeof ( config ) , & config ) ; }
CFArrayRef GetConverterConfig ( ) ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// --- I/O ---
// All I/O is sequential, but you can seek to an arbitrary position when reading.
// SeekToPacket and TellPacket's packet numbers are in the file's data format, not the client's.
// However, ReadPackets/WritePackets use packet counts in the client data format.
void Read ( UInt32 & ioNumFrames , AudioBufferList * ioData ) ;
void Write ( UInt32 numFrames , const AudioBufferList * data ) ;
// These can fail for files without a constant mFramesPerPacket
void Seek ( SInt64 frameNumber ) ;
SInt64 Tell ( ) const ; // frameNumber
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// --- Accessors ---
// note: client parameters only valid if SetClientFormat has been called
AudioFileID GetAudioFileID ( ) const { return mAudioFile ; }
const CAStreamBasicDescription & GetFileDataFormat ( ) const { return mFileDataFormat ; }
const CAStreamBasicDescription & GetClientDataFormat ( ) const { return mClientDataFormat ; }
const CAAudioChannelLayout & GetFileChannelLayout ( ) const { return mFileChannelLayout ; }
const CAAudioChannelLayout & GetClientChannelLayout ( ) const { return mClientChannelLayout ; }
AudioConverterRef GetConverter ( ) const { return mConverter ; }
UInt32 GetFileMaxPacketSize ( ) const { return mFileMaxPacketSize ; }
UInt32 GetClientMaxPacketSize ( ) const { return mClientMaxPacketSize ; }
SInt64 GetNumberPackets ( ) const {
SInt64 npackets ;
UInt32 propertySize = sizeof ( npackets ) ;
XThrowIfError ( AudioFileGetProperty ( mAudioFile , kAudioFilePropertyAudioDataPacketCount , & propertySize , & npackets ) , " get audio file's packet count " ) ;
return npackets ;
}
SInt64 GetNumberFrames ( ) const ;
// will be 0 if the file's frames/packet is 0 (variable)
void SetNumberFrames ( SInt64 length ) ; // should only be set on a PCM file
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// --- Tunable performance parameters ---
void SetUseCache ( bool b ) { mUseCache = b ; }
void SetIOBufferSizeBytes ( UInt32 bufferSizeBytes ) { mIOBufferSizeBytes = bufferSizeBytes ; }
UInt32 GetIOBufferSizeBytes ( ) { return mIOBufferSizeBytes ; }
void * GetIOBuffer ( ) { return mIOBufferList . mBuffers [ 0 ] . mData ; }
void SetIOBuffer ( void * buf ) ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// -- Profiling ---
# if CAAUDIOFILE_PROFILE
void EnableProfiling ( bool b ) { mProfiling = b ; }
UInt64 TicksInConverter ( ) const { return ( mTicksInConverter > 0 ) ? ( mTicksInConverter - mTicksInReadInConverter ) : 0 ; }
UInt64 TicksInIO ( ) const { return mTicksInIO ; }
# endif
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// _______________________________________________________________________________________
private :
SInt64 FileDataOffset ( ) ;
void SeekToPacket ( SInt64 packetNumber ) ;
SInt64 TellPacket ( ) const { return mPacketMark ; } // will be imprecise if SeekToFrame was called
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
void SetConverterChannelLayout ( bool output , const CAAudioChannelLayout & layout ) ;
void WritePacketsFromCallback (
AudioConverterComplexInputDataProc inInputDataProc ,
void * inInputDataProcUserData ) ;
// will use I/O buffer size
void InitFileMaxPacketSize ( ) ;
void FileFormatChanged ( const FSRef * parentDir = 0 , CFStringRef filename = 0 , AudioFileTypeID filetype = 0 ) ;
void GetExistingFileInfo ( ) ;
void FlushEncoder ( ) ;
void CloseConverter ( ) ;
void UpdateClientMaxPacketSize ( ) ;
void AllocateBuffers ( bool okToFail = false ) ;
SInt64 PacketToFrame ( SInt64 packet ) const ;
SInt64 FrameToPacket ( SInt64 inFrame ) const ;
static OSStatus ReadInputProc ( AudioConverterRef inAudioConverter ,
UInt32 * ioNumberDataPackets ,
AudioBufferList * ioData ,
AudioStreamPacketDescription * * outDataPacketDescription ,
2015-10-05 10:17:49 -04:00
void * inUserData ) ;
2008-06-02 17:41:35 -04:00
static OSStatus WriteInputProc ( AudioConverterRef inAudioConverter ,
UInt32 * ioNumberDataPackets ,
AudioBufferList * ioData ,
AudioStreamPacketDescription * * outDataPacketDescription ,
2015-10-05 10:17:49 -04:00
void * inUserData ) ;
2008-06-02 17:41:35 -04:00
// _______________________________________________________________________________________
private :
// the file
FSRef mFSRef ;
AudioFileID mAudioFile ;
bool mOwnOpenFile ;
bool mUseCache ;
bool mFinishingEncoding ;
enum { kClosed , kReading , kPreparingToCreate , kPreparingToWrite , kWriting } mMode ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// SInt64 mNumberPackets; // in file's format
SInt64 mFileDataOffset ;
SInt64 mPacketMark ; // in file's format
SInt64 mFrameMark ; // this may be offset from the start of the file
// by the codec's latency; i.e. our frame 0 could
// lie at frame 2112 of a decoded AAC file
SInt32 mFrame0Offset ;
UInt32 mFramesToSkipFollowingSeek ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// buffers
UInt32 mIOBufferSizeBytes ;
UInt32 mIOBufferSizePackets ;
AudioBufferList mIOBufferList ; // only one buffer -- USE ACCESSOR so it can be lazily initialized
bool mClientOwnsIOBuffer ;
AudioStreamPacketDescription * mPacketDescs ;
UInt32 mNumPacketDescs ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// formats/conversion
AudioConverterRef mConverter ;
CAStreamBasicDescription mFileDataFormat ;
CAStreamBasicDescription mClientDataFormat ;
CAAudioChannelLayout mFileChannelLayout ;
CAAudioChannelLayout mClientChannelLayout ;
UInt32 mFileMaxPacketSize ;
UInt32 mClientMaxPacketSize ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// cookie
Byte * mMagicCookie ;
UInt32 mMagicCookieSize ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// for ReadPackets
UInt32 mMaxPacketsToRead ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
// for WritePackets
UInt32 mWritePackets ;
CABufferList * mWriteBufferList ;
2015-10-05 10:17:49 -04:00
2008-06-02 17:41:35 -04:00
# if CAAUDIOFILE_PROFILE
// performance
bool mProfiling ;
UInt64 mTicksInConverter ;
UInt64 mTicksInReadInConverter ;
UInt64 mTicksInIO ;
bool mInConverter ;
# endif
# endif // CAAF_USE_EXTAUDIOFILE
} ;
# endif // __CAAudioFile_h__