16,472
社区成员
发帖
与我相关
我的任务
分享
typedef DWORD FOURCC; /* a four character code */
void CWaveDiagramDoc::OnOpenwav()
{
// TODO: 在此添加命令处理程序代码
//使用宏进行ASCII到宽字符的转换
USES_CONVERSION;
//创建文件选择对话框
CFileDialog dlg(TRUE,A2CW("wav"),A2CW("*.wav"),OFN_HIDEREADONLY,A2CW("WaveFiles(*.wav)|*.wav||"));
if (dlg.DoModal()==IDOK)
{
//打开文件
CFile file;
CString path=dlg.GetPathName();
file.Open(path,CFile::modeRead );
//创建CArchive对象
CArchive ar(&file,CArchive::load);
FOURCC id,chkLen,dw; //无符号双字节类型
BYTE b; //无符号字节
WORD w; //unsigned short 无符号单字长
WORD fmtTag; //格式标记
WORD wBitsPerSample; //样本位数
FOURCC dwAvgBytesRate; //平均字节率
FOURCC Len; //数据块的字节长度
ar>>id; //读取文件标识符串
if (id!=ID_RIFF) { return; }
ar>>dw>>id; //读取头后文件长度和波形文件标识符
if (id!=ID_WAVE) { return; }
ar>>id; //读取格式块标识符串
if (id!=ID_fmt) { return; }
ar>>chkLen; //读取头后块长度
ar>>fmtTag; //读取格式标记
if (fmtTag!=1) //只处理PCM(Pulse Code Modulation, 脉冲编码调制)情况
{
return;
}
ar>>wChannel; //声道数
ar>>dw; //采样率
ar>>dwAvgBytesRate; //平均字节率
ar>>w; //数据块对齐
ar>>wBitsPerSample; //样本位数
if (chkLen==18)
{
ar>>w; //扩展域大小
for (int i=0;i<w;i++) //读走扩展域的内容
{
ar>>b;
}
}
ar>>id; //读取数据块标识符
if (id==ID_fact) { ar>>dw>>dw; ar>>id; }//如果有fact块,就读取fact块的内容
if (id!=ID_data) { return; }
ar>>Len; //文件长度
BytesPerSample=wBitsPerSample/8; //一个样本的字节数
num=Len/BytesPerSample; //样本数
if (wChannel==1) //单声道
{
data=new LONG[num];
//单字节样本值v为无符号整数(0~255),实际样本值应为v-128;多字节样本值本身就是有符号的,可直接使用
if (BytesPerSample==1)
{
for (int i=0;i<num;i++)
{
ar>>b;
data[i]=b-128;
}
}
else if (BytesPerSample==2)
{
for (int i=0;i<num;i++)
{
ar>>w;
data[i]=(SHORT)w; //无符号转换成有符号数
}
}
else if (BytesPerSample==4)
{
for (int i=0;i<num;i++)
{
ar>>dw;
data[i]=(LONG)dw; //无符号转换成有符号数
}
}
else if (BytesPerSample==3)
{
for (int i=0;i<num;i++)
{
ar>>b>>w;
data[i]=w+b;
}
}
}
else if (wChannel==2) //双声道
{
LData=new LONG[num/2];
RData=new LONG[num/2];
//一个声道的样本数为num/2,左右声道交替采集
if (BytesPerSample==1)
{
for (int i=0;i<num/2;i++)
{
ar>>b;
LData[i]=b-128;
ar>>b;
RData[i]=b-128;
}
}
else if (BytesPerSample==2)
{
for (int i=0;i<num/2;i++)
{
ar>>w;
LData[i]=(SHORT)w;
ar>>w;
RData[i]=(SHORT)w;
}
}
else if (BytesPerSample==4)
{
for (int i=0;i<num/2;i++)
{
ar>>dw;
LData[i]=(LONG)dw;
ar>>dw;
RData[i]=(LONG)dw;
}
}
else if (BytesPerSample==3)
{
for (int i=0;i<num/2;i++)
{
ar>>b>>w;
LData[i]=w+b;
ar>>b>>w;
RData[i]=w+b;
}
}
}
ar.Flush(); //清除缓冲区
file.Close(); //关于文件句柄
//获取当前活动视图,强制重绘,调用OnDraw函数
CMainFrame *Mainfrm=(CMainFrame*)AfxGetMainWnd();
Mainfrm->GetActiveView()->Invalidate();
//播放声音
//PlaySound(path,NULL,SND_ASYNC);
}
}
friend CArchive& operator >>(
CArchive& ar,
CObject *& pOb
);
throw(
CArchiveException*,
CFileException*,
CMemoryException*
);
friend CArchive& operator >>(
CArchive& ar,
const CObject *& pOb
);
throw(
CArchiveException*,
CFileException*,
CMemoryException*
);
CArchive& AFXAPI operator >>(
CArchive& ar,
const RECT& rect
);
CArchive& AFXAPI operator >>(
CArchive& ar,
POINT point
);
CArchive& AFXAPI operator >>(
CArchive& ar,
SIZE size
);
template<
typename BaseType,
class StringTraits
>
CArchive& operator>>(
ATL::CStringT<
BaseType,
StringTraits
>& str
);
CArchive& operator >>(
BYTE& by
);
CArchive& operator >>(
WORD& w
);
CArchive& operator >>(
int& i
);
CArchive& operator >>(
LONG& l
);
CArchive& operator >>(
DWORD& dw
);
CArchive& operator >>(
float& f
);
CArchive& operator >>(
double& d
);
CArchive& operator >>(
short& w
);
CArchive& operator >>(
char& ch
);
CArchive& operator>>(
wchar_t& ch);
CArchive& operator >>(
unsigned& u
);
CArchive& operator >>(
bool& b
);
CArchive& operator >>(
ULONGLONG& dwdw
);
CArchive& operator >>(
LONGLONG& dwdw
);