WaveFile.h
上传用户:goak128
上传日期:2013-07-17
资源大小:155k
文件大小:7k
源码类别:

控制台编程

开发平台:

C/C++

  1. //////////////////////////////////////////////////////////////////////////
  2. // class CWaveFile
  3. //
  4. // 功能: 实现wav文件的操作
  5. // 创建人: 陈文凯 (chwkai@gmail.com)
  6. // 创建日期:2005年5月19日
  7. // 修改人:
  8. // 修改日期:
  9. // 版本
  10. #ifndef _WAVEFILE_H_
  11. #define _WAVEFILE_H_
  12. //////////////////////////////////////////////////////////////////////////
  13. // RIFF WAV文件结构(未压缩)
  14. // __________________________
  15. // | RIFF WAVE Chunk    |
  16. // |   groupID  = 'RIFF'      |
  17. // |   riffType = 'WAVE'      |
  18. // |    __________________    |
  19. // |   | Format Chunk     |   |
  20. // |   | ckID = 'fmt '  |   |
  21. // |   |__________________|   |
  22. // |    __________________    |
  23. // |   | Sound Data Chunk |   |
  24. // |   | ckID = 'data'  |   |
  25. // |   |__________________|   |
  26. // |__________________________|
  27. //////////////////////////////////////////////////////////////////////////
  28. // 定义RIFF Header数据结构
  29. //
  30. // RIFF Header
  31. // A RIFF file has an 8-byte RIFF header, identifying the file, 
  32. // and giving the residual length after the header (i.e. file_length - 8):
  33. // struct {     
  34. //   char  id[4];   // identifier string = "RIFF"
  35. // DWORD len;     // remaining length after this header
  36. // } riff_hdr;
  37. //
  38. // The riff_hdr is immediately followed by a 4-byte data type identifier.  
  39. // For .WAV files this is "WAVE" as follows:
  40. // char wave_id[4]; // WAVE file identifier = "WAVE"
  41. #define DEFAULT_RIFF_TYPE "WAVE"
  42. #define DEFAULT_RIFF_ID "RIFF"
  43. typedef struct _riffHeader
  44. {
  45. char groupId[4]; // "RIFF"
  46. DWORD chunkSize; // remaining length of this header, not including length of groupdId and len
  47. char riffTypeId[4]; // "WAVE"
  48. } RiffHeader, *LPRiffHeader;
  49. //////////////////////////////////////////////////////////////////////////
  50. // 定义Format Chunk数据结构, 仅对wFormatTag为WAVE_FORMAT_PCM情况适用
  51. //
  52. // The WAVE form is defined as follows. 
  53. // Programs must expect(and ignore) any unknown chunks encountered, as with all RIFF forms. 
  54. // However, <fmt-ck> must always occur before <wave-data>, 
  55. // and both of these chunks are mandatory in a WAVE file.
  56. // <WAVE-form> ->
  57. // RIFF( 'WAVE'
  58. //  <fmt-ck>      // Format
  59. // [<fact-ck>]   // Fact chunk
  60. // [<cue-ck>]   // Cue points
  61. // [<playlist-ck>]  // Playlist
  62. // [<assoc-data-list>]  // Associated data list
  63. // <wave-data>   )  // Wave data
  64. #include <MMSystem.h>
  65. #define DEFAULT_FMT_ID "fmt"
  66. // 定义win32中的WAVE_FORMAT_PCM
  67. #ifndef WAVE_FORMAT_PCM
  68. #define WAVE_FORMAT_PCM 0x0001
  69. #endif
  70. // 定义win32中的 WAVEFORMATEX
  71. #ifndef _WAVEFORMATEX_
  72. #define _WAVEFORMATEX_
  73. /*
  74. *  extended waveform format structure used for all non-PCM formats. this
  75. *  structure is common to all non-PCM formats.
  76. */
  77. typedef struct tWAVEFORMATEX
  78. {
  79. WORD        wFormatTag;         /* format type */
  80. WORD        nChannels;          /* number of channels (i.e. mono, stereo...) */
  81. DWORD       nSamplesPerSec;     /* sample rate */
  82. DWORD       nAvgBytesPerSec;    /* for buffer estimation */
  83. WORD        nBlockAlign;        /* block size of data */
  84. WORD        wBitsPerSample;     /* number of bits per sample of mono data */
  85. WORD        cbSize;             /* the count in bytes of the size of */
  86. /* extra information (after cbSize) */
  87. } WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX;
  88. #endif /* _WAVEFORMATEX_ */
  89. //////////////////////////////////////////////////////////////////////////
  90. // 定义format chunk 信息
  91. typedef struct _formatchunk
  92. {
  93. char chunkId[4]; // "fmt"
  94. DWORD chunkSize; // numbers of bits of this chunk, not including chunkId and chunkSize
  95. WORD wFormatTag; // Format category, 对于未压缩的WAV,取值为WAVE_FORMAT_PCM 0x0001
  96. WORD wChannels; // Number of channels
  97. DWORD dwSamplesPerSec; // Sampling rate
  98. DWORD dwAvgBytesPerSec; // For buffer estimation
  99. WORD wBlockAlign; // Data block size, or say the size of the sample frame, equals
  100. // wBlockAlign = (wBitsPerSample % 8) * wChannels
  101. WORD wBitsPerSample; // Sample size, wFormatTag is PCM
  102. WORD wReserved; // Reserved Field;
  103. } FormatChunk, *LPFormatChunk;
  104. //////////////////////////////////////////////////////////////////////////
  105. // 定义Data Chunk数据结构
  106. //
  107. #define DEFAULT_DATA_ID "data"
  108. typedef struct _datachunkheader
  109. {
  110. char chunkId[4];
  111. DWORD chunkSize; // numbers of bits in the chunk, not including chuckId and chunkSize
  112. } DataChunkHeader, *LPDataChunkHeader;
  113. //////////////////////////////////////////////////////////////////////////
  114. // 定义Fact Chunk数据结构
  115. #define DEFAULT_FACT_ID "fact"
  116. typedef struct _factchunk
  117. {
  118. char chunkId[4];
  119. DWORD chunkSize;
  120. DWORD dwFileSize; // numbers of samples before compress
  121. } FactChunk, *LPFactChunk;
  122. //////////////////////////////////////////////////////////////////////////
  123. //定义音频文件类
  124. //负责WAV文件的打开关闭、chunk数据的获取
  125. //
  126. //Author: 陈文凯 chwkai@163.com
  127. //Create:2005年5月5日
  128. class CWaveFile
  129. {
  130. //构造和析构函数
  131. public:
  132. CWaveFile(LPCTSTR lpszFileName, UINT nOpenFlags);
  133. CWaveFile();
  134. ~CWaveFile(void);
  135. public:
  136. //////////////////////////////////////////////////////////////////////////
  137. // 返回文件是否读取至末尾
  138. BOOL IsEOF() const
  139. {
  140. return 
  141. (this->m_wavFile.GetLength() == this->m_wavFile.GetPosition());
  142. }
  143. //////////////////////////////////////////////////////////////////////////
  144. // 打开wave文件,并读入header信息
  145. BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);
  146. //////////////////////////////////////////////////////////////////////////
  147. // 关闭wave文件
  148. void Close();
  149. //////////////////////////////////////////////////////////////////////////
  150. // 读取裸音频数据
  151. UINT ReadBytes(void* pData, UINT nCount);
  152. //////////////////////////////////////////////////////////////////////////
  153. // 写入裸音频数据
  154. void WriteBytes(void* pData, UINT nCount);
  155. //////////////////////////////////////////////////////////////////////////
  156. // 预备要写入的header信息
  157. void PrepareWriteHeader(WAVEFORMATEX& fmt);
  158. //////////////////////////////////////////////////////////////////////////
  159. // 写入header信息
  160. void WriteHeader();
  161. //////////////////////////////////////////////////////////////////////////
  162. // 文件指针返回至裸音频数据开始位置
  163. void Reset();
  164. // 格式信息访问操作
  165. //////////////////////////////////////////////////////////////////////////
  166. // 返回wave文件中所包含的样本数
  167. inline DWORD GetSampleFramesCount() const
  168. {
  169. return (this->m_dwDataChunkSize / this->m_format.wBlockAlign);
  170. }
  171. //////////////////////////////////////////////////////////////////////////
  172. // 返回wave文件的formatex信息
  173. WAVEFORMATEX GetWaveFormat() const;
  174. //////////////////////////////////////////////////////////////////////////
  175. // 返回wave文件中所包含的裸音频数据的字节数
  176. inline DWORD GetDataChunkSize() const
  177. {
  178. return this->m_dwDataChunkSize;
  179. }
  180. private:
  181. //////////////////////////////////////////////////////////////////////////
  182. // 读取wave文件的Format信息,被Open调用来设置m_format
  183. void ReadHeader();
  184. private:
  185. CFile m_wavFile; // wave文件
  186. FormatChunk m_format; // wav文件格式
  187. DWORD m_dwDataChunkSize; // 数据部分的长度
  188. ULONGLONG m_nDataStartFrom; // 裸音频数据开始的位置
  189. DWORD m_nBytesWritten; // 已写入字节数
  190. };
  191. #endif /*_WAVEFILE_H_*/