www.pudn.com > audioTest.rar > Wave.cpp
// Wave.cpp: implementation of the CWave class.
//the base class for loading or saving wave files.
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Wave.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL(CWave,CObject,1)
///////////////////////////////////////////////////////////////////////
CWave::CWave()
{
//置空
ZeroMemory((void*)&m_pcmWaveFormat,sizeof(m_pcmWaveFormat));
m_pcmWaveFormat.wFormatTag = 1;//PCM格式
}
CWave::CWave(const CWave ©)
{
m_pcmWaveFormat=copy.GetFormat();
m_buffer.SetNumSamples(copy.GetNumSamples(),copy.GetFormat().nBlockAlign);//nBlockAlign为指定
//数据格式最小单元
m_buffer.CopyBuffer(copy.GetBuffer(),copy.GetNumSamples(),copy.GetFormat().nBlockAlign);
}
///////////////////////////////
//重载=运算符
CWave &CWave::operator =(const CWave &wave)
{
if(&wave !=this)
{
m_pcmWaveFormat=wave.GetFormat();
m_buffer.SetNumSamples(wave.GetNumSamples(),wave.GetFormat().nBlockAlign);
m_buffer.CopyBuffer(wave.GetBuffer(),wave.GetNumSamples(),wave.GetFormat().nBlockAlign);
}
return *this;
}
///////////////////////////////////
CWave::~CWave()
{
}
//////////////////////////////////////
void CWave::BuildFormat(WORD nChannels,DWORD nFrequency,WORD nBits)
{
m_pcmWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
m_pcmWaveFormat.nChannels = nChannels;//通道数
m_pcmWaveFormat.nSamplesPerSec = nFrequency;//采样频率
m_pcmWaveFormat.nAvgBytesPerSec=nFrequency*nChannels*nBits/8;//指定数据传输率
m_pcmWaveFormat.nBlockAlign = nChannels*nBits/8;//指定数据格式的最小单元
m_pcmWaveFormat.wBitsPerSample=nBits;//指定样本大小
m_buffer.SetNumSamples(0L,m_pcmWaveFormat.nBlockAlign);
}
//////////////////////////////////////////
inline WAVEFORMATEX CWave::GetFormat() const
{
return m_pcmWaveFormat;
}
///////////////////////////////////////////
void CWave::Serialize(CArchive &archive)
{
CFile *f=archive.GetFile();
if(archive.IsLoading())
Load(f);
else
Save(f);
}
///////////////////////////////////////////
void CWave::Load(const CString &strFile)
{
CFile f(strFile,CFile::modeRead);
Load(&f);
f.Close();
}
///////////////////////////////////////////
void CWave::Load(CFile *f)
{
char szTmp[10];
WAVEFORMATEX pcmWaveFormat;
ZeroMemory(szTmp, 10 * sizeof(char));
f->Read(szTmp, 4 * sizeof(char)) ;
if (strncmp(szTmp, _T("RIFF"), 4) != 0)
::AfxThrowFileException(CFileException::invalidFile, -1, f->GetFileName());
DWORD dwFileSize/*=m_buffer.GetNumSamples() * m_pcmWaveFormat.nBlockAlign + 36*/;
f->Read(&dwFileSize,sizeof(dwFileSize));
ZeroMemory(szTmp,10 *sizeof(char));
f->Read(szTmp,8*sizeof(char));
if(strncmp(szTmp,_T("WAVEfmt"),8)!=0)
::AfxThrowFileException(CFileException::invalidFile,-1,f->GetFileName());
DWORD dwFmtSize/*= 16L*/;
f->Read(&dwFmtSize,sizeof(dwFmtSize));
f->Read(&pcmWaveFormat.wFormatTag,sizeof(pcmWaveFormat.wFormatTag));
f->Read(&pcmWaveFormat.nChannels,sizeof(pcmWaveFormat.nChannels));
f->Read(&pcmWaveFormat.nSamplesPerSec,sizeof(pcmWaveFormat.nSamplesPerSec));
f->Read(&pcmWaveFormat.nAvgBytesPerSec,sizeof(pcmWaveFormat.nAvgBytesPerSec));
f->Read(&pcmWaveFormat.nBlockAlign,sizeof(pcmWaveFormat.nBlockAlign));
f->Read(&pcmWaveFormat.wBitsPerSample,sizeof(pcmWaveFormat.wBitsPerSample));
ZeroMemory(szTmp,10 * sizeof(char));
f->Read(szTmp,4*sizeof(char));
if(strncmp(szTmp,_T("data"),4)!=0)
::AfxThrowFileException(CFileException::invalidFile,-1,f->GetFileName());
m_pcmWaveFormat=pcmWaveFormat;
DWORD dwNum;//dwNum为数据传输率
f->Read(&dwNum,sizeof(dwNum));
m_buffer.SetNumSamples(dwNum/pcmWaveFormat.nBlockAlign,pcmWaveFormat.nBlockAlign);
f->Read(m_buffer.GetBuffer(),dwNum);
}
//////////////////////////////////////
void CWave::Save(const CString &strFile)
{
CFile f(strFile,CFile::modeCreate|CFile::modeWrite);
Save(&f);
f.Close();
}
////////////////////////////////////////
void CWave::Save(CFile *f)
{
ASSERT(m_buffer.GetNumSamples() >0);
f->Write("RIFF",4);
DWORD dwFileSize = m_buffer.GetNumSamples() *m_pcmWaveFormat.nBlockAlign+36;
f->Write(&dwFileSize,sizeof(dwFileSize));
f->Write("WAVEfmt",8);
DWORD dwFmtSize = 16L;
f->Write(&dwFmtSize, sizeof(dwFmtSize)) ;
f->Write(&m_pcmWaveFormat.wFormatTag, sizeof(m_pcmWaveFormat.wFormatTag)) ;
f->Write(&m_pcmWaveFormat.nChannels, sizeof(m_pcmWaveFormat.nChannels)) ;
f->Write(&m_pcmWaveFormat.nSamplesPerSec, sizeof(m_pcmWaveFormat.nSamplesPerSec)) ;
f->Write(&m_pcmWaveFormat.nAvgBytesPerSec, sizeof(m_pcmWaveFormat.nAvgBytesPerSec)) ;
f->Write(&m_pcmWaveFormat.nBlockAlign, sizeof(m_pcmWaveFormat.nBlockAlign)) ;
f->Write(&m_pcmWaveFormat.wBitsPerSample, sizeof(m_pcmWaveFormat.wBitsPerSample)) ;
f->Write("data", 4) ;
DWORD dwNum= m_buffer.GetNumSamples() *m_pcmWaveFormat.nBlockAlign;
f->Write(&dwNum,sizeof(dwNum));
f->Write(m_buffer.GetBuffer(),dwNum);
}
////////////////////////////////////////////////
void *CWave::GetBuffer() const
{
return m_buffer.GetBuffer();
}
//////////////////////////////////////
DWORD CWave::GetNumSamples() const
{
return m_buffer.GetNumSamples();
}
/////////////////////////////////////
DWORD CWave::GetBufferLength() const
{
return(m_buffer.GetNumSamples() *m_pcmWaveFormat.nBlockAlign);
}
///////////////////////////////////////
void CWave::SetBuffer(void *pBuffer,DWORD dwNumSample,bool bCopy)
{
ASSERT(pBuffer);
ASSERT(dwNumSample >0);
ASSERT(m_pcmWaveFormat.nBlockAlign >0);
if(bCopy)
{
m_buffer.CopyBuffer(pBuffer,dwNumSample,m_pcmWaveFormat.nBlockAlign);
}
else
{
m_buffer.SetBuffer(pBuffer,dwNumSample,m_pcmWaveFormat.nBlockAlign);
}
}