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

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