www.pudn.com > WavePlayer_Record_Save.rar > WavePlayerDlg.cpp
// WavePlayerDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "WavePlayer.h"
#include "WavePlayerDlg.h"
#include ".\waveplayerdlg.h"
#include "WaveAudio.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CWavePlayerDlg 对话框
CWavePlayerDlg::CWavePlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWavePlayerDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWavePlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CWavePlayerDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_OPEN, OnOpen)
ON_BN_CLICKED(IDC_PLAY, OnPlay)
ON_BN_CLICKED(IDC_RECORD, OnRecord)
ON_BN_CLICKED(IDC_SAVE, OnSave)
ON_BN_CLICKED(IDC_STOP, OnStop)
END_MESSAGE_MAP()
// CWavePlayerDlg 消息处理程序
BOOL CWavePlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将\“关于...\”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_bOpen=FALSE;
//还没有文件打开,所以先禁止一些按钮
CWnd *m_pWnd;
m_pWnd = GetDlgItem(IDC_SAVE);
m_pWnd->EnableWindow(false);
m_pWnd = GetDlgItem(IDC_PLAY);
m_pWnd->EnableWindow(false);
m_pWnd = GetDlgItem(IDC_STOP);
m_pWnd->EnableWindow(false);
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CWavePlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CWavePlayerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
if(m_bOpen)
{
CWnd *m_pWnd;
CRect rect;
m_pWnd=GetDlgItem(IDC_WAVE_GRAPH);
m_pWnd->GetClientRect(rect);
INFO_WAVEWIDE=rect.Width();
INFO_WAVEDEEP=rect.Height();
//CString str;str.Format("%d",rect.left); MessageBox("left",str,MB_OK);
//str.Format("%d",rect.top); MessageBox("top",str,MB_OK);
//str.Format("%d",INFO_WAVEWIDE); MessageBox("INFO_WAVEWIDE",str,MB_OK);
//str.Format("%d",INFO_WAVEDEEP); MessageBox("INFO_WAVEDEEP",str,MB_OK);
CClientDC dc(m_pWnd);
DrawWave(dc.m_hDC,rect.left,rect.top,(char *)path.operator LPCTSTR());
}
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CWavePlayerDlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}
void CWavePlayerDlg::OnOpen()
{
// TODO: 在此添加控件通知处理程序代码
CString Files;
CString str;
//char buf[128];
//DWORD dFlag;
Files = "波形音频文件(*.WAV)|*.WAV||";
CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,Files);
if(FileDlg.DoModal()==IDOK)
{
if(!m_Wave.Load(FileDlg.GetPathName()))
{
MessageBox("不能打开文件","错误",MB_OK|MB_ICONSTOP);
}
//strStatus.Format("文件已经正确打开");
//SetDlgItemText(IDC_STATIC_STATUS,strStatus);
CWnd *pWnd;
pWnd = GetDlgItem(IDC_PLAY);
pWnd->EnableWindow(true);
}
path=FileDlg.GetPathName();
SetDlgItemText(IDC_WAVE_NAME,FileDlg.GetFileName());
str.Format("%5.3f",m_Wave.GetSampleRate()/1000.);
str+=_T("kHZ");
SetDlgItemText(IDC_SAMPLE_RATE,str);
str.Empty();
switch(m_Wave.GetChannel())
{
case 1:
str="单声道";
break;
case 2:
str="立体声";
break;
}
SetDlgItemText(IDC_CHANNEL,str);
str.Empty();
str.Format("%d",m_Wave.GetResolution());
str+="位";
SetDlgItemText(IDC_RESOLUTION,str);
str.Empty();
str.Format("%2.2u:%02.2f:%02.2u",m_Wave.GetWaveLength()/1000/60,m_Wave.GetWaveLength()/1000.,m_Wave.GetWaveLength()/1000/3600);
SetDlgItemText(IDC_WAVE_LENGTH,str);
m_bOpen=TRUE;
}
void CWavePlayerDlg::OnPlay()
{
// TODO: 在此添加控件通知处理程序代码
m_Wave.Play();
CWnd *pWnd;
pWnd = GetDlgItem(IDC_RECORD);
pWnd->EnableWindow(false);
pWnd = GetDlgItem(IDC_STOP);
pWnd->EnableWindow(true);
}
void CWavePlayerDlg::OnRecord()
{
// TODO: 在此添加控件通知处理程序代码
CWnd *pWnd;
pWnd = GetDlgItem(IDC_PLAY);
pWnd->EnableWindow(false);
pWnd = GetDlgItem(IDC_SAVE);
pWnd->EnableWindow(true);
pWnd = GetDlgItem(IDC_OPEN);
pWnd->EnableWindow(false);
m_Wave.Record();
}
void CWavePlayerDlg::OnSave()
{
// TODO: 在此添加控件通知处理程序代码
CString Filter;
Filter = "波形文件(*.wav)|*.WAV||";
CFileDialog FileDlg(false,NULL,NULL,OFN_OVERWRITEPROMPT,Filter);
FileDlg.m_ofn.lpstrDefExt = "wav";
if(FileDlg.DoModal()==IDOK)
//strStatus.Format("正在保存文件……");
//SetDlgItemText(IDC_STATIC_STATUS,strStatus);
m_Wave.Save(FileDlg.GetPathName());
//strStatus.Empty();
//strStatus.Format("文件保存结束");
//SetDlgItemText(IDC_STATIC_STATUS,strStatus);
}
void CWavePlayerDlg::OnStop()
{
// TODO: 在此添加控件通知处理程序代码
CWnd *pWnd;
pWnd = GetDlgItem(IDC_PLAY);
pWnd->EnableWindow(true);
pWnd = GetDlgItem(IDC_OPEN);
pWnd->EnableWindow(true);
pWnd = GetDlgItem(IDC_SAVE);
pWnd->EnableWindow(true);
pWnd = GetDlgItem(IDC_RECORD);
pWnd->EnableWindow(true);
m_Wave.Stop();
}
void CWavePlayerDlg::DrawWave(HDC hdc,unsigned int x,unsigned int y,char *path)
{
HMMIO h;
MMCKINFO mmParent,mmSub;
GLOBALHANDLE gh;
PCMWAVEFORMAT waveformat;
char *p;
unsigned long nextsample;
float afactor = (float) 0.0;
unsigned int i,n,amp;
int *ip;
HPEN OldPen=(HPEN)SelectObject(hdc,GetStockObject(BLACK_PEN));
HBRUSH OldBrush=(HBRUSH)SelectObject(hdc,GetStockObject(WHITE_PEN));
Rectangle(hdc,x,y,x+INFO_WAVEWIDE,y+INFO_WAVEDEEP);
SelectObject(hdc,OldPen);
(HBRUSH)SelectObject(hdc,OldBrush);
if((h=mmioOpen(path,NULL,MMIO_READ))==NULL)
return;
mmParent.fccType=mmioFOURCC('W','A','V','E');
if(mmioDescend(h,(LPMMCKINFO)&mmParent,NULL,MMIO_FINDRIFF))
{
MessageBox("ok","1",MB_OK);
mmioClose(h,0);
return;
}
mmSub.ckid=mmioFOURCC('f','m','t',' ');
if(mmioDescend(h,(LPMMCKINFO)&mmSub,(LPMMCKINFO)&mmParent,MMIO_FINDCHUNK))
{
MessageBox("ok","2",MB_OK);
mmioClose(h,0);
return;
}
n=min((unsigned int)mmSub.cksize,sizeof(PCMWAVEFORMAT));
if(mmioRead(h,(LPSTR)&waveformat,n)!=n)
{
MessageBox("ok","3",MB_OK);
mmioClose(h,0);
return;
}CString s;
if(waveformat.wf.wFormatTag!=WAVE_FORMAT_PCM)
{
MessageBox("ok","不是PCM文件",MB_OK);
mmioClose(h,0);
return;
}
mmioAscend(h,&mmSub,0);
mmSub.ckid=mmioFOURCC('d','a','t','a');
if(mmioDescend(h,(LPMMCKINFO)&mmSub,(LPMMCKINFO)&mmParent,MMIO_FINDCHUNK))
{
MessageBox("ok","4",MB_OK);
mmioClose(h,0);
return;
}
// CString str; str.Format("%d",waveformat.wBitsPerSample);MessageBox("ok",str,MB_OK);
//str.Format("%d",waveformat.wBitsPerSample); MessageBox("waveformat.wBitsPerSample",str,MB_OK);
//str.Format("%d",waveformat.wf.nChannels); MessageBox("waveformat.wf.nChannels",str,MB_OK);
if(waveformat.wBitsPerSample==8&&waveformat.wf.nChannels==1)
{
nextsample=mmSub.cksize / INFO_WAVEWIDE;
afactor = (((2 * 255) / (float) INFO_WAVEDEEP));
//__asm int 3// 需要断点的地方加上这句
CString str;
//str.Format("%d",mmSub.cksize); MessageBox("mmSub.cksize",str,MB_OK);
//str.Format("%.4f",afactor); MessageBox("afactor",str,MB_OK);
//str.Format("%d",nextsample); MessageBox("nextsample",str,MB_OK);
//str.Format("%d",INFO_WAVEDEEP); MessageBox("INFO_WAVEDEEP",str,MB_OK);
//str.Format("%d",INFO_WAVEWIDE); MessageBox("INFO_WAVEWIDE",str,MB_OK);
//return;
}
else if(waveformat.wBitsPerSample==8&&waveformat.wf.nChannels==2)
{
nextsample=2L*((mmSub.cksize/2L)/(long)INFO_WAVEWIDE);
afactor=2L*(255L/(long)INFO_WAVEDEEP);
}
else if(waveformat.wBitsPerSample>8&&waveformat.wf.nChannels==1)
{
nextsample=2L*((mmSub.cksize/(long)INFO_WAVEWIDE))&0xfffffffeL;
afactor=2L*(65535L/(long)INFO_WAVEDEEP);
}
else
{
nextsample=4L*((mmSub.cksize/4L)/(long)INFO_WAVEWIDE)&0xfffffffeL;
afactor=2L*(65535L/(long)INFO_WAVEDEEP);
}
MoveToEx(hdc,x,y+INFO_WAVEDEEP/2,NULL);
LineTo(hdc,x+INFO_WAVEWIDE,y+INFO_WAVEDEEP/2);
if((gh=GlobalAlloc(GMEM_MOVEABLE,mmSub.cksize))!=NULL)
{
if((p=(char*)GlobalLock(gh))!=NULL)
{
if(mmioRead(h,p,mmSub.cksize)==mmSub.cksize)
{
for(i=0;i8&&waveformat.wf.nChannels==1)
amp=(unsigned int)max(labs((long)ip[0]/afactor),1L);
else
amp=(unsigned int)max(labs((((long)ip[0]+(long)ip[1])/2)/afactor),1L);
MoveToEx(hdc,x+i,y+(INFO_WAVEDEEP/2)-amp,NULL);
LineTo(hdc,x+i,y+(INFO_WAVEDEEP/2)+amp);
//CString str; str.Format("%d",x); MessageBox("x",str,MB_OK);
//str.Format("%d",y); MessageBox("y",str,MB_OK);
//str.Format("%d",y+(INFO_WAVEDEEP/2)-amp); MessageBox("y+(INFO_WAVEDEEP/2)-amp",str,MB_OK);
//CString str; str.Format("%d",x+i); MessageBox("x+i",str,MB_OK);
//str.Format("%d",y+(INFO_WAVEDEEP/2)+amp); MessageBox("y+(INFO_WAVEDEEP/2)+amp",str,MB_OK);
//return;
//i+=2;
p+=nextsample;
}
}
GlobalUnlock(gh);
}
GlobalFree(gh);
}
//SelectObject(hdc,OldPen);
//(HBRUSH)SelectObject(hdc,OldBrush);
//CString str; str.Format("%d",i); MessageBox("i",str,MB_OK);
mmioClose(h,0);
return;
}