ImageVerifierCode 换一换
格式:DOCX , 页数:26 ,大小:138.67KB ,
资源ID:4134140      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4134140.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于VC++60的音频信号采集系统.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于VC++60的音频信号采集系统.docx

1、基于VC+60的音频信号采集系统C+课程设计报告课题名称:基于VC+6.0的音频信号采集系统 课程名称 C+程序课程 指导教师 班 级 学 号 学生姓名 完成日期 基于VC+6.0的音频采集系统【摘 要】 本课程设计将实现一个音频采集的录音系统。其不仅实现了录音的功能,同时可以播放录音。整个系统利用MFC进行框架设计,同时利用消息响应机制对窗口的消息进行处理。整个系统主要分为录音和播放录音,录音时要打开录音设备,准备缓存区,录音完成后可以播放录音,播放时要打开设备播放录音。在实现录音和播放录音的过程中,系统会自动调用程序的消息函数从而对进行相应的操作。【关键词】 MFC框架;消息响应机制;音频

2、采集1、引 言本文详细介绍了声音波形文件的存储格式,以及Windows提供的有关WAVE输入输出的API函数,对VC+中声音波形文件及声卡的编程进行了说明,并给出了一个实现声卡操作的类。1.1课题背景随着多媒体计算机的发展,声卡已经成为标准设备,它为我们提供了一个非常有用的接口,除播放声音之外,还可利用其A/D转换功能进行低速数据采集、甚至通信。在Windows环境下,波形文件的播放和录制可以通过MCI调用很方便的实现,但是它无法做到对原始数据进行操作,难以在如数据采集情况下应用。本文详细介绍了声音波形文件的存储格式,以及Windows提供的有关WAVE输入输出的API函数,对VC+中声音波形

3、文件及声卡的编程进行了说明,并给出了一个实现声卡操作的类。在具体说明软件编程以前,了解一些声卡的硬件原理和音频采样的基本知识是有帮助的。声卡是一个能够完成A/D和D/A转换的设备,录音时,它将输入的模拟的信号进行采样并将其幅度用二进制数值来表示,回放过程与之相反。对声音波形而言,有两个重要的参数:采样频率和量化位数。采样频率表示每秒从模拟信号中取多少个点的数据,根据采样定理,采样频率必须大于原信号最高频率的2倍,因此在采样之前都对模拟信号进行低通滤波,使之满足采样定律。电话的采样频率为8KHz,理论上其频率范围为0-4KHz,CD为48KHz,频率范围为0-24KHz。1.2 课程设计目的在程

4、序设计中,通过设计、编制、调试音频采集的程序,加深对语法及语义分析原理的理解,并实现对命令语句的灵活应用。VC+编程方两种法有,一种是非windows编程,另一种就是windows编程,本系统用到的编程方法就是第二种。面向对象程序设计中关键是如何将问题域中的实体(即日常所见的概念)抽取出来,作为C+程序中的类,而属性与行为作为类的两类要素通常是必不可少的,甚至还应考虑类必须满足的约束。2、需求分析2.1 开发工具介绍C+语言是在C语言的基础上不断发展和完善起来的,而C是吸收了其他语言的一些优点逐步成为实用性很强的一种语言。C+语言主要有如下特点:a)C语言是一种结构化的程序设计语言,语言简洁,

5、使用灵活方便。它既适用于设计和编写大的系统程序,又适用于编写小的控制程序,同样也适用于科学计算器。b)它既有高级语言的特点,又有汇编语言的特点。其运算丰富,除了能提供对数据的算术运算外,还提供了二进制的位运算,并且提供了灵活的数据结构。c)程序的可移植性好,在某一种型号的计算机上开发的用C语言编写的程序,基本上可以不做修改,而可直接移植到其他型号和不同档次的计算机上运行。d)程序的结构不够严密,程序设计的自由度大。这对于比较精通C语言的程序设计者来说,可以更方便的设计出高质量的非常通用的程序。2.2 需求分析本系统要实现一个录音的功能,除了录音的功能,还需要能够播放录音和暂停播放录音,整个系统

6、通过Visual C+6.0实现,需要调用电脑的声卡来完成整个系统。在录音开始阶段通过调用声卡录音,录音完成并保存,最后通过声卡来播放录音。3、设计背景3.1、MFC框架MFC(Microsoft Foundation Classes),是一个微软公司提供的类库(class libraries),以C+类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。MFC 提供了MFC AppWizard 自动生成框架。 3.2 窗体设计及控件资源利用Visual C+提供

