?? recorderdlg.cpp
字號:
// RecorderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Recorder.h"
#include "RecorderDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRecorderDlg dialog
CRecorderDlg::CRecorderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRecorderDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CRecorderDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CRecorderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRecorderDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRecorderDlg, CDialog)
//{{AFX_MSG_MAP(CRecorderDlg)
ON_BN_CLICKED(IDC_REC_START, OnRecStart)
ON_BN_CLICKED(IDC_REC_STOP, OnRecStop)
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_BN_CLICKED(IDC_PLAY_START, OnPlayStart)
ON_BN_CLICKED(IDC_PLAY_PAUSE, OnPlayPause)
ON_BN_CLICKED(IDC_PLAY_STOP, OnPlayStop)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRecorderDlg message handlers
BOOL CRecorderDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
//給wave header分配內存
pWaveHdr1=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
pWaveHdr2=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
//給保存聲音數據的buffer分配內存
pSaveBuffer = reinterpret_cast<PBYTE>(malloc(1));
return TRUE; // return TRUE unless you set the focus to a control
}
void CRecorderDlg::OnRecStart()
{
//分配buffer內存
pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE);
pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE);
if (!pBuffer1 || !pBuffer2) {
if (pBuffer1) free(pBuffer1);
if (pBuffer2) free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox(_T("內存申請失敗!"));
return ;
}
//打開波形設備并錄音
waveform.wFormatTag=WAVE_FORMAT_PCM;
waveform.nChannels=1;
waveform.nSamplesPerSec=11025;
waveform.nAvgBytesPerSec=11025;
waveform.nBlockAlign=1;
waveform.wBitsPerSample=8;
waveform.cbSize=0;
if (waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
free(pBuffer1);
free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox(_T("無法打開音頻設備!"));
}
pWaveHdr1->lpData=(char*)pBuffer1;
pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr1->dwBytesRecorded=0;
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=1;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
pWaveHdr2->lpData=(char*)pBuffer2;
pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr2->dwBytesRecorded=0;
pWaveHdr2->dwUser=0;
pWaveHdr2->dwFlags=0;
pWaveHdr2->dwLoops=1;
pWaveHdr2->lpNext=NULL;
pWaveHdr2->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
//////////////////////////////////////////////////////////////////////////
pSaveBuffer = (PBYTE)realloc (pSaveBuffer, 1) ;
//添加緩沖
waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
//開始采樣
bRecording = TRUE ;
bEnding = FALSE ;
dwDataLength = 0 ;
waveInStart (hWaveIn) ;
}
void CRecorderDlg::OnRecStop()
{
TRACE(_T("停止錄音 \n"));
bEnding=TRUE;
Sleep(500);
waveInReset(hWaveIn);
}
void CRecorderDlg::OnMM_WIM_OPEN(UINT wParam, LONG lParam)
{
// TODO: Add your message handler code here and/or call default
((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE);
SetTimer(1,100,NULL);
bRecording=TRUE;
TRACE(L"MM_WIM_OPEN\n");
}
void CRecorderDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam)
{
// TODO: Add your message handler code here and/or call default
//重新分配聲音數據緩沖內存
//////////////////////////////////////////////////////////////////////////
pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength +
((PWAVEHDR) lParam)->dwBytesRecorded) ;
if (pNewBuffer == NULL)
{
waveInClose (hWaveIn) ;
MessageBeep (MB_ICONEXCLAMATION) ;
AfxMessageBox(_T("erro memory"));
return ;
}
pSaveBuffer = pNewBuffer ;
//////////////////////////////////////////////////////////////////////////
CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) lParam)->lpData,
((PWAVEHDR) lParam)->dwBytesRecorded) ;
dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ;
if (bEnding)
{
waveInClose (hWaveIn) ;
return ;
}
//添加一個新的緩沖
waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
TRACE(_T("done input data\n"));
return ;
}
void CRecorderDlg::OnMM_WIM_CLOSE(UINT wParam, LONG lParam)
{
// TODO: Add your message handler code here and/or call default
KillTimer(1);
TRACE(_T("MM_WIM_CLOSE\n"));
if (0==dwDataLength) {
return;
}
waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
free (pBuffer1) ;
free (pBuffer2) ;
if (dwDataLength > 0)
{
//錄音結束,有音頻數據的時候,讓播放按鈕能夠使用
((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE);
}
bRecording = FALSE ;
((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE);
return;
}
void CRecorderDlg::OnDestroy()
{
CDialog::OnDestroy();
if (bRecording)
{
bTerminating=TRUE;
bEnding=TRUE;
waveInReset(hWaveIn);
TRACE(_T("waveInReset\n"));
Sleep(500);
//return CWinThread::ExitInstance();
}
if (bPlaying)
{
bTerminating=TRUE;
bEnding=TRUE;
waveOutReset(hWaveOut);
Sleep(500);
//return CWinThread::ExitInstance();
}
free (pWaveHdr1) ;
free (pWaveHdr2) ;
free (pSaveBuffer) ;
}
void CRecorderDlg::OnPlayStart()
{
if (bPlaying) {
waveOutReset(hWaveOut);
}
//打開音頻設備的輸出
waveform.wFormatTag = WAVE_FORMAT_PCM;
waveform.nChannels = 1;
waveform.nSamplesPerSec =11025;
waveform.nAvgBytesPerSec=11025;
waveform.nBlockAlign =1;
waveform.wBitsPerSample =8;
waveform.cbSize =0;
if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox(_T("Audio output erro"));
}
}
void CRecorderDlg::OnPlayPause()
{
if (!bPlaying)
{
return;
}
if (!bPaused)
{
waveOutPause(hWaveOut);
bPaused = TRUE;
}
else
{
waveOutRestart(hWaveOut);
bPaused=FALSE;
}
}
void CRecorderDlg::OnPlayStop()
{
if (!bPlaying)
{
return ;
}
bEnding=TRUE;
waveOutReset(hWaveOut);
}
void CRecorderDlg::OnMM_WOM_OPEN(UINT wParam, LONG lParam)
{
TRACE(_T("open MM_WOM_OPEN\n"));
//建立音頻設備header
pWaveHdr1->lpData = (char*)pSaveBuffer ;
pWaveHdr1->dwBufferLength = dwDataLength ;
pWaveHdr1->dwBytesRecorded = 0 ;
pWaveHdr1->dwUser = 0 ;
pWaveHdr1->dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
pWaveHdr1->dwLoops = dwRepetitions ;
pWaveHdr1->lpNext = NULL ;
pWaveHdr1->reserved = 0 ;
//準備輸出Header并將數據寫入,實現音頻輸出
waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
bEnding = FALSE ;
bPlaying = TRUE ;
((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(TRUE);
}
void CRecorderDlg::OnMM_WOM_DONE(UINT wParam, LONG lParam)
{
TRACE(_T("open MM_WOM_DONE\n"));
waveOutUnprepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
waveOutClose (hWaveOut) ;
bPaused = FALSE ;
dwRepetitions = 1 ;
bPlaying = FALSE ;
return ;
}
void CRecorderDlg::OnMM_WOM_CLOSE(UINT wParam, LONG lParam)
{
TRACE(_T("open MM_WOM_CLOSE\n"));
bPaused = FALSE ;
dwRepetitions = 1 ;
bPlaying = FALSE ;
((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(TRUE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE);
((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE);
return ;
}
void CRecorderDlg::OnTimer(UINT nIDEvent)
{
MMTIME mmTime;
mmTime.wType=TIME_MS;
TCHAR time[20];
switch(nIDEvent)
{
case 1:
//顯示錄音時間
waveInGetPosition(hWaveIn,&mmTime,sizeof(MMTIME));
CString time;
time.Format(_T("錄音時間:%d"),(int)(mmTime.u.ms/10000));
SetDlgItemText(IDC_STATIC_TIME,time);
}
CDialog::OnTimer(nIDEvent);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -