知识大全 在Delphi下用Direct Sound 实现混音器组件

Posted

篇首语:学在苦中求,艺在勤中练。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 在Delphi下用Direct Sound 实现混音器组件相关的知识,希望对你有一定的参考价值。

在Delphi下用Direct Sound 实现混音器组件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Direct X是微软公司提供给游戏编写人员的一套应用程序编程接口(APIs) 它为编写高效 实时的应用程序提供了有力的支持 因此 有必要将这个接口封装到Delphi的组件库中 Direct X SDK是面向Visual C/C++和Wat C/C++的 因而使用Object Pascal直接存取Direct X SDK 将带来诸多不便 但我们可先在VC下将Direct X接口封装成动态链接库 然后在Delphi下通过该动态链接库去存取Direct X

  本文介绍用Delphi封装Direct Sound的方法 这种方法同样也可以应用到Direct Draw(但建议不要使用独占模式 否则会带来不少问题)

  先简单介绍一下Direct Sound的接口界面 Direct Sound的基本对象有两个 即IDirectDraw和IDirectDrawBuffer 前者代表声卡 后者代表声音数据缓冲区

  IDirectDraw是整个Direct Sound的基础 其建立方法如下

  LPDIRECTSOUND lpDS;

  HRESULT ErrorCode;

  HWND hwnd=Mainhwnd;//窗口句柄

  ErrorCode=DirectSoundCreate(NULL &lpDS NULL); //建立对象

  if(ErrorCode!=DS_OK)return FALSE; //失败则返回

   ErrorCode=lpDS >SetCooperativeLevel(hwnd DSSCL_NORMAL);//设置存取模式

  if(ErrorCode!=DS_OK) //失败则返回

  

   lpDS >Release();

   lpDS=NULL;

   return FALSE;

  

  IDirectDrawBuffer通过IDirectDraw建立 IDirectDrawBuffer有两种基本类型 一种被称作 基本缓冲区 (Primary Buffer) 另一种被称作 辅助缓冲区 (Secondary Buffer) 基本缓冲区是Direct Sound 混音的基础 一般不直接存取这个缓冲区(虽然也可以) 但可以通过该缓冲区去存取初始化声卡 方法如下

  HRESULT ErrorCode;

  LPDIRECTSOUND lpDS=lpMainDS;//Direct Sound对象

  LPDIRECTSOUNDBUFFER lpDBP;

  DSBUFFERDESC dsbds;

  ZeroMemory(&dsbds sizeof(dsbds));

  dsbds dwSize=sizeof(dsbds);

  dsbds dwFlags=DSBCAPS_PRIMARYBUFFER;

  ErrorCode=lpDS >CreateSoundBuffer(&dsbds &lpDBP NULL);//建立基本缓冲区

  if(ErrorCode!=DS_OK)return FALSE;//失败则返回

   ErrorCode=lpDBP >Play( DSBPLAY_LOOPING);//初始化

  if(ErrorCode!=DS_OK)//失败则返回

  

   lpDBP >Release();

   lpDBP=NULL;

   lpDS >Release();

   lpDS=NULL;

   return FALSE;

  

  lpDBP >Release();//释放基本缓冲区

  return TRUE; //初始化成功

  辅助缓冲区可以建立任意多个 声音数据就放在这种缓冲区内 每个缓冲区可被独立播放(IDirectSoundBuffer::Play) Direct Sound会处理这些声音并实现混音的效果 其建立方法与基本缓冲区的差不多 只是对DSBUFFERDESC的填写有些不一样

  ZeroMemory(&dsbufferdesc sizeof(dsbufferdesc));

  dsbufferdesc dwSize=sizeof(dsbufferdesc);

  dsbufferdesc dwFlags=DSBCAPS_STATIC|DSBCAPS_CTRLDEFAULT;

  dsbufferdesc dwBufferBytes=BufferSize;//缓冲区大小

  dsbufferdesc lpwfxFormat=(LPWAVEFORMATEX)&pcmformat;//wav文件的PCM格式

  ErrorCode=lpDS >CreateSoundBuffer(&dsbd &lpSB NULL);

  建立该缓冲区后 通过IDirectSoundBuffer::Lock锁定内存即可写入数据 数据可以用普通MCI的多媒体函数读取 由于篇幅所限 这里不再详述 读者可以参考Win SDK手册和Direct X SDK的联机帮助 值得注意的是 Direct Sound的缓冲区是循环的 Lock返回两个指针 数据必须分成两部分写入

  数据进入DirectSoundBuffer后 就可以调用IDirectSoundBuffer的声音控制方法来控制声音的播放 停止 频率 声道等特性 但要注意的是 因为Win 是多任务的 设备有可能被别的程序占用 所以IDirectSoundBuffer的功能调用可能会引发DSERR_BUFFERLOST错误 此时 如果要确保你的请求一定会得到响应 则必须调用IDirectSoundBuffer::Restore以重新获得设备

  掌握了这些基本概念后 就可以在C++中编写Direct Sound的控制程序了 但Delphi无法直接存取上面提及的数据结构 为了解决这个问题 我们可以定义一个数组 分别代表不同的辅助缓冲区 Dephi通过该数组的索引来使用多个缓冲区 因此 我们的DLL中至少包括以下的接口函数

  CreateDSoundInterface(HWND hwnd)//初始化

  LoadWave(int index char *filename)//装入wav数据

  Play(int Index) //播放

  Stop(int Index)//停止

  Clear(int Index)//释放缓冲区

  当然 还可以加入其它控制 例如对频率 声道等的控制

  有了动态链接库后 在Delphi中编写混音器组件的方法就比较简单了 与其它组件基本上没什么区别

  首先 新建一个组件(New Component) 设定其祖先类型为TComponent 然后 编写相应的方法初始化设备 实现DLL中提供的功能 这里只作两点说明

   不要在继承的Create函数中加载DLL和初始化设备 不在构造方法中初始化设备是明智的做法 因为这样做较安全

   因为DLL是用C编写的 所以接口函数说明必须是C的调用标准 例如可以像下面这个样子

  Var

   DllFunction :

  function(Parametre : ParaType) : RusultType; cdecl;

  

  LibraryHandle=LoadLibrary( DllFile dll );

  

  @DllFunction:=GetProcAddress(LibHandle DllFunction_Name );

  组件单元编好以后 可通过选择Component|Install Component菜单来将组件装入Delphi的组件库即可使用它

