基于vc.net 2003 的声音信号采集与分析处理

上传人:wm****3 文档编号:47187391 上传时间:2018-06-30 格式:PDF 页数:6 大小:328.77KB
返回 下载 相关 举报
基于vc.net 2003 的声音信号采集与分析处理_第1页
第1页 / 共6页
基于vc.net 2003 的声音信号采集与分析处理_第2页
第2页 / 共6页
基于vc.net 2003 的声音信号采集与分析处理_第3页
第3页 / 共6页
基于vc.net 2003 的声音信号采集与分析处理_第4页
第4页 / 共6页
基于vc.net 2003 的声音信号采集与分析处理_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《基于vc.net 2003 的声音信号采集与分析处理》由会员分享,可在线阅读,更多相关《基于vc.net 2003 的声音信号采集与分析处理(6页珍藏版)》请在金锄头文库上搜索。

1、http:/ - 1 - 基于基于VC.Net 2003 的声音信号采集与分析处理的声音信号采集与分析处理 叶峰 河海大学电气学院,南京(210098) E-mail:Yefeng_ 摘摘 要:要: 本文讨论在 VC.Net 环境下利用低层音频服务 API 函数基于多线程程序设计方法实现 一种基于计算机普通声卡的数据采集系统, 可以实时显示采样信号的波形,本文介绍了利用 VC + 实现声音信号的采集与分析处理过程,并结合实例程序进行分析说明。 关键词:关键词:VC.NET;声音信号采集;频谱分析;声卡;低层音频服务 API 函数;实时 1 引言引言 硬件方面,数据采集系统是指将特定的物理信号真

2、实的记录,一般基于计算机的数据采集系统包括传感器、信号调理器、数据采集卡和控制软件等。其中数据采集卡是核心部件,但其价格昂贵。 而一般计算机配备的16位精度,44.1kHz采样频率的声卡本身就是一块性价就比较高的数据采集转换卡。声卡处理信号的上限频率理论上达到了22kHz左右,对于大部分低频电路的采样分析已经满足性能要求。 软件方面, 采用 VC.NET 多线程程序设计方法, 使单 CPU 系统似乎能够同时执行不同的线程,对于多 CPU 系统,操作系统就会将不同的线程交给不同的 CPU 进行处理,真正的实现同时处理,无论对于单 CPU、多 CPU 来说,多线程程序设计提高了应用程序的执行以及响

3、应速度,这对于进行实时采集声音具有重要的意义。本文中在声音信号采集与分析处理过程中采用在主线程中连续采集声音信号,在工作者线程中对采集的数据进行处理操作。 2 声音信号的采集声音信号的采集 在采样过程中, 为避免出现混叠现象,根据奈奎斯特采样定理,必须使 Ws 2Wr ,其中Ws 为采样频率, Wr为信号的最高频率。 由于各种客观因素的影响,采集到的信号中不可避免的混有噪声,因此,在对信号分析之前,需要进行一些处理,减小噪声对有用信号的干扰,提高信号的信噪比。由于外界干扰、仪器故障等原因,有时会出现异常数据,一般剔除方法是基于正态分布的肖维涅(W.Chauvennent) 法。在信号分析中,常

4、常会存在一些高频噪声成分,这就是说,在信号分析时应首先对信号进行滤波,分离出我们感兴趣的频段。 3 声音信号采集的软件实现声音信号采集的软件实现 在Windows 环境下,对波形音频设备进行处理有3 种方法,高层音频服务的MCI 函数、DirectX 的音频服务技术、低层音频服务API 函数5。 MCI 提供了一组与设备无关的控制命令,使用简便,灵活性较差,在录音的过程中不能直接访问内存中的采样数据,难以满足实时性要求。DirectSound 是DirectX 的声音组件,DirectX 具有DOS 的直接硬件访问特性,同时又具有硬件独立性,避免了添加新硬件时的硬件识别问题,另外,Direct

