熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

在Delphi下用Direct Sound 實現混音器組件

2013-11-23 17:42:15  來源: Delphi編程 

  Direct X是微軟公司提供給游戲編寫人員的一套應用程序編程接口(APIs)它為編寫高效實時的應用程序提供了有力的支持因此有必要將這個接口封裝到Delphi的組件庫中Direct X SDK是面向Visual C/C++和Watcom 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(&dsbdssizeof(dsbds));

  dsbdsdwSize=sizeof(dsbds);

  dsbdsdwFlags=DSBCAPS_PRIMARYBUFFER;

  ErrorCode=lpDS>CreateSoundBuffer(&dsbds&lpDBPNULL);//建立基本緩沖區

  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(&dsbufferdescsizeof(dsbufferdesc));

  dsbufferdescdwSize=sizeof(dsbufferdesc);

  dsbufferdescdwFlags=DSBCAPS_STATIC|DSBCAPS_CTRLDEFAULT;

  dsbufferdescdwBufferBytes=BufferSize;//緩沖區大小

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

  ErrorCode=lpDS>CreateSoundBuffer(&dsbd&lpSBNULL);

  建立該緩沖區後通過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(DllFiledll);

  

  @DllFunction:=GetProcAddress(LibHandleDllFunction_Name);

  組件單元編好以後可通過選擇Component|Install Component菜單來將組件裝入Delphi的組件庫即可使用它

  本文所介紹的程序在Visual C++ Delphi Direct X SDK下通過但程序功能只需VC Delphi Direct X (Visual C 內置Direct X SDK)支持即可若要確保程序能夠正常運行則必須在Win下安裝Direct X並將DLL文件放到\Windows\System目錄下


From:http://tw.wingwit.com/Article/program/Delphi/201311/24919.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.