접기
class CSoundRecDlg : public CDialog
{
// {
enum { MAX_BUFFERS=3 };
static void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
VOID ProcessHeader(WAVEHDR * pHdr);
VOID PrepareBuffers();
VOID UnPrepareBuffers();
VOID CloseDevice();
VOID OpenDevice();
WAVEHDR m_stWHDR[MAX_BUFFERS];
WAVEFORMATEX m_stWFEX;
HWAVEIN m_hWaveIn;
// }
// Construction
public:
CSoundRecDlg(CWnd* pParent = NULL); // standard constructor
...
// Generated message map functions
//{{AFX_MSG(CSoundRecDlg)
...
afx_msg void OnBnClickedRec();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
...
};
#pragma comment(lib,"winmm")
...
CSoundRecDlg::CSoundRecDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSoundRecDlg::IDD, pParent), m_hWaveIn(NULL)
{
...
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// {
ZeroMemory(&m_stWFEX,sizeof(WAVEFORMATEX ));
ZeroMemory(m_stWHDR,MAX_BUFFERS*sizeof(WAVEHDR));
// }
}
...
BEGIN_MESSAGE_MAP(CSoundRecDlg, CDialog)
//{{AFX_MSG_MAP(CSoundRecDlg)
...
ON_BN_CLICKED(ID_REC, OnBnClickedRec)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
...
BOOL CSoundRecDlg::OnInitDialog()
{
...
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// {
ZeroMemory(&m_stWFEX,sizeof(WAVEFORMATEX ));
ZeroMemory(m_stWHDR,MAX_BUFFERS*sizeof(WAVEHDR));
...
// }
return TRUE; // return TRUE unless you set the focus to a control
}
...
void CSoundRecDlg::OnBnClickedRec()
{
// TODO: Add your control notification handler code here
CString csT1;
GetDlgItem(ID_REC)->GetWindowText(csT1);
GetDlgItem(ID_REC)->EnableWindow(FALSE);
if(csT1.Compare("&Start")==0)
{
GetDlgItem(ID_REC)->SetWindowText("&Stop");
MMRESULT mRes;
try
{
OpenDevice();
PrepareBuffers();
mRes=waveInStart (m_hWaveIn);
if(mRes!=0)
{
throw ...;
}
}
catch(PCHAR pErrorMsg)
{
...
}
}
else
{
CloseDevice();
}
GetDlgItem(ID_REC)->EnableWindow(TRUE);
}
VOID CSoundRecDlg::OpenDevice()
{
MMRESULT mRes=0;
m_stWFEX.wBitsPerSample =...;
m_stWFEX.nSamplesPerSec =...;
m_stWFEX.nChannels =...;
m_stWFEX.wFormatTag=WAVE_FORMAT_PCM;
m_stWFEX.nBlockAlign=m_stWFEX.nChannels*m_stWFEX.wBitsPerSample/8;
m_stWFEX.nAvgBytesPerSec=m_stWFEX.nSamplesPerSec*m_stWFEX.nBlockAlign;
m_stWFEX.cbSize=sizeof(WAVEFORMATEX);
mRes=waveInOpen (&m_hWaveIn,WAVE_MAPPER,&m_stWFEX,(DWORD_PTR)waveInProc,(DWORD_PTR)this,CALLBACK_FUNCTION );
if(mRes!=MMSYSERR_NOERROR)
{
throw ...;
}
...
}
VOID CSoundRecDlg::CloseDevice()
{
MMRESULT mRes=0;
if(m_hWaveIn)
{
UnPrepareBuffers();
mRes=waveInClose (m_hWaveIn);
}
m_hWaveIn=NULL;
...
}
VOID CSoundRecDlg::PrepareBuffers()
{
MMRESULT mRes=0;
int nT1=0;
for(nT1=0;nT1<MAX_BUFFERS;++nT1)
{
m_stWHDR[nT1].lpData=(LPSTR)HeapAlloc(GetProcessHeap(),8,m_stWFEX.nAvgBytesPerSec);
m_stWHDR[nT1].dwBufferLength=m_stWFEX.nAvgBytesPerSec;
m_stWHDR[nT1].dwUser=nT1;
mRes=waveInPrepareHeader (m_hWaveIn,&m_stWHDR[nT1],sizeof(WAVEHDR));
if(mRes!=0)
{
throw ...;
}
mRes=waveInAddBuffer (m_hWaveIn,&m_stWHDR[nT1],sizeof(WAVEHDR));
if(mRes!=0)
{
throw ...;
}
}
}
VOID CSoundRecDlg::UnPrepareBuffers()
{
MMRESULT mRes=0;
int nT1=0;
if(m_hWaveIn)
{
mRes=waveInStop (m_hWaveIn);
for(nT1=0;nT1<3;++nT1)
{
if(m_stWHDR[nT1].lpData)
{
mRes=waveInUnprepareHeader (m_hWaveIn,&m_stWHDR[nT1],sizeof(WAVEHDR));
HeapFree(GetProcessHeap(),0,m_stWHDR[nT1].lpData);
ZeroMemory(&m_stWHDR[nT1],sizeof(WAVEHDR));
}
}
}
}
void CALLBACK CSoundRecDlg::waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
WAVEHDR *pHdr=NULL;
switch(uMsg)
{
case WIM_OPEN :
break;
case WIM_CLOSE :
break;
case WIM_DATA :
{
CSoundRecDlg *pDlg=(CSoundRecDlg*)dwInstance;
pDlg->ProcessHeader((WAVEHDR *)dwParam1);
}
break;
default:
break;
}
}
VOID CSoundRecDlg::ProcessHeader(WAVEHDR * pHdr)
{
MMRESULT mRes=0;
if (WHDR_DONE==(WHDR_DONE & pHdr->dwFlags))
{
... pHdr->lpData ... pHdr->dwBytesRecorded ... pHdr->dwUse ...
mRes=waveInAddBuffer (m_hWaveIn,pHdr,sizeof(WAVEHDR));
if(mRes!=0) {
...
}
}
}
접기