5、X具有利用硬件加速的能力,不需要写任何专用代码,就能自动地实现硬件加速。 低层音频API函数可直接与声卡驱动程序进行通信,提供了对声卡直接灵活操作,因此本文使用低层音频API 函数进行采集软件的设计。 http:/ - 2 - 3. 1 波形音频文件的格式波形音频文件的格式 图1 波形音频文件的存储格式 资源交互文件(RIFF)是面向部分(Chunk)的,如图1,一个RIFF文件是由一个或多个部分组成的,其中每一个部分指向下一个部分,每一个部分都有一个类型,后面跟随一些数据。波形音频文件为RIFF文件(资源交互文件格式)文件的一种,一个基本的波形文件的实际结构是一个WAVE部分,包括fmt部分

6、和data部分。 FMT 部分的结构声明如下: typedef struct WORD wFormatTag; /格式标识,这里是 WAVE_FORMAT_PCM WORD nChannels; /通道数,单声道为1 ,双声道为2 WORD nSamplesPerSec; /采样频率,常用的采样频率为8.0 kHz, 11.025 kHz, 22.05 kHz, 44.1 kHz. WORD nAvgBytesPerSec;/音频的每秒字节数,对于格式为WAVE_FORMAT_PCM /其值是 nBlockAlign * nSamplesPerSec WORD nBlockAlign; /一个

7、采样所占据数据块的最小字节数,对于格式为WAVE_FORMAT_PCM /其值是WBitsPerSample* nChannels / 8 WORD wBitsPerSample; /表示量化的比特数,通常为8 或 16 WORD cbSize; /对于WAVE_FORMAT_PCM,其为0 WAVEFORMATEX; 从波形文件中读出、写入信息需要使用多媒体I/O函数1,这些函数都具有前缀mmio,可以通过查阅2MSDN得到这些函数的具体使用。 3. 2 实现声音信号采集类的实现实现声音信号采集类的实现 为了能够实现复用,便于维护升级以及扩充函数,采用面向对象的编程的方法,将音频的具体操作放

8、入一个固定的CWAVE类中,主要参数和函数定义如下: class CWave HWAVEIN hWaveIn; /指向打开的输入波形音频设备的的句柄 HWAVEOUT hWaveOut; WAVEFORMATEX waveForm; /定义波形音频的数据格式 HANDLE hData; / allocate memory for Play function HANDLE hWaveHdr; HANDLE hBuffer0, hBuffer1, hWaveHdr0, hWaveHdr1 ;/ allocate memory for Record function public: http:/ -

9、 3 - BOOL GetDeviceCapacity(void); / 获得音频输入设备的属性 BOOL Record(HWND pHwnd); / 录音程序段,pHwnd 为指定传递消息的父窗口的句柄 BOOL Play(HWND pHwnd, LPCSTR path); /播放程序段,path 为文件路径 BOOL Play(HWND pHwnd); /播放内存中的音频程序段 BOOL Stop(void); BOOL Pause(void); / 显示错误信息 void ErrorWaveInMsg(MMRESULT dwError); void ErrorWaveOutMsg(MMR

10、ESULT dwError); BOOL SaveStream(LPTSTR path ,LPSTR data_Chunk, DWORD length_Chunk); /将数据块转存到硬盘 ; 这里仅列出录音程序段主要内容,在此函数中采用双缓冲区循环技术,保证实现声音信号采集不丢失。 BOOL CWave:Record(HWND pHwnd) /定义局部变量,设置录音格式,如同上面介绍的FMT部分的结构, waveForm.wFormatTag = WAVE_FORMAT_PCM; /打开波形音频设备 mmResult= waveInOpen(LPHWAVEIN) /分配第一块缓存及波形数据头

