2015-11-16 19:59:27 +00:00
//( { file_desc: "Read and write AIFF and WAV audio files." kw:[file audio] }
//
// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files.
// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats.
//
//)
2012-10-30 03:52:39 +00:00
# ifndef cmAudioFile_h
# define cmAudioFile_h
# ifdef __cplusplus
extern " C " {
# endif
2015-11-16 19:59:27 +00:00
//(
2012-10-30 03:52:39 +00:00
# ifndef cmAudioFile_MAX_FRAME_READ_CNT
2015-11-16 19:59:27 +00:00
// Maximum number of samples which will be read in one call to fread().
// This value is only significant in that an internal buffer is created on the stack
// whose size must be limited to prevent stack overflows.
2012-10-30 03:52:39 +00:00
# define cmAudioFile_MAX_FRAME_READ_CNT (8192)
# endif
2015-11-16 19:59:27 +00:00
// Audio file result codes.
2012-10-30 03:52:39 +00:00
enum
{
kOkAfRC = 0 ,
kOpenFailAfRC ,
kReadFailAfRC ,
kWriteFailAfRC ,
kSeekFailAfRC ,
kCloseFailAfRC ,
kNotAiffAfRC ,
kInvalidBitWidthAfRC ,
kInvalidFileModeAfRC ,
kInvalidHandleAfRC ,
2014-01-31 07:35:25 +00:00
kInvalidChCountAfRC ,
2012-10-30 03:52:39 +00:00
kUnknownErrAfRC
} ;
2015-11-16 19:59:27 +00:00
// Informational flags used by audioFileInfo
2012-10-30 03:52:39 +00:00
enum
{
2015-11-16 19:59:27 +00:00
kAiffAfFl = 0x01 , // this is an AIFF file
kWavAfFl = 0x02 , // this is a WAV file
kSwapAfFl = 0x04 , // file header bytes must be swapped
kAifcAfFl = 0x08 , // this is an AIFC file
kSwapSamplesAfFl = 0x10 // file sample bytes must be swapped
2012-10-30 03:52:39 +00:00
} ;
2015-11-16 19:59:27 +00:00
// Constants
2012-10-30 03:52:39 +00:00
enum
{
kAudioFileLabelCharCnt = 256 ,
kAfBextDescN = 256 ,
kAfBextOriginN = 32 ,
kAfBextOriginRefN = 32 ,
kAfBextOriginDateN = 10 ,
kAfBextOriginTimeN = 8
} ;
2015-11-16 19:59:27 +00:00
// Aiff marker record
2012-10-30 03:52:39 +00:00
typedef struct
{
unsigned id ;
unsigned frameIdx ;
char label [ kAudioFileLabelCharCnt ] ;
} cmAudioFileMarker_t ;
2015-11-16 19:59:27 +00:00
// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format
// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer
// to the position on the Protools time-line rather than the wall clock time.
2012-10-30 03:52:39 +00:00
typedef struct
{
char desc [ kAfBextDescN + 1 ] ;
char origin [ kAfBextOriginN + 1 ] ;
char originRef [ kAfBextOriginRefN + 1 ] ;
char originDate [ kAfBextOriginDateN + 1 ] ;
char originTime [ kAfBextOriginTimeN + 1 ] ;
unsigned timeRefLow ; // sample count since midnight low word
unsigned timeRefHigh ; // sample count since midnight high word
} cmAudioFileBext_t ;
2015-11-16 19:59:27 +00:00
// Audio file information record used by audioFileNew and audioFileOpen
2012-10-30 03:52:39 +00:00
typedef struct
{
2015-11-16 19:59:27 +00:00
unsigned bits ; // bits per sample
unsigned chCnt ; // count of audio file channels
double srate ; // audio file sample rate in samples per second
unsigned frameCnt ; // total number of sample frames in the audio file
unsigned flags ; // informational flags
unsigned markerCnt ; // count of markers in markerArray
cmAudioFileMarker_t * markerArray ; // array of markers
cmAudioFileBext_t bextRecd ; // only used with Broadcast WAV files
2012-10-30 03:52:39 +00:00
} cmAudioFileInfo_t ;
2015-11-16 19:59:27 +00:00
typedef cmHandle_t cmAudioFileH_t ; // opaque audio file handle
extern cmAudioFileH_t cmNullAudioFileH ; // NULL audio file handle
// Create an audio file handle and optionally use the handle to open an audio file.
//
// fn The audio file name to open or NULL to create the audio file handle without opening the file.
// infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
// rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore.
// rpt A pointer to a cmRpt_t object which error messages from this class will be directed to.
// Returns cmAudioFileH_t A new audio file handle.
//
2012-10-30 03:52:39 +00:00
cmAudioFileH_t cmAudioFileNewOpen ( const cmChar_t * fn , cmAudioFileInfo_t * infoPtr , cmRC_t * rcPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Open an audio file for writing
2012-10-30 03:52:39 +00:00
cmAudioFileH_t cmAudioFileNewCreate ( const cmChar_t * fn , double srate , unsigned bits , unsigned chCnt , cmRC_t * rcPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX().
//
// h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate().
// fn The audio file name to open or NULL to create the audio file handle without opening the file.
// infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
// Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call.
//
// If the audio file handle 'h' refers to an open file then it is automatically closed prior to being
// reopened with the new file.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileOpen ( cmAudioFileH_t h , const cmChar_t * fn , cmAudioFileInfo_t * infoPtr ) ;
2015-11-16 19:59:27 +00:00
// Open an audio file for writing. The type of the audio file, AIF or WAV
// is determined by the file name extension.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileCreate (
2015-11-16 19:59:27 +00:00
cmAudioFileH_t h , // Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
const cmChar_t * fn , // File name of the new file.
double srate , // Sample rate of the new file.
unsigned bits , // Sample word width for the new file in bits (must be 8,16,24 or 32).
unsigned chCnt // Audio channel count for the new file.
2012-10-30 03:52:39 +00:00
) ;
2015-11-16 19:59:27 +00:00
// Close a the file associated with handle 'h' but do not release the handle.
// If the file was opened for writing (cmAudioFileCreate()) then this function will
// write the file header prior to closing the file.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileClose ( cmAudioFileH_t * h ) ;
2015-11-16 19:59:27 +00:00
// Close the file associated with handle 'h' (via an internal call to
// cmAudioFileClose()) and release the handle and any resources
// associated with it. This is the complement to cmAudioFileOpen/Create().
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileDelete ( cmAudioFileH_t * h ) ;
2015-11-16 19:59:27 +00:00
// Return true if the handle is not closed or deleted.
2012-10-30 03:52:39 +00:00
bool cmAudioFileIsValid ( cmAudioFileH_t h ) ;
2015-11-16 19:59:27 +00:00
// Return true if the handle is open.
2012-10-30 03:52:39 +00:00
bool cmAudioFileIsOpen ( cmAudioFileH_t h ) ;
2015-11-16 19:59:27 +00:00
// Return true if the current file position is at the end of the file.
2012-10-30 03:52:39 +00:00
bool cmAudioFileIsEOF ( cmAudioFileH_t h ) ;
2015-11-16 19:59:27 +00:00
// Return the current file position as a frame index.
2012-10-30 03:52:39 +00:00
unsigned cmAudioFileTell ( cmAudioFileH_t h ) ;
2015-11-16 19:59:27 +00:00
// Set the current file position as an offset from the first frame.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileSeek ( cmAudioFileH_t h , unsigned frmIdx ) ;
2015-11-16 19:59:27 +00:00
// Sample Reading Functions.
//
// Fill a user suppled buffer with up to frmCnt samples.
// If less than frmCnt samples are available at the specified audio file location then the unused
// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available
// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from
// the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an
// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
// frmCnt samples.
//
//
// h An audio file handle returned from an earlier call to audioFileNew()
// fn The name of the audio file to read.
// begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See cmAudioFileTell()).
// frmCnt The number of samples allocated in buf.
// chIdx The index of the first channel to read.
// chCnt The count of channels to read.
// buf An array containing chCnt pointers to arrays of frmCnt samples.
// actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL)
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileReadInt ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , int * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileReadFloat ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , float * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileReadDouble ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , double * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileGetInt ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , int * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileGetFloat ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , float * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileGetDouble ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , double * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Sum the returned samples into the output buffer.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileReadSumInt ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , int * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileReadSumFloat ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , float * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileReadSumDouble ( cmAudioFileH_t h , unsigned frmCnt , unsigned chIdx , unsigned chCnt , double * * buf , unsigned * actualFrmCntPtr ) ;
cmRC_t cmAudioFileGetSumInt ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , int * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileGetSumFloat ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , float * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileGetSumDouble ( const char * fn , unsigned begFrmIdx , unsigned frmCnt , unsigned chIdx , unsigned chCnt , double * * buf , unsigned * actualFrmCntPtr , cmAudioFileInfo_t * afInfoPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Sample Writing Functions
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileWriteInt ( cmAudioFileH_t h , unsigned frmCnt , unsigned chCnt , int * * bufPtrPtr ) ;
cmRC_t cmAudioFileWriteFloat ( cmAudioFileH_t h , unsigned frmCnt , unsigned chCnt , float * * bufPtrPtr ) ;
cmRC_t cmAudioFileWriteDouble ( cmAudioFileH_t h , unsigned frmCnt , unsigned chCnt , double * * bufPtrPtr ) ;
cmRC_t cmAudioFileWriteFileInt ( const char * fn , double srate , unsigned bit , unsigned frmCnt , unsigned chCnt , int * * bufPtrPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileWriteFileFloat ( const char * fn , double srate , unsigned bit , unsigned frmCnt , unsigned chCnt , float * * bufPtrPtr , cmRpt_t * rpt ) ;
cmRC_t cmAudioFileWriteFileDouble ( const char * fn , double srate , unsigned bit , unsigned frmCnt , unsigned chCnt , double * * bufPtrPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate
// type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL.
2012-10-30 03:52:39 +00:00
# if CM_FLOAT_SMP == 1
# define cmAudioFileReadSample cmAudioFileReadFloat
# define cmAudioFileReadSumSample cmAudioFileReadSumFloat
# define cmAudioFileGetSample cmAudioFileGetFloat
# define cmAudioFileGetSumSample cmAudioFileGetSumFloat
# define cmAudioFileWriteSample cmAudioFileWriteFloat
# define cmAudioFileWriteFileSample cmAudioFileWriteFileFloat
# else
# define cmAudioFileReadSample cmAudioFileReadDouble
# define cmAudioFileReadSumSample cmAudioFileReadSumDouble
# define cmAudioFileGetSample cmAudioFileGetDouble
# define cmAudioFileGetSumSample cmAudioFileGetSumDouble
# define cmAudioFileWriteSample cmAudioFileWriteDouble
# define cmAudioFileWriteFileSample cmAudioFileWriteFileDouble
# endif
# if CM_FLOAT_REAL == 1
# define cmAudioFileReadReal cmAudioFileReadFloat
# define cmAudioFileReadSumReal cmAudioFileReadSumFloat
# define cmAudioFileGetReal cmAudioFileGetFloat
# define cmAudioFileGetSumReal cmAudioFileGetSumFloat
# define cmAudioFileWriteReal cmAudioFileWriteFloat
# define cmAudioFileWriteFileReal cmAudioFileWriteFileFloat
# else
# define cmAudioFileReadReal cmAudioFileReadDouble
# define cmAudioFileReadSumReal cmAudioFileReadSumDouble
# define cmAudioFileGetReal cmAudioFileGetDouble
# define cmAudioFileGetSumReal cmAudioFileGetSumDouble
# define cmAudioFileWriteReal cmAudioFileWriteDouble
# define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble
# endif
2015-11-16 19:59:27 +00:00
// Scan an entire audio file and return the minimum, maximum and mean sample value.
// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileMinMaxMean ( cmAudioFileH_t h , unsigned chIdx , cmSample_t * minPtr , cmSample_t * maxPtr , cmSample_t * meanPtr ) ;
cmRC_t cmAudioFileMinMaxMeanFn ( const cmChar_t * fn , unsigned chIdx , cmSample_t * minPtr , cmSample_t * maxPtr , cmSample_t * meanPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Return the file name associated with a audio file handle.
2012-10-30 03:52:39 +00:00
const cmChar_t * cmAudioFileName ( cmAudioFileH_t h ) ;
2015-11-16 19:59:27 +00:00
// Given an error code return the associated message.
2012-10-30 03:52:39 +00:00
const char * cmAudioFileErrorMsg ( unsigned rc ) ;
2015-11-16 19:59:27 +00:00
// Return the cmAudioFileInfo_t record associated with a file.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileGetInfo ( const cmChar_t * fn , cmAudioFileInfo_t * infoPtr , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Print the cmAudioFileInfo_t to a file.
2012-10-30 03:52:39 +00:00
void cmAudioFilePrintInfo ( const cmAudioFileInfo_t * infoPtr , cmRpt_t * ) ;
2015-11-16 19:59:27 +00:00
// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileReport ( cmAudioFileH_t h , cmRpt_t * rpt , unsigned frmIdx , unsigned frmCnt ) ;
2015-11-16 19:59:27 +00:00
// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
2012-10-30 03:52:39 +00:00
cmRC_t cmAudioFileReportFn ( const cmChar_t * fn , unsigned frmIdx , unsigned frmCnt , cmRpt_t * rpt ) ;
2015-11-16 19:59:27 +00:00
// Change the sample rate value in the header. Note that this function does not resample the audio
// signal it simply changes the value of the sample rate in the header.
2015-04-10 18:58:10 +00:00
cmRC_t cmAudioFileSetSrate ( const cmChar_t * audioFn , unsigned srate ) ;
// Generate a sine tone and write it to a file.
cmRC_t cmAudioFileSine ( cmCtx_t * ctx , const cmChar_t * fn , double srate , unsigned bits , double hz , double gain , double secs ) ;
2015-11-16 19:59:27 +00:00
// Testing and example routine for functions in cmAudioFile.h.
// Also see cmProcTest.c cmAudioFileReadWriteTest()
2015-04-10 18:58:10 +00:00
void cmAudioFileTest ( cmCtx_t * ctx , int argc , const char * argv [ ] ) ;
2015-11-16 19:59:27 +00:00
//)
2015-04-10 18:58:10 +00:00
2012-10-30 03:52:39 +00:00
# ifdef __cplusplus
}
# endif
# endif