音频处理:关于wavein和waveout的使用. 怎样用wavein和waveout分别指定不同的声卡呀?我现在要用wavein指定到一个固定的虚拟声卡去,用waveout指定到真实声卡,请问怎样寻找真实声卡?怎样指定真实声卡?还有如果系统默认声卡不是我的虚拟声卡我怎么更改默认为虚拟声卡呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 WaveIn(录音)WaveHdr.lpData Buffer size is Format.nAvgBytesPerSec;WaveOut(输出)那就想多大就多大,不超过内存即可。WaveOut:WaveOutOpen(FWaveID, 0, @FFormat, Handle, 0, CALLBACK_WINDOW or WAVE_MAPPED); //用这个Flag//对应的消息是:MM_WOM_DONE//procedure WaveOutCallback(var msg: TMessage); message MM_WOM_DONE;procedure TWaveOut.WaveOutCallback(var msg: TMessage);var Header: PWaveHdr;begin Header := PWaveHdr(msg.LParam); try if FActive then begin WaveOutUnPrepareHeader(FWaveID^, Header, SizeOf(TWaveHdr)); //再继续输出,就是增加输出Buffer AutoPlayBuffer; end; finally DeleteBuffer(Header); //删除/Free指针 end;end;还有错误处理,只要调用对应的GetErrorText即可,不要用上面的raiseException(ErrorCode)函数了。function GetLen(S: string): Integer;var Len: Integer;begin Result := 1; Len := Length(S); while not (S[Result] = #0) and (Result < Len) do Inc(Result);end;procedure TWaveOut.CheckError(Res: Integer);var S: string;begin if Res <> 0 then begin SetLength(S, MAXERRORLENGTH); waveOutGetErrorText(Res, PChar(S), MAXERRORLENGTH); //waveInGetErrorText(Res, PChar(S), MAXERRORLENGTH); SetLength(msg, GetLen(msg)); raise EWaveException.Create(msg); end;end;Wave一般操作是:New(WaveID); //var WaveID: PInteger;WaveInOpen/WaveOutOpen打开这个WaveID,并为它提供消息回调之后WaveIn: 在回调函数中,进行录音数据处理(数据在消息的LParam, WParam中),因为在作存数据(Buffer),所以要增加一定的Buffer给它,waveInPrepareHeader-->waveInAddBuffer然后就可能WaveInStart了。WaveOut简单,打开后就直接WaveOutPrepareHeader-->WaveOutWrite http://search.csdn.net/Expert/topic/952/952985.xml?temp=.8836176 多谢各位!我知道waveinopen和waveoutopen的用法,但是我一般都只用于打开系统默认的设备。现在我就是要用他打开非默认的设备,例如,我现在机上装了两个虚拟声卡,一个真实声卡,所以在我机器的默认播放和录音设备就有三个,我现在要用waveinopen指向三个中的一个,waveoutopen指向另外一个,请问这样该怎么作? MMRESULT waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen );MMRESULT waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen );第二个参数就是指定设备ID的,0,1,2.... 到MSDN上去查帮助,一定可以找到绑定指定设备的API函数 看看这个函数的用法waveInGetNumDevs 多谢flyforlove(为情飞),我知道waveInOpen和waveoutopen的第二个参数是设备的ID号,问题是我怎么知道我要的设备的ID号是多少呢?设备号的排列应该是按照名称排的吧,那么我装的虚拟声卡可能是设备1,也有可能是设备2呀,怎么知道这个设备的名称呀?多谢了!waveInGetNumDevs只是得到当前设备数,无法得到当前设备的名称。 使用UINT waveInGetNumDevs(VOID);得到输入设备数目,然后使用MMRESULT waveInGetDevCaps( UINT uDeviceID, LPWAVEINCAPS pwic, UINT cbwic );得到一个WAVEINCAPS结构体变量的值。typedef struct { WORD wMid; WORD wPid; MMVERSION vDriverVersion; CHAR szPname[MAXPNAMELEN]; //这个是产品名称。 DWORD dwFormats; WORD wChannels; WORD wReserved1; } WAVEINCAPS; flyforlove(为情飞) ,多谢你关注此贴我现在用if (waveInOpen (&hwi, WAVE_MAPPER, &waveformat, (DWORD)handle, 0, CALLBACK_WINDOW) != MMSYSERR_NOERROR)打开默认录音设备,用if (waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS))!= MMSYSERR_NOERROR),怎么得到的pwic.szPname是:微软 声音映射器。怎么会这样呀,我要确认的是当前系统默认录音设备是否是我需要用的声卡驱动,得到这样的字符串我就无法确认了。再次麻烦你了 if (waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS))!= MMSYSERR_NOERROR)不要使用WAVE_MAPPER,看看名字就知道这是个映射器,既然你要指定具体的输入设备,这个参数就要使用具体的ID号,先用waveInGetNumDevs得到播放器的数目,然后ID号的指定是从0开始,依次递增。比如你有三个输入设备,那么ID号就是0,1,2 首先确定你要使用哪一个输入设备(根据名字判断),输入设备的名称和设备ID号是对应的,这样以后操作就一直都用这个ID号就可以了。我不知道你想要得是什么功能。获得硬件信息,好像MMSDK中没有提供这些函数,得通过其他途径,对这方面我没有研究过。 我要实现的功能是这样的,我要将系统播放出来的声音数据保存下来,我作了一个虚拟声卡,如果将系统默认播放和录音设备改为我作的这个虚拟声卡,那么我通过waveinopen打开这个设备就可以得到系统播放的声音数据。如果系统默认的录音和播放设备不是我作的这个设备,那么我就无法得到这些数据了,所以我必须判断系统默认的录放音设备是否是我作的这个虚拟声卡设备。我现在只知道用if (waveInOpen (&hwi, WAVE_MAPPER, &waveformat, (DWORD)handle, 0, CALLBACK_WINDOW) != MMSYSERR_NOERROR)来打开默认设备,但是这样用waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS)就返回不了当前设备名称,请问怎么解决?输入设备的名称好像是按名称排列的,对应的ID就是排列顺序,那么不同机器中同一个设备的ID可能不同,一直用这个ID号好像行不通吧。 我的意思是说,你想要使用的设备名称应该是已知的,既然这样在程序使用设备之前,就可以查找这个设备所对应的ID(不是让你在一台机子上得到一个ID后就在所有机子上都使用这个ID,这显然是行不通的。)。对于你想纪录声音数据,我想使用WAVE_MAPPER不是总能行得通的,比如说winamp吧,他是可以指定输出设备的,并不一定是用的默认输出设备,如果你想录音的话,就要手工指定你的虚拟声卡作为输出设备。但是显然你很难用程序操控所有的播放软件都指定到你的虚拟声卡上。 首选设备是保存在注册表的HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper位置,你可以通过查询注册表的形式来判断系统的首选设备到底是不是你的虚拟声卡,对于更改这个设备,当然也可以通过更改这个注册表的数据来更改,但是更改以后能不能立即生效,因为没有做过这方面的东西,所以不知道,也许像更改默认打印机一样要广播一个消息。可以提示对话框,让用户自己去更改默认设备。 如何将韩文转换成unicode码? 80分,哪位帮忙解释几行代码? 如何强制关闭\重起串口服务 显示器上一毫米的长度转化为像素点数 想问一下,如果用update语句会不会把以前的记录覆盖? 问一下‘流’和Tlist的问题,谢谢! 如何 在 我的程序中打开 一个 .exe 文件! 怎样改变dbgrid当前光棒颜色? 如何利用filter属性进行模糊过滤? 谁能知道李维先生的电子邮箱地址或其他联系方法? dbExpress的几个简单问题 求助一个关于求平均分的程序?
WaveOut(输出)那就想多大就多大,不超过内存即可。WaveOut:WaveOutOpen(FWaveID, 0, @FFormat, Handle, 0, CALLBACK_WINDOW or WAVE_MAPPED); //用这个Flag//对应的消息是:MM_WOM_DONE
//procedure WaveOutCallback(var msg: TMessage); message MM_WOM_DONE;
procedure TWaveOut.WaveOutCallback(var msg: TMessage);
var
Header: PWaveHdr;
begin
Header := PWaveHdr(msg.LParam);
try
if FActive then
begin
WaveOutUnPrepareHeader(FWaveID^, Header, SizeOf(TWaveHdr));
//再继续输出,就是增加输出Buffer
AutoPlayBuffer;
end;
finally
DeleteBuffer(Header); //删除/Free指针
end;
end;还有错误处理,只要调用对应的GetErrorText即可,不要用上面的raiseException(ErrorCode)函数了。function GetLen(S: string): Integer;
var
Len: Integer;
begin
Result := 1;
Len := Length(S);
while not (S[Result] = #0) and (Result < Len) do Inc(Result);
end;procedure TWaveOut.CheckError(Res: Integer);
var
S: string;
begin
if Res <> 0 then
begin
SetLength(S, MAXERRORLENGTH);
waveOutGetErrorText(Res, PChar(S), MAXERRORLENGTH);
//waveInGetErrorText(Res, PChar(S), MAXERRORLENGTH);
SetLength(msg, GetLen(msg));
raise EWaveException.Create(msg);
end;
end;Wave一般操作是:
New(WaveID); //var WaveID: PInteger;
WaveInOpen/WaveOutOpen打开这个WaveID,并为它提供消息回调
之后
WaveIn: 在回调函数中,进行录音数据处理(数据在消息的LParam, WParam中)
,因为在作存数据(Buffer),所以要增加一定的Buffer给它,waveInPrepareHeader-->waveInAddBuffer
然后就可能WaveInStart了。WaveOut简单,打开后就直接WaveOutPrepareHeader-->WaveOutWrite
UINT uDeviceID,
LPWAVEFORMATEX pwfx,
DWORD dwCallback,
DWORD dwCallbackInstance,
DWORD fdwOpen
);MMRESULT waveOutOpen( LPHWAVEOUT phwo,
UINT uDeviceID,
LPWAVEFORMATEX pwfx,
DWORD dwCallback,
DWORD dwCallbackInstance,
DWORD fdwOpen
);第二个参数就是指定设备ID的,0,1,2....
waveInGetNumDevs
得到输入设备数目,然后使用
MMRESULT waveInGetDevCaps(
UINT uDeviceID,
LPWAVEINCAPS pwic,
UINT cbwic
);得到一个WAVEINCAPS结构体变量的值。
typedef struct {
WORD wMid;
WORD wPid;
MMVERSION vDriverVersion;
CHAR szPname[MAXPNAMELEN]; //这个是产品名称。
DWORD dwFormats;
WORD wChannels;
WORD wReserved1;
} WAVEINCAPS;
(DWORD)handle, 0, CALLBACK_WINDOW) != MMSYSERR_NOERROR)
打开默认录音设备,用
if (waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS))!= MMSYSERR_NOERROR),怎么得到的pwic.szPname是:微软 声音映射器。怎么会这样呀,我要确认的是当前系统默认录音设备是否是我需要用的声卡驱动,得到这样的字符串我就无法确认了。再次麻烦你了
比如你有三个输入设备,那么ID号就是0,1,2
if (waveInOpen (&hwi, WAVE_MAPPER, &waveformat,
(DWORD)handle, 0, CALLBACK_WINDOW) != MMSYSERR_NOERROR)
来打开默认设备,但是这样用
waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS)就返回不了当前设备名称,请问怎么解决?输入设备的名称好像是按名称排列的,对应的ID就是排列顺序,那么不同机器中同一个设备的ID可能不同,一直用这个ID号好像行不通吧。