cha138/Article/program/Delphi/201311/24919

相关参考

适用中高浓度有机废水的BIO-SOUND技术

中高浓度废水的处理在国内还未有完全成熟的范例,桑德集团综合多年设计、施工经验,分析比较各种工艺特点的基础上开发出新型生物处理技术----BIO-SOUND技术。BIO-SOUND生物处理系统包括BIO

适用中高浓度有机废水的BIO-SOUND技术

中高浓度废水的处理在国内还未有完全成熟的范例,桑德集团综合多年设计、施工经验,分析比较各种工艺特点的基础上开发出新型生物处理技术----BIO-SOUND技术。BIO-SOUND生物处理系统包括BIO

知识大全 使用直接模式direct=y导出数据比传统方式

  最近发现使用直接导出模式direct=yexp比传统模式导出快很多而且似乎也不会遇见什么bug(至今没有遇见过)  oracle提供种模式导出表数据传统模式CONVENTIONALPATH和直接模

知识大全 DWR - Direct Web Remoting 实际使用

DWR-DirectWebRemoting实际使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 VC.NET的Direct3D极速入门宝典

VC.NET的Direct3D极速入门宝典  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  听说D

知识大全 C#+Direct3D9.0开发实例之月亮绕着地球转

C#+Direct3D9.0开发实例之月亮绕着地球转  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

DMA方式,即直接存储器访问(Direct Memory Access)方式。这种方式中()

DMA方式,即直接存储器访问(DirectMemoryAccess)方式。这种方式中()A、数据在外部设备和主存储器间通过总线直接传送,不需CPU干预。B、CPU控制在外部设备和主存储器间的数据传送。

DMA方式,即直接存储器访问(Direct Memory Access)方式。这种方式中()

DMA方式,即直接存储器访问(DirectMemoryAccess)方式。这种方式中()A、数据在外部设备和主存储器间通过总线直接传送,不需CPU干预。B、CPU控制在外部设备和主存储器间的数据传送。

知识大全 在C#下用Microsoft Agent创建超酷语言精灵

在C#下用MicrosoftAgent创建超酷语言精灵  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 c#中什么情况下用Convert.ToInt32?

c#中什么情况下用Convert.ToInt32?  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&