由于wave族函数进行声音采集和播放时,会以下几个消息:

 MM_WIM_OPEN、 MM_WIM_DATA、MM_WIM_CLOSE、MM_WOM_OPEN、MM_WOM_DONE、MM_WOM_CLOSE

所以想在自己定义的类中能够响应这几个消息。

 

首先应将类定义为CWnd的派生类,因为MFC中的消息只发送给一个窗口或线程。

然后在自定义的类声明之后,还需要调用其Create函数创造一个窗口。然后就能够响应消息了。

 

其实定义为CCmdTarget的派生类就已经有消息响应的映射(CWnd也是CCmdTarget的派生类),利用VC类生成器,选择继承CCmdTarget类,自动生成的头文件和cpp文件中会出现如下的代码:

 

.h文件中:

 

//{{AFX_MSG(CSound)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()

 

.cpp文件中:


BEGIN_MESSAGE_MAP(CSound, CWnd)
 //{{AFX_MSG_MAP(CSound)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

 

在其中加上响应的函数入口和对应消息即可:

.h文件:
 //{{AFX_MSG(CSound)
 afx_msg void OnMM_WIM_OPEN(UINT wParam,LONG lParam);
 afx_msg void OnMM_WIM_DATA(UINT wParam,LONG lParam);
 afx_msg void OnMM_WIM_CLOSE(UINT wParam,LONG lParam);
 afx_msg void OnMM_WOM_OPEN(UINT wParam,LONG lParam);
 afx_msg void OnMM_WOM_DONE(UINT wParam,LONG lParam);
 afx_msg void OnMM_WOM_CLOSE(UINT wParam,LONG lParam);
 afx_msg void OnDestroy();
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 //}}AFX_MSG

 

.cpp文件:
BEGIN_MESSAGE_MAP(CSound, CWnd)
 //{{AFX_MSG_MAP(CSound)
 ON_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN)
 ON_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)
 ON_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)
 ON_MESSAGE(MM_WOM_OPEN,OnMM_WOM_OPEN)
 ON_MESSAGE(MM_WOM_DONE,OnMM_WOM_DONE)
 ON_MESSAGE(MM_WOM_CLOSE,OnMM_WOM_CLOSE)
 ON_WM_DESTROY()
 ON_WM_CREATE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

 

应用程序文件中调用create函数:
 m_sound.Create(_T("STATIC"), NULL, WS_CHILD | WS_VISIBLE,
  CRect(0, 0, 0, 0),this,1234,NULL);//1234为窗口ID

原文:http://blog.csdn.net/cabeauty/article/details/6238404

posted @ 2011-08-24 18:07 Luxh 阅读(58) 评论(0) 编辑

第一部分:

WAV文件结构解析:

WAVE文件由"块"组成。块的基本结构如下:

------------------------------
偏移量  名称    字节数    类型    
------------------------------
00      块标志    4       字符    
04      块长度    4       长整型 
08      块内容             数据   
--------------------------------

WAVE文件一般有四种块,它们依次是:RIFF块、格式块、附加块(可选),数据块

--------------------------------
名称    字节数         说明
--------------------------------
RIFF块   12          RIFF WAVE Chunk 
格式块   24或26      Format Chunk
附加块   12          Fact Chunk 
数据块   不定        Data Chunk
--------------------------------

1.RIFF块的数据结构
---------------------------------------------------
偏移量    名称      字节数   数据类型       内容
---------------------------------------------------
00     标志符      4       字符     “RIFF”的Ascii码

04     文件长度   4       长整形    文件的总字节数

08     WAV标志    4       字符     “WAVE”的Ascii码
---------------------------------------------------

2.格式块的数据结构
----------------------------------------------------------------------------
偏移地址  字节数    数据类型      内容
----------------------------------------------------------------------------
0C         4         字符       波形格式标志“fmt ”
10         4         长整型     格式块长度(一般=16,若=18表示最后有2字节附加信息)
14         2         整型      格式类别(值=1表示编码方式为PCMμ律编码)
16         2         整型       声道数(单声道=1,双声音=2)
18         4         长整型    采样频率(每秒样本数,表示每个通道的播放速度)
1C         4         长整型     数据传送速率(每秒字节=采样频率×每个样本字节数)
20         2         整型       每个样本字节数(又称基准块=每个样本位数×声道数÷8)
22         2        整型      每个样本位数(又称量化位数)
24         2         整型      附加信息(可选,通过块长度来判断有无)
----------------------------------------------------------------------------


3.附加块的数据结构
---------------------------------------------------
偏移地址      字节数   数据类型     内容
---------------------------------------------------
24         4         字符     标志符“fact”
28         4         长整形   块长度(=4)
2C         4 
---------------------------------------------------


