libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmAudioFile.h 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /// \file cmAudioFile.h
  2. /// \brief Audio file reader/writer class.
  3. ///
  4. /// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files.
  5. /// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats.
  6. ///
  7. /// Testing and example usage for this API can be found in cmProcTest.c cmAudioReadWriteTest().
  8. ///
  9. /// Usage example:
  10. /// \snippet cmAudioFile.c cmAudioFileExample
  11. #ifndef cmAudioFile_h
  12. #define cmAudioFile_h
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. #ifndef cmAudioFile_MAX_FRAME_READ_CNT
  17. /// Maximum number of samples which will be read in one call to fread().
  18. /// This value is only significant in that an internal buffer is created on the stack
  19. /// whose size must be limited to prevent stack overflows.
  20. #define cmAudioFile_MAX_FRAME_READ_CNT (8192)
  21. #endif
  22. /// Audio file result codes.
  23. enum
  24. {
  25. kOkAfRC = 0,
  26. kOpenFailAfRC,
  27. kReadFailAfRC,
  28. kWriteFailAfRC,
  29. kSeekFailAfRC,
  30. kCloseFailAfRC,
  31. kNotAiffAfRC,
  32. kInvalidBitWidthAfRC,
  33. kInvalidFileModeAfRC,
  34. kInvalidHandleAfRC,
  35. kInvalidChCountAfRC,
  36. kUnknownErrAfRC
  37. };
  38. /// Informational flags used by audioFileInfo
  39. enum
  40. {
  41. kAiffAfFl = 0x01, ///< this is an AIFF file
  42. kWavAfFl = 0x02, ///< this is a WAV file
  43. kSwapAfFl = 0x04, ///< file header bytes must be swapped
  44. kAifcAfFl = 0x08, ///< this is an AIFC file
  45. kSwapSamplesAfFl = 0x10 ///< file sample bytes must be swapped
  46. };
  47. /// Constants
  48. enum
  49. {
  50. kAudioFileLabelCharCnt = 256,
  51. kAfBextDescN = 256,
  52. kAfBextOriginN = 32,
  53. kAfBextOriginRefN = 32,
  54. kAfBextOriginDateN = 10,
  55. kAfBextOriginTimeN = 8
  56. };
  57. /// Aiff marker record
  58. typedef struct
  59. {
  60. unsigned id;
  61. unsigned frameIdx;
  62. char label[kAudioFileLabelCharCnt];
  63. } cmAudioFileMarker_t;
  64. /// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format
  65. /// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer
  66. /// to the position on the Protools time-line rather than the wall clock time.
  67. typedef struct
  68. {
  69. char desc[ kAfBextDescN + 1 ];
  70. char origin[ kAfBextOriginN + 1 ];
  71. char originRef[ kAfBextOriginRefN + 1 ];
  72. char originDate[kAfBextOriginDateN + 1 ];
  73. char originTime[kAfBextOriginTimeN + 1 ];
  74. unsigned timeRefLow; // sample count since midnight low word
  75. unsigned timeRefHigh; // sample count since midnight high word
  76. } cmAudioFileBext_t;
  77. /// Audio file information record used by audioFileNew and audioFileOpen
  78. typedef struct
  79. {
  80. unsigned bits; ///< bits per sample
  81. unsigned chCnt; ///< count of audio file channels
  82. double srate; ///< audio file sample rate in samples per second
  83. unsigned frameCnt; ///< total number of sample frames in the audio file
  84. unsigned flags; ///< informational flags
  85. unsigned markerCnt; ///< count of markers in markerArray
  86. cmAudioFileMarker_t* markerArray; ///< array of markers
  87. cmAudioFileBext_t bextRecd; ///< only used with Broadcast WAV files
  88. } cmAudioFileInfo_t;
  89. typedef cmHandle_t cmAudioFileH_t; ///< opaque audio file handle
  90. extern cmAudioFileH_t cmNullAudioFileH; ///< NULL audio file handle
  91. /// Create an audio file handle and optionally use the handle to open an audio file.
  92. ///
  93. /// \param fn The audio file name to open or NULL to create the audio file handle without opening the file.
  94. /// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
  95. /// \param rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore.
  96. /// \param rpt A pointer to a cmRpt_t object which error messages from this class will be directed to.
  97. /// \retval cmAudioFileH_t A new audio file handle.
  98. ///
  99. cmAudioFileH_t cmAudioFileNewOpen( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRC_t* rcPtr, cmRpt_t* rpt );
  100. /// Open an audio file for writing
  101. cmAudioFileH_t cmAudioFileNewCreate( const cmChar_t* fn, double srate, unsigned bits, unsigned chCnt, cmRC_t* rcPtr, cmRpt_t* rpt );
  102. /// Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX().
  103. ///
  104. /// \param h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate().
  105. /// \param fn The audio file name to open or NULL to create the audio file handle without opening the file.
  106. /// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
  107. /// \retval Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call.
  108. ///
  109. /// If the audio file handle 'h' refers to an open file then it is automatically closed prior to being
  110. /// reopened with the new file.
  111. cmRC_t cmAudioFileOpen( cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr );
  112. /// Open an audio file for writing.
  113. cmRC_t cmAudioFileCreate(
  114. cmAudioFileH_t h, ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
  115. const cmChar_t* fn, ///< File name of the new file.
  116. double srate, ///< Sample rate of the new file.
  117. unsigned bits, ///< Sample word width for the new file in bits (must be 8,16,24 or 32).
  118. unsigned chCnt ///< Audio channel count for the new file.
  119. );
  120. /// Close a the file associated with handle 'h' but do not release the handle.
  121. /// If the file was opened for writing (cmAudioFileCreate()) then this function will
  122. /// write the file header prior to closing the file.
  123. cmRC_t cmAudioFileClose( cmAudioFileH_t* h );
  124. /// Close the file associated with handle 'h' (via an internal call to
  125. /// cmAudioFileClose()) and release the handle and any resources
  126. /// associated with it. This is the complement to cmAudioFileOpen/Create().
  127. cmRC_t cmAudioFileDelete( cmAudioFileH_t* h );
  128. /// Return true if the handle is not closed or deleted.
  129. bool cmAudioFileIsValid( cmAudioFileH_t h );
  130. /// Return true if the handle is open.
  131. bool cmAudioFileIsOpen( cmAudioFileH_t h );
  132. /// Return true if the current file position is at the end of the file.
  133. bool cmAudioFileIsEOF( cmAudioFileH_t h );
  134. /// Return the current file position as a frame index.
  135. unsigned cmAudioFileTell( cmAudioFileH_t h );
  136. /// Set the current file position as an offset from the first frame.
  137. cmRC_t cmAudioFileSeek( cmAudioFileH_t h, unsigned frmIdx );
  138. /// \name Sample Reading Functions.
  139. ///@{
  140. /// Fill a user suppled buffer with up to frmCnt samples.
  141. /// If less than frmCnt samples are available at the specified audio file location then the unused
  142. /// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available
  143. /// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from
  144. /// the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an
  145. /// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
  146. /// frmCnt samples.
  147. ///
  148. /// \param h An audio file handle returned from an earlier call to audioFileNew()
  149. /// \param fn The name of the audio file to read.
  150. /// \param 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()).
  151. /// \param frmCnt The number of samples allocated in buf.
  152. /// \param chIdx The index of the first channel to read.
  153. /// \param chCnt The count of channels to read.
  154. /// \param buf An array containing chCnt pointers to arrays of frmCnt samples.
  155. /// \param actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL)
  156. cmRC_t cmAudioFileReadInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
  157. cmRC_t cmAudioFileReadFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
  158. cmRC_t cmAudioFileReadDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr );
  159. cmRC_t cmAudioFileGetInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  160. cmRC_t cmAudioFileGetFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  161. cmRC_t cmAudioFileGetDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  162. ///@}
  163. /// \name Sum the returned samples into the output buffer.
  164. ///@{
  165. cmRC_t cmAudioFileReadSumInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
  166. cmRC_t cmAudioFileReadSumFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
  167. cmRC_t cmAudioFileReadSumDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr );
  168. cmRC_t cmAudioFileGetSumInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  169. cmRC_t cmAudioFileGetSumFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  170. cmRC_t cmAudioFileGetSumDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
  171. ///@}
  172. ///@}
  173. /// \name Sample Writing Functions
  174. ///@{
  175. cmRC_t cmAudioFileWriteInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr );
  176. cmRC_t cmAudioFileWriteFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr );
  177. cmRC_t cmAudioFileWriteDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr );
  178. cmRC_t cmAudioFileWriteFileInt( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr, cmRpt_t* rpt );
  179. cmRC_t cmAudioFileWriteFileFloat( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr, cmRpt_t* rpt );
  180. cmRC_t cmAudioFileWriteFileDouble( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr, cmRpt_t* rpt );
  181. ///@}
  182. /// \name cmSample_t and cmReal_t Alias Macros
  183. ///@{
  184. /// Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate
  185. /// type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL.
  186. #if CM_FLOAT_SMP == 1
  187. #define cmAudioFileReadSample cmAudioFileReadFloat
  188. #define cmAudioFileReadSumSample cmAudioFileReadSumFloat
  189. #define cmAudioFileGetSample cmAudioFileGetFloat
  190. #define cmAudioFileGetSumSample cmAudioFileGetSumFloat
  191. #define cmAudioFileWriteSample cmAudioFileWriteFloat
  192. #define cmAudioFileWriteFileSample cmAudioFileWriteFileFloat
  193. #else
  194. #define cmAudioFileReadSample cmAudioFileReadDouble
  195. #define cmAudioFileReadSumSample cmAudioFileReadSumDouble
  196. #define cmAudioFileGetSample cmAudioFileGetDouble
  197. #define cmAudioFileGetSumSample cmAudioFileGetSumDouble
  198. #define cmAudioFileWriteSample cmAudioFileWriteDouble
  199. #define cmAudioFileWriteFileSample cmAudioFileWriteFileDouble
  200. #endif
  201. #if CM_FLOAT_REAL == 1
  202. #define cmAudioFileReadReal cmAudioFileReadFloat
  203. #define cmAudioFileReadSumReal cmAudioFileReadSumFloat
  204. #define cmAudioFileGetReal cmAudioFileGetFloat
  205. #define cmAudioFileGetSumReal cmAudioFileGetSumFloat
  206. #define cmAudioFileWriteReal cmAudioFileWriteFloat
  207. #define cmAudioFileWriteFileReal cmAudioFileWriteFileFloat
  208. #else
  209. #define cmAudioFileReadReal cmAudioFileReadDouble
  210. #define cmAudioFileReadSumReal cmAudioFileReadSumDouble
  211. #define cmAudioFileGetReal cmAudioFileGetDouble
  212. #define cmAudioFileGetSumReal cmAudioFileGetSumDouble
  213. #define cmAudioFileWriteReal cmAudioFileWriteDouble
  214. #define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble
  215. #endif
  216. ///@}
  217. /// \name Minimum, Maximum, Mean
  218. ///@{
  219. /// Scan an entire audio file and return the minimum, maximum and mean sample value.
  220. /// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively
  221. cmRC_t cmAudioFileMinMaxMean( cmAudioFileH_t h, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr );
  222. cmRC_t cmAudioFileMinMaxMeanFn( const cmChar_t* fn, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr, cmRpt_t* rpt );
  223. ///@}
  224. /// Return the file name associated with a audio file handle.
  225. const cmChar_t* cmAudioFileName( cmAudioFileH_t h );
  226. /// Given an error code return the associated message.
  227. const char* cmAudioFileErrorMsg( unsigned rc );
  228. /// \name Get information about an audio file
  229. ///@{
  230. /// Return the cmAudioFileInfo_t record associated with a file.
  231. cmRC_t cmAudioFileGetInfo( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRpt_t* rpt );
  232. /// Print the cmAudioFileInfo_t to a file.
  233. void cmAudioFilePrintInfo( const cmAudioFileInfo_t* infoPtr, cmRpt_t* );
  234. /// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
  235. cmRC_t cmAudioFileReport( cmAudioFileH_t h, cmRpt_t* rpt, unsigned frmIdx, unsigned frmCnt );
  236. /// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
  237. cmRC_t cmAudioFileReportFn( const cmChar_t* fn, unsigned frmIdx, unsigned frmCnt, cmRpt_t* rpt );
  238. ///@}
  239. /// Testing and example routine for functions in cmAudioFile.h.
  240. /// Also see cmProcTest.c cmAudioFileReadWriteTest()
  241. void cmAudioFileTest( const cmChar_t* audioFn, const cmChar_t* outFn, cmRpt_t* rpt );
  242. #ifdef __cplusplus
  243. }
  244. #endif
  245. #endif