www.pudn.com > hmmPlatform.rar > WaveFile.h


////////////////////////////////////////////////////////////////////////// 
// class CWaveFile 
// 
// 功能:	实现wav文件的操作 
// 创建人:	陈文凯 (chwkai@gmail.com) 
// 创建日期:2005年5月19日 
// 修改人: 
// 修改日期: 
// 版本 
 
#ifndef _WAVEFILE_H_ 
#define _WAVEFILE_H_ 
////////////////////////////////////////////////////////////////////////// 
//	RIFF WAV文件结构(未压缩) 
//	__________________________ 
//	| RIFF WAVE Chunk		   | 
//	|   groupID  = 'RIFF'      | 
//	|   riffType = 'WAVE'      | 
//	|    __________________    | 
//	|   | Format Chunk     |   | 
//	|   |	ckID = 'fmt '  |   | 
//	|   |__________________|   | 
//	|    __________________    | 
//	|   | Sound Data Chunk |   | 
//	|   |	ckID = 'data'  |   | 
//	|   |__________________|   | 
//	|__________________________| 
 
////////////////////////////////////////////////////////////////////////// 
//	定义RIFF Header数据结构 
// 
//	RIFF Header 
//	A RIFF file has an 8-byte RIFF header, identifying the file,  
//	and giving the residual length after the header (i.e. file_length - 8): 
//	struct {      
//	 	char  id[4];  	// identifier string = "RIFF" 
//		DWORD len;    	// remaining length after this header 
//	} riff_hdr; 
// 
//	The riff_hdr is immediately followed by a 4-byte data type identifier.   
//	For .WAV files this is "WAVE" as follows: 
//	char wave_id[4];	// WAVE file identifier = "WAVE" 
#define DEFAULT_RIFF_TYPE "WAVE" 
#define DEFAULT_RIFF_ID "RIFF" 
 
typedef struct _riffHeader 
{ 
	char groupId[4];			// "RIFF" 
	DWORD chunkSize;			// remaining length of this header, not including length of groupdId and len 
	char riffTypeId[4];			// "WAVE" 
 
} RiffHeader, *LPRiffHeader; 
 
////////////////////////////////////////////////////////////////////////// 
// 定义Format Chunk数据结构, 仅对wFormatTag为WAVE_FORMAT_PCM情况适用 
// 
//	The WAVE form is defined as follows.  
//	Programs must expect(and ignore) any unknown chunks encountered, as with all RIFF forms.  
//	However,  must always occur before ,  
//	and both of these chunks are mandatory in a WAVE file. 
//	 -> 
//	RIFF( 'WAVE' 
//		      		// Format 
//		[]  		// Fact chunk 
//		[]  		// Cue points 
//		[] 		// Playlist 
//		[] 	// Associated data list 
//		   ) 		// Wave data 
#include  
#define DEFAULT_FMT_ID "fmt" 
 
// 定义win32中的WAVE_FORMAT_PCM 
#ifndef WAVE_FORMAT_PCM 
#define WAVE_FORMAT_PCM 0x0001 
#endif 
 
// 定义win32中的 WAVEFORMATEX 
#ifndef _WAVEFORMATEX_ 
#define _WAVEFORMATEX_ 
 
/* 
*  extended waveform format structure used for all non-PCM formats. this 
*  structure is common to all non-PCM formats. 
*/ 
typedef struct tWAVEFORMATEX 
{ 
	WORD        wFormatTag;         /* format type */ 
	WORD        nChannels;          /* number of channels (i.e. mono, stereo...) */ 
	DWORD       nSamplesPerSec;     /* sample rate */ 
	DWORD       nAvgBytesPerSec;    /* for buffer estimation */ 
	WORD        nBlockAlign;        /* block size of data */ 
	WORD        wBitsPerSample;     /* number of bits per sample of mono data */ 
	WORD        cbSize;             /* the count in bytes of the size of */ 
	/* extra information (after cbSize) */ 
} WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX; 
 
#endif /* _WAVEFORMATEX_ */ 
 
