为什么象这样一移 ar>>id; 就可读取文件标识符串。

66i88 2009-08-20 01:14:05
找到一段打开 *.wav 文件并读取信息的代码。
但不明白 为什么象这样一移 ar>>id; 就可读取文件标识符串。


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);
}
}

...全文
86 点赞 收藏 4
写回复
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
heiheizh618 2009-08-20
这是文件串行化相关的知识。
如果楼主需要知道详细原理的话,建议去看看深入浅出MFC。从里面的动态创建看起,看到文件串行化之后就会明白了~~ 这些东西比较多,也比较杂,不是发一个贴就能解释清楚的~
如果不需要知道详细的原理的话,这就类似于C++标准库里面的cin和cout.可通过这两个去大致了解文件串行化Serialization
回复
操作符重载
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
);
回复
zw0558 2009-08-20
顶一下,学习、
回复
mazm_yanzhu 2009-08-20
Loads the indicated object or primitive type from the archive.

查查MSDN,CArchive类的用法
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告