7、的资源编辑器对对话框资源进行编辑。删除对话框中默认的”确定”和”取消”按钮。添加Text控件和添加若干按钮控件,其ID如表3-1所示:表3-1 控件资源清单控件名称控件ID用途信息采集IDC_REC_START开始录音计时器IDC_STATIC记录录音时长停止IDC_REC_STOP停止录音播放IDC_PLAY_START播放录音暂停IDC_PLAY_PAUSE暂停播放停止IDC_PLAY_STOP停止播放退出IDC_exit退出窗口3.3、MFC实现框架下图1-1为整体界面的截图:图1-1 界面截图下图1-2为图标界面的截图:图1-2 图标设计截图4、设计概要4.1、设计思路1.设定音频采集

8、参数(采样率、声道等);2.打开音频设备、准备wave数据头和开辟缓存,操作采集的数据并保存录音;3.设定音频回放参数,打开回放设备、准备wave数据头和写wave数据;4.界面框架利用MFC生成。 下图2-1为系统整体架构流程图:图2-1 总体架构设计流程图4.2、Windows波形录入的函数Windows下的音频采集,会用到的函数及类库:1、WaveIn函数簇 (1). WaveInOpen /为录音而打开一个波形输入设备 (2). WaveInPrepareHeader /为波形输入准备一个输入缓冲区 (3). WaveInAddBuffer /向波形输入设备添加一个输入缓冲区 (4).

9、 WaveInStart /启动在指定的波形输入设备的输入 2、WaveOut函数簇 (1). WaveOutOpen /为播放而打开一个波形输出设备 (2). WaveOutPrepareHeader /为播放准备一个波形缓冲区 (3). WaveOutPause /暂停指定波形输出设备上的播放 (4). WaveOutRestart /重新启动一个被暂停的波形输出设备 4.3、系统分析设计一个以Cdialog为基类的CrecordHWndDlg派生类,定义数据成员和成员函数如下:/*数据成员*/HICON m_hIcon; /图标的句柄BOOL bRecording,bPlaying,bR

10、everse,bPaused,bEnding,bTerminating; / bEnding用来判断外部是否按下停止按钮;是则不分配内存,直接返回;DWORD dwDataLength,dwRepetitions;/ dwRepetitions是重复次数 /dwDataLength是一个外部定义的DWORD变量,用来记录数据的长度;HWAVEIN hWaveIn;/输入设备句柄HWAVEOUT hWaveOut;/输出设备句柄PBYTE pBuffer1,pBuffer2,pSaveBuffer,pNewBuffer;/pBuffer1 pBuffer2 保存输入数据的两个缓冲区,/pSave

11、Buffer是外部定义的一个临时缓存PWAVEHDR pWaveHdr1,pWaveHdr2;/两个声音文件头WAVEFORMATEX waveform;/音频格式/*成员函数*/void DrawWave(CDC* pDC,PBYTE pData,DWORD dwLength);/绘制音频波形的函数设计一个以Cdialog为基类的CAboutDlg派生类,该类首先获取系统菜单句柄并对其进行处理,然后对窗口进行初始化等操作。这样之后就可以进入采集音频阶段了。音频采集流程:1.设置两个缓冲区:pBuffer1 pBuffer2 /*最先,我们要分配两个缓冲区.因为数据首先要保存到内存中,两个内存

12、缓存区间可以较快进行切换,可以避免录音有断断续续的现象.*/pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE);pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE);/* 如果只要一个缓冲区,当缓冲区满,保存数据时,会无法保存这段时间采集的语音,导致最后获得的声音断断续续。使用两个缓冲区,当一个缓冲区满的时候,保存这个已满的缓冲区数据,而由另一个缓冲区继续采集语音。*/ 2.设置录音方式:waveformwaveform.wFormatTag=WAVE_FORMAT_PCM;/录音的格式waveform.nChannels=1; /单声道数

13、,数值可为1或2waveform.nSamplesPerSec=40000; /采样率waveform.nAvgBytesPerSec=40000;/是每秒钟的字节数waveform.nBlockAlign=1;/是每个样本的字节数waveform.wBitsPerSample=8;/采样位,模拟信号转数字信号的精准度waveform.cbSize=0;/是附加信息的字节大小3.打开录音设备: waveInOpenwaveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)this-m_hWnd,NULL,CALLBACK_WINDOW)4.为录音设备准备