4.数据块的数据结构
----------------------------------------
偏移地址 字节数   类型         内容
----------------------------------------
24          4        字符      数据标志符“data” 
28          4        长整型    样本数据长度 
2C       不定           样本数据 
----------------------------------------

第二部分:

参考VC代码:

void CWAVinfoDlg::OnBnClickedLoad() //读取信息,存入Buf中
{
DWORD dwFileLen;
pBuf
= NULL;

CFileDialog fileDlg(TRUE);
fileDlg.m_ofn.lpstrTitle
=_T("打开文件");
fileDlg.m_ofn.lpstrFilter
=_T("Wav音频文件(*.wav)\0*.wav\0");
if(IDOK == fileDlg.DoModal())
{
m_nPath
= fileDlg.GetPathName();
FileName
= fileDlg.GetFileName();
}
CFile file(m_nPath,CFile::modeRead
|CFile::typeBinary|CFile::shareDenyWrite);
dwFileLen
= file.GetLength();
FileSize
= dwFileLen;

//pBuf = new BYTE[dwFileLen + 1];
pBuf = new unsigned char[dwFileLen + 1]; //定义pBuf缓冲区,长度为 存档文件的长度 +1
pBuf[dwFileLen] = 0; //设置pBuf的索引(最后一个元素)为0,表示结束
file.Read(pBuf,dwFileLen); //将长度为dwFileLen的字符串从file中写到pBuf中,也就是全部,//**可以将二进制文件全部读入
file.Close();
UpdateData(FALSE);

analyse();
}

  


void CWAVinfoDlg::analyse()//分析wav文件信息
{
bool riff = false; //首先判断wav文件标志
bool wave = false;
bool fmt = false;

if ((pBuf[0] == 'R') && (pBuf[1] == 'I') && (pBuf[2] == 'F') && (pBuf[3] == 'F'))
{
riff
= true;
}
if ((pBuf[8] == 'W') && (pBuf[9] == 'A') && (pBuf[10] == 'V') && (pBuf[11] == 'E'))
{
wave
= true;
}
if ((pBuf[12] == 'f') && (pBuf[13] == 'm') && (pBuf[14] == 't'))
{
fmt
= true;
}

if (riff && wave && fmt) //wav文件标志正确
{
CString wav_size_str;
CString FileSize_str;
unsigned
double wav_size = 0.0;
int channel_num = 0;
int sample_rate = 0;
int sample_bit = 0;
unsigned
double length = 0.0;
CString length_str;

wav_size
= pBuf[43]*256*256*256 + pBuf[42]*256*256 + pBuf[41]*256 + pBuf[40];
channel_num
= pBuf[23]*256 + pBuf[22];
sample_rate
= pBuf[27]*256*256*256 + pBuf[26]*256*256 + pBuf[25]*256 + pBuf[24];
sample_bit
= pBuf[35]*256 + pBuf[34];

if (wav_size >= (1024*1024)) //通过文件信息得到wav大小
{
wav_size_str.Format(L
"%.2f MB",(wav_size/(1024.0*1024.0)));
}
else if (wav_size >= 1024)
{
wav_size_str.Format(L
"%.2f KB",(wav_size/1024.0));
}
else
{
wav_size_str.Format(L
"%f B",wav_size);
}
//通过wav大小得到持续时间(单位:秒)
length = (wav_size*8.0)/(sample_rate*channel_num*sample_bit*1.0);

if (FileSize >= (1024*1024)) //文件实际大小
{
FileSize_str.Format(L
"%.2f MB",(FileSize/(1024.0*1024.0)));
}
else if (FileSize >= 1024)
{
FileSize_str.Format(L
"%.2f KB",(FileSize/1024.0));
}
else
{
FileSize_str.Format(L
"%f B",FileSize);
}

CTimeSpan ts(length);
//格式化时间显示
length_str = ts.Format(_T("%H:%M:%S"));

MessageBox(L
"wav文件载入成功");
m_nInfo.Format(L
"文件大小: %s\r\nWav大小: %s\r\n通道数目: %d\r\n采样率 : %d HZ\r\n采样位数: %d bits\r\n持续时间: %s\r\n",FileSize_str,wav_size_str,channel_num,sample_rate,sample_bit,length_str);
UpdateData(FALSE);
}
else
{
MessageBox(L
"wav文件验证错误,不是正确的wav文件");
}
}

第三部分:

相关参考资料:

http://www.cnblogs.com/CPFlying/archive/2011/05/13/2045510.html

posted @ 2011-08-24 11:03 Luxh 阅读(82) 评论(0) 编辑