11、WAVEHDR分配、锁定内存 hBuffer0 = GlobalAlloc( GMEM_MOVEABLE ,BUFFER_SIZE); lpBuffer0 = (HPSTR)GlobalLock(hBuffer0); /省略部分为检测程序部分 hWaveHdr0 = (LPWAVEHDR)GlobalAlloc(GMEM_MOVEABLE, (long)sizeof(WAVEHDR); waveHdrFst = (LPWAVEHDR)GlobalLock(hWaveHdr0); waveHdrFst-lpData = lpBuffer0; waveHdrFst-dwBufferLength =

12、 BUFFER_SIZE; waveHdrFst-dwBytesRecorded = 0l; waveHdrFst-dwFlags = 0l; mmResult = waveInPrepareHeader(hWaveIn,waveHdrFst,sizeof(WAVEHDR); mmResult = waveInAddBuffer(hWaveIn,waveHdrFst,sizeof(WAVEHDR); /同上面的过程分配第二块缓存 mmResult = waveInStart(hWaveIn); /启动录音设备 3. 3 输入缓冲区的分配和管理 输入缓冲区的分配和管理 从上面的录音程序可以看出其

13、简单流程,在开始采集前, GlobalAlloc 函数申请两块较小的内存空间,并获取内存对象的句柄,然后锁定内存,并为每一块缓冲区填写相应的缓冲区头结构体WAVEHDR。接着调用waveInPrepareHeader 函数准备缓冲区,它会对数据缓冲区作Page Lock 操作,以保证缓冲区不会被置换到硬盘中, 使采集工作更加流畅。最后调用waveInAddBuffer 函数把两块缓冲区全部传递给声卡驱动程序。添加好输入缓冲区后,直接调用waveInStart 函数就可以开始数据采集。 3. 4 消息的处理 消息的处理 在录音或播放时,主线程可以捕捉到从CWave类发出的六类消息,主要有二条(见

14、表1),在MFC主框架下简单重写函数WindowProc(UINT message, WPARAM wParam, LPARAM lParam),捕捉具体消息。如在录音程序中,当一块缓冲区录满时,驱动程序就会向相应的窗口发送MM_WIM_DATA 消息,同时自动使用另一块缓冲区来保存新采集的数据。这时,在主线程中,http:/ - 4 - 主要将缓冲区的内容转移到一段公共内存中,然后将缓冲区清零,然后再把该缓冲区重新传递给驱动程序,在辅助线程中就显示和保存已录制设定一定长度的数据。如此循环交替,使得声卡驱动程序在任何时候都至少有一个缓冲区可用。 表1 引用消息说明 消息 函数说明 MM_WIM

15、_DATA 缓冲区满或者在调用waveInReset函数后发出 MM_WOM_DONE 缓冲区的数据播放完毕或者调用waveOutReset函数后发出此消息 3. 5 波形的显示波形的显示 每当一个输入缓冲区存满数据后,采用调用线程的办法实现波形的显示,并采用双缓冲技术消除闪屏现象,即只需绘图时使用GDI绘制到内存上,最用使用一次BitBlt 函数快速调用。 波形显示时应注意下面几个问题:1) A/D 转化后的数据是PCM 格式,即:若用8位量化,则对应着8位无符号数,若用16位量化,则表示为有符号数的补码形式。 2) 若用双通道采集,先存储左声道的一个采样点,然后再存储右声道的一个采样点。3)声卡采样数据是无量纲的,显示时需要采用对应的工程单位对信号幅度进行标定。4)由于线程处理的数据块始终滞后,所以在最后录音结束后,使用WaitForSingleObject函数等待线程调用结束后才能释放内存,其次由于主线程与辅助线程公用一段内存,所以要注意在读写内存时互斥信号量的设置。 4 声音信号的分析与处理声音信号的分析与处理 4. 1 设计滤波器设计滤波器 在采集得到的声音信号中,有些信号是研究中不需要的,通过滤波器3对所采集的声音信号进行滤波,以提高研究的精确性与针对性。 滤波器可分为两大类,即经典滤波器和现代滤波器。经典滤波器是假定输入信号x ( n) 中的有用成

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号