14、缓存: waveInPrepareHeader/*设备可以打开后,就需要初始化两个输入缓存区的声音文件头了声音文件头主要是在录音时,记录相关的数据,以方便后期的处理.*/waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR);waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR);5.为输入设备增加缓存: waveInAddBufferwaveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR) ;waveInAddBuffer (hWaveIn

15、, pWaveHdr2, sizeof (WAVEHDR) ;6.启动录音: waveInStartwaveInStart (hWaveIn) ;/打开输入设备,开始录音7.清除缓存: waveInUnprepareHeaderwaveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR) ;waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR) ;8.停止录音: waveInResetwaveInReset(hWaveIn); /停止录音,关闭输入设备/waveInRese

16、t 停止给定的波形输入设备的输入,且将当前位置清零.9.关闭录音设备: waveInClosewaveInClose (hWaveIn) ;音频输出流程1.打开输出设备: waveOutOpenwaveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this-m_hWnd,NULL,CALLBACK_WINDOW)2.为输出设备准备缓存: waveOutPrepareHeaderwaveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR) ;3.写数据导输出设备缓存: waveOutWrit

17、ewaveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR) ;/ 写数据导输出设备缓存4.清除输出缓存: waveOutUnprepareHeaderwaveOutUnprepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR) ;5.停止输出: waveOutResetwaveOutReset(hWaveOut);/停止回放,关闭输出设备6.关闭输出设备: waveOutClosewaveOutClose (hWaveOut) ;/waveOutClose 关闭指定的波形输出设备实现声音波形的绘制Dra

18、wWave(CDC *pDC,PBYTE pData,DWORD dwDrawLength)/通过采集的音频进行绘制声音波形退出void CRecordHWndDlg:Onexit() /退出(按钮)4.4、设计重点上面主要概述了采集音频和播放录音的整体流程,在采集音频和播放音频是有几个很重要的消息处理函数,下面主要来解释它们的作用和调用时间.采集音频消息函数:MM_WIM_OPEN /录音设备的打开 MM_WIM_DATA /录音设备数据的采集及操作 MM_WIM_CLOSE /录音设备的关闭采集音频消息函数:MM_WOM_OPEN /录音播放时MM_WOM_DATA /录音暂停时MM_WO

19、M_CLOSE /录音停止时其中,MM_WIM_DATA 函数是本程序的核心。其主要作用是将输入数据另行保存在一缓冲区内(pSave Buffer),该缓冲区的长度将随着已录入数据的大小而增加,从而实现保存输入话音数据的功能。注意:消息处理函数是消息自我驱动的,不需要我们的人为干预。比如:当我们打开设备时,系统会自动调用MM_WIM_OPEN,当我们将数据添加到缓冲区,而缓冲区满时,系统会自动调用MM_WIM_DATA,我们所需要做的,就是对该函数编好相应的源代码。那么消息函数到底是怎么实现的呢?消息响应机制实现: 1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,

20、LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。 2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。 3、未处理的消息到那里

21、去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。 4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。5、系统实现5.1、

22、调试环境测试环境如下: 测试系统: Windows XP 或 Win7测试工具: Visual Studio C+ 6.0 5.2、运行调试下图3-1为采集音频时截图:图3-1采集音频截图通过点击图3-1中信息采集按钮就可以开始采集音频了,同时声音波形也开始绘制,直到停止采集.下图3-2为停止采集音频时的截图:图3-2停止采集音频截图通过点击图3-2停止按钮时,系统停止音频采集同时声音波形的绘制也停止,系统内部会调用相应的消息函数来实现.下图3-3为播放音频时的截图:图3-3播放音频截图通过点击图3-3中播放按钮,可以听到刚才采集音频时录的音,这是通过系统中消息相应机制实现的。6、心得体会6.

23、1、系统改进 虽然这个系统对于基本的音频采集功能能够实现,但是它还存在许多不足之处,比如:1.设计界面过于简洁,不够美观;2.录音后必须手动存储,只能回放当前录音;3.录音中存在杂音较严重的问题;没有调节音量大小功能等所以后期我还要对系统进行更进一步的升级,使其尽可能满足各方面的需求。6.2、总结两周的课程设计很快就结束了,通过这次C+课程设计,我学到了很多课程之外的C+知识,其中利用MFC框架设计界面非常方便,也很快捷,还有消息相应机制是怎么实现的等。实践出真知,之前我的C+知识只是停留在理论水平,而且就算理论水平,也存在很多漏洞。有时,在做课题的时候,理论的漏洞冒了出来,我就只能在看着课本

