社区
Delphi
帖子详情
请教高手一个难题!如何采集声卡信号???
zcroot
2003-08-29 03:48:30
通过麦克风说话以后,希望将声音的波形采集到,进行频普分析,比如说把波形中UM71的信号取出来,用DELPHI如何采集???
...全文
413
16
打赏
收藏
请教高手一个难题!如何采集声卡信号???
通过麦克风说话以后,希望将声音的波形采集到,进行频普分析,比如说把波形中UM71的信号取出来,用DELPHI如何采集???
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
16 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
zcroot
2003-09-05
打赏
举报
回复
1. 打开波形输入设备。函数waveInOpen用于打开波形输入设备,其原型如下:
① WORD waveInOpen(lphWaveIn,wDeviceID,lpFormat,dwCallback,dwCallbackInstan
ce, dwFlags)
LPHWaveIn: lphWaveIn 该变量用来接收波形输入设备的句柄,该句柄应当保存下来,因为
其他的波形输入函数还会用到它.
②WORD wDeviceID 该变量用来指明波形输入设备的标记号.当PC中有多块声卡(准确地说
是波形输入设备)时,操作系统会为每一块声卡分配一个标记号.可以用waveInGetNumDev
s函数来得到能够作为波形输入设备的数目N,则wDeviceID的取值范围为0~N-1.如果想得
到没个标记号所对应的录音性能,可以使用函数waveInGetDevCaps.若把wDeviceID设为W
AVE_MAPPER(即-1),则系统会自动选择一符合要求的设备(根据lpFormat的要求).
③lpFormat是一个指向PCMWAVEFORMAT数据结构的指针,应当在这个数据结构中指明所期
望的采样模式,这个数据结构的定义是这样的:
Typedef structure pcmwaveformat_tag {
WAVEFORMAT wf; //有关PCM格式设置的另外一种数据结构
WORD wBitsPerSample; //量化位数
}PCMWAVEFORMAT;
Typedef structure waveformat_tag {
WORD wFormatTag; //采样数据格式,目前只能用PCM格式
WORD nChannels; //通道数目(1或2)
DWORD nSamplesPerSec; //采样速率
DWORD nAvgBytesPerSec;//每秒采样得到的数据
WORD nBlockAlign; //记录区块对齐的单位。此值为nChannels*wBitsPerSample/8
}WAVEFORMAT;
④ DWORD dwCallback.定义回调函数的地址或回调窗口的句柄。回调函数的地址或回调
窗口用来处理波形
输入设备产生的消息。
⑤DWORD dwCallbackInstance。这是一个用户自定义的数据,该数据会一并传给回调函
数(或窗口)。
⑥DWORD dwFlags。定义打开波形输入设备的标记。
CALLBACK_WINDOW 定义dwCallback为窗口句柄。
CALLBACK_FUNCTION 定义dwCallback为函数地址。
另外还可以在此指定:
WAVE_FORMAT_QUERY 只查询波形输入设备是否支持给定格式而不真的打开波形输
入设备。
WAVE_ALLOWSYNC 同步方式开启波形输入设备,录音工作在后台进行。
下面一段Delphi程序说明了打开波形输入设备的过程:
type
TRecorder = class
private
…
FWaveFmt : TWaveFormatEx;//Delphi中,WAVEFORMAT和PCMWAVEFORMAT合为TwaveFor
matEx。
WaveHandle : HWaveIn;
WaveHdr1 : PWAVEHDR; //数据缓冲区头结构的指针 (见下文)
WaveBuffer1 : lpstr; //数据缓冲区的指针 (见下文)
procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2 : DWORD); stdcall;
…
end;
…
Recorder:=TRecorder.Create;
…
Recorder.FWaveFmt.wFormatTag:=WAVE_FORMAT_PCM;
Recorder.FWaveFmt.wBitsPerSample:=16;
Recorder.FWaveFmt.nSamplesPerSec:=11025;
Recorder.FWaveFmt.nAvgBytesPerSec:=22050;
Recorder.FWaveFmt.nBlockAlign:=2;
WaveInOpen(@Recorder.WaveHandle,Wave_Mapper,mailto:@Recorder.FWaveFmt,
DWORD(@TRecorder.CallBack),DWORD(@Recorder),CALLBACK_FUNCTION + WAVE_ALLOW
SYNC);
…
2. 为采样数据分配缓冲空间
在Windows环境,可以用GlobalAllocPtr来获取一段内存空间,但是由于Windows操作
系统采用了虚拟存储管理机制,这块内存空间随时有可能会被置换到硬盘上,读写硬盘
所耗费的时间会造成采样的不连续。因此,在将缓冲区送往波形输入设备之前,必须调
用WaveInPrepareHeader函数以保证缓冲区不会被置换到硬盘上。当然在用GlobalFreeP
tr来释放缓冲区之前,必须先要用WaveInUnprepareHeader函数来解除这种保护。
下面几行Delphi语句说明了使用录音缓冲区的过程。
…
Recorder.WaveHdr1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(WAVEHDR));
Recorder.WaveBuffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,1024);
Recorder.WaveHdr1.lpData := Recorder.WaveBuffer1;
Recorder.WaveHdr1.dwBufferLength:=1024;
WaveInPrepareHeader(Recorder.WaveHandle, Recorder.WaveHdr1, sizeof(WAVEHDR
));
WaveInAddBuffer(Recorder.WaveHandle, Recorder.WaveHdr1, sizeof(WAVEHDR));
…
WaveInUnprepareHeader(Recorder.WaveHandle, Recorder.WaveHdr1, sizeof(TWAVE
HDR));
GlobalFreePtr(Recorder.WaveBuffer1);
…
但是,如果只为波形输入设备开辟一个缓冲区,则当该缓冲区被采样数据填满后,波
形输入设备就无缓冲区可用,不得不停止采样,从而造成了采样的断续。所以在实际应
用中,至少要为波形输入设备准备两个缓冲区,用上述方法同时送给波形输入设备。
3. 启动波形输入设备
当上述一切都准备好后,用WaveInStart启动波形输入设备,即可开始进行数据采集,
在采集的过程中,一旦有缓冲区被采样数据填满,系统就回调WaveInOpen中指定的dwCa
llback函数(或向指定的窗口发送消息)。在Delphi4.0中,回调函数的格式是这样的:
procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2 : DWORD); stdcall;
其中uMsg是Windows的消息标记号,有三种情况:
MM_WIM_OPEN 表示波形输入设备开启成功
MM_WIM_DATA 表示一个缓冲区已满。此时dwParam1中携带有数据缓冲区头结的
指针。正是通过这个指针,才可以随机地访问缓冲区中的每一个采样数据。如下面
程序所示:
…
procedure TRecorder.CallBack(uMsg,dwInstance,dwParam1,dwParam2 : DWORD); st
dcall;
var i:Integer;
SPByte : ^Byte; //假设在打开设备时采用8位量化
SingleData : Integer;
BEGIN
case uMsg of //uMsg是Windows的消息标记号
MM_WIM_OPEN : //波形输入设备开启成功发回的消息
…
MM_WIM_DATA : //一个缓冲区已满发回的消息
begin
SPByte := Pointer(dwParam1);
for i :=0 to Recorder.DataLength-1 do
begin
SingleData := SPByte^; //通过SPByte来访问缓冲区中的数据
…
Inc(SPByte);
end;
end;
MM_WIM_CLOSE : //波形输入设备关闭成功发回的消息
…
end;
END;
…
MM_WIM_CLOSE 表示波形输入设备关闭成功。当波形输入设备关闭后,别忘了用Wave
InPrepareHeader和GlobalFreePtr来释放缓冲区内存。
4. 关闭语音输入设备
waveInStop(hWaveIn) 停止语音输入
waveInReset(hWaveIn) 重置语音输入设备
waveInClose(hWaveIn) 关闭语音输入设备。其中hWaveIn是WaveInOpen得到的设备句
柄。
在关闭语音输入设备前,必须重置语音输入设备,否则系统会出现这样的错误提示:
"MMSYSTEM033 媒体数据仍在播放中,请重置设备或等到数据播放完毕"。但是只有当一
个缓冲区填满数据后,才能重置语音输入设备
以上波形输入函数,若调用成功则返回0;否则返回非0,此时可以用waveInGetError
Text函数来得到出错信息,这样做的目的是方便调试。
三、必须注意的几点
以上阐述了作为A/D卡的声卡编程技术,但是还必须注意以下几点
1. 声卡的采样频率并不只限于11025Hz,22050Hz,44100 Hz三种,大多数声卡的采样
频率在一定的范围内是可调的(当然会存在一定的偏差)。有的声卡的最高采样频率可
达200K Hz(有可能随不同品牌而异)。
2. 缓冲区不能设得太小,否则也会造成采样的不连续。在作者的声卡上,若采用16为
量化,22050Hz的采样速率,缓冲区设为1K字节,理论上每秒钟可以得到22050*2个字节
的数据,实际上每秒钟只能得到大约16000*2个字节的数据。若缓冲区设为2K字节,则与
理论值一致。
3. A/D转化后的数据格式是PCM格式,即:若是8位量化,对应着8位无符号数据,0对应
着负满幅值,128对应着零电平,255对应着正满幅值;若是16位量化,对应着16位有符
号数据,-32768对应着负满幅值,0对应着零电平,32767对应着正满幅值。编程过程中
应注意所声明的数据类型是否与之相符合,比如在Delphi4.0中,8位无符号数据对应着
Byte型数据,16位有符号数据对应着SmallInt型数据。
4. 由于声卡的输入端往往带有隔直电容,所以不能用声卡直接对直流量进行采集。解
决的办法就是将这个隔直电容短接。
5. 同样地,利用windows的API函数和声卡的D/A功能也可以使声卡产生模拟音频信号输
出。
zcroot
2003-09-05
打赏
举报
回复
贴:
一、特点
声卡作为语音信号与计算机的接口卡件,其最基本的一项功能就是A/D转换。实际上,
除了语音外,很多信号的频率都落在音频范围内(比如机械量信号,过程量信号等),
当我们需要对这些信号进行采集时,使用声卡作为采集卡是一种相当令人满意的解决方
案,其理由如下:
1. 价格便宜。一般声卡的价格才一百多元,比起自己从头到尾开发一块采集卡的成本
低 得多。比起目前市场上的采集卡的价格,更是不可同日而语。相应地,产品成本也会
降低。
2. 即买即用。完全省略了A/D卡的的硬件开发过程,很大程度上缩短了产品的开发周期
。
3. 灵活性好。量化位数可编程(8位或16位);采样频率可编程(一般声卡的最高采样
频率可达200KHz,并且连续可调);采样通道可编程(1通道或2通道);由于可以使用
在Windows操作系统下,可以用通用的软件开发工具对其进行开发(如Delphi,VB,VC等
)。
当然也有其局限性,那就是声卡一般只能作为PC插卡用在PC机上,很难用微控制器对
其进行控制(因为要用到中断和DMA技术),因而很难用在小型的仪器仪表里。再者由于
声卡是专门针对音频信号而设计的,所以它的采样速率不可能很高。
二、编程技术
既然声卡本身就是一块很好的A/D卡,硬件部分已经不需操心了,那么最终的问题就是
怎样对其编程才能够取得A/D的数据。
事实上,声卡是PC的一种多媒体设备,所以可以用Windows 的MCI(Media Control I
nterface)命令来控制声卡。MCI它提供了一组与设备无关的控制命令,是一种访问多媒
体设备的高层次方法。也正因为它属于一种高层次方法,所以它提供给程序员的灵活性
有限,利用MCI命令来控制声卡录音时,程序员不能在录音的过程中访问内存中的采样数
据,只有在录音完成后通过访问*.WAV文件才可以得到采样数据,尽管最终还是得到了采
样数据,但是这样做一方面嫌其麻烦,更重要的是存取文件需要耗费时间,声卡在采样
的过程中有可能会停止下来等待文件操作,造成了采样的断续。在一些实时性要求比较
高的场合(比如波形分析,实时控制等),断续的采样明显是不行的。
Windows的低级波形音频函数提供了对声卡的最大灵活性的操作,它允许在采样过程中
随机地访问内存中的每个采样数据,完全可以克服使用MCI命令所遇到的实时性问题。
Windows以动态连接库Mmsystem.dll的形式提供低级波形音频函数,在Mmsystem.dll中
总共包括了以下几个有关波形录入的函数:
waveInAddBuffer :向声音输入设备发送缓冲区 ;waveInClose :关闭声音输入设
备
waveInGetDevCaps:获取声音输入设备性能; waveInGetErrorText:获取声音出错
信息文本
waveInGetID :获取声音输入设备ID; waveInGetNumDevs:返回声音输入设备
数量
waveInGetPosition :获取声音设备输入位置; waveInMessage :向声音输入设
备发送信息
waveInOpen :打开声音输入设备; waveInPrepareHeader:预备声音输入缓
冲区
waveInReset :停止声音输入设备工作; waveInStart :停止声音输
入设备工作
waveInStop :停止声音输入; waveInUnprepareHeader : 清除预备的声音
文件头
需要说明的是:不同的编程工具多会含有对这些低级波形音频函数进行说明的头文件
(比如在Delphi4.0中,对Mmsystem.dll说明的文件是Mmsystem.pas),所以在不同的编
程工具中调用这些函数时有可能会使用不同的名称。
与使用其他设备一样,要想用波形音频函数来控制声卡,必须要经过以下的步骤:
tong_jin
2003-09-05
打赏
举报
回复
zcroot(僵尸) 为什么不贴出来??
zcroot
2003-09-05
打赏
举报
回复
SOFTWATER(软水) ,感谢你,我给你发了一篇文章,有关如何采集PCI声卡数据的,有空了可以看看
SOFTWATER
2003-09-05
打赏
举报
回复
zcroot(僵尸) ,不好意思,前天我给你发的是C++BULDER 的控件,不过能解压啊,网上有delphi那方面的,你可以搜一下"音频采集控件",就能搜到了@
zcroot
2003-09-04
打赏
举报
回复
楼上的,你昨天给我发的控件我解压缩不开,能不能在给我发一个,你知道不知道有没有哪个函数可以采集PCI声卡的信号?
zcroot
2003-09-03
打赏
举报
回复
谢谢,我的信箱是:zcroot@sina.com
SOFTWATER
2003-09-03
打赏
举报
回复
我也有控件 ,我会发给你的,共同学习,共同进步!
zcroot
2003-09-03
打赏
举报
回复
郁闷!我等了2天了,再up一下
我的email是:zcroot@sina.com
楼上的,感谢你
rwdx
2003-09-03
打赏
举报
回复
留下email,我给你发一个控件
zcroot
2003-09-03
打赏
举报
回复
郁闷!我等了2天了,再up一下
hexenzhou
2003-09-02
打赏
举报
回复
可以使用MMTools控件包,其提供了大量可以显示声音波形的控件。
e5022
2003-09-02
打赏
举报
回复
up
hawk_js
2003-09-02
打赏
举报
回复
边学习,边UP
zcroot
2003-09-02
打赏
举报
回复
楼上的,能不能说的详细一点,我现在主要是想把声音的频率采集过来,如何能够同pci声卡通讯?windows 自带的录音机是如何把波采集到的,用什么函数可以同pci声卡通讯?
zcroot
2003-08-29
打赏
举报
回复
up
v8
声卡
调音软件_V8
声卡
的福音! V8
声卡
用什么机架VST插件
声卡
调试?
原标题:V8
声卡
的福音! V8
声卡
用什么机架VST插件
声卡
调试?V8
声卡
是一款非常流行的亲民
声卡
, 那么怎么用VST插件机架调试出好效果呢?变声?喊麦?主持?唱歌?我们来试试吧.V8
声卡
V8
声卡
本身的功能也不少,但是很多小伙伴想调出更多更好的效果怎么办呢?今天为大家介绍一款
声卡
调试调音神器:爱调音软件 铛铛铛当!就是上面这款神器啦, [爱调音]软件.这是小编最近发现的最神奇的软件啦.下载这个软件...
虚拟服务器
声卡
,什么是虚拟
声卡
?虚拟
声卡
可以当
声卡
使用吗?
大家都知道,电脑上一般都会安装
声卡
,但是有些设备无需安装,比如说服务器主板,一般就不会去安装
声卡
。但是万一我们在使用的时候,可能会用到怎么办,所以在这种情况下,我们会采用虚拟
声卡
。但是很多人对这方面可能不太了解,那么什么是虚拟
声卡
?小编给大家做个普及。什么是虚拟
声卡
?什么是虚拟
声卡
?说的简单一点,那就是在没有
声卡
的机器上面要播放相关的文件而去安装类似
声卡
的一种软件,虚拟
声卡
就是这种软件,安装之后,...
基于Labview的计算机
声卡
声音
信号
的
采集
系统设计
基于Labview的计算机
声卡
声音
信号
的
采集
系统设计
windows10怎么卸载计算机,Win10怎么卸载
声卡
驱动?电脑
声卡
驱动怎么卸载?
Win10怎么卸载
声卡
驱动?为什么要卸载
声卡
呢?为了更好的安装下
一个
声卡
设备或者
声卡
有问题,需要重新安装
声卡
,都是需要卸载
声卡
驱动的,但就换
声卡
设备,如果有专业级的
声卡
需要安装,卸载原由
声卡
驱动是正确的。Win10怎么卸载
声卡
驱动方法一:1、将鼠标移到屏幕左下角点击右键或者同时按下Windows徽标键+X键,调出超级菜单,点击“程序和功能”;2、选择需要卸载的驱动程序,在“Realtek High...
虚拟服务器
声卡
,如何使用虚拟
声卡
?虚拟
声卡
安装教程!
在没有
声卡
的机器上播放音频和视频文件时,将出现诸如“找不到音频设备”的提示,并且无法播放. 虚拟
声卡
是一种软件的名称,可用于在没有
声卡
的机器上实现诸如声音回放之类的功能. 如何使用虚拟
声卡
?我需要设置虚拟
声卡
吗?以下是详细的介绍.【虚拟
声卡
】如何使用虚拟
声卡
?是否需要设置虚拟
声卡
什么是虚拟
声卡
虚拟
声卡
实际上是一种软件的名称,该软件可用于在没有
声卡
的机器上实现声音播放和其他功能. 众所周知,在没有声...
Delphi
5,939
社区成员
262,944
社区内容
发帖
与我相关
我的任务
Delphi
Delphi 开发及应用
复制链接
扫一扫
分享
社区描述
Delphi 开发及应用
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章