我们有了这两个强有力的类的支持就可以开始我们的编程工作了….
1.用VC6++建立一个MFC基于对话框的工程:MicDemo;
2.添加我们的两个类CSoundIn,CwaveFile;
3.当我们点击开始(Start)按钮的时候我们就要开始录音了…
void CMicDemoDlg::OnStart()
{
m_btnStart.EnableWindow(FALSE);
if(theSoundCapture().__initMic())
{
m_filePath.SetWindowText(_T("yangchen.wav."));
theSoundCapture().__createOutputWaveFile(_T("yangchen.wav"));
if(!theSoundCapture().__openMic())
{
::MessageBox(this->m_hWnd,_T("Can not open microphone!"), _T("Error"),MB_OK|MB_ICONERROR);
return;
}
}
m_btnStop.EnableWindow(TRUE);
// 设置定时器是为了画波形用的
SetTimer(1, 200 /*start slow*/, NULL);
}
4.在定时器的回调函数中画波形.
void CMicDemoDlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 1)
{
static const int xCon = 13;
static const int yCon = 13;
static const int wCon = 623;
static const int hCon = 80;
CClientDC dc(this);
CBitmap Bitmap;
CBitmap * pbmOld = NULL;
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
Bitmap.CreateCompatibleBitmap(&dc,wCon,hCon);
pbmOld = dcMem.SelectObject(&Bitmap);
dcMem.PatBlt(0,0,wCon,hCon, WHITENESS);
dcMem.MoveTo(0,hCon/2);
//
// display incomming signal--key idea!
//
for(int x =0 ; x < wCon; x++) // display Input
{
dcMem.LineTo(x,(hCon >> 1) - (theSoundCapture().InputBuffer[x] >> 7));
}
dc.BitBlt(xCon,yCon,wCon,hCon,&dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pbmOld);
dcMem.DeleteDC();
}
else
CDialog::OnTimer(nIDEvent);
}
5.点击停止(Stop)按钮的时候停止录音和写WAV文件
void CMicDemoDlg::OnStop()
{
m_btnStop.EnableWindow(FALSE);
theSoundCapture().__closeMic();
m_btnStart.EnableWindow(TRUE);
}
看完整段代码你可能会很奇怪怎么在CmicDemoDlg中居然都没有定义一个CSoundIn对象??呵呵,原因很简单,因为设备的独占性所以在一个时刻只能有一个CSoundIn对象存在(因为CSoundIn对象需要占据录音设备),所以我们必须限制程序员生成CSoundIn对象的数量,怎么限制呢?那就是把CSoundIn的构造函数放在private区域里面:
private:
BOOL GetBestWaveFormat(WAVEFORMATEX & waveFormatEx);
// because sound card is one and only so i must limit the number of CSoundIn object,
// but how to limit the class object nums?maybe put constructor into private scope is
// a good idea,:-)
CSoundIn();
这样的话就根本无法声明一个CSoundIn对象,不信你试一下在你的代码中写上:
CSoundIn soundInObj;
能编译通过吗?肯定是不能,那如何调用CSoundIn的成员函数呢?答案是通过一个全局函数:
// global function,:-(
// client can only through this function to use CSoundIn object
CSoundIn & theSoundCapture()
{
static CSoundIn p;
return p;
}
这时候你应该明白了为什么上面的代码中调用CSoundIn的成员函数的时候都是用theSoundCapture来做的原因了吧.