////////////////////////////////////////////////////////////////////////// 
// 定义format chunk 信息 
typedef struct _formatchunk 
{ 
	char chunkId[4];			// "fmt" 
	DWORD chunkSize;			// numbers of bits of this chunk, not including chunkId and chunkSize 
 
	WORD wFormatTag;			// Format category, 对于未压缩的WAV,取值为WAVE_FORMAT_PCM 0x0001 
	WORD wChannels;				// Number of channels 
	DWORD dwSamplesPerSec;		// Sampling rate 
	DWORD dwAvgBytesPerSec;		// For buffer estimation 
	WORD wBlockAlign;			// Data block size, or say the size of the sample frame, equals 
	// wBlockAlign = (wBitsPerSample % 8) * wChannels 
	WORD wBitsPerSample;		// Sample size, wFormatTag is PCM 
	WORD wReserved;				// Reserved Field; 
 
} FormatChunk, *LPFormatChunk; 
 
////////////////////////////////////////////////////////////////////////// 
//	定义Data Chunk数据结构 
// 
#define DEFAULT_DATA_ID "data" 
typedef struct _datachunkheader 
{ 
	char chunkId[4]; 
	DWORD chunkSize;			// numbers of bits in the chunk, not including chuckId and chunkSize 
 
} DataChunkHeader, *LPDataChunkHeader; 
 
////////////////////////////////////////////////////////////////////////// 
// 定义Fact Chunk数据结构 
#define DEFAULT_FACT_ID "fact" 
 
typedef struct _factchunk 
{ 
	char chunkId[4]; 
	DWORD chunkSize; 
 
	DWORD dwFileSize;			// numbers of samples before compress 
} FactChunk, *LPFactChunk; 
 
////////////////////////////////////////////////////////////////////////// 
//定义音频文件类 
//负责WAV文件的打开关闭、chunk数据的获取 
// 
//Author:	陈文凯 chwkai@163.com 
//Create:2005年5月5日 
 
class CWaveFile 
{ 
	//构造和析构函数 
public: 
	CWaveFile(LPCTSTR lpszFileName, UINT nOpenFlags); 
	CWaveFile(); 
	~CWaveFile(void); 
 
public: 
	////////////////////////////////////////////////////////////////////////// 
	// 返回文件是否读取至末尾 
	BOOL IsEOF() const 
	{ 
		return  
			(this->m_wavFile.GetLength() == this->m_wavFile.GetPosition()); 
	} 
 
	////////////////////////////////////////////////////////////////////////// 
	// 打开wave文件,并读入header信息 
	BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);	 
 
	////////////////////////////////////////////////////////////////////////// 
	// 关闭wave文件 
	void Close(); 
 
	////////////////////////////////////////////////////////////////////////// 
	// 读取裸音频数据 
	UINT ReadBytes(void* pData, UINT nCount);			 
 
	////////////////////////////////////////////////////////////////////////// 
	// 写入裸音频数据 
	void WriteBytes(void* pData, UINT nCount); 
 
	////////////////////////////////////////////////////////////////////////// 
	// 预备要写入的header信息 
	void PrepareWriteHeader(WAVEFORMATEX& fmt); 
 
	////////////////////////////////////////////////////////////////////////// 
	// 写入header信息 
	void WriteHeader(); 
 
	////////////////////////////////////////////////////////////////////////// 
	// 文件指针返回至裸音频数据开始位置 
	void Reset(); 
 
	// 格式信息访问操作 
	////////////////////////////////////////////////////////////////////////// 
	// 返回wave文件中所包含的样本数 
	inline DWORD GetSampleFramesCount() const 
	{ 
		return (this->m_dwDataChunkSize / this->m_format.wBlockAlign); 
	} 
 
	////////////////////////////////////////////////////////////////////////// 
	// 返回wave文件的formatex信息 
	WAVEFORMATEX GetWaveFormat() const;		 
 
	////////////////////////////////////////////////////////////////////////// 
	// 返回wave文件中所包含的裸音频数据的字节数 
	inline DWORD GetDataChunkSize() const 
	{ 
		return this->m_dwDataChunkSize; 
	} 
 
private: 
	////////////////////////////////////////////////////////////////////////// 
	// 读取wave文件的Format信息,被Open调用来设置m_format 
	void ReadHeader(); 
 
private: 
	CFile m_wavFile;					// wave文件 
 
	FormatChunk m_format;				// wav文件格式 
	DWORD m_dwDataChunkSize;			// 数据部分的长度 
	ULONGLONG m_nDataStartFrom;			// 裸音频数据开始的位置 
	DWORD m_nBytesWritten;				// 已写入字节数 
}; 
 
 
#endif /*_WAVEFILE_H_*/