24、慢慢的再学习一遍,因为当时有些东西就没有搞懂,所以现在就又翻出课本,看着课本编程,也算是将旧的东西复习了一遍。同时,有的理论在实习操作过程中印象更加深刻。成功=勤奋+合作。我暂且将我的课程设计成果用成功来代替,虽然离成功差的还很远。开始时我笨拙的读着老师给的相关的程序,发现有什么不懂得,先是一个人自主的思考,实在解决不了的就和其他同学讨论,有时别的同学会很清晰的给我说明一些课题的思路,但大多数,其他同学也不懂、或者也在这方面存在疑问,于是,大家发表各自的看法、思路,然后就讨论了起来,最后,在大家的共同努力之下,问题的答案逐渐浮出水面。交流与合作在实习过程中给我很大的帮助,我得到了很多,每次看到

25、解决一道问题后大家的愉悦,我想大家应该与我一样收获很大吧。说真的,我挺喜欢这种讨论的氛围,它也让实习过程变得趣味横生,不再只是呆滞的盯着屏幕写程序。本次课程设计的缺陷,对我来说就是,所有程序的原始数据都来自老师给的数据或者是网上的数据,跟其他同学会有所重复,但所幸代码能够读懂。这次实习总体来说,每天我的过的挺累,但累是值得的,这个值得不仅仅是课题成果上,更重要的让我成长好多,也许这就是我在这短短的十天左右的时间里最好的回报吧。最后,真心感激跟我一起完成课题的同学们和耐心指导我们的惠老师,我会在以后的路上更加努力!7、参考文献1 刘锐宁,梁水等编.Visual C+ 开发实例1200例.清华大学

26、出版社. 2011.12 侯俊杰编.深入浅出MFC.华中科技大学出版社. 2001.13 爬罗塞斯等编.MFC Windows程序设计. 清华大学出版社. 2007.54 佩措尔德等编.方敏,张胜等译.Windows程序设计. 清华大学出版社. 2010.95 陈哲,魏衍君编.Visual C+ 程序设计. 西北工业大学出版社. 2009.28、附录部分核心代码:void CRecordHWndDlg:OnRecStart() /开始录音准备(信号采集按钮) / TODO: Add your control notification handler code here /allocate bu

27、ffer memory /*最先,我们要分配两个缓冲区.因为数据首先要保存到内存中, 两个内存缓存区间可以较快进行切换,可以避免录音有断断续续的现象.*/ /如果只要一个缓冲区,当缓冲区满,保存数据时,会无法保存这段时间采集的语音,导致最后获得的声音断断续续。 /使用两个缓冲区,当一个缓冲区满的时候,保存这个已满的缓冲区数据,而由另一个缓冲区继续采集语音。 pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE); pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE); if (!pBuffer1 | !pBuffer2) if (pBuffer

28、1) free(pBuffer1); if (pBuffer2) free(pBuffer2); MessageBeep(MB_ICONEXCLAMATION); AfxMessageBox(Memory erro!); return ; /*接下来需要设置录音的方式,需要用到WAVEFORMATEX结构.声道数, 采样位和采样率都可以在这结构中设置.*/ waveform.wFormatTag=WAVE_FORMAT_PCM;/录音的格式 waveform.nChannels=1; /单声道数,数值可为1或2 waveform.nSamplesPerSec=40000; /采样率,每秒采集次

29、数,数值有:11025,22050,44100 waveform.nAvgBytesPerSec=40000;/是每秒钟的字节数 waveform.nBlockAlign=1;/是每个样本的字节数 waveform.wBitsPerSample=8;/采样位,模拟信号转数字信号的精准度,数值有:8,16 waveform.cbSize=0;/是附加信息的字节大小 方式为WAVE_FORMAT_PCM时此参数可以忽略 /open waveform audo for input /设置完毕之后,就可以用waveInOpen函数打开输入设备. if (waveInOpen(&hWaveIn,WAVE

30、_MAPPER,&waveform,(DWORD)this-m_hWnd,NULL,CALLBACK_WINDOW) free(pBuffer1); free(pBuffer2); MessageBeep(MB_ICONEXCLAMATION); AfxMessageBox(Audio can not be open!); /*设备可以打开后,就需要初始化两个输入缓存区的声音文件头了 声音文件头主要是在录音时,记录相关的数据,以方便后期的处理.*/* 第一个缓冲区 */ pWaveHdr1-lpData=(LPTSTR)pBuffer1;/第一个缓冲区地址 pWaveHdr1-dwBufferLength=INP_BUFFER_SIZE; /缓冲区长度 pWaveHdr1-dwBytesRecorded=0;/是已录音数据大小 pWaveHdr1-dwUser=0;/是用户数据 pWaveHdr1-dwFlags=0;/是控制标志表

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1