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_*/