实验四 声音录制程序实现 实验指导.pdf
上传人:qw****27 上传时间:2024-09-12 格式:PDF 页数:12 大小:1.3MB 金币:15 举报 版权申诉
预览加载中,请您耐心等待几秒...

实验四 声音录制程序实现 实验指导.pdf

实验四声音录制程序实现实验指导.pdf

预览

免费试读已结束,剩余 2 页请下载文档后查看

15 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

实验四声音录制程序实现实验指导第一部分如何利用DirectSound实现声卡录音如何利用DirectSound对经过声卡和麦克风的数据进行捕获,进行录音,并保存为wave格式的文件。一、使用到的DirectSound主要对象DirectSound录音用到的三个非常重要的对象:1、IDirectSoundCapture8,设备对象,根据你录音的设备创建的设备对象,利用该对象可以获取设备的属性。2、IDirectSoundCaptureBuffer8,缓冲区对象,该对象由设备对象创建,主要用来操作音频数据。3、IDirectSoundNotify8,事件通知对象,该对象用来通知应用程序从缓冲区中将数据取走,写入文件保存起来。二、利用DirectSound录音的主要思路先根据选择的录音设备创建设备对象,然后通过设备对象创建辅助缓冲区对象,开始录音的时候,设备将数据写入缓冲区,应用程序主动的从缓冲区将数据读出来写文件即可,就实现了录音功能。这里简单介绍一下dsound的通知功能,应用程序会创建一个通知对象,然后将通知对象邦定,再设定通知位置(position),什么是通知位置,比如缓冲区的大小为4000字节,如果你想当数据达到缓冲区一半的时候能得到通知开始copy数据,那么此时你就可以将通知位置设定为2000,通知位置可以任意的设定,当缓冲区的数据达到你设定的位置时,就会通知应用程序将缓冲区的数据copy到文件中,缓冲区是循环利用的,当缓冲区填充满了以后,就会从头开始充填数据,所以,缓冲区就是一边读,一边写的过程。三、录音的主要步骤1、枚举录音的设备2、根据选择的设备创建设备对象3、利用设备对象创建缓冲区对象4、设置通知机制5、创建工作线程,用来将缓冲区的数据写入文件。四、用到的数据定义LPDIRECTSOUNDCAPTURE8g_pDSCapture=NULL;//设备对象指针LPDIRECTSOUNDCAPTUREBUFFERg_pDSBCapture=NULL;//缓冲区对象指针LPDIRECTSOUNDNOTIFY8g_pDSNotify=NULL;//用来设置通知的对象接口GUIDg_guidCaptureDevice=GUID_NULL;//设备idBOOLg_bRecording=FALSE;//是否正在录音WAVEFORMATEXg_wfxInput;//输入的音频格式DSBPOSITIONNOTIFYg_aPosNotify[NUM_REC_NOTIFICATIONS+1];//设置通知标志的数组HANDLEg_hNotificationEvent;//通知事件BOOLg_abInputFormatSupported[20];DWORDg_dwCaptureBufferSize;//录音用缓冲区的大小DWORDg_dwNextCaptureOffset;//偏移位置DWORDg_dwNotifySize;//通知位置CWaveFile*g_pWaveFile;//五、使用DirectSound录音的关键步骤详细描述1、枚举录音的设备如果程序只是想从用户缺省的设备上进行声音的录制,那么就没有必要来枚举出系统中的所有录音的设备,当你调用DirectSoundCaptureCreate8或者另外一个函数DirectSoundFullDuplexCreate8的时候,其实就默认指定了一个缺省的录音设备。当然,在下面的情况下,你就必须要枚举系统中所有的设备,例如,你的应用程序并不支持所有的输出设备,或者你的应用程需要两个或者多个设备,或者你希望用户自己来选择输出设备。枚举设备,你首先要定义一个回调函数,这个回调函数可以被系统中的每个设备来调用,你可以在各函数做任何事情,这个函数的命名也没有任何的限制,但是函数应该以DSEnumCallback为原型,如果枚举没有结束,这个回调函数就返回TRUE,如果枚举结束,例如你找到合适的设备,这个函数就要返回FALSE。下面是回调函数的一个例子,这个函数将枚举的每一个设备都添加到一个combox中,将设备的GUID保存到一个item中,这个函数的前三个参数由设备的驱动程序提供,第四个参数有DirectSoundCaptureEnumerate函数提供,这个参数可以是任意的32位值,这个例子里是combox的句柄,BOOLCALLBACKDSEnumProc(LPGUIDlpGUID,LPCTSTRlpszDesc,LPCTSTRlpszDrvName,LPVOIDlpContext){HWND