DSP

DirectSound学习笔记之 枚举音频设备

2019-07-13 20:23发布

       DirectX是微软的一个在多媒体处理方面的SDK开发库,功能很强大,近来由于需要做音频的采集与播放的一些个东西,所以也正开始学习DirectSound的一些功能。记录下来,给自己留个纪念,同时在写博文的过程中对其进一步熟悉。        今天就开始,咱的第一步:        首先,咱需要选择一个开发库。在Delphi下有好几个版本的库吧,有JEDI的DirectX库,DsPack中也带有一个DirectX库,还有DelphiX,具体的需要,就要看各位自己所好了,我这里选择的是Dspack中的开发库。        在应用程序中,如果用户使用默认的输出设备来输出声音,那么咱就没有必要来枚举所有的输出设备了。但是,当应用程序并不支持所有的输出设备,或者程序中需要两个或多个设备的时候或需要用户自己来选择设备的时候,咱就要枚举各个设备了。        枚举设备,首先,需要定义一个回调函数,该回调函数可以被系统中的每个设备来调用,该函数的命名没有限制,但是函数的声明方式必须是DSEnumCallBack为原型,该类型的样式在Delphi中为: DelphiCode: function DsEnumProc(lpGuid: PGUID; lpcstrDescription, lpcstrModule: PAnsiChar; lpContext: Pointer): BOOL;stdcall;     该函数被作为参数传递给枚举设备的函数 DirectSoundEnumerate,该函数的原型在Delphi中声明样式为: DelphiCode: function DirectSoundEnumerate(lpDSEnumCallback: TDSEnumCallback; lpContext: Pointer): HResult; stdcall; external DirectSoundDLL name 'DirectSoundEnumerateA';    第一个参数,TDSEnumCallBack就是上面给出的那个回调函数的样式了。第二个参数为任何一个你想要传入的东西的指针。 函数返回类型HResult,可以通过Succeeded来判断函数是否调用成功。    咱们在使用DirectSoundEnumerate函数的时候,可以想象该函数的实现方式,肯定是带有一个循环的,每枚举到一个设备的时候,会调用一次咱给的回调函数DsEnumCallBack,那么该回调函数在调用的过程中,如果该回调函数返回True,那么DirectSoundEnumerate就会继续下一次枚举,直到所有的设备都被枚举,函数返回,否则,只要咱给该回调函数返回False,那么DirectSoundEnumerate就不继续下一次枚举(不管设备是否全部枚举完成),而直接返回。     这里给一个枚举设备的例子,本例子中,将所有枚举到的设备都添加到Combobox中,将设备的GUID也保存在Combobox中,代码如下: DelphiCode: function DsEnumProc(lpGuid: PGUID; lpcstrDescription, lpcstrModule: PAnsiChar;lpContext: Pointer): BOOL;stdcall; var tempGuid: PGUID; begin Result := True; if lpGuid <> nil then begin tempGuid := GetMemory(SizeOf(TGUID)); if tempGuid = nil then begin Result := true; exit; end; CopyMemory(tempGuid,lpGuid,SizeOf(TGuid)); //这里的lpContext就是咱在DirectSoundEnumerate函数中传递的Combobox,所以直接转化就好了 TComboBox(lpContext).Items.AddObject(string(lpcstrDescription),TObject(tempGuid)); //不要主声音驱动程序 end; end; procedure TForm2.FormCreate(Sender: TObject); begin DirectSoundEnumerate(DsEnumProc,self.ComboBox1); end; 上面给讲的是枚举输出设备,自然DirectSound也提供枚举输入设备(录音设备)的,操作方式都一样,只是枚举函数名称不同而已,输出设备的枚举函数为: DirectSoundCaptureEnumerate 所以,枚举输入设备,咱们只用按照上面的代码将 DirectSoundEnumerate 换成DirectSoundCaptureEnumerate,其他不变,则可