623实验报告Word格式.docx
《623实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《623实验报告Word格式.docx(43页珍藏版)》请在冰点文库上搜索。
UINTuDeviceID,//要打开设备的标识,设为WAVE_MAPPER自动选择
LPWAVEFORMATEXpwfx,//指向一个WAVEFORMATEX结构体的指针
DWORDdwCallback,//事件处理回调函数入口,当输入缓冲区满时,调用该函数
DWORDdwCallbackInstance,//用户进程传递给回调函数的数据
DWORDfdwOpen//打开方式标志
);
RESULTwaveInPrepareHeader(//为声音波形输入准备一个缓冲区
HWAVEINhwi,//波形输入设备句柄
LPWAVEHDRpwh,//标识缓冲区的WAVEHDR结构体入口地址
UINTcbwh//WAVEHDR结构体的大小,以字节为单位
);
MMRESULTwaveInAddBuffer(//向输入设备指定缓冲区,当缓冲区满时,通知用户程序
HWAVEINhwi,//波形输入设备句柄
LPWAVEHDRpwh,//标识缓冲区的WAVEHDR结构体入口地址
UINTcbwh//WAVEHDR结构体的大小,以字节为单位
MMRESULTwaveInStart(//开始指定设备采集
MMRESULTwaveInReset(//停止指定设备输入,重置缓冲区
HWAVEINhwi//波形输入设备句柄
MMRESULTwaveInUnprepareHeader(//取消所准备的缓冲区
HWAVEINhwi,//波形输入设备句柄
LPWAVEHDRpwh,//标识缓冲区的WAVEHDR结构体入口地址
UINTcbwh//WAVEHDR结构体的大小,以字节为单位
MMRESULTwaveInClose(//关闭指定输入设备
HWAVEINhwi//波形输入设备句柄
其中WAVEHDR结构体定义了声形波形数据的格式,
ormatTag;
//波形格式标签频率数=列块大小*采样频率列;
来扩充此结构体,以指定特殊格式(如压缩)
typedefstruct{
WORDwFormatTag;
//波形格式标签
WORDnChannels;
//声道数
DWORDnSamplesPerSec;
//采样频率
DWORDnAvgBytesPerSec;
//每秒字节数=列块大小*采样频率
WORDnBlockAlign;
//列块大小=声道数*量化位数/8
WORDwBitsPerSample//量化位数
WORDcbSize;
//附加结构字节数,用来扩充此结构体,以指定特殊格式(如缩)
}WAVEFORMATEX;
声卡采集输入的过程是:
①打开设备->
②准备缓冲区->
③指定缓冲区->
④开始输入->
⑤等待系统填充缓冲区->
⑥读取数据,重复⑤⑥直到输入结束,⑦停止输入->
⑧取消缓冲区->
⑨关闭设备,输出的过程与之相似。
系统在缓冲区满/空时执行用户指定的回调函数,因此构造一个波形输入/输出事件,在回调函数中触发此事件,而在缓冲区读/写函数(用户工作线程)中等待此事件。
此外,用户程序必须处理各种可能的错误。
由于API函数在使用时操作繁琐、不易理解。
为方便引用,本次实验给出一个CSoundIn类,它将上述API函数进行封装,提供如下接口函数:
MMRESULTOpenMic(intchannel,intsamples,intbitSamples);
//打开输入设备
voidStartMic();
//开始录音
voidStopMic();
//停止录音
voidCloseMic();
//关闭输入设备
voidGetHwnd(HWNDhwnd);
//获取主窗口句柄,用于关联示波器显示
声音数据采集的过程就是
打开输入设备
开始录音
停止录音
关闭输入设备。
本次实验除了提供CSoundIn类外,为了方便程序显示波形,还提供了一个示波器类CScope,它有以下接口函数:
voidSetTitle(CStringstrTitle);
//设置示波器的标题
voidSetDimT(doublenewDimT);
//设置横坐标显示间隔
voidSetDimy(doublenewDimY);
//设置纵坐标显示间隔
voidUpdateCurve();
//更新曲线
voidAddValue(doubledTime,doubledValue);
//加载示波器要显示的输入数据
六、编程步骤
1、创建一个对话框程序,在对话框类定义中声明一个CSoundIn对象、一个CScope对象以及一个函数:
scope(intnTime,intdata)。
加入必要的控件,以使程序能设置采样条件,并能控制采样。
2、在初始化对话框时,即在OnInitDialog函数中,设置示波器的横纵坐标间隔;
调用CSoundIn对象的GetHwnd函数,即m_soundIn.GetHwnd(this->
m_hWnd);
3、CScope对象用来显示声音波形,实现的方法是先在对话框资源上放置一个静态文本框,将ID值改为IDC_SCOPE(可自定),在对话框类的DoDataExchange函数中将CScope对象与该静态文本资源相关联,即在//}}AFX_DATA_MAP之前加入一句话
DDX_Control(pDX,IDC_SCOPE,m_scope);
1)按钮控件:
voidCVirtualOscilloscopeDlg:
:
OnButton1()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_soundIn.OpenMic(m_channel,m_samples,m_bitSamples);
}
OnButton3()
m_soundIn.StartMic();
OnButton4()
m_soundIn.StopMic();
2)采样频率
OnRadio1()
m_samples=8000;
OnRadio3()
m_samples=11025;
OnRadio2()
m_samples=22050;
OnRadio4()
m_samples=44100;
3)采样位数
OnRadio5()
m_bitSamples=8;
OnRadio6()
m_bitSamples=16;
4)采样通道数
OnRadio7()
m_channel=1;
OnRadio8()
m_channel=2;
5)幅值
步骤:
首先在VirtualOscilloscopeDlg加入m_fz成员变量:
在对话框的CPP文件中,加入如下代码:
scope(intnTime,intdata)
m_fz.Format("
%d"
data);
GetDlgItem(IDC_EDIT1)->
SetWindowText(m_fz);
m_scope.AddValue(nTime,(-(double)data+128)/20);
//m_scope.AddValue(nTime,(data+128)/20);
num++;
if(num==2048)
{
m_scope.UpdateCurve();
num=0;
}
4、对话框类的scope函数实现代码,该函数在CSoundIn中被调用
//将128定为中线
if(num==2048)//在CSoundIn类中缓冲区定义为2048
7、实验结果
8、实验源程序
#include"
stdafx.h"
virtualOscilloscope.h"
virtualOscilloscopeDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
intnum=0;
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
CAboutDlg():
CDialog(CAboutDlg:
IDD)
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
voidCAboutDlg:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CVirtualOscilloscopeDlgdialog
CVirtualOscilloscopeDlg:
CVirtualOscilloscopeDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CVirtualOscilloscopeDlg:
IDD,pParent)
//{{AFX_DATA_INIT(CVirtualOscilloscopeDlg)
m_bitSamples=-1;
m_samples=-1;
m_channel=-1;
m_fz=_T("
"
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
//{{AFX_DATA_MAP(CVirtualOscilloscopeDlg)
DDX_Control(pDX,IDC_BUTTON4,m_BUTTON4);
DDX_Control(pDX,IDC_BUTTON3,m_BUTTON3);
DDX_Control(pDX,IDC_BUTTON2,m_BUTTON2);
DDX_Control(pDX,IDC_BUTTON1,m_BUTTON1);
DDX_Control(pDX,IDC_SCOPE,m_scope);
DDX_Radio(pDX,IDC_RADIO5,m_bitSamples);
DDX_Radio(pDX,IDC_RADIO1,m_samples);
DDX_Radio(pDX,IDC_RADIO7,m_channel);
DDX_Text(pDX,IDC_EDIT1,m_fz);
BEGIN_MESSAGE_MAP(CVirtualOscilloscopeDlg,CDialog)
//{{AFX_MSG_MAP(CVirtualOscilloscopeDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RADIO1,OnRadio1)
ON_BN_CLICKED(IDC_BUTTON1,OnButton1)
ON_BN_CLICKED(IDC_BUTTON2,OnButton2)
ON_BN_CLICKED(IDC_BUTTON3,OnButton3)
ON_BN_CLICKED(IDC_BUTTON4,OnButton4)
ON_BN_CLICKED(IDC_RADIO7,OnRadio7)
ON_BN_CLICKED(IDC_RADIO8,OnRadio8)
ON_BN_CLICKED(IDC_RADIO3,OnRadio3)
ON_BN_CLICKED(IDC_RADIO2,OnRadio2)
ON_BN_CLICKED(IDC_RADIO4,OnRadio4)
ON_BN_CLICKED(IDC_RADIO5,OnRadio5)
ON_BN_CLICKED(IDC_RADIO6,OnRadio6)
ON_EN_CHANGE(IDC_EDIT1,OnChangeEdit1)
ON_BN_CLICKED(IDC_SCOPE,OnScope)
//CVirtualOscilloscopeDlgmessagehandlers
BOOLCVirtualOscilloscopeDlg:
OnInitDialog()
OnInitDialog();
//Add"
About..."
menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&
0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<
0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->
AppendMenu(MF_SEPARATOR);
AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'
smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);
//Setbigicon
SetIcon(m_hIcon,FALSE);
//Setsmallicon
Addextrainitializationhere
//设置示波器横纵坐标单位
m_soundIn.GetHwnd(this->
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
OnSysCommand(UINTnID,LPARAMlParam)
if((nID&
0xFFF0)==IDM_ABOUTBOX)
CAboutDlgdlgAbout;
dlgAbout.DoModal();
else
CDialog:
OnSysCommand(nID,lParam);
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
OnPaint()
if(IsIconic())
CPaintDCdc(this);
//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&
rect);
intx=(rect.Width()-cxIcon+1)/2;
int