怎样用wavein和waveout分别指定不同的声卡呀?我现在要用wavein指定到一个固定的虚拟声卡去,用waveout指定到真实声卡,请问怎样寻找真实声卡?怎样指定真实声卡?还有如果系统默认声卡不是我的虚拟声卡我怎么更改默认为虚拟声卡呢?

解决方案 »

  1.   

    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
      

  2.   

    http://search.csdn.net/Expert/topic/952/952985.xml?temp=.8836176
      

  3.   

    多谢各位!我知道waveinopen和waveoutopen的用法,但是我一般都只用于打开系统默认的设备。现在我就是要用他打开非默认的设备,例如,我现在机上装了两个虚拟声卡,一个真实声卡,所以在我机器的默认播放和录音设备就有三个,我现在要用waveinopen指向三个中的一个,waveoutopen指向另外一个,请问这样该怎么作?
      

  4.   

    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....
      

  5.   

    到MSDN上去查帮助,一定可以找到绑定指定设备的API函数
      

  6.   

    看看这个函数的用法
    waveInGetNumDevs
      

  7.   

    多谢flyforlove(为情飞),我知道waveInOpen和waveoutopen的第二个参数是设备的ID号,问题是我怎么知道我要的设备的ID号是多少呢?设备号的排列应该是按照名称排的吧,那么我装的虚拟声卡可能是设备1,也有可能是设备2呀,怎么知道这个设备的名称呀?多谢了!waveInGetNumDevs只是得到当前设备数,无法得到当前设备的名称。
      

  8.   

    使用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; 
      

  9.   

    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是:微软 声音映射器。怎么会这样呀,我要确认的是当前系统默认录音设备是否是我需要用的声卡驱动,得到这样的字符串我就无法确认了。再次麻烦你了
      

  10.   

    if (waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS))!= MMSYSERR_NOERROR)不要使用WAVE_MAPPER,看看名字就知道这是个映射器,既然你要指定具体的输入设备,这个参数就要使用具体的ID号,先用waveInGetNumDevs得到播放器的数目,然后ID号的指定是从0开始,依次递增。
    比如你有三个输入设备,那么ID号就是0,1,2
      

  11.   

    首先确定你要使用哪一个输入设备(根据名字判断),输入设备的名称和设备ID号是对应的,这样以后操作就一直都用这个ID号就可以了。我不知道你想要得是什么功能。获得硬件信息,好像MMSDK中没有提供这些函数,得通过其他途径,对这方面我没有研究过。
      

  12.   

    我要实现的功能是这样的,我要将系统播放出来的声音数据保存下来,我作了一个虚拟声卡,如果将系统默认播放和录音设备改为我作的这个虚拟声卡,那么我通过waveinopen打开这个设备就可以得到系统播放的声音数据。如果系统默认的录音和播放设备不是我作的这个设备,那么我就无法得到这些数据了,所以我必须判断系统默认的录放音设备是否是我作的这个虚拟声卡设备。我现在只知道用
    if (waveInOpen (&hwi, WAVE_MAPPER, &waveformat,
              (DWORD)handle, 0, CALLBACK_WINDOW) != MMSYSERR_NOERROR)
    来打开默认设备,但是这样用
    waveInGetDevCaps(WAVE_MAPPER,&pwic,sizeof(WAVEINCAPS)就返回不了当前设备名称,请问怎么解决?输入设备的名称好像是按名称排列的,对应的ID就是排列顺序,那么不同机器中同一个设备的ID可能不同,一直用这个ID号好像行不通吧。
      

  13.   

    我的意思是说,你想要使用的设备名称应该是已知的,既然这样在程序使用设备之前,就可以查找这个设备所对应的ID(不是让你在一台机子上得到一个ID后就在所有机子上都使用这个ID,这显然是行不通的。)。对于你想纪录声音数据,我想使用WAVE_MAPPER不是总能行得通的,比如说winamp吧,他是可以指定输出设备的,并不一定是用的默认输出设备,如果你想录音的话,就要手工指定你的虚拟声卡作为输出设备。但是显然你很难用程序操控所有的播放软件都指定到你的虚拟声卡上。
      

  14.   

    首选设备是保存在注册表的HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper位置,你可以通过查询注册表的形式来判断系统的首选设备到底是不是你的虚拟声卡,对于更改这个设备,当然也可以通过更改这个注册表的数据来更改,但是更改以后能不能立即生效,因为没有做过这方面的东西,所以不知道,也许像更改默认打印机一样要广播一个消息。可以提示对话框,让用户自己去